Mercurial > illumos > illumos-gate
changeset 3621:2cbc0f92c696
PSARC 2007/074 -L option for nm(1) to display SHT_SUNW_LDYNSYM symbols
6518322 Some ELF utilities need updating for .SUNW_ldynsym section
line wrap: on
line diff
--- a/usr/src/cmd/sgs/gprof/common/readelf.c Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/gprof/common/readelf.c Thu Feb 08 11:58:00 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -454,48 +453,75 @@ static void get_symtab(Elf *elf, mod_info_t *module) { - Elf_Scn *scn = NULL, *sym = NULL; + Elf_Scn *scn = NULL, *sym_pri = NULL, *sym_aux = NULL; GElf_Word strndx = 0; sztype nsyms, i; - Elf_Data *symdata; + Elf_Data *symdata_pri; + Elf_Data *symdata_aux; + GElf_Xword nsyms_pri, nsyms_aux = 0; nltype *etext = NULL; + nltype *l_nl, *l_npe; + sztype l_nname; + extern sztype total_names; + int symtab_found = 0; + - nltype *l_nl, *l_npe; - sztype l_nname; - extern sztype total_names; - - while ((scn = elf_nextscn(elf, scn)) != NULL) { + /* + * Scan the section headers looking for a symbol table. Our + * preference is to use .symtab, because it contains the full + * set of symbols. If we find it, we stop looking immediately + * and use it. In the absence of a .symtab section, we are + * willing to use the dynamic symbol table (.dynsym), possibly + * augmented by the .SUNW_ldynsym, which contains local symbols. + */ + while ((symtab_found == 0) && ((scn = elf_nextscn(elf, scn)) != NULL)) { GElf_Shdr shdr; if (gelf_getshdr(scn, &shdr) == NULL) continue; - if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) { - GElf_Xword chk = shdr.sh_size / shdr.sh_entsize; - - nsyms = (sztype)(shdr.sh_size / shdr.sh_entsize); - - if (chk != (GElf_Xword)nsyms) - fatal_error("32-bit gprof cannot handle" - "more than 2^32 symbols"); + switch (shdr.sh_type) { + case SHT_SYMTAB: + nsyms_pri = shdr.sh_size / shdr.sh_entsize; + strndx = shdr.sh_link; + sym_pri = scn; + /* Throw away .SUNW_ldynsym. It is for .dynsym only */ + nsyms_aux = 0; + sym_aux = NULL; + /* We have found the best symbol table. Stop looking */ + symtab_found = 1; + break; + case SHT_DYNSYM: + /* We will use .dynsym if no .symtab is found */ + nsyms_pri = shdr.sh_size / shdr.sh_entsize; strndx = shdr.sh_link; - sym = scn; - } + sym_pri = scn; + break; - /* - * If we've found a real symbol table, we're done. - */ - if (shdr.sh_type == SHT_SYMTAB) + case SHT_SUNW_LDYNSYM: + /* Auxiliary table, used with .dynsym */ + nsyms_aux = shdr.sh_size / shdr.sh_entsize; + sym_aux = scn; break; + } } - if (sym == NULL || strndx == 0) + if (sym_pri == NULL || strndx == 0) fatal_error("can't find symbol table.\n"); - if ((symdata = elf_getdata(scn, NULL)) == NULL) + nsyms = (sztype)(nsyms_pri + nsyms_aux); + if ((nsyms_pri + nsyms_aux) != (GElf_Xword)nsyms) + fatal_error( + "32-bit gprof cannot handle more than 2^32 symbols"); + + if ((symdata_pri = elf_getdata(sym_pri, NULL)) == NULL) fatal_error("can't read symbol data.\n"); + if ((sym_aux != NULL) && + ((symdata_aux = elf_getdata(sym_aux, NULL)) == NULL)) + fatal_error("can't read .SUNW_ldynsym symbol data.\n"); + if ((l_nl = l_npe = (nltype *)calloc(nsyms + PRF_SYMCNT, sizeof (nltype))) == NULL) fatal_error("cannot allocate symbol data.\n"); @@ -511,7 +537,16 @@ GElf_Sym gsym; char *name; - (void) gelf_getsym(symdata, i, &gsym); + /* + * Look up the symbol. In the case where we have a + * .SUNW_ldynsym/.dynsym pair, we treat them as a single + * logical table, with the data from .SUNW_ldynsym coming + * before the data in .dynsym. + */ + if (i >= nsyms_aux) + (void) gelf_getsym(symdata_pri, i - nsyms_aux, &gsym); + else + (void) gelf_getsym(symdata_aux, i, &gsym); name = elf_strptr(elf, strndx, gsym.st_name);
--- a/usr/src/cmd/sgs/lari/lari.pl Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/lari/lari.pl Thu Feb 08 11:58:00 2007 -0800 @@ -1385,7 +1385,8 @@ return; } - # Process elfdump(1) once more to obtain the .dynsym symbol table. + # Process elfdump(1) once more to obtain the .dynsym symbol table. We + # are only interested in global symbols, so .SUNW_ldynsym is not needed. open($FileHandle, "LC_ALL=C elfdump -sN.dynsym '$Obj' 2> /dev/null |"); while (defined(my $Line = <$FileHandle>)) {
--- a/usr/src/cmd/sgs/libelf/common/checksum.c Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/libelf/common/checksum.c Thu Feb 08 11:58:00 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -141,9 +140,17 @@ if ((shdr = elf64_getshdr(scn)) == 0) return (0); + /* Exclude strippable sections */ if (!(shdr->sh_flags & SHF_ALLOC)) continue; + /* + * Exclude allocable sections that can change: + * - The .dynsym section can contain section symbols + * that strip might remove. + * - The .dynamic section is modified by the setting of + * this checksum value. + */ if ((shdr->sh_type == SHT_DYNSYM) || (shdr->sh_type == SHT_DYNAMIC)) continue;
--- a/usr/src/cmd/sgs/libelf/common/decl.h Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/libelf/common/decl.h Thu Feb 08 11:58:00 2007 -0800 @@ -23,7 +23,7 @@ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -455,8 +455,8 @@ extern Okay _elf64_cookscn(Elf_Scn * s); extern Dnode *_elf_dnode(void); extern Elf_Data *_elf_locked_getdata(Elf_Scn *, Elf_Data *); -extern size_t _elf32_entsz(Elf32_Word, unsigned); -extern size_t _elf64_entsz(Elf64_Word, unsigned); +extern size_t _elf32_entsz(Elf *elf, Elf32_Word, unsigned); +extern size_t _elf64_entsz(Elf *elf, Elf64_Word, unsigned); extern Okay _elf_inmap(Elf *); extern char *_elf_outmap(int, size_t, unsigned *); extern size_t _elf_outsync(int, char *, size_t, unsigned);
--- a/usr/src/cmd/sgs/libelf/common/update.c Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/libelf/common/update.c Thu Feb 08 11:58:00 2007 -0800 @@ -24,7 +24,7 @@ * All Rights Reserved * * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -173,7 +173,7 @@ (void) _elfxx_cookscn(s); sh->sh_addralign = 1; - if ((sz = (Xword)_elf_entsz(sh->sh_type, ver)) != 0) + if ((sz = (Xword)_elf_entsz(elf, sh->sh_type, ver)) != 0) /* LINTED */ sh->sh_entsize = (Half)sz; sz = 0;
--- a/usr/src/cmd/sgs/libelf/common/xlate.m4 Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/libelf/common/xlate.m4 Thu Feb 08 11:58:00 2007 -0800 @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -689,18 +689,6 @@ size_t -_elf32_entsz(Elf32_Word shtype, unsigned ver) -{ - Elf_Type ttype; - - if (shtype >= sizeof (mtype[0]) / sizeof (mtype[0][0]) || - (ttype = mtype[ver - 1][shtype]) == ELF_T_BYTE) - return (0); - return (fmsize[ver - 1][ttype].s_filesz); -} - - -size_t elf32_fsize(Elf_Type type, size_t count, unsigned ver) { if (--ver >= EV_CURRENT) { @@ -731,6 +719,11 @@ return (mtype[ver - 1][shtype]); switch (shtype) { + case SHT_SUNW_symsort: + case SHT_SUNW_tlssort: + return (ELF_T_WORD); + case SHT_SUNW_LDYNSYM: + return (ELF_T_SYM); case SHT_SUNW_dof: return (ELF_T_BYTE); case SHT_SUNW_cap: @@ -794,6 +787,16 @@ } +size_t +_elf32_entsz(Elf *elf, Elf32_Word shtype, unsigned ver) +{ + Elf_Type ttype; + + ttype = _elf32_mtype(elf, shtype, ver); + return ((ttype == ELF_T_BYTE) ? 0 : fmsize[ver - 1][ttype].s_filesz); +} + + /* * XX64 This routine is also used to 'version' interactions with Elf64 * applications, but there's no way to figure out if the caller is
--- a/usr/src/cmd/sgs/libelf/common/xlate64.m4 Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/libelf/common/xlate64.m4 Thu Feb 08 11:58:00 2007 -0800 @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -740,18 +740,6 @@ size_t -_elf64_entsz(Elf64_Word shtype, unsigned ver) -{ - Elf_Type ttype; - - if (shtype >= sizeof (mtype[0]) / sizeof (mtype[0][0]) || - (ttype = mtype[ver - 1][shtype]) == ELF_T_BYTE) - return (0); - return (fmsize[ver - 1][ttype].s_filesz); -} - - -size_t elf64_fsize(Elf_Type type, size_t count, unsigned ver) { if (--ver >= EV_CURRENT) { @@ -783,6 +771,11 @@ return (mtype[ver - 1][shtype]); switch (shtype) { + case SHT_SUNW_symsort: + case SHT_SUNW_tlssort: + return (ELF_T_WORD); + case SHT_SUNW_LDYNSYM: + return (ELF_T_SYM); case SHT_SUNW_dof: return (ELF_T_BYTE); case SHT_SUNW_cap: @@ -841,6 +834,16 @@ } +size_t +_elf64_entsz(Elf *elf, Elf64_Word shtype, unsigned ver) +{ + Elf_Type ttype; + + ttype = _elf64_mtype(elf, shtype, ver); + return ((ttype == ELF_T_BYTE) ? 0 : fmsize[ver - 1][ttype].s_filesz); +} + + static Elf_Data * xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof) /* !0 -> xlatetof */
--- a/usr/src/cmd/sgs/libelf/demo/README Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/libelf/demo/README Thu Feb 08 11:58:00 2007 -0800 @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #pragma ident "%Z%%M% %I% %E% SMI" @@ -54,9 +53,9 @@ Demonstrates that libelf is MT-Hot and can be used in a threaded program. -dispsyms.c print symbols: scans a ELF file for either - a symbol table (either SHT_DYNSYM or SHT_SYMTAB) - and displays the symbol tables contents. +dispsyms.c print symbols: scans a ELF file for any symbol tables + (SHT_SYMTAB, SHT_DYNSYM, or SHT_SUNW_LDYNSYM) and + displays the symbol tables contents. Makefile make file to build the above programs.
--- a/usr/src/cmd/sgs/libelf/demo/dispsyms.c Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/libelf/demo/dispsyms.c Thu Feb 08 11:58:00 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -31,9 +30,8 @@ * This program demonstrates the use of the libelf interface to * read an ELF file. dispsyms will open an ELF file using * elf_begin(ELF_C_READ) and examine search the ELF file - * for either a SHT_SYMTAB or SHT_DYNSYM symbol table. - * If it finds either - it will display the contents of - * the symbol tables it finds. + * for a symbol table (SHT_SYMTAB, SHT_DYNSYM, or SHT_SUNW_LDYNSYM). + * It will display the contents of any symbol tables it finds. * * Note: This program also understands about the use * of 'Extended ELF Section indexes' and will @@ -106,7 +104,8 @@ return; } if ((shdr.sh_type != SHT_SYMTAB) && - (shdr.sh_type != SHT_DYNSYM)) + (shdr.sh_type != SHT_DYNSYM) && + (shdr.sh_type != SHT_SUNW_LDYNSYM)) continue; /*
--- a/usr/src/cmd/sgs/librtld_db/rdb_demo/common/maps.c Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/librtld_db/rdb_demo/common/maps.c Thu Feb 08 11:58:00 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -297,6 +296,7 @@ mp->mi_pltbase = 0; mp->mi_pltsize = 0; mp->mi_pltentsz = 0; + mp->mi_dynsym.st_symn = 0; while ((scn = elf_nextscn(mp->mi_elf, scn)) != 0) { GElf_Shdr shdr; Elf_Data * dp; @@ -311,16 +311,23 @@ switch (shdr.sh_type) { case SHT_DYNSYM: dp = elf_getdata(scn, 0); - mp->mi_dynsym.st_syms = dp; + mp->mi_dynsym.st_syms_pri = dp; tscn = elf_getscn(mp->mi_elf, shdr.sh_link); - mp->mi_dynsym.st_symn = + mp->mi_dynsym.st_symn += shdr.sh_size / shdr.sh_entsize; dp = elf_getdata(tscn, 0); mp->mi_dynsym.st_strs = (char *)dp->d_buf; break; + case SHT_SUNW_LDYNSYM: + dp = elf_getdata(scn, 0); + mp->mi_dynsym.st_syms_aux = dp; + mp->mi_dynsym.st_symn_aux = + shdr.sh_size / shdr.sh_entsize; + mp->mi_dynsym.st_symn += mp->mi_dynsym.st_symn_aux; + break; case SHT_SYMTAB: dp = elf_getdata(scn, 0); - mp->mi_symtab.st_syms = dp; + mp->mi_symtab.st_syms_pri = dp; tscn = elf_getscn(mp->mi_elf, shdr.sh_link); mp->mi_symtab.st_symn = shdr.sh_size / shdr.sh_entsize;
--- a/usr/src/cmd/sgs/librtld_db/rdb_demo/common/rdb.h Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/librtld_db/rdb_demo/common/rdb.h Thu Feb 08 11:58:00 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2000 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -72,28 +71,46 @@ RET_OK = 0 } retc_t; +/* + * sym_tbl_t contains a primary and an (optional) auxiliary symbol table, which + * we wish to treat as a single logical symbol table. In this logical table, + * the data from the auxiliary table preceeds that from the primary. Symbol + * indices start at [0], which is the first item in the auxiliary table + * if there is one. The sole purpose for this is so that we can treat the + * combination of .SUNW_ldynsym and .dynsym sections as a logically single + * entity without having to violate the public interface to libelf. + * + * Both tables must share the same string table section. + * + * The symtab_getsym() function serves as a gelf_getsym() replacement + * that is aware of the two tables and makes them look like a single table + * to the caller. + * + */ typedef struct sym_tbl { - Elf_Data * st_syms; /* start of table */ - char * st_strs; /* ptr to strings */ - size_t st_symn; /* number of entries */ + Elf_Data * st_syms_pri; /* start of primary table */ + Elf_Data * st_syms_aux; /* start of auxiliary table */ + char *st_strs; /* ptr to strings */ + size_t st_symn; /* Total # of entries in both tables */ + size_t st_symn_aux; /* # of entries in auxiliary table */ } sym_tbl_t; typedef struct map_info { - char * mi_name; /* file info */ - char * mi_refname; /* filter reference name */ + char *mi_name; /* file info */ + char *mi_refname; /* filter reference name */ ulong_t mi_addr; /* start address */ ulong_t mi_end; /* end address */ int mi_mapfd; /* file desc. for mapping */ unsigned mi_pltentsz; /* size of PLT entries */ - Elf * mi_elf; /* elf handle so we can close */ + Elf *mi_elf; /* elf handle so we can close */ GElf_Ehdr mi_ehdr; sym_tbl_t mi_symtab; /* symbol table */ sym_tbl_t mi_dynsym; /* dynamic symbol table */ Lmid_t mi_lmident; /* Link Map Ident */ ulong_t mi_pltbase; /* PLT base address */ ulong_t mi_pltsize; /* size of PLT table */ - struct map_info * mi_next; + struct map_info *mi_next; ulong_t mi_flags; /* misc flags */ rd_loadobj_t mi_loadobj; /* keep the old loadobj for */ /* good luck */ @@ -109,8 +126,8 @@ typedef struct map_list { - map_info_t * ml_head; - map_info_t * ml_tail; + map_info_t *ml_head; + map_info_t *ml_tail; } map_list_t; @@ -121,7 +138,7 @@ ulong_t bl_addr; /* address of breakpoint */ bptinstr_t bl_instr; /* original instruction */ unsigned bl_flags; /* break point flags */ - struct bpt_struct * bl_next; + struct bpt_struct *bl_next; } bptlist_t; #define FLG_BP_USERDEF 0x0001 /* user defined BP */ @@ -143,7 +160,7 @@ struct ps_prochandle { pid_t pp_pid; /* debug process pid */ - rd_agent_t * pp_rap; /* rtld_db handle */ + rd_agent_t *pp_rap; /* rtld_db handle */ int pp_ctlfd; /* open ctl proc fd */ int pp_statusfd; /* open status proc fd */ int pp_asfd; /* open as proc fd */ @@ -153,8 +170,8 @@ map_info_t pp_ldsomap; /* ld.so.1 map info */ map_info_t pp_execmap; /* exec map info */ map_list_t pp_lmaplist; /* list of link map infos */ - bptlist_t * pp_breakpoints; /* break point list */ - void * pp_auxvp; /* pointer to AUX vectors */ + bptlist_t *pp_breakpoints; /* break point list */ + void *pp_auxvp; /* pointer to AUX vectors */ int pp_flags; /* misc flags */ int pp_dmodel; /* data model */ }; @@ -196,10 +213,10 @@ /* * Functions */ -extern map_info_t * addr_to_map(struct ps_prochandle *, ulong_t); +extern map_info_t *addr_to_map(struct ps_prochandle *, ulong_t); extern retc_t addr_to_sym(struct ps_prochandle *, ulong_t, GElf_Sym *, char **); -extern void CallStack(struct ps_prochandle * ph); +extern void CallStack(struct ps_prochandle *ph); extern unsigned continue_to_break(struct ps_prochandle *); extern retc_t delete_all_breakpoints(struct ps_prochandle *); extern retc_t delete_breakpoint(struct ps_prochandle *, ulong_t, @@ -210,15 +227,15 @@ extern retc_t display_maps(struct ps_prochandle *); extern retc_t display_linkmaps(struct ps_prochandle *); extern void free_linkmaps(struct ps_prochandle *); -extern bptlist_t * find_bp(struct ps_prochandle * ph, ulong_t addr); +extern bptlist_t *find_bp(struct ps_prochandle *ph, ulong_t addr); extern retc_t get_linkmaps(struct ps_prochandle *); extern ulong_t hexstr_to_num(const char *); extern ulong_t is_plt(struct ps_prochandle *, ulong_t); extern void list_breakpoints(struct ps_prochandle *); extern retc_t load_map(struct ps_prochandle *, caddr_t, - map_info_t * mp); -extern char * print_address(unsigned long); -extern char * print_address_ps(struct ps_prochandle *, + map_info_t *mp); +extern char *print_address(unsigned long); +extern char *print_address_ps(struct ps_prochandle *, unsigned long, unsigned); extern void print_mem(struct ps_prochandle *, ulong_t, int, char *); @@ -239,7 +256,7 @@ extern void step_to_addr(struct ps_prochandle *, ulong_t); extern retc_t str_map_sym(const char *, map_info_t *, GElf_Sym *, char **); -extern map_info_t * str_to_map(struct ps_prochandle *, const char *); +extern map_info_t *str_to_map(struct ps_prochandle *, const char *); extern retc_t str_to_sym(struct ps_prochandle *, const char *, GElf_Sym *); extern int yyparse(void);
--- a/usr/src/cmd/sgs/librtld_db/rdb_demo/common/syms.c Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/librtld_db/rdb_demo/common/syms.c Thu Feb 08 11:58:00 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1996 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -31,17 +30,38 @@ #include "rdb.h" +/* + * Given a symbol index, look up the corresponding symbol from the + * given symbol table. + * + * This function allows the caller to treat the symbol table as a single + * logical entity even though there may be 2 actual ELF symbol tables + * involved. See the comments in Pcontrol.h for details. + */ +static GElf_Sym * +symtab_getsym(sym_tbl_t *symtab, int ndx, GElf_Sym *dst) +{ + /* If index is in range of primary symtab, look it up there */ + if (ndx >= symtab->st_symn_aux) { + return (gelf_getsym(symtab->st_syms_pri, + ndx - symtab->st_symn_aux, dst)); + } + + /* Not in primary: Look it up in the auxiliary symtab */ + return (gelf_getsym(symtab->st_syms_aux, ndx, dst)); +} + retc_t -str_map_sym(const char * symname, map_info_t * mp, GElf_Sym * symptr, - char ** str) +str_map_sym(const char *symname, map_info_t *mp, GElf_Sym *symptr, + char **str) { - sym_tbl_t * symp; - char * strs; + sym_tbl_t *symp; + char *strs; int i; - if (mp->mi_symtab.st_syms) + if (mp->mi_symtab.st_syms_pri) symp = &(mp->mi_symtab); - else if (mp->mi_dynsym.st_syms) + else if (mp->mi_dynsym.st_syms_pri) symp = &(mp->mi_dynsym); else return (RET_FAILED); @@ -51,8 +71,8 @@ for (i = 0; i < (int)symp->st_symn; i++) { GElf_Sym sym; - if (gelf_getsym(symp->st_syms, i, &sym) == 0) { - printf("gelf_getsym(): %s\n", elf_errmsg(-1)); + if (symtab_getsym(symp, i, &sym) == 0) { + printf("symtab_getsym(): %s\n", elf_errmsg(-1)); return (RET_FAILED); } @@ -105,13 +125,13 @@ retc_t -addr_map_sym(map_info_t * mp, ulong_t addr, GElf_Sym * symptr, - char ** str) +addr_map_sym(map_info_t *mp, ulong_t addr, GElf_Sym *symptr, + char **str) { - sym_tbl_t * symp; + sym_tbl_t *symp; GElf_Sym sym; - GElf_Sym * symr = 0; - GElf_Sym * lsymr = 0; + GElf_Sym *symr = 0; + GElf_Sym *lsymr = 0; GElf_Sym rsym; GElf_Sym lsym; ulong_t baseaddr = 0; @@ -120,9 +140,9 @@ if ((mp->mi_flags & FLG_MI_EXEC) == 0) baseaddr = (ulong_t)mp->mi_addr; - if (mp->mi_symtab.st_syms) + if (mp->mi_symtab.st_syms_pri) symp = &(mp->mi_symtab); - else if (mp->mi_dynsym.st_syms) + else if (mp->mi_dynsym.st_syms_pri) symp = &(mp->mi_dynsym); else return (RET_FAILED); @@ -134,8 +154,8 @@ for (i = 0; i < (int)symp->st_symn; i++) { ulong_t svalue; - if (gelf_getsym(symp->st_syms, i, &sym) == 0) { - printf("gelf_getsym(): %s\n", elf_errmsg(-1)); + if (symtab_getsym(symp, i, &sym) == 0) { + printf("symtab_getsym(): %s\n", elf_errmsg(-1)); return (RET_FAILED); } if ((sym.st_name == 0) || (sym.st_shndx == SHN_UNDEF)) @@ -191,10 +211,10 @@ retc_t -addr_to_sym(struct ps_prochandle * ph, ulong_t addr, - GElf_Sym * symp, char ** str) +addr_to_sym(struct ps_prochandle *ph, ulong_t addr, + GElf_Sym *symp, char **str) { - map_info_t * mip; + map_info_t *mip; if ((mip = addr_to_map(ph, addr)) == 0) return (RET_FAILED); @@ -204,10 +224,9 @@ retc_t -str_to_sym(struct ps_prochandle * ph, const char * name, - GElf_Sym * symp) +str_to_sym(struct ps_prochandle *ph, const char *name, GElf_Sym *symp) { - map_info_t * mip; + map_info_t *mip; if (ph->pp_lmaplist.ml_head == 0) { if (str_map_sym(name, &(ph->pp_ldsomap), symp, NULL) == RET_OK)
--- a/usr/src/cmd/sgs/mcs/common/file.c Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/mcs/common/file.c Thu Feb 08 11:58:00 2007 -0800 @@ -23,7 +23,7 @@ * Copyright (c) 1988 AT&T * All Rights Reserved * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -786,7 +786,13 @@ } *elf_data = *data; - /* SHT_{DYNSYM, SYMTAB} might need some change */ + /* + * SHT_{DYNSYM, SYMTAB} might need some change, as + * they may contain section symbols that reference + * removed sections. SHT_SUNW_LDYNSYM does not + * contain section symbols, and therefore does not + * have this issue. + */ if (((src_shdr.sh_type == SHT_SYMTAB) || (src_shdr.sh_type == SHT_DYNSYM)) && src_shdr.sh_entsize != 0 &&
--- a/usr/src/cmd/sgs/nm/common/nm.c Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/nm/common/nm.c Thu Feb 08 11:58:00 2007 -0800 @@ -24,7 +24,7 @@ * Copyright (c) 1989 AT&T * All Rights Reserved * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -78,7 +78,7 @@ #define REG_WEAK "R*" #define REG_LOCL "r" -#define OPTSTR ":APDoxhvnursplCVefgRTt:" /* option string for getopt() */ +#define OPTSTR ":APDoxhvnursplLCVefgRTt:" /* option string for getopt() */ #define DATESIZE 60 @@ -127,6 +127,7 @@ p_flag = 0, /* produce terse output */ P_flag = 0, /* Portable format output */ l_flag = 0, /* produce long listing of output */ + L_flag = 0, /* print SUNW_LDYNSYM instead of SYMTAB */ D_flag = 0, /* print DYNSYM instead of SYMTAB */ C_flag = 0, /* print decoded C++ names */ A_flag = 0, /* File name */ @@ -285,7 +286,17 @@ break; case 'l': l_flag = 1; break; - case 'D': D_flag = 1; + case 'L': if (D_flag == 1) { + (void) fprintf(stderr, gettext( + "nm: -D set. -L ignored\n")); + } else + L_flag = 1; + break; + case 'D': if (L_flag == 1) { + (void) fprintf(stderr, gettext( + "nm: -L set. -D ignored\n")); + } else + D_flag = 1; break; case 'C': C_flag = 1; @@ -565,6 +576,8 @@ if (D_flag) symtabtype = SHT_DYNSYM; + else if (L_flag) + symtabtype = SHT_SUNW_LDYNSYM; else symtabtype = SHT_SYMTAB;
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README Thu Feb 08 11:58:00 2007 -0800 @@ -1160,8 +1160,12 @@ 6475344 DTrace needs ELF function and data symbols sorted by address (D) PSARC/2007/026 ELF symbol sort sections 6494228 pclose() error when an audit library calls popen() and the main target - is being run under ldd + is being run under ldd (D) 6518480 ld -melf_i386 doesn't complain (D) +6519951 bfu is just another word for exit today (RPATH -> RUNPATH conversion + bites us) (D) 6521504 ld: hardware capabilities processing from relocatables objects needs hardening. 6521608 assertion failure in runtime linker related to auditing +6518322 Some ELF utilities need updating for .SUNW_ldynsym section (D) + PSARC/2007/074 -L option for nm(1) to display SHT_SUNW_LDYNSYM symbols
--- a/usr/src/cmd/sgs/prof/common/prof.c Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/prof/common/prof.c Thu Feb 08 11:58:00 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1310,10 +1309,10 @@ int lth; /* space needed for name */ int get; /* amount of space to get */ - name = &(ldpter->pf_symstr_p)[symbol.ps_sym.st_name]; - if (name == NULL) { + name = elf_strptr(ldpter->pf_elf_p, ldpter->pf_symstr_ndx, + symbol.ps_sym.st_name); + if (name == NULL) return ("<<bad symbol name>>"); - } if (Cflag) name = demangled_name(name);
--- a/usr/src/cmd/sgs/prof/common/rdelf.c Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/prof/common/rdelf.c Thu Feb 08 11:58:00 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -211,51 +210,81 @@ static void fetch_symtab(Elf *elf, char *filename, mod_info_t *module) { - Elf_Scn *scn = NULL, *sym = NULL; + Elf_Scn *scn = NULL, *sym_pri = NULL, *sym_aux = NULL; GElf_Word strndx = 0; size_t i, nsyms, nfuncs; - Elf_Data *symdata; + GElf_Xword nsyms_pri, nsyms_aux = 0; + Elf_Data *symdata_pri, *symdata_aux; nltype *nl, *npe; + int symtab_found = 0; - while ((scn = elf_nextscn(elf, scn)) != NULL) { + + /* + * Scan the section headers looking for a symbol table. Our + * preference is to use .symtab, because it contains the full + * set of symbols. If we find it, we stop looking immediately + * and use it. In the absence of a .symtab section, we are + * willing to use the dynamic symbol table (.dynsym), possibly + * augmented by the .SUNW_ldynsym, which contains local symbols. + */ + while ((symtab_found == 0) && ((scn = elf_nextscn(elf, scn)) != NULL)) { GElf_Shdr shdr; if (gelf_getshdr(scn, &shdr) == NULL) continue; - if (shdr.sh_type == SHT_SYMTAB || - shdr.sh_type == SHT_DYNSYM) { - GElf_Xword chk = shdr.sh_size / shdr.sh_entsize; - - nsyms = (size_t)(shdr.sh_size / shdr.sh_entsize); + switch (shdr.sh_type) { + case SHT_SYMTAB: + nsyms_pri = shdr.sh_size / shdr.sh_entsize; + strndx = shdr.sh_link; + sym_pri = scn; + /* Throw away .SUNW_ldynsym. It is for .dynsym only */ + nsyms_aux = 0; + sym_aux = NULL; + /* We have found the best symbol table. Stop looking */ + symtab_found = 1; + break; - if (chk != (GElf_Xword) nsyms) { - (void) fprintf(stderr, "%s: can't handle" - "more than 2^32 symbols", cmdname); - exit(ERR_INPUT); - } - + case SHT_DYNSYM: + /* We will use .dynsym if no .symtab is found */ + nsyms_pri = shdr.sh_size / shdr.sh_entsize; strndx = shdr.sh_link; - sym = scn; - } + sym_pri = scn; + break; - /* - * If we've found a real symbol table, we're done. - */ - if (shdr.sh_type == SHT_SYMTAB) + case SHT_SUNW_LDYNSYM: + /* Auxiliary table, used with .dynsym */ + nsyms_aux = shdr.sh_size / shdr.sh_entsize; + sym_aux = scn; break; + } } - if (sym == NULL || strndx == 0) { + if (sym_pri == NULL || strndx == 0) { (void) fprintf(stderr, "%s: missing symbol table in %s\n", cmdname, filename); exit(ERR_ELF); } - if ((symdata = elf_getdata(scn, NULL)) == NULL) { + nsyms = (size_t)(nsyms_pri + nsyms_aux); + if ((nsyms_pri + nsyms_aux) != (GElf_Xword)nsyms) { + (void) fprintf(stderr, + "%s: can't handle more than 2^32 symbols", cmdname); + exit(ERR_INPUT); + } + + if ((symdata_pri = elf_getdata(sym_pri, NULL)) == NULL) { (void) fprintf(stderr, "%s: can't read symbol data from %s\n", - cmdname, filename); + cmdname, filename); + exit(ERR_ELF); + } + + if ((sym_aux != NULL) && + ((symdata_aux = elf_getdata(sym_aux, NULL)) == NULL)) { + (void) fprintf(stderr, + "%s: can't read .SUNW_ldynsym symbol data from %s\n", + cmdname, filename); exit(ERR_ELF); } @@ -276,7 +305,16 @@ GElf_Sym gsym; char *name; - (void) gelf_getsym(symdata, i, &gsym); + /* + * Look up the symbol. In the case where we have a + * .SUNW_ldynsym/.dynsym pair, we treat them as a single + * logical table, with the data in .SUNW_ldynsym coming + * before the data in .dynsym. + */ + if (i >= nsyms_aux) + (void) gelf_getsym(symdata_pri, i - nsyms_aux, &gsym); + else + (void) gelf_getsym(symdata_aux, i, &gsym); name = elf_strptr(elf, strndx, gsym.st_name);
--- a/usr/src/cmd/sgs/prof/common/symintHdr.h Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/prof/common/symintHdr.h Thu Feb 08 11:58:00 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -23,7 +22,7 @@ /* All Rights Reserved */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -159,22 +158,28 @@ typedef struct symint_prof_file PROF_FILE; + +/* + * symint_prof_file contains a primary and an (optional) auxiliary + * symbol table, which we wish to treat as a single logical symbol table. + * In this logical table, the data from the auxiliary table preceeds that + * from the primary. Symbol indices start at [0], which is the first item + * in the auxiliary table if there is one. The sole purpose for this is so + * that we can treat the combination of .SUNW_ldynsym and .dynsym sections + * as a logically single entity. + * + * Both tables must share the same string table section. + */ struct symint_prof_file { int pf_fildes; /* file descriptor */ Elf *pf_elf_p; /* elf descriptor */ Elf32_Ehdr *pf_elfhd_p; /* elf header */ - Elf32_Shdr *pf_snmshd_p; /* section names header */ Elf_Data *pf_snmdat_p; /* section names data */ - Elf32_Shdr *pf_symshd_p; /* symbol table header */ - Elf_Data *pf_symdat_p; /* symbol table data */ - Elf32_Shdr *pf_strshd_p; /* symbol strings header */ - Elf_Data *pf_strdat_p; /* symbol strings data */ - char *pf_symstr_p; /* symbol table strings */ - int pf_nstsyms; /* number of symbols in symbol table */ - Elf32_Shdr *pf_debugshd_p; /* debug header */ - Elf_Data *pf_debugdat_p; /* debug data */ - Elf32_Shdr *pf_lineshd_p; /* line header */ - Elf_Data *pf_linedat_p; /* line data */ + Elf_Data *pf_symdat_pri_p; /* primary symbol table data */ + Elf_Data *pf_symdat_aux_p; /* auxiliary symbol table data */ + Elf32_Word pf_symstr_ndx; /* Section index of string table */ + int pf_nstsyms; /* total # symbols in both tables */ + int pf_nstsyms_aux; /* # symbols in auxiliary table */ Elf32_Shdr *pf_shdarr_p; /* complete array of section hdrs */
--- a/usr/src/cmd/sgs/prof/common/symintLoad.c Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/prof/common/symintLoad.c Thu Feb 08 11:58:00 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -119,7 +118,10 @@ PROF_SYMBOL * _symintLoad(PROF_FILE *proffilePtr) { - Elf_Data *symdat_p; + Elf_Data *symdat_pri_p; + Elf_Data *symdat_aux_p; + size_t nsyms_pri; + PROF_SYMBOL *symlist; DEBUG_LOC("_symintLoad: top"); @@ -129,17 +131,20 @@ * sanity checks. */ DEBUG_EXP(printf("profPtr = %x\n", profPtr)); - DEBUG_EXP(printf("profPtr->pf_symdat_p = %x\n", profPtr->pf_symdat_p)); + DEBUG_EXP(printf("profPtr->pf_symdat_p = %x\n", + profPtr->pf_symdat_pri_p)); DEBUG_EXP(printf("profPtr->pf_nstsyms = %x\n", profPtr->pf_nstsyms)); assert(profPtr != 0); - assert(profPtr->pf_symdat_p != 0); + assert(profPtr->pf_symdat_pri_p != 0); assert(profPtr->pf_nstsyms != 0); - symdat_p = profPtr->pf_symdat_p; - DEBUG_EXP(printf("symdat_p->d_size = %x\n", symdat_p->d_size)); + symdat_pri_p = profPtr->pf_symdat_pri_p; + symdat_aux_p = profPtr->pf_symdat_aux_p; + nsyms_pri = profPtr->pf_nstsyms - profPtr->pf_nstsyms_aux; + DEBUG_EXP(printf("symdat_pri_p->d_size = %x\n", symdat_pri_p->d_size)); - prstsym_size = (symdat_p->d_size / profPtr->pf_nstsyms); + prstsym_size = (symdat_pri_p->d_size / profPtr->pf_nstsyms); DEBUG_EXP(printf("_symintLoad: prstsym_size = %d\n", prstsym_size)); @@ -149,22 +154,34 @@ * ARE THE SAME SIZE & (effectively) HAVE THE SAME FIELDS! * Set the descriptive `parameters' accordingly. * - * (We'll take a copy, to simplify the 'Drop' - * logic.) + * If there is an auxiliary symbol table (.SUNW_ldynsym) augmenting + * the dynamic symbol table (.dynsym), then we copy both tables + * into our copy, with the auxiliary coming first. + * + * (We'll take a copy, to simplify the 'Drop' logic.) */ { - int st_size; /* size of symbol table data */ + size_t st_size; /* size of symbol table data */ - st_size = symdat_p->d_size; + st_size = symdat_pri_p->d_size; + if (profPtr->pf_nstsyms_aux != 0) + st_size += symdat_aux_p->d_size; NO_DEBUG_LOC("_symintLoad: before malloc for symbol list (PROF)"); - prsym_list_p = (PROF_SYMBOL *)_Malloc(st_size, 1); + prsym_list_p = symlist = (PROF_SYMBOL *)_Malloc(st_size, 1); NO_DEBUG_LOC("_symintLoad: after malloc for symbol list (PROF)"); + if (profPtr->pf_nstsyms_aux > 0) { + NO_DEBUG_LOC("_symintLoad: before memcpy for " + "auxiliary symbol list (PROF)"); + (void) memcpy(symlist, symdat_aux_p->d_buf, + symdat_aux_p->d_size); + symlist += profPtr->pf_nstsyms_aux; + } + NO_DEBUG_LOC("_symintLoad: before memcpy for symbol list (PROF)"); - (void) memcpy((char *)&(prsym_list_p->ps_sym), symdat_p->d_buf, - st_size); + (void) memcpy(symlist, symdat_pri_p->d_buf, symdat_pri_p->d_size); profPtr->pf_nsyms = profPtr->pf_nstsyms; }
--- a/usr/src/cmd/sgs/prof/common/symintOpen.c Thu Feb 08 10:43:29 2007 -0800 +++ b/usr/src/cmd/sgs/prof/common/symintOpen.c Thu Feb 08 11:58:00 2007 -0800 @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -85,14 +84,9 @@ */ /* - * #defines and globals. + * globals */ -#define SCN_NAME_DEBUG ".debug" /* debug information section */ -#define SCN_NAME_LINE ".line" /* line number section */ -#define SCN_NAME_SYM ".symtab" /* symbol table entry section */ -#define SCN_NAME_SST ".strtab" /* symbol table string table */ - static char *fail_open_s = "Unable to open file", @@ -103,7 +97,8 @@ *fail_dat_s = "Unable to get data for section", *fail_sym_s = "Cannot find symbol table section in", *fail_pfsym_s = "Unable to process symbols in", - *fail_buf_s = "Data buffer is null for section" + *fail_buf_s = "Data buffer is null for section", + *fail_sym32_s = "Cannot handle more than 2^32 symbols" ; @@ -157,6 +152,7 @@ Elf_Scn *tscn_p; Elf32_Shdr *tshd_p; int k; + Elf64_Xword nsyms_pri = 0, nsyms_aux = 0; executableName = aout_name; @@ -186,7 +182,7 @@ if (tscn_p == NULL) _err_exit("%s %d in %s.", fail_sec_s, k, aout_name); - if ((pfile_p->pf_snmshd_p = elf32_getshdr(tscn_p)) == NULL) + if (elf32_getshdr(tscn_p) == NULL) _err_exit("%s %s in %s.", fail_shd_s, "header names", aout_name); if ((pfile_p->pf_snmdat_p = elf_getdata(tscn_p, NULL)) == NULL) @@ -224,11 +220,20 @@ int shdsize = pfile_p->pf_elfhd_p->e_shentsize; int i; char *s; + int symtab_found = 0; - i = 0; tscn_p = 0; DEBUG_EXP(printf("Section header entry size = %d\n", shdsize)); DEBUG_EXP(printf("First section header name = %s\n", &shdnms_p[1])); + pfile_p->pf_symdat_aux_p = NULL; + /* + * Scan the section headers looking for a symbol table. Our + * preference is to use .symtab, because it contains the full + * set of symbols. If we find it, we stop looking immediately + * and use it. In the absence of a .symtab section, we are + * willing to use the dynamic symbol table (.dynsym), possibly + * augmented by the .SUNW_ldynsym, which contains local symbols. + */ while ((tscn_p = elf_nextscn(telf_p, tscn_p)) != NULL) { if ((tshd_p = elf32_getshdr(tscn_p)) == NULL) _err_exit("%s %d in %s.", fail_shd_s, i, aout_name); @@ -240,35 +245,52 @@ DEBUG_EXP(printf("index of section name = %d\n", tshd_p->sh_name)); DEBUG_EXP(printf("_symintOpen: reading section %s\n", s)); - if (strcmp(s, SCN_NAME_DEBUG) == 0) { - DEBUG_LOC("_symintOpen: found debug section"); - pfile_p->pf_debugshd_p = tshd_p; - pfile_p->pf_debugdat_p = section_data_p(tscn_p, - "debug"); - } else if (strcmp(s, SCN_NAME_LINE) == 0) { - DEBUG_LOC("_symintOpen: found line section"); - pfile_p->pf_lineshd_p = tshd_p; - pfile_p->pf_linedat_p = section_data_p(tscn_p, "line"); - } else if (strcmp(s, SCN_NAME_SYM) == 0) { + + if (symtab_found) + continue; + switch (tshd_p->sh_type) { + case SHT_SYMTAB: DEBUG_LOC("_symintOpen: found symbol section"); - pfile_p->pf_symshd_p = tshd_p; - pfile_p->pf_symdat_p = section_data_p(tscn_p, "symtab"); - pfile_p->pf_nstsyms = - tshd_p->sh_size / tshd_p->sh_entsize; - } else if (strcmp(s, SCN_NAME_SST) == 0) { - DEBUG_LOC("_symintOpen: found symbol table strings"); - pfile_p->pf_strshd_p = tshd_p; - pfile_p->pf_strdat_p = section_data_p(tscn_p, "strtab"); - pfile_p->pf_symstr_p = pfile_p->pf_strdat_p->d_buf; + pfile_p->pf_symstr_ndx = tshd_p->sh_link; + pfile_p->pf_symdat_pri_p = + section_data_p(tscn_p, "symtab"); + nsyms_pri = tshd_p->sh_size / tshd_p->sh_entsize; + /* Throw away .SUNW_ldynsym. It is for .dynsym only */ + nsyms_aux = 0; + pfile_p->pf_symdat_aux_p = NULL; + /* We have found the best symbol table. Stop looking */ + symtab_found = 1; + break; + + case SHT_DYNSYM: + /* We will use .dynsym if no .symtab is found */ + DEBUG_LOC("_symintOpen: found dynamic symbol section"); + pfile_p->pf_symstr_ndx = tshd_p->sh_link; + pfile_p->pf_symdat_pri_p = + section_data_p(tscn_p, "dynsym"); + nsyms_pri = tshd_p->sh_size / tshd_p->sh_entsize; + break; + + case SHT_SUNW_LDYNSYM: + /* Auxiliary table, used with .dynsym */ + DEBUG_LOC("_symintOpen: found dynamic symbol section"); + pfile_p->pf_symdat_aux_p = + section_data_p(tscn_p, "SUNW_ldynsym"); + nsyms_aux = tshd_p->sh_size / tshd_p->sh_entsize; + break; } - i++; } } - if (!pfile_p->pf_symdat_p) { + if (pfile_p->pf_symdat_pri_p == NULL || pfile_p->pf_symstr_ndx == 0) _err_exit("%s %s.", fail_sym_s, executableName); - } + + pfile_p->pf_nstsyms = (int)(nsyms_pri + nsyms_aux); + pfile_p->pf_nstsyms_aux = (int)nsyms_aux; + if ((nsyms_pri + nsyms_aux) != (Elf64_Xword)pfile_p->pf_nstsyms) + _err_exit("%s %s.", fail_sym32_s, executableName); + DEBUG_LOC("_symintOpen: after for loop that reads the sections");