From owner-svn-src-stable-7@FreeBSD.ORG Sat Aug 21 19:09:34 2010 Return-Path: Delivered-To: svn-src-stable-7@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 81F0B10656A3; Sat, 21 Aug 2010 19:09:34 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 706EE8FC08; Sat, 21 Aug 2010 19:09:34 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o7LJ9Ys1078660; Sat, 21 Aug 2010 19:09:34 GMT (envelope-from avg@svn.freebsd.org) Received: (from avg@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o7LJ9Yvm078657; Sat, 21 Aug 2010 19:09:34 GMT (envelope-from avg@svn.freebsd.org) Message-Id: <201008211909.o7LJ9Yvm078657@svn.freebsd.org> From: Andriy Gapon Date: Sat, 21 Aug 2010 19:09:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r211590 - stable/7/cddl/contrib/opensolaris/lib/libdtrace/common X-BeenThere: svn-src-stable-7@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 7-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 21 Aug 2010 19:09:34 -0000 Author: avg Date: Sat Aug 21 19:09:34 2010 New Revision: 211590 URL: http://svn.freebsd.org/changeset/base/211590 Log: MFC r210425: dtrace: correctly map sections to addresses in elf object modules (amd64) Modified: stable/7/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h stable/7/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c Directory Properties: stable/7/cddl/contrib/opensolaris/ (props changed) Modified: stable/7/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h ============================================================================== --- stable/7/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h Sat Aug 21 19:02:49 2010 (r211589) +++ stable/7/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h Sat Aug 21 19:09:34 2010 (r211590) @@ -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/7/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c ============================================================================== --- stable/7/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c Sat Aug 21 19:02:49 2010 (r211589) +++ stable/7/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c Sat Aug 21 19:09:34 2010 (r211590) @@ -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