sigsegv dereferencing l_addr in link_map

Carlo Kok ck@remobjects.com
Sat Jun 11 22:09:00 GMT 2016


On some (ubuntu 14.04.4, libc 2.19-0ubuntu6.9) systems I'm getting a 
sigsegv when casting the link_map's l_addr to Elf64_Ehdr. This is 
something libgc does and works fine on most linux systems, but not all.

What am I missing here, and if this isn't guaranteed to work, how else 
can I get all the loaded data segments.

Code like this shows it:

#include <link.h>
#include <stdio.h>

# pragma weak _DYNAMIC
extern Elf64_Dyn _DYNAMIC[];

int main() {
   int tag;
   Elf64_Dyn* dp;
   struct link_map* cachedResult;
   for( dp = _DYNAMIC; (tag = dp->d_tag) != 0; dp++ ) {
     if( tag == DT_DEBUG ) {
        struct link_map *lm = ((struct r_debug 
*)(dp->d_un.d_ptr))->r_map;
        if( lm != 0 ) cachedResult = lm->l_next; /* might be NULL */
           break;
      }
   }
   printf("%p cached result; %p dyn \n", cachedResult, dp->d_un.d_ptr);
   while(cachedResult) {
     printf("%p %p %s\n", cachedResult->l_addr, cachedResult->l_ld, 
cachedResult->l_name);
         Elf64_Ehdr* e = (Elf64_Ehdr *)cachedResult->l_addr;
         printf("machine: %d\n", e->e_machine); // CRASH here, first 
iteration.

     cachedResult = cachedResult->l_next;
   }
   return 0;
}



More information about the Libc-help mailing list