summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlrich Drepper <[email protected]>2007-02-05 07:25:33 +0000
committerUlrich Drepper <[email protected]>2007-02-05 07:25:33 +0000
commitaa915fd3d70b4cbe4581f9ec170d986c6ba35063 (patch)
tree7345e23df9aa4cfcab4eb9afafa0dac6ed16e182
parentce0bdb6ee5f977af9e565f2871ba2b1b37d162a5 (diff)
propagate from branch 'com.redhat.elfutils.roland.pending' (head c44dcfac5b545aecb173fede31f34cb003be0173)
to branch 'com.redhat.elfutils' (head 4196d4e01486bdeb0c0632291881d1c6d7163fab)
-rw-r--r--backends/ChangeLog7
-rw-r--r--backends/ia64_init.c3
-rw-r--r--backends/ia64_symbol.c11
-rw-r--r--libdw/ChangeLog7
-rw-r--r--libdw/dwarf_getelf.c4
-rw-r--r--libdw/libdw.map8
-rw-r--r--libdwfl/ChangeLog29
-rw-r--r--libdwfl/argp-std.c6
-rw-r--r--libdwfl/derelocate.c15
-rw-r--r--libdwfl/dwfl_addrmodule.c15
-rw-r--r--libdwfl/dwfl_module_addrname.c67
-rw-r--r--libdwfl/dwfl_version.c4
-rw-r--r--libdwfl/libdwfl.h3
-rw-r--r--libdwfl/linux-kernel-modules.c6
-rw-r--r--libdwfl/offline.c13
-rw-r--r--libdwfl/relocate.c15
-rw-r--r--libebl/ChangeLog9
-rw-r--r--libebl/Makefile.am5
-rw-r--r--libebl/ebl-hooks.h5
-rw-r--r--libebl/eblmachinesectionflagcheck.c63
-rw-r--r--libebl/eblopenbackend.c10
-rw-r--r--libebl/libebl.h5
-rw-r--r--libelf/ChangeLog13
-rw-r--r--libelf/elf32_getshdr.c69
-rw-r--r--libelf/gelf_rawchunk.c3
-rw-r--r--libelf/gnuhash_xlate.h4
-rw-r--r--src/ChangeLog5
-rw-r--r--src/elflint.c25
-rw-r--r--tests/ChangeLog23
-rw-r--r--tests/Makefile.am7
-rwxr-xr-xtests/run-addrname-test.sh47
-rwxr-xr-xtests/run-elflint-test.sh8
-rw-r--r--tests/testfile32.bz2bin0 -> 5778 bytes
-rw-r--r--tests/testfile33.bz2bin0 -> 35075 bytes
-rw-r--r--tests/testfile34.bz2bin0 -> 315 bytes
35 files changed, 430 insertions, 84 deletions
diff --git a/backends/ChangeLog b/backends/ChangeLog
index 86ac44b9..57f33608 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,10 @@
+2007-01-11 Roland McGrath <[email protected]>
+
+ * 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 <[email protected]>
* 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 acae2346..290c192c 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 <[email protected]>, 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 4faec0c9..2609db0f 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 <[email protected]>, 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 19c5d11b..814299b8 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,10 @@
+2007-02-03 Roland McGrath <[email protected]>
+
+ * 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 <[email protected]>
* dwarf_getlocation.c (dwarf_getlocation_addr): Use zero as base
diff --git a/libdw/dwarf_getelf.c b/libdw/dwarf_getelf.c
index a6724623..daf3b9a7 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 <[email protected]>, 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 6ee42ece..71e9f50f 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 0439d4cf..71b167f3 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,32 @@
+2007-02-02 Roland McGrath <[email protected]>
+
+ * 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 <[email protected]>
+
+ * dwfl_version.c (dwfl_version): Return PACKAGE_VERSION,
+ not PACKAGE_STRING.
+
+2007-01-20 Roland McGrath <[email protected]>
+
+ * 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 <[email protected]>
+
+ * 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 <[email protected]>
* linux-kernel-modules.c (report_kernel): Check asprintf return value
diff --git a/libdwfl/argp-std.c b/libdwfl/argp-std.c
index bec370a3..c12cb1dd 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 c26be8d8..d110299e 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 98c4b39f..54d9a3d9 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 19b4c2d3..b107448b 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 c78d828b..9c7074c5 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 9fe3dca0..ec006562 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 a3986386..4ea391c0 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 c5193860..bde2aeb9 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 96cedcc3..f37f8350 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 33fde08b..07f640ed 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,12 @@
+2007-01-11 Roland McGrath <[email protected]>
+
+ * 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 <[email protected]>
* ebl-hooks.h: Replace register_name hook with register_info.
diff --git a/libebl/Makefile.am b/libebl/Makefile.am
index 48042d9f..741e5eee 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 944e6404..5344df09 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 00000000..9eb6d386
--- /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
+ <http://www.openinventionnetwork.com>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+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 dba22ba1..5b1a7193 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 3375525d..1465fb1a 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 14001c7a..17985781 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -8,6 +8,19 @@
* nlist.c: Close file descriptor before returning.
+2007-01-20 Roland McGrath <[email protected]>
+
+ * 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 <[email protected]>
+
+ * gelf_rawchunk.c (gelf_rawchunk): Clear RESULT pointer after freeing
+ it on read error.
+
2006-10-13 Roland McGrath <[email protected]>
* 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 4abd2c10..cafb1d4f 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 <[email protected]>, 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 cab07be5..ced6f9ef 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 <[email protected]>, 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 9012ffa1..d79764d8 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 <[email protected]>, 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 6e619e0d..c2ce90fd 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2007-01-11 Roland McGrath <[email protected]>
+
+ * 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 <[email protected]>
* ar.c: New file.
diff --git a/src/elflint.c b/src/elflint.c
index 79e52299..09c7fbd2 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 2aaba2fa..5b188f84 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,26 @@
+2007-02-02 Roland McGrath <[email protected]>
+
+ * 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 <[email protected]>
+
+ * testfile33.bz2: New data file.
+ * Makefile.am (EXTRA_DIST): Add it.
+ * run-elflint-test.sh: Test on it too.
+
+2007-01-18 Roland McGrath <[email protected]>
+
+ * Makefile.am (CFLAGS): Don't molest it.
+
+2007-01-11 Roland McGrath <[email protected]>
+
+ * testfile32.bz2: New data file.
+ * Makefile.am (EXTRA_DIST): Add it.
+ * run-elflint-test.sh: Test on it too.
+
2007-02-04 Ulrich Drepper <[email protected]>
* arls.c: New file.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index bd56f7b7..bff5568b 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 00000000..6469646c
--- /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
+# <http://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 02180204..660f1070 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 <[email protected]>, 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 00000000..7e3c73e6
--- /dev/null
+++ b/tests/testfile32.bz2
Binary files differ
diff --git a/tests/testfile33.bz2 b/tests/testfile33.bz2
new file mode 100644
index 00000000..f3dbc73c
--- /dev/null
+++ b/tests/testfile33.bz2
Binary files differ
diff --git a/tests/testfile34.bz2 b/tests/testfile34.bz2
new file mode 100644
index 00000000..a417fcb5
--- /dev/null
+++ b/tests/testfile34.bz2
Binary files differ