From: Ulrich Drepper Date: Mon, 5 Feb 2007 07:25:33 +0000 (+0000) Subject: propagate from branch 'com.redhat.elfutils.roland.pending' (head c44dcfac5b545aecb173... X-Git-Tag: elfutils-0.126~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aa915fd3d70b4cbe4581f9ec170d986c6ba35063;p=thirdparty%2Felfutils.git propagate from branch 'com.redhat.elfutils.roland.pending' (head c44dcfac5b545aecb173fede31f34cb003be0173) to branch 'com.redhat.elfutils' (head 4196d4e01486bdeb0c0632291881d1c6d7163fab) --- diff --git a/backends/ChangeLog b/backends/ChangeLog index 86ac44b96..57f33608b 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,10 @@ +2007-01-11 Roland McGrath + + * ia64_symbol.c (ia64_machine_section_flag_check): New function. + * ia64_init.c (ia64_init): Use it. + + * ia64_symbol.c (ia64_section_type_name): Typo fix in string. + 2006-10-09 Roland McGrath * ia64_symbol.c (ia64_reloc_simple_type): Treat SECREL types as simple. diff --git a/backends/ia64_init.c b/backends/ia64_init.c index acae23463..290c192c8 100644 --- a/backends/ia64_init.c +++ b/backends/ia64_init.c @@ -1,5 +1,5 @@ /* Initialization of IA-64 specific backend library. - Copyright (C) 2002, 2003, 2005, 2006 Red Hat, Inc. + Copyright (C) 2002, 2003, 2005, 2006, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper , 2002. @@ -55,6 +55,7 @@ ia64_init (elf, machine, eh, ehlen) HOOK (eh, dynamic_tag_name); HOOK (eh, dynamic_tag_check); HOOK (eh, machine_flag_check); + HOOK (eh, machine_section_flag_check); HOOK (eh, register_info); HOOK (eh, return_value_location); diff --git a/backends/ia64_symbol.c b/backends/ia64_symbol.c index 4faec0c9b..2609db0f4 100644 --- a/backends/ia64_symbol.c +++ b/backends/ia64_symbol.c @@ -1,5 +1,5 @@ /* IA-64 specific symbolic name handling. - Copyright (C) 2002, 2003, 2005, 2006 Red Hat, Inc. + Copyright (C) 2002, 2003, 2005, 2006, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper , 2002. @@ -86,6 +86,13 @@ ia64_machine_flag_check (GElf_Word flags) return ((flags &~ EF_IA_64_ABI64) == 0); } +/* Check whether SHF_MASKPROC flags are valid. */ +bool +ia64_machine_section_flag_check (GElf_Xword sh_flags) +{ + return (sh_flags &~ (SHF_IA_64_SHORT | SHF_IA_64_NORECOV)) == 0; +} + /* Return symbolic representation of section type. */ const char * ia64_section_type_name (int type, @@ -97,7 +104,7 @@ ia64_section_type_name (int type, case SHT_IA_64_EXT: return "SHT_IA_64_EXT"; case SHT_IA_64_UNWIND: - return "HT_IA_64_UNWIND"; + return "SHT_IA_64_UNWIND"; } return NULL; diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 19c5d11b9..814299b89 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,10 @@ +2007-02-03 Roland McGrath + + * dwarf_getelf.c (dwarf_getelf): Renamed from dwarf_get_elf. + * libdw.map (ELFUTILS_0.126): New version set, inherits from + ELFUTILS_0.122. Move dwarf_getelf there; it was never truly + exported in the past. + 2006-12-17 Roland McGrath * dwarf_getlocation.c (dwarf_getlocation_addr): Use zero as base diff --git a/libdw/dwarf_getelf.c b/libdw/dwarf_getelf.c index a67246237..daf3b9a79 100644 --- a/libdw/dwarf_getelf.c +++ b/libdw/dwarf_getelf.c @@ -1,5 +1,5 @@ /* Retrieve ELF descriptor used for DWARF access. - Copyright (C) 2002, 2004 Red Hat, Inc. + Copyright (C) 2002, 2004, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper , 2002. @@ -58,7 +58,7 @@ Elf * -dwarf_get_elf (dwarf) +dwarf_getelf (dwarf) Dwarf *dwarf; { if (dwarf == NULL) diff --git a/libdw/libdw.map b/libdw/libdw.map index 6ee42ece5..71e9f50fe 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -44,7 +44,6 @@ ELFUTILS_0.122 { dwarf_getaranges; dwarf_getattrcnt; dwarf_getattrs; - dwarf_getelf; dwarf_getfuncs; dwarf_getlocation; dwarf_getlocation_addr; @@ -146,3 +145,10 @@ ELFUTILS_0.122 { local: *; } ELFUTILS_0; +ELFUTILS_0.126 { + global: + dwarf_getelf; + + local: + *; +} ELFUTILS_0.122; diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 0439d4cf2..71b167f35 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,32 @@ +2007-02-02 Roland McGrath + + * dwfl_addrmodule.c (dwfl_addrmodule): Match a module's high boundary + address exactly if it's no other module's low boundary. + + * dwfl_module_addrname.c (dwfl_module_addrname): If no symbol's value + and size cover the address, select the closest symbol with st_size==0 + that lies in the same section. + +2007-01-29 Roland McGrath + + * dwfl_version.c (dwfl_version): Return PACKAGE_VERSION, + not PACKAGE_STRING. + +2007-01-20 Roland McGrath + + * relocate.c (__libdwfl_relocate_value): Treat section_address of -1 + as omitted, not 0. + * libdwfl.h (Dwfl_Callbacks): Update comment. + * derelocate.c (cache_sections): Don't ignore sh_addr == 0 sections. + * linux-kernel-modules.c (dwfl_linux_kernel_module_section_address): + For ignored missing section, use -1 instead of 0. + * offline.c (dwfl_offline_section_address): Expect a call for 0. + +2007-01-19 Roland McGrath + + * argp-std.c (parse_opt): For -e, reset DWFL->offline_next_address to + zero so a lone -e foo.so is shown without address bias. + 2007-01-10 Roland McGrath * linux-kernel-modules.c (report_kernel): Check asprintf return value diff --git a/libdwfl/argp-std.c b/libdwfl/argp-std.c index bec370a3e..c12cb1ddf 100644 --- a/libdwfl/argp-std.c +++ b/libdwfl/argp-std.c @@ -1,5 +1,5 @@ /* Standard argp argument parsers for tools using libdwfl. - Copyright (C) 2005 Red Hat, Inc. + Copyright (C) 2005, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -137,6 +137,10 @@ parse_opt (int key, char *arg, struct argp_state *state) if (dwfl == NULL) return fail (dwfl, -1, arg); state->hook = dwfl; + + /* Start at zero so if there is just one -e foo.so, + the DSO is shown without address bias. */ + dwfl->offline_next_address = 0; } if (dwfl->callbacks == &offline_callbacks) { diff --git a/libdwfl/derelocate.c b/libdwfl/derelocate.c index c26be8d84..d110299e8 100644 --- a/libdwfl/derelocate.c +++ b/libdwfl/derelocate.c @@ -1,5 +1,5 @@ /* Recover relocatibility for addresses computed from debug information. - Copyright (C) 2005, 2006 Red Hat, Inc. + Copyright (C) 2005, 2006, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -99,7 +99,18 @@ cache_sections (Dwfl_Module *mod) if (shdr == NULL) return -1; - if ((shdr->sh_flags & SHF_ALLOC) && shdr->sh_addr != 0) + if ((shdr->sh_flags & SHF_ALLOC) && shdr->sh_addr == 0) + { + /* This section might not yet have been looked at. */ + if (__libdwfl_relocate_value (mod, symshstrndx, elf_ndxscn (scn), + &shdr->sh_addr) != DWFL_E_NOERROR) + continue; + shdr = gelf_getshdr (scn, &shdr_mem); + if (shdr == NULL) + return -1; + } + + if (shdr->sh_flags & SHF_ALLOC) { const char *name = elf_strptr (mod->symfile->elf, symshstrndx, shdr->sh_name); diff --git a/libdwfl/dwfl_addrmodule.c b/libdwfl/dwfl_addrmodule.c index 98c4b39fd..54d9a3d92 100644 --- a/libdwfl/dwfl_addrmodule.c +++ b/libdwfl/dwfl_addrmodule.c @@ -1,5 +1,5 @@ /* Find module containing address. - Copyright (C) 2005, 2006 Red Hat, Inc. + Copyright (C) 2005, 2006, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -55,6 +55,8 @@ dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address) if (dwfl == NULL || dwfl->modules == NULL) return NULL; + Dwfl_Module *boundary = NULL; + /* Do binary search on the array indexed by module load address. */ size_t l = 0, u = dwfl->nmodules; while (l < u) @@ -64,11 +66,18 @@ dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address) if (address < m->low_addr) u = idx; else if (address >= m->high_addr) - l = idx + 1; + { + l = idx + 1; + if (address == m->high_addr) + /* If the high bound of this module is not the low bound of + another, then consider the boundary address to be inside + this module. */ + boundary = m; + } else return m; } - return NULL; + return boundary; } INTDEF (dwfl_addrmodule) diff --git a/libdwfl/dwfl_module_addrname.c b/libdwfl/dwfl_module_addrname.c index 19b4c2d3d..b107448bc 100644 --- a/libdwfl/dwfl_module_addrname.c +++ b/libdwfl/dwfl_module_addrname.c @@ -1,5 +1,5 @@ /* Find debugging and symbol information for a module in libdwfl. - Copyright (C) 2005, 2006 Red Hat, Inc. + Copyright (C) 2005, 2006, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -56,15 +56,70 @@ dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr addr) if (syments < 0) return NULL; + /* Return true iff we consider ADDR to lie in the same section as SYM. */ + GElf_Word addr_shndx = SHN_UNDEF; + inline bool same_section (const GElf_Sym *sym, GElf_Word shndx) + { + /* For absolute symbols and the like, only match exactly. */ + if (shndx >= SHN_LORESERVE) + return sym->st_value == addr; + + /* Ignore section and other special symbols. */ + switch (GELF_ST_TYPE (sym->st_info)) + { + case STT_SECTION: + case STT_FILE: + case STT_TLS: + return false; + } + + /* Figure out what section ADDR lies in. */ + if (addr_shndx == SHN_UNDEF) + { + GElf_Addr mod_addr = addr - mod->symfile->bias; + Elf_Scn *scn = NULL; + addr_shndx = SHN_ABS; + while ((scn = elf_nextscn (mod->symfile->elf, scn)) != NULL) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (likely (shdr != NULL) + && mod_addr >= shdr->sh_addr + && mod_addr < shdr->sh_addr + shdr->sh_size) + { + addr_shndx = elf_ndxscn (scn); + break; + } + } + } + + return shndx == addr_shndx; + } + /* Look through the symbol table for a matching symbol. */ + const char *closest = NULL; + GElf_Addr closest_value = 0; for (int i = 1; i < syments; ++i) { GElf_Sym sym; - const char *name = INTUSE(dwfl_module_getsym) (mod, i, &sym, NULL); - if (name != NULL - && sym.st_value <= addr && addr < sym.st_value + sym.st_size) - return name; + GElf_Word shndx; + const char *name = INTUSE(dwfl_module_getsym) (mod, i, &sym, &shndx); + if (name != NULL && sym.st_value <= addr) + { + if (addr < sym.st_value + sym.st_size) + return name; + + /* Handwritten assembly symbols sometimes have no st_size. + If no symbol with proper size includes the address, we'll + use the closest one that is in the same section as ADDR. */ + if (sym.st_size == 0 && sym.st_value >= closest_value + && same_section (&sym, shndx)) + { + closest_value = sym.st_value; + closest = name; + } + } } - return NULL; + return closest; } diff --git a/libdwfl/dwfl_version.c b/libdwfl/dwfl_version.c index c78d828b3..9c7074c55 100644 --- a/libdwfl/dwfl_version.c +++ b/libdwfl/dwfl_version.c @@ -1,5 +1,5 @@ /* Return implementation's version string suitable for printing. - Copyright (C) 2006 Red Hat, Inc. + Copyright (C) 2006, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -53,5 +53,5 @@ const char * dwfl_version (dwfl) Dwfl *dwfl __attribute__ ((unused)); { - return PACKAGE_STRING; + return PACKAGE_VERSION; } diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index 9fe3dca0e..ec0065627 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -76,7 +76,8 @@ typedef struct char **debuginfo_file_name); /* Fill *ADDR with the loaded address of the section called SECNAME in - the given module. This is called exactly once for each SHF_ALLOC + the given module. Use (Dwarf_Addr) -1 if this section is omitted from + accessible memory. This is called exactly once for each SHF_ALLOC section that relocations affecting DWARF data refer to, so it can easily be used to collect state about the sections referenced. */ int (*section_address) (Dwfl_Module *mod, void **userdata, diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c index a39863866..4ea391c07 100644 --- a/libdwfl/linux-kernel-modules.c +++ b/libdwfl/linux-kernel-modules.c @@ -431,14 +431,14 @@ dwfl_linux_kernel_module_section_address CONFIG_MODULE_UNLOAD, the .exit.* sections are not actually loaded at all. - Just relocate these bogusly to zero. This part of the - debug information will not be of any use. */ + Setting *ADDR to -1 tells the caller this section is + actually absent from memory. */ if (!strcmp (secname, ".modinfo") || !strcmp (secname, ".data.percpu") || !strncmp (secname, ".exit", 5)) { - *addr = 0; + *addr = (Dwarf_Addr) -1l; return DWARF_CB_OK; } diff --git a/libdwfl/offline.c b/libdwfl/offline.c index c5193860a..bde2aeb91 100644 --- a/libdwfl/offline.c +++ b/libdwfl/offline.c @@ -1,5 +1,5 @@ /* Recover relocatibility for addresses computed from debug information. - Copyright (C) 2005, 2006 Red Hat, Inc. + Copyright (C) 2005, 2006, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -52,8 +52,9 @@ /* Since dwfl_report_elf lays out the sections already, this will only be called when the section headers of the debuginfo file are being - consulted instead. With binutils strip-to-debug, the symbol table - is in the debuginfo file and relocation looks there. */ + consulted instead, or for a section located at zeron. With binutils + strip-to-debug, the symbol table is in the debuginfo file and relocation + looks there. */ int dwfl_offline_section_address (Dwfl_Module *mod, void **userdata __attribute__ ((unused)), @@ -64,8 +65,6 @@ dwfl_offline_section_address (Dwfl_Module *mod, const GElf_Shdr *shdr __attribute__ ((unused)), Dwarf_Addr *addr) { - assert (mod->symfile != &mod->main); - GElf_Shdr shdr_mem; GElf_Shdr *main_shdr = gelf_getshdr (elf_getscn (mod->main.elf, shndx), &shdr_mem); @@ -74,9 +73,11 @@ dwfl_offline_section_address (Dwfl_Module *mod, assert (shdr->sh_addr == 0); assert (shdr->sh_flags & SHF_ALLOC); - assert (main_shdr->sh_addr != 0); assert (main_shdr->sh_flags == shdr->sh_flags); + if (main_shdr->sh_addr != 0) + assert (mod->symfile != &mod->main); + *addr = main_shdr->sh_addr; return 0; } diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c index 96cedcc34..f37f83509 100644 --- a/libdwfl/relocate.c +++ b/libdwfl/relocate.c @@ -1,5 +1,5 @@ /* Relocate debug information. - Copyright (C) 2005, 2006 Red Hat, Inc. + Copyright (C) 2005, 2006, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -78,11 +78,14 @@ __libdwfl_relocate_value (Dwfl_Module *mod, size_t symshstrndx, &refshdr->sh_addr)) return CBFAIL; - if (refshdr->sh_addr == 0) - /* The callback resolved this to zero, indicating it wasn't - really loaded but we don't really care. Mark it so we - don't check it again for the next relocation. */ - refshdr->sh_flags &= ~SHF_ALLOC; + if (refshdr->sh_addr == (Dwarf_Addr) -1l) + { + /* The callback indicated this section wasn't really loaded but we + don't really care. Mark it so we don't check it again for the + next relocation. */ + refshdr->sh_flags &= ~SHF_ALLOC; + refshdr->sh_addr = 0; /* Make no adjustment below. */ + } /* Update the in-core file's section header to show the final load address (or unloadedness). This serves as a cache, diff --git a/libebl/ChangeLog b/libebl/ChangeLog index 33fde08b5..07f640edb 100644 --- a/libebl/ChangeLog +++ b/libebl/ChangeLog @@ -1,3 +1,12 @@ +2007-01-11 Roland McGrath + + * ebl-hooks.h (machine_section_flag_check): New hook. + * libebl.h: Declare ebl_machine_section_flag_check. + * eblmachinesectionflagcheck.c: New file. + * Makefile.am (gen_SOURCES): Add it. + * eblopenbackend.c (default_machine_section_flag_check): New function. + (fill_defaults): Use it. + 2006-09-04 Roland McGrath * ebl-hooks.h: Replace register_name hook with register_info. diff --git a/libebl/Makefile.am b/libebl/Makefile.am index 48042d9fe..741e5eee3 100644 --- a/libebl/Makefile.am +++ b/libebl/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to create Makefile.in ## -## Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. +## Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. ## This file is part of Red Hat elfutils. ## ## Red Hat elfutils is free software; you can redistribute it and/or modify @@ -49,7 +49,8 @@ gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \ eblsymboltypename.c ebldynamictagname.c eblsectionname.c \ eblobjecttypename.c eblsymbolbindingname.c \ eblbackendname.c eblshflagscombine.c eblwstrtab.c \ - eblgstrtab.c eblosabiname.c eblmachineflagcheck.c \ + eblgstrtab.c eblosabiname.c \ + eblmachineflagcheck.c eblmachinesectionflagcheck.c \ eblreloctypecheck.c eblrelocvaliduse.c eblrelocsimpletype.c \ ebldynamictagcheck.c eblcorenotetypename.c eblobjnotetypename.c \ eblcorenote.c eblobjnote.c ebldebugscnp.c \ diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h index 944e6404e..5344df094 100644 --- a/libebl/ebl-hooks.h +++ b/libebl/ebl-hooks.h @@ -1,5 +1,5 @@ /* Backend hook signatures internal interface for libebl. - Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -80,6 +80,9 @@ const char *EBLHOOK(machine_flag_name) (GElf_Word *); /* Check whether machine flags are valid. */ bool EBLHOOK(machine_flag_check) (GElf_Word); +/* Check whether SHF_MASKPROC flag bits are valid. */ +bool EBLHOOK(machine_section_flag_check) (GElf_Xword); + /* Return symbolic representation of symbol type. */ const char *EBLHOOK(symbol_type_name) (int, char *, size_t); diff --git a/libebl/eblmachinesectionflagcheck.c b/libebl/eblmachinesectionflagcheck.c new file mode 100644 index 000000000..9eb6d386f --- /dev/null +++ b/libebl/eblmachinesectionflagcheck.c @@ -0,0 +1,63 @@ +/* Check SHF_MASKPROC flags. + Copyright (C) 2007 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +bool +ebl_machine_section_flag_check (ebl, flags) + Ebl *ebl; + GElf_Xword flags; +{ + return ebl != NULL ? ebl->machine_section_flag_check (flags) : (flags == 0); +} diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c index dba22ba17..5b1a7193a 100644 --- a/libebl/eblopenbackend.c +++ b/libebl/eblopenbackend.c @@ -1,5 +1,5 @@ /* Generate ELF backend handle. - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -171,6 +171,7 @@ static const char *default_section_name (int ignore, int ignore2, char *buf, size_t len); static const char *default_machine_flag_name (Elf64_Word *ignore); static bool default_machine_flag_check (Elf64_Word flags); +static bool default_machine_section_flag_check (GElf_Xword flags); static const char *default_symbol_type_name (int ignore, char *buf, size_t len); static const char *default_symbol_binding_name (int ignore, char *buf, @@ -221,6 +222,7 @@ fill_defaults (Ebl *result) result->section_name = default_section_name; result->machine_flag_name = default_machine_flag_name; result->machine_flag_check = default_machine_flag_check; + result->machine_section_flag_check = default_machine_section_flag_check; result->symbol_type_name = default_symbol_type_name; result->symbol_binding_name = default_symbol_binding_name; result->dynamic_tag_name = default_dynamic_tag_name; @@ -502,6 +504,12 @@ default_machine_flag_check (Elf64_Word flags __attribute__ ((unused))) return flags == 0; } +static bool +default_machine_section_flag_check (GElf_Xword flags) +{ + return flags == 0; +} + static const char * default_symbol_type_name (int ignore __attribute__ ((unused)), char *buf __attribute__ ((unused)), diff --git a/libebl/libebl.h b/libebl/libebl.h index 3375525d9..1465fb1aa 100644 --- a/libebl/libebl.h +++ b/libebl/libebl.h @@ -1,5 +1,5 @@ /* Interface for libebl. - Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006 Red Hat, Inc. + Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -138,6 +138,9 @@ extern const char *ebl_machine_flag_name (Ebl *ebl, GElf_Word flags, /* Check whether machine flag is valid. */ extern bool ebl_machine_flag_check (Ebl *ebl, GElf_Word flags); +/* Check whether SHF_MASKPROC flags are valid. */ +extern bool ebl_machine_section_flag_check (Ebl *ebl, GElf_Xword flags); + /* Return symbol type name. */ extern const char *ebl_symbol_type_name (Ebl *ebl, int symbol, char *buf, size_t len); diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 14001c7a1..17985781b 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -8,6 +8,19 @@ * nlist.c: Close file descriptor before returning. +2007-01-20 Roland McGrath + + * gnuhash_xlate.h (elf_cvt_gnuhash): Fix fence-post error so we + convert the final word. + + * elf32_getshdr.c: Don't byteswap shdr fields when EI_DATA matches + MY_ELFDATA on !ALLOW_UNALIGNED machines. + +2007-01-18 Roland McGrath + + * gelf_rawchunk.c (gelf_rawchunk): Clear RESULT pointer after freeing + it on read error. + 2006-10-13 Roland McGrath * elf32_updatenull.c: Look for and accept phdr also for ET_CORE. diff --git a/libelf/elf32_getshdr.c b/libelf/elf32_getshdr.c index 4abd2c103..cafb1d4f1 100644 --- a/libelf/elf32_getshdr.c +++ b/libelf/elf32_getshdr.c @@ -1,5 +1,5 @@ /* Return section header. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Red Hat, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper , 1998. @@ -105,7 +105,7 @@ elfw2(LIBELFBITS,getshdr) (scn) goto out; size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr)); - /* Allocate memory for the program headers. We know the number + /* Allocate memory for the section headers. We know the number of entries from the ELF header. */ ElfW2(LIBELFBITS,Shdr) *shdr = elf->state.ELFW(elf,LIBELFBITS).shdr = (ElfW2(LIBELFBITS,Shdr) *) malloc (size); @@ -122,41 +122,50 @@ elfw2(LIBELFBITS,getshdr) (scn) /* All the data is already mapped. If we could use it directly this would already have happened. */ + void *file_shdr = ((char *) elf->map_address + + elf->start_offset + ehdr->e_shoff); + assert (ehdr->e_ident[EI_DATA] != MY_ELFDATA || (! ALLOW_UNALIGNED - && (((uintptr_t) elf->map_address + elf->start_offset - + ehdr->e_shoff) + && ((uintptr_t) file_shdr & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0)); - /* Now copy the data and at the same time convert the byte - order. */ - if (ALLOW_UNALIGNED - || (((uintptr_t) elf->map_address + elf->start_offset - + ehdr->e_shoff) - & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) == 0) - notcvt = (ElfW2(LIBELFBITS,Shdr) *) - ((char *) elf->map_address - + elf->start_offset + ehdr->e_shoff); - else + /* Now copy the data and at the same time convert the byte order. */ + if (ehdr->e_ident[EI_DATA] == MY_ELFDATA) { - notcvt = (ElfW2(LIBELFBITS,Shdr) *) alloca (size); - memcpy (notcvt, ((char *) elf->map_address - + elf->start_offset + ehdr->e_shoff), - size); + assert (! ALLOW_UNALIGNED); + memcpy (shdr, file_shdr, size); } - - for (size_t cnt = 0; cnt < shnum; ++cnt) + else { - CONVERT_TO (shdr[cnt].sh_name, notcvt[cnt].sh_name); - CONVERT_TO (shdr[cnt].sh_type, notcvt[cnt].sh_type); - CONVERT_TO (shdr[cnt].sh_flags, notcvt[cnt].sh_flags); - CONVERT_TO (shdr[cnt].sh_addr, notcvt[cnt].sh_addr); - CONVERT_TO (shdr[cnt].sh_offset, notcvt[cnt].sh_offset); - CONVERT_TO (shdr[cnt].sh_size, notcvt[cnt].sh_size); - CONVERT_TO (shdr[cnt].sh_link, notcvt[cnt].sh_link); - CONVERT_TO (shdr[cnt].sh_info, notcvt[cnt].sh_info); - CONVERT_TO (shdr[cnt].sh_addralign, notcvt[cnt].sh_addralign); - CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize); + if (ALLOW_UNALIGNED + || ((uintptr_t) file_shdr + & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) == 0) + notcvt = (ElfW2(LIBELFBITS,Shdr) *) + ((char *) elf->map_address + + elf->start_offset + ehdr->e_shoff); + else + { + notcvt = (ElfW2(LIBELFBITS,Shdr) *) alloca (size); + memcpy (notcvt, ((char *) elf->map_address + + elf->start_offset + ehdr->e_shoff), + size); + } + + for (size_t cnt = 0; cnt < shnum; ++cnt) + { + CONVERT_TO (shdr[cnt].sh_name, notcvt[cnt].sh_name); + CONVERT_TO (shdr[cnt].sh_type, notcvt[cnt].sh_type); + CONVERT_TO (shdr[cnt].sh_flags, notcvt[cnt].sh_flags); + CONVERT_TO (shdr[cnt].sh_addr, notcvt[cnt].sh_addr); + CONVERT_TO (shdr[cnt].sh_offset, notcvt[cnt].sh_offset); + CONVERT_TO (shdr[cnt].sh_size, notcvt[cnt].sh_size); + CONVERT_TO (shdr[cnt].sh_link, notcvt[cnt].sh_link); + CONVERT_TO (shdr[cnt].sh_info, notcvt[cnt].sh_info); + CONVERT_TO (shdr[cnt].sh_addralign, + notcvt[cnt].sh_addralign); + CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize); + } } } else if (likely (elf->fildes != -1)) diff --git a/libelf/gelf_rawchunk.c b/libelf/gelf_rawchunk.c index cab07be53..ced6f9efe 100644 --- a/libelf/gelf_rawchunk.c +++ b/libelf/gelf_rawchunk.c @@ -1,5 +1,5 @@ /* Retrieve uninterpreted chunk of the file contents. - Copyright (C) 2002, 2005 Red Hat, Inc. + Copyright (C) 2002, 2005, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Contributed by Ulrich Drepper , 2002. @@ -101,6 +101,7 @@ gelf_rawchunk (elf, offset, size) /* Something went wrong. */ __libelf_seterrno (ELF_E_READ_ERROR); free (result); + result = NULL; } return result; diff --git a/libelf/gnuhash_xlate.h b/libelf/gnuhash_xlate.h index 9012ffa11..d79764d8c 100644 --- a/libelf/gnuhash_xlate.h +++ b/libelf/gnuhash_xlate.h @@ -1,5 +1,5 @@ /* Conversion functions for versioning information. - Copyright (C) 2006 Red Hat, Inc. + Copyright (C) 2006, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper , 2006. @@ -87,7 +87,7 @@ elf_cvt_gnuhash (void *dest, const void *src, size_t len, int encode) /* The rest are 32 bit words again. */ src32 = (const Elf32_Word *) &src64[bitmask_words]; dest32 = (Elf32_Word *) &dest64[bitmask_words]; - while (len > 4) + while (len >= 4) { *dest32++ = bswap_32 (*src32++); len -= 4; diff --git a/src/ChangeLog b/src/ChangeLog index 6e619e0db..c2ce90fd6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2007-01-11 Roland McGrath + + * elflint.c (check_sections): Use ebl_machine_section_flag_check on + SHF_MASKPROC bits separately from generic sh_flags validation. + 2007-02-04 Ulrich Drepper * ar.c: New file. diff --git a/src/elflint.c b/src/elflint.c index 79e52299c..09c7fbd2f 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -3338,12 +3338,25 @@ section [%2zu] '%s': size not multiple of entry size\n"), #define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \ | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \ | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS) - if (shdr->sh_flags & ~ALL_SH_FLAGS) - ERROR (gettext ("section [%2zu] '%s' contains unknown flag(s)" - " %#" PRIx64 "\n"), - cnt, section_name (ebl, cnt), - (uint64_t) shdr->sh_flags & ~(uint64_t) ALL_SH_FLAGS); - else if (shdr->sh_flags & SHF_TLS) + if (shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS) + { + GElf_Xword sh_flags = shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS; + if (sh_flags & SHF_MASKPROC) + { + if (!ebl_machine_section_flag_check (ebl, + sh_flags & SHF_MASKPROC)) + ERROR (gettext ("section [%2zu] '%s'" + " contains invalid processor-specific flag(s)" + " %#" PRIx64 "\n"), + cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC); + sh_flags &= ~(GElf_Xword) SHF_MASKPROC; + } + if (sh_flags != 0) + ERROR (gettext ("section [%2zu] '%s' contains unknown flag(s)" + " %#" PRIx64 "\n"), + cnt, section_name (ebl, cnt), sh_flags); + } + if (shdr->sh_flags & SHF_TLS) { // XXX Correct? if (shdr->sh_addr != 0 && !gnuld) diff --git a/tests/ChangeLog b/tests/ChangeLog index 2aaba2faa..5b188f845 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,26 @@ +2007-02-02 Roland McGrath + + * run-addrname-test.sh: New file. + * Makefile.am (TESTS, EXTRA_DIST): Add it. + * testfile34.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + +2007-01-20 Roland McGrath + + * testfile33.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + * run-elflint-test.sh: Test on it too. + +2007-01-18 Roland McGrath + + * Makefile.am (CFLAGS): Don't molest it. + +2007-01-11 Roland McGrath + + * testfile32.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + * run-elflint-test.sh: Test on it too. + 2007-02-04 Ulrich Drepper * arls.c: New file. diff --git a/tests/Makefile.am b/tests/Makefile.am index bd56f7b7a..bff5568b5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -34,7 +34,6 @@ AM_CFLAGS = -Wall -Werror -Wextra -std=gnu99 \ $(if $($(*F)_no_Wformat),-Wno-format,-Wformat=2) BUILT_RPATH = \$$ORIGIN/../libasm:\$$ORIGIN/../libdw:\$$ORIGIN/../backends:\$$ORIGIN/../libelf endif -CFLAGS := $(filter-out -Wall,$(CFLAGS)) AM_LDFLAGS = @@ -77,7 +76,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \ run-addrscopes.sh run-strings-test.sh run-funcscopes.sh \ run-find-prologues.sh run-allregs.sh run-readelf-test1.sh \ run-native-test.sh run-bug1-test.sh \ - dwfl-bug-addr-overflow + dwfl-bug-addr-overflow run-addrname-test.sh # run-show-ciefde.sh if !STANDALONE @@ -106,6 +105,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ run-ranlib-test3.sh run-ranlib-test4.sh \ run-addrscopes.sh run-strings-test.sh run-funcscopes.sh \ run-find-prologues.sh run-allregs.sh run-native-test.sh \ + run-addrname-test.sh \ testfile15.bz2 testfile15.debug.bz2 \ testfile16.bz2 testfile16.debug.bz2 \ testfile17.bz2 testfile17.debug.bz2 \ @@ -117,7 +117,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ coverage.sh test-subr.sh test-wrapper.sh run-readelf-test1.sh \ run-bug1-test.sh testfile28.bz2 testfile28.rdwr.bz2 \ testfile29.bz2 testfile29.rdwr.bz2 \ - testfile30.bz2 testfile31.bz2 + testfile30.bz2 testfile31.bz2 testfile32.bz2 testfile33.bz2 \ + testfile34.bz2 installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir) \ bindir=$(DESTDIR)$(bindir) \ diff --git a/tests/run-addrname-test.sh b/tests/run-addrname-test.sh new file mode 100755 index 000000000..6469646c1 --- /dev/null +++ b/tests/run-addrname-test.sh @@ -0,0 +1,47 @@ +#! /bin/sh +# Copyright (C) 2007 Red Hat, Inc. +# This file is part of Red Hat elfutils. +# +# Red Hat elfutils is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# Red Hat elfutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Red Hat elfutils; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. +# +# Red Hat elfutils is an included package of the Open Invention Network. +# An included package of the Open Invention Network is a package for which +# Open Invention Network licensees cross-license their patents. No patent +# license is granted, either expressly or impliedly, by designation as an +# included package. Should you wish to participate in the Open Invention +# Network licensing program, please visit www.openinventionnetwork.com +# . + +. $srcdir/test-subr.sh + +testfiles testfile34 + +testrun_compare ../src/addr2line -f -e testfile34 \ + 0x08048074 0x08048075 0x08048076 \ + 0x08049078 0x08048080 0x08049080 <<\EOF +foo +??:0 +bar +??:0 +_etext +??:0 +data1 +??:0 +?? +??:0 +_end +??:0 +EOF + +exit 0 diff --git a/tests/run-elflint-test.sh b/tests/run-elflint-test.sh index 021802042..660f10703 100755 --- a/tests/run-elflint-test.sh +++ b/tests/run-elflint-test.sh @@ -1,5 +1,5 @@ #! /bin/sh -# Copyright (C) 2005 Red Hat, Inc. +# Copyright (C) 2005, 2007 Red Hat, Inc. # This file is part of Red Hat elfutils. # Written by Ulrich Drepper , 2005. # @@ -32,4 +32,10 @@ testrun_compare ../src/elflint --gnu-ld testfile18 <<\EOF section [ 8] '.rela.dyn': relocation 1: copy relocation against symbol of type FUNC EOF +testfiles testfile32 +testrun ../src/elflint -q testfile32 + +testfiles testfile33 +testrun ../src/elflint -q testfile33 + exit 0 diff --git a/tests/testfile32.bz2 b/tests/testfile32.bz2 new file mode 100644 index 000000000..7e3c73e6b Binary files /dev/null and b/tests/testfile32.bz2 differ diff --git a/tests/testfile33.bz2 b/tests/testfile33.bz2 new file mode 100644 index 000000000..f3dbc73c9 Binary files /dev/null and b/tests/testfile33.bz2 differ diff --git a/tests/testfile34.bz2 b/tests/testfile34.bz2 new file mode 100644 index 000000000..a417fcb53 Binary files /dev/null and b/tests/testfile34.bz2 differ