This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
sigsegv dereferencing l_addr in link_map
- From: Carlo Kok <ck at remobjects dot com>
- To: libc-help at sourceware dot org
- Date: Sun, 12 Jun 2016 00:12:32 +0200
- Subject: sigsegv dereferencing l_addr in link_map
- Authentication-results: sourceware.org; auth=none
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;
}