Date: Sat, 21 Aug 2010 19:02:49 +0000 (UTC) From: Andriy Gapon <avg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r211589 - stable/8/cddl/contrib/opensolaris/lib/libdtrace/common Message-ID: <201008211902.o7LJ2n94078459@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avg Date: Sat Aug 21 19:02:49 2010 New Revision: 211589 URL: http://svn.freebsd.org/changeset/base/211589 Log: MFC r210425: dtrace: correctly map sections to addresses in elf object modules (amd64) Modified: stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c Directory Properties: stable/8/cddl/contrib/opensolaris/ (props changed) Modified: stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h ============================================================================== --- stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h Sat Aug 21 18:55:28 2010 (r211588) +++ stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h Sat Aug 21 19:02:49 2010 (r211589) @@ -137,6 +137,7 @@ typedef struct dt_module { dt_idhash_t *dm_extern; /* external symbol definitions */ #if !defined(sun) caddr_t dm_reloc_offset; /* Symbol relocation offset. */ + uintptr_t *dm_sec_offsets; #endif } dt_module_t; Modified: stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c ============================================================================== --- stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c Sat Aug 21 18:55:28 2010 (r211588) +++ stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c Sat Aug 21 19:02:49 2010 (r211589) @@ -83,6 +83,14 @@ dt_module_syminit32(dt_module_t *dmp) uint_t i, n = dmp->dm_nsymelems; uint_t asrsv = 0; +#if defined(__FreeBSD__) + GElf_Ehdr ehdr; + int is_elf_obj; + + gelf_getehdr(dmp->dm_elf, &ehdr); + is_elf_obj = (ehdr.e_type == ET_REL); +#endif + for (i = 0; i < n; i++, sym++) { const char *name = base + sym->st_name; uchar_t type = ELF32_ST_TYPE(sym->st_info); @@ -97,8 +105,12 @@ dt_module_syminit32(dt_module_t *dmp) (ELF32_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size)) { asrsv++; /* reserve space in the address map */ -#if !defined(sun) +#if defined(__FreeBSD__) sym->st_value += (Elf_Addr) dmp->dm_reloc_offset; + if (is_elf_obj && sym->st_shndx != SHN_UNDEF && + sym->st_shndx < ehdr.e_shnum) + sym->st_value += + dmp->dm_sec_offsets[sym->st_shndx]; #endif } @@ -117,6 +129,14 @@ dt_module_syminit64(dt_module_t *dmp) uint_t i, n = dmp->dm_nsymelems; uint_t asrsv = 0; +#if defined(__FreeBSD__) + GElf_Ehdr ehdr; + int is_elf_obj; + + gelf_getehdr(dmp->dm_elf, &ehdr); + is_elf_obj = (ehdr.e_type == ET_REL); +#endif + for (i = 0; i < n; i++, sym++) { const char *name = base + sym->st_name; uchar_t type = ELF64_ST_TYPE(sym->st_info); @@ -130,9 +150,12 @@ dt_module_syminit64(dt_module_t *dmp) if (sym->st_value != 0 && (ELF64_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size)) { asrsv++; /* reserve space in the address map */ - -#if !defined(sun) +#if defined(__FreeBSD__) sym->st_value += (Elf_Addr) dmp->dm_reloc_offset; + if (is_elf_obj && sym->st_shndx != SHN_UNDEF && + sym->st_shndx < ehdr.e_shnum) + sym->st_value += + dmp->dm_sec_offsets[sym->st_shndx]; #endif } @@ -722,7 +745,12 @@ dt_module_unload(dtrace_hdl_t *dtp, dt_m free(dmp->dm_asmap); dmp->dm_asmap = NULL; } - +#if defined(__FreeBSD__) + if (dmp->dm_sec_offsets != NULL) { + free(dmp->dm_sec_offsets); + dmp->dm_sec_offsets = NULL; + } +#endif dmp->dm_symfree = 0; dmp->dm_nsymbuckets = 0; dmp->dm_nsymelems = 0; @@ -846,9 +874,12 @@ dt_module_update(dtrace_hdl_t *dtp, stru (void) snprintf(fname, sizeof (fname), "%s/%s/object", OBJFS_ROOT, name); #else + GElf_Ehdr ehdr; GElf_Phdr ph; char name[MAXPATHLEN]; + uintptr_t mapbase, alignmask; int i = 0; + int is_elf_obj; (void) strlcpy(name, k_stat->name, sizeof(name)); (void) strlcpy(fname, k_stat->pathname, sizeof(fname)); @@ -893,7 +924,20 @@ dt_module_update(dtrace_hdl_t *dtp, stru dt_module_destroy(dtp, dmp); return; } - +#if defined(__FreeBSD__) + mapbase = (uintptr_t)k_stat->address; + gelf_getehdr(dmp->dm_elf, &ehdr); + is_elf_obj = (ehdr.e_type == ET_REL); + if (is_elf_obj) { + dmp->dm_sec_offsets = + malloc(ehdr.e_shnum * sizeof(*dmp->dm_sec_offsets)); + if (dmp->dm_sec_offsets == NULL) { + dt_dprintf("failed to allocate memory\n"); + dt_module_destroy(dtp, dmp); + return; + } + } +#endif /* * Iterate over the section headers locating various sections of * interest and use their attributes to flesh out the dt_module_t. @@ -902,7 +946,19 @@ dt_module_update(dtrace_hdl_t *dtp, stru if (gelf_getshdr(sp, &sh) == NULL || sh.sh_type == SHT_NULL || (s = elf_strptr(dmp->dm_elf, shstrs, sh.sh_name)) == NULL) continue; /* skip any malformed sections */ - +#if defined(__FreeBSD__) + if (sh.sh_size == 0) + continue; + if (is_elf_obj && (sh.sh_type == SHT_PROGBITS || + sh.sh_type == SHT_NOBITS)) { + alignmask = sh.sh_addralign - 1; + mapbase += alignmask; + mapbase &= ~alignmask; + sh.sh_addr = mapbase; + dmp->dm_sec_offsets[elf_ndxscn(sp)] = sh.sh_addr; + mapbase += sh.sh_size; + } +#endif if (strcmp(s, ".text") == 0) { dmp->dm_text_size = sh.sh_size; dmp->dm_text_va = sh.sh_addr; @@ -927,6 +983,13 @@ dt_module_update(dtrace_hdl_t *dtp, stru #if defined(sun) dmp->dm_modid = (int)OBJFS_MODID(st.st_ino); #else + /* + * Include .rodata and special sections into .text. + * This depends on default section layout produced by GNU ld + * for ELF objects and libraries: + * [Text][R/O data][R/W data][Dynamic][BSS][Non loadable] + */ + dmp->dm_text_size = dmp->dm_data_va - dmp->dm_text_va; #if defined(__i386__) /* * Find the first load section and figure out the relocation
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008211902.o7LJ2n94078459>