Search code examples
linuxrpath

Is there a programmatic way to inspect the current rpath on Linux?


I'm aware that it is possible to use readelf -d <elf> | grep RPATH to inspect a given binary from the shell, but is it possible to do this within a process?

Something like (my completely made up system call):

  /* get a copy of current rpath into buffer */
  sys_get_current_rpath(&buffer);

I'm trying to diagnose some suspect SO linking issues in our codebase, and would like to inspect the RPATH this way if possible (I'd rather not have to spawn an external script).


Solution

  • The question is specifically about RPATH, but modern linkers use RUNPATH instead. See this answer -- there is a subtle semantic difference between the two.

    The answer is updated to print either.

    #include <assert.h>
    #include <stdio.h>
    #include <elf.h>
    #include <link.h>
    
    int main()
    {
      const ElfW(Dyn) *dyn = _DYNAMIC;
      const ElfW(Dyn) *rpath = NULL;
      const ElfW(Dyn) *runpath = NULL;
      const char *strtab = NULL;
      for (; dyn->d_tag != DT_NULL; ++dyn) {
        if (dyn->d_tag == DT_RPATH) {
          rpath = dyn;
        } else if (dyn->d_tag == DT_RUNPATH) {
          runpath = dyn;
        } else if (dyn->d_tag == DT_STRTAB) {
          strtab = (const char *)dyn->d_un.d_val;
        }
      }
    
      assert(strtab != NULL);
    
      if (rpath != NULL) {
        printf("RPATH: %s\n", strtab + rpath->d_un.d_val);
      } else if (runpath != NULL) {
        printf("RUNPATH: %s\n", strtab + runpath->d_un.d_val);
      }
      return 0;
    }