elfdump.c revision 8521e5e6630b57b9883c3979cd5589e53f09e044
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#pragma ident "%Z%%M% %I% %E% SMI"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Dump an elf file.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * VERSYM_STATE is used to maintain information about the VERSYM section
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in the object being analyzed. It is filled in by versions(), and used
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by init_symtbl_state() when displaying symbol information.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note that the value of the gnu field is a hueristic guess,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * based on the section names.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortetypedef struct {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Cache *cache; /* Pointer to cache entry for VERSYM */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int num_verdef; /* # of versions defined in object */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int gnu; /* True if we think obj produced by GNU tools */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SYMTBL_STATE is used to maintain information about a single symbol
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * table section, for use by the routines that display symbol information.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortetypedef struct {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Cache *seccache; /* Cache of symbol table section hdr */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Word secndx; /* Index of symbol table section hdr */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct { /* Extended section index data */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int checked; /* TRUE if already checked for shxndx */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Word *data; /* NULL, or extended section index */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* used for symbol table entries */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte VERSYM_STATE *versym; /* NULL, or associated VERSYM section */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Focal point for verifying symbol names.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic const char *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestring(Cache *refsec, Word ndx, Cache *strsec, const char *file, Word name)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *strs;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Only print a diagnostic regarding an empty string table once per
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * input section being processed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Is the string table offset within range of the available strings?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Do we have a empty string table?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSTOFF),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte file, refsec->c_name, EC_WORD(ndx), strsec->c_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return the empty string so that the calling function can
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * continue it's output diagnostics.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * Relocations can reference section symbols and standard symbols. If the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * former, establish the section name.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic const char *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterelsymname(Cache *cache, Cache *csec, Cache *strsec, Word symndx, Word symnum,
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik Word relndx, Sym *syms, char *secstr, size_t secsz, const char *file,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, MSG_INTL(MSG_ERR_RELBADSYMNDX),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the symbol represents a section offset construct an appropriate
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ELF_ST_TYPE(sym->st_info) == STT_SECTION) && (sym->st_name == 0)) {
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik return ((const char *)secstr);
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik return (string(csec, symndx, strsec, file, sym->st_name));
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * Focal point for establishing a string table section. Data such as the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dynamic information simply points to a string table. Data such as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * relocations, reference a symbol table, which in turn is associated with a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * string table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestringtbl(Cache *cache, int symtab, Word ndx, Word shnum, const char *file,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Validate the symbol table section.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte file, cache[ndx].c_name, EC_WORD(shdr->sh_link));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Obtain, and verify the symbol table data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Establish the string table index.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return symbol table information.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Validate the associated string table section.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte file, cache[ndx].c_name, EC_WORD(shdr->sh_link));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Lookup a symbol and set Sym accordingly.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesymlookup(const char *name, Cache *cache, Word shnum, Sym **sym,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Determine the symbol data and number.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get the associated string table section.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Loop through the symbol table to find a match.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte symname = string(symtab, cnt, &cache[shdr->sh_link], file,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Print section headers.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesections(const char *file, Cache *cache, Word shnum, Ehdr *ehdr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *name)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Although numerous section header entries can be zero, it's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * usually a sign of trouble if the type is zero.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHTYPE),
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * Identify any sections that are suspicious. A .got section
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * shouldn't exist in a relocatable object.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dbg_print(0, MSG_INTL(MSG_ELF_SHDR), EC_WORD(seccnt), secname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A couple of instances of unwind data are printed as tables of 8 data items
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * expressed as 0x?? integers.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteunwindtbl(uint64_t *ndx, uint_t len, uchar_t *data, uint64_t doff,
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (void) snprintf(&buffer[boff], UNWINDTBLSZ - boff,
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik MSG_ORIG(MSG_UNW_TBLENTRY), data[doff + (*ndx)++]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Obtain a specified Phdr entry.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortegetphdr(Word phnum, Word type, const char *file, Elf *elf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteunwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, const char *name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For the moment - UNWIND is only relevant for a AMD64 object.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uphdr = getphdr(phnum, PT_SUNW_UNWIND, file, elf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint_t vers, frame_ptr_enc, fde_cnt_enc, table_enc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * AMD64 - this is a strmcp() just to find the gcc produced
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sections. Soon gcc should be setting the section type - and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we'll not need this strcmp().
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRMHDR),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dbg_print(0, MSG_INTL(MSG_ELF_SCN_UNWIND), _cache->c_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Is this a .eh_frame_hdr
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((uphdr && (shdr->sh_addr == uphdr->p_vaddr)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRMHDR),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte frame_ptr = dwarf_ehe_extract(data, &ndx, frame_ptr_enc,
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik conv_dwarf_ehe(frame_ptr_enc), EC_XWORD(frame_ptr));
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik fde_cnt = dwarf_ehe_extract(data, &ndx, fde_cnt_enc,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Walk the Eh_frame's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * extract length in lsb format
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * extract CIE id in lsb format
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A CIE record has a id of '0', otherwise this is a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FDE entry and the 'id' is the CIE pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Print the hardware/software capabilities. For executables and shared objects
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this should be accompanied with a program header.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurikcap(const char *file, Cache *cache, Word shnum, Word phnum, Ehdr *ehdr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Determine if a hardware/software capabilities header exists.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Determine if a hardware/software capabilities section exists.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cphdr_off && ((cphdr_off < shdr->sh_offset) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (cphdr_off + cphdr_sz) > (shdr->sh_offset + shdr->sh_size)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cshdr->sh_entsize == 0) || (cshdr->sh_size == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Print the hardware/software capabilities section.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik dbg_print(0, MSG_INTL(MSG_ELF_SCN_CAP), ccache->c_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte capn = (Word)(cshdr->sh_size / cshdr->sh_entsize);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVCAP1), file);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If this object is an executable or shared object, then the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * hardware/software capabilities section should have an accompanying
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * program header.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik if (cshdr && ((ehdr->e_type == ET_EXEC) || (ehdr->e_type == ET_DYN))) {
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVCAP2),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVCAP3),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Print the interpretor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteinterp(const char *file, Cache *cache, Word shnum, Word phnum, Elf *elf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Determine if an interp header exists.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik if ((phdr = getphdr(phnum, PT_INTERP, file, elf)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Determine if an interp section exists.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Scan sections to find a section which contains the PT_INTERP
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * string. The target section can't be in a NOBITS section.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iphdr_off + iphdr_fsz) > (shdr->sh_offset + shdr->sh_size))
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * Print the interpreter string based on the offset defined in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * program header, as this is the offset used by the kernel.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dbg_print(0, MSG_INTL(MSG_ELF_SCN_INTERP), icache->c_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVINTERP1), file);
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * If there are any inconsistences between the program header and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * section information, flag them.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVINTERP2), file,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Print the syminfo section.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Juriksyminfo(Cache *cache, Word shnum, const char *file)
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik if (cache[cnt].c_shdr->sh_type == SHT_SUNW_syminfo) {
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik if ((infoshdr->sh_entsize == 0) || (infoshdr->sh_size == 0)) {
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik infonum = (Word)(infoshdr->sh_size / infoshdr->sh_entsize);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get the data buffer of the associated dynamic section.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((infoshdr->sh_info == 0) || (infoshdr->sh_info >= shnum)) {
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHINFO),
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik file, infocache->c_name, EC_WORD(infoshdr->sh_info));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get the data buffer for the associated symbol table and string table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Loop through the syminfo entries.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dbg_print(0, MSG_INTL(MSG_ELF_SCN_SYMINFO), infocache->c_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ndx = 1, info++; ndx < infonum; ndx++, info++) {
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik if ((info->si_flags == 0) && (info->si_boundto == 0))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte name = string(infocache, ndx, strsec, file, sym->st_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Print version definition section entries.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteversion_def(Verdef *vdf, Word shnum, Cache *vcache, Cache *scache,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *file)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vdf = (Verdef *)((uintptr_t)vdf + vdf->vd_next)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Obtain the name and first dependency (if any).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte name = string(vcache, cnt, scache, file, vdap->vda_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next);
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik dep = string(vcache, cnt, scache, file, vdap->vda_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) snprintf(index, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Print any additional dependencies.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next);
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik Elf_ver_line_2(0, MSG_ORIG(MSG_STR_EMPTY), dep);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Print a version needed section entries.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteversion_need(Verneed *vnd, Word shnum, Cache *vcache, Cache *scache,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *file)
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik vnd = (Verneed *)((uintptr_t)vnd + vnd->vn_next)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Obtain the name of the needed file and the version name
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * within it that we're dependent on. Note that the count
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * should be at least one, otherwise this is a pretty bogus
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik name = string(vcache, cnt, scache, file, vnd->vn_file);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dep = string(vcache, cnt, scache, file, vnap->vna_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Elf_ver_line_1(0, MSG_ORIG(MSG_STR_EMPTY), name, dep,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Print any additional version dependencies.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vnap = (Vernaux *)((uintptr_t)vnap + vnap->vna_next);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Display version section information if the flags require it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return version information needed by other output.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * cache - Cache of all section headers
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * shnum - # of sections in cache
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * file - Name of file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flags - Command line option flags
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * versym - VERSYM_STATE block to be filled in.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteversions(Cache *cache, Word shnum, const char *file, uint_t flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the section names starts with the .gnu.version prefix,
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * then this object was almost certainly produced by the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * GNU ld and not the native Solaris ld.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik if (strncmp(gnu_prefix, secname, gnu_prefix_len) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If this is the version symbol table record its data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * address for later symbol processing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If this is a version definition section, retain # of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * version definitions for later symbol processing.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * Determine the version section data and number.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((ver = (void *)_cache->c_data->d_buf) == NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHINFO),
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * Get the data buffer for the associated string table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dbg_print(0, MSG_INTL(MSG_ELF_SCN_VERDEF), secname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dbg_print(0, MSG_INTL(MSG_ELF_SCN_VERNEED), secname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Initialize a symbol table state structure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * state - State structure to be initialized
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cache - Cache of all section headers
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * shnum - # of sections in cache
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * secndx - Index of symbol table section
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ehdr - ELF header for file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * versym - Information about versym section
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file - Name of file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flags - Command line option flags
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteinit_symtbl_state(SYMTBL_STATE *state, Cache *cache, Word shnum, Word secndx,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Ehdr *ehdr, VERSYM_STATE *versym, const char *file, uint_t flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check the symbol data and per-item size.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte state->symn = (Word)(shdr->sh_size / shdr->sh_entsize);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte state->sym = (Sym *)state->seccache->c_data->d_buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check associated string table section.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Determine if there is a associated Versym section
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with this Symbol Table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (versym->cache->c_shdr->sh_link == state->secndx))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Determine the extended section index used for symbol tables entries.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte state->shxndx.checked = 1; /* Note that we've been called */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (symcnt = 1; symcnt < state->shnum; symcnt++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((symn = (uint_t)(shdr->sh_size / shdr->sh_entsize)) == 0))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Produce a line of output for the given symbol
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * state - Symbol table state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * symndx - Index of symbol within the table
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * symndx_disp - Index to display. This may not be the same
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as symndx if the display is relative to the logical
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * combination of the SUNW_ldynsym/dynsym tables.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sym - Symbol to display
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteoutput_symbol(SYMTBL_STATE *state, Word symndx, Word disp_symndx, Sym *sym)
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * Symbol types for which we check that the specified
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * address/size land inside the target section.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik 0, /* STT_NOTYPE */
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik 0, /* STT_SECTION */
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik 0, /* STT_FILE */
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik 0, /* STT_TLS */
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik#error "STT_NUM has grown. Update addr_symtype[]"
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik /* Ensure symbol index is in range */
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSORTNDX),
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * If we are using extended symbol indexes, find the
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * corresponding SHN_SYMTAB_SHNDX table.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik if ((sym->st_shndx == SHN_XINDEX) && (state->shxndx.checked == 0))
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik /* LINTED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &state->cache[state->seccache->c_shdr->sh_link], state->file,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((_shxndx =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If versioning is available display the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * version index. If not, then use 0.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check to see if this is a defined symbol with a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * version index that is outside the valid range for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the file. If so, then there are two possiblities:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - Files produced by the GNU ld use the top (16th) bit
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as a "hidden symbol" marker. If we have
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * detected that this object comes from GNU ld,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * then check to see if this is the case and that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the resulting masked version is in range. If so,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * issue a warning describing it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - If this is not a GNU "hidden bit" issue, then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * issue a generic "out of range" error.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (VERNDX_INVALID(sym->st_shndx, state->versym->num_verdef,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else { /* Generic version range error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Error checking for TLS.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte state->secname, demangle(symname, state->flags));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((type != STT_SECTION) && sym->st_size &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte state->secname, demangle(symname, state->flags));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If a symbol with non-zero size has a type that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * specifies an address, then make sure the location
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it references is actually contained within the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * section. UNDEF symbols don't count in this case,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so we ignore them.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The meaning of the st_value field in a symbol
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * depends on the type of object. For a relocatable
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * object, it is the offset within the section.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For sharable objects, it is the offset relative to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the base of the object, and for other types, it is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the virtual address. To get an offset within the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * section for non-ET_REL files, we subtract the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * base address of the section.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (sym->st_shndx != SHN_UNDEF) && ((sym->st_shndx < SHN_LORESERVE) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (sym->st_shndx == SHN_XINDEX)) && (tshdr != NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EC_XWORD(sym->st_value), EC_XWORD(sym->st_size));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte state->ehdr->e_machine, sym, verndx, sec, symname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Search for and process any symbol tables.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesymbols(Cache *cache, Word shnum, Ehdr *ehdr, const char *name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte VERSYM_STATE *versym, const char *file, uint_t flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!init_symtbl_state(&state, cache, shnum, secndx, ehdr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Loop through the symbol tables entries.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dbg_print(0, MSG_INTL(MSG_ELF_SCN_SYMTAB), state.secname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Search for and process any SHT_SUNW_symsort or SHT_SUNW_tlssort sections.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * These sections are always associated with the .SUNW_ldynsym./.dynsym pair.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesunw_sort(Cache *cache, Word shnum, Ehdr *ehdr, const char *name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte VERSYM_STATE *versym, const char *file, uint_t flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (sortsecndx = 1; sortsecndx < shnum; sortsecndx++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the section references a SUNW_ldynsym, then we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * expect to see the associated .dynsym immediately
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * following. If it references a .dynsym, there is no
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SUNW_ldynsym. If it is any other type, then we don't
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * know what to do with it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((sortshdr->sh_link == 0) || (sortshdr->sh_link >= shnum)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!init_symtbl_state(&ldynsym_state, cache, shnum,
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * We know that the dynsym follows immediately
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * after the SUNW_ldynsym, and so, should be at
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (sortshdr->sh_link + 1). However, elfdump is a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * diagnostic tool, so we do the full paranoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * search instead.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (symsecndx = 1; symsecndx < shnum; symsecndx++) {
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik if (symsecndx >= shnum) { /* Dynsym not found! */
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik /* Fallthrough to process associated dynsym */
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik /*FALLTHROUGH*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!init_symtbl_state(&dynsym_state, cache, shnum,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADNDXSEC),
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * Output header
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The data for .SUNW_ldynsym and dynsym sections
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is supposed to be adjacent with SUNW_ldynsym coming
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * first. Check, and issue a warning if it isn't so.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* If not first one, insert a line of whitespace */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SUNW_dynsymsort and SUNW_dyntlssort are arrays of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * symbol indices. Iterate over the array entries,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dispaying the referenced symbols.
void *rels;
const char *symname;
flags);
if (symndx == 0) {
int badrel = 0;
badrel++;
badrel++;
badrel++;
if (badrel) {
Elf_dyn_title(0);
const char *name;
case DT_NULL:
dyn++;
end_ndx++;
case DT_NEEDED:
case DT_SONAME:
case DT_FILTER:
case DT_AUXILIARY:
case DT_CONFIG:
case DT_RPATH:
case DT_RUNPATH:
case DT_USED:
case DT_DEPAUDIT:
case DT_AUDIT:
case DT_SUNW_AUXILIARY:
case DT_SUNW_FILTER:
case DT_FLAGS:
case DT_FLAGS_1:
case DT_POSFLAG_1:
case DT_FEATURE_1:
const char *fmt = 0;
if (fmt == 0)
const char *symname;
flags);
while (size > 0) {
if (namesz) {
if (descsz) {
tok);
word++;
byte = 0;
word = 0;
if (chain == 0) {
hashndx);
if (*hash == 0) {
count[0]++;
while (_ndx) {
_cnt++;
if (cnt) {
bkts);
flags));
const char *name;
char *gotdata;
MSG_ELF_GOT_SIZE) == 0) {
if (gotcache == 0)
void *rels;
if (symndx)
file))
Elf_got_title(0);
char *names = 0;
shdr = 0;
if (Nname &&
_cache++;
int cnt1;