summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRoland McGrath <[email protected]>2011-02-15 09:34:08 -0800
committerRoland McGrath <[email protected]>2011-02-15 09:34:08 -0800
commitdb9d94008cbb190a35d4107554f7766fbaa3e40e (patch)
tree66e655bcb90227c34dba1b83df9cc8cf7b1ddaba /src
parenta74a3171e247e6433df37a95f0d0d6404aa07594 (diff)
parent170ecbd2b0578aa9b9408432dbca1fada0f9d80e (diff)
Merge commit 'elfutils-0.152' into dwarf
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog24
-rw-r--r--src/elfcmp.c169
-rw-r--r--src/elflint.c20
-rw-r--r--src/ldgeneric.c4
-rw-r--r--src/ldscript.y5
-rw-r--r--src/unstrip.c4
6 files changed, 177 insertions, 49 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 338eedb8..096c4e7a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,27 @@
+2011-02-11 Roland McGrath <[email protected]>
+
+ * elfcmp.c (verbose): New variable.
+ (options, parse_opt): Grok -l/--verbose to set it.
+ (main): Under -l, keep going after first difference.
+
+ * elfcmp.c (ignore_build_id): New variable.
+ (options, parse_opt): Grok --ignore-build-id to set it.
+ (main): For SHT_NOTE sections, compare note details rather than raw
+ bytes. Under --ignore-build-id, don't complain about differing build
+ ID contents if lengths match.
+
+2011-02-08 Roland McGrath <[email protected]>
+
+ * ldscript.y (filename_id_star): Remove unused variable.
+
+ * unstrip.c (copy_elided_sections): Remove unused variable.
+
+ * elflint.c (check_dynamic): Remove unused variables.
+
+ * elflint.c (check_symtab): Warn about missing xndx section only once.
+
+ * ldgeneric.c (check_for_duplicate2): Remove unused variable.
+
2011-01-06 Roland McGrath <[email protected]>
* strip.c (handle_elf): Under --strip-sections, remove all
diff --git a/src/elfcmp.c b/src/elfcmp.c
index 71a80092..b589dda8 100644
--- a/src/elfcmp.c
+++ b/src/elfcmp.c
@@ -1,5 +1,5 @@
/* Compare relevant content of two ELF files.
- Copyright (C) 2005-2010 Red Hat, Inc.
+ Copyright (C) 2005-2011 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <[email protected]>, 2005.
@@ -62,14 +62,19 @@ ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
/* Values for the parameters which have no short form. */
#define OPT_GAPS 0x100
#define OPT_HASH_INEXACT 0x101
+#define OPT_IGNORE_BUILD_ID 0x102
/* Definitions of arguments for argp functions. */
static const struct argp_option options[] =
{
{ NULL, 0, NULL, 0, N_("Control options:"), 0 },
+ { "verbose", 'l', NULL, 0,
+ N_("Output all differences, not just the first"), 0 },
{ "gaps", OPT_GAPS, "ACTION", 0, N_("Control treatment of gaps in loadable segments [ignore|match] (default: ignore)"), 0 },
{ "hash-inexact", OPT_HASH_INEXACT, NULL, 0,
N_("Ignore permutation of buckets in SHT_HASH section"), 0 },
+ { "ignore-build-id", OPT_IGNORE_BUILD_ID, NULL, 0,
+ N_("Ignore differences in build ID"), 0 },
{ "quiet", 'q', NULL, 0, N_("Output nothing; yield exit status only"), 0 },
{ NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 },
@@ -112,9 +117,15 @@ struct region
/* Nonzero if only exit status is wanted. */
static bool quiet;
+/* True iff multiple differences should be output. */
+static bool verbose;
+
/* True iff SHT_HASH treatment should be generous. */
static bool hash_inexact;
+/* True iff build ID notes should be ignored. */
+static bool ignore_build_id;
+
static bool hash_content_equivalent (size_t entsize, Elf_Data *, Elf_Data *);
@@ -142,6 +153,9 @@ main (int argc, char *argv[])
exit (1);
}
+ if (quiet)
+ verbose = false;
+
/* Comparing the files is done in two phases:
1. compare all sections. Sections which are irrelevant (i.e., if
strip would remove them) are ignored. Some section types are
@@ -173,6 +187,15 @@ main (int argc, char *argv[])
error (2, 0, gettext ("cannot get ELF header of '%s': %s"),
fname2, elf_errmsg (-1));
+#define DIFFERENCE \
+ do \
+ { \
+ result = 1; \
+ if (! verbose) \
+ goto out; \
+ } \
+ while (0)
+
/* Compare the ELF headers. */
if (unlikely (memcmp (ehdr1->e_ident, ehdr2->e_ident, EI_NIDENT) != 0
|| ehdr1->e_type != ehdr2->e_type
@@ -188,8 +211,7 @@ main (int argc, char *argv[])
{
if (! quiet)
error (0, 0, gettext ("%s %s diff: ELF header"), fname1, fname2);
- result = 1;
- goto out;
+ DIFFERENCE;
}
size_t shnum1;
@@ -204,8 +226,7 @@ main (int argc, char *argv[])
{
if (! quiet)
error (0, 0, gettext ("%s %s diff: section count"), fname1, fname2);
- result = 1;
- goto out;
+ DIFFERENCE;
}
size_t phnum1;
@@ -221,8 +242,7 @@ main (int argc, char *argv[])
if (! quiet)
error (0, 0, gettext ("%s %s diff: program header count"),
fname1, fname2);
- result = 1;
- goto out;
+ DIFFERENCE;
}
/* Iterate over all sections. We expect the sections in the two
@@ -277,11 +297,9 @@ main (int argc, char *argv[])
location. */
if (unlikely (strcmp (sname1, sname2) != 0))
{
- header_mismatch:
- error (0, 0, gettext ("%s %s differ: section header"),
- fname1, fname2);
- result = 1;
- goto out;
+ error (0, 0, gettext ("%s %s differ: section [%zu], [%zu] name"),
+ fname1, fname2, elf_ndxscn (scn1), elf_ndxscn (scn2));
+ DIFFERENCE;
}
/* We ignore certain sections. */
@@ -301,7 +319,11 @@ main (int argc, char *argv[])
|| shdr1->sh_info != shdr2->sh_info
|| shdr1->sh_addralign != shdr2->sh_addralign
|| shdr1->sh_entsize != shdr2->sh_entsize)
- goto header_mismatch;
+ {
+ error (0, 0, gettext ("%s %s differ: section [%zu] '%s' header"),
+ fname1, fname2, elf_ndxscn (scn1), sname1);
+ DIFFERENCE;
+ }
Elf_Data *data1 = elf_getdata (scn1, NULL);
if (data1 == NULL)
@@ -363,8 +385,8 @@ main (int argc, char *argv[])
fname1, fname2, elf_ndxscn (scn1),
elf_ndxscn (scn2));
}
- result = 1;
- goto out;
+ DIFFERENCE;
+ break;
}
if (sym1->st_shndx == SHN_UNDEF
@@ -385,6 +407,102 @@ main (int argc, char *argv[])
}
break;
+ case SHT_NOTE:
+ /* Parse the note format and compare the notes themselves. */
+ {
+ GElf_Nhdr note1;
+ GElf_Nhdr note2;
+
+ size_t off1 = 0;
+ size_t off2 = 0;
+ size_t name_offset;
+ size_t desc_offset;
+ while (off1 < data1->d_size
+ && (off1 = gelf_getnote (data1, off1, &note1,
+ &name_offset, &desc_offset)) > 0)
+ {
+ const char *name1 = data1->d_buf + name_offset;
+ const void *desc1 = data1->d_buf + desc_offset;
+ if (off2 >= data2->d_size)
+ {
+ if (! quiet)
+ error (0, 0, gettext ("\
+%s %s differ: section [%zu] '%s' number of notes"),
+ fname1, fname2, elf_ndxscn (scn1), sname1);
+ DIFFERENCE;
+ }
+ off2 = gelf_getnote (data2, off2, &note2,
+ &name_offset, &desc_offset);
+ if (off2 == 0)
+ error (2, 0, gettext ("\
+cannot read note section [%zu] '%s' in '%s': %s"),
+ elf_ndxscn (scn2), sname2, fname2, elf_errmsg (-1));
+ const char *name2 = data2->d_buf + name_offset;
+ const void *desc2 = data2->d_buf + desc_offset;
+
+ if (note1.n_namesz != note2.n_namesz
+ || memcmp (name1, name2, note1.n_namesz))
+ {
+ if (! quiet)
+ error (0, 0, gettext ("\
+%s %s differ: section [%zu] '%s' note name"),
+ fname1, fname2, elf_ndxscn (scn1), sname1);
+ DIFFERENCE;
+ }
+ if (note1.n_type != note2.n_type)
+ {
+ if (! quiet)
+ error (0, 0, gettext ("\
+%s %s differ: section [%zu] '%s' note '%s' type"),
+ fname1, fname2, elf_ndxscn (scn1), sname1, name1);
+ DIFFERENCE;
+ }
+ if (note1.n_descsz != note2.n_descsz
+ || memcmp (desc1, desc2, note1.n_descsz))
+ {
+ if (note1.n_type == NT_GNU_BUILD_ID
+ && note1.n_namesz == sizeof "GNU"
+ && !memcmp (name1, "GNU", sizeof "GNU"))
+ {
+ if (note1.n_descsz != note2.n_descsz)
+ {
+ if (! quiet)
+ error (0, 0, gettext ("\
+%s %s differ: build ID length"),
+ fname1, fname2);
+ DIFFERENCE;
+ }
+ else if (! ignore_build_id)
+ {
+ if (! quiet)
+ error (0, 0, gettext ("\
+%s %s differ: build ID content"),
+ fname1, fname2);
+ DIFFERENCE;
+ }
+ }
+ else
+ {
+ if (! quiet)
+ error (0, 0, gettext ("\
+%s %s differ: section [%zu] '%s' note '%s' content"),
+ fname1, fname2, elf_ndxscn (scn1), sname1,
+ name1);
+ DIFFERENCE;
+ }
+ }
+ }
+ if (off2 < data2->d_size)
+ {
+ if (! quiet)
+ error (0, 0, gettext ("\
+%s %s differ: section [%zu] '%s' number of notes"),
+ fname1, fname2, elf_ndxscn (scn1), sname1);
+ DIFFERENCE;
+ }
+ }
+ break;
+
default:
/* Compare the section content byte for byte. */
assert (shdr1->sh_type == SHT_NOBITS
@@ -415,8 +533,7 @@ main (int argc, char *argv[])
fname1, fname2, elf_ndxscn (scn1),
elf_ndxscn (scn2), sname1);
}
- result = 1;
- goto out;
+ DIFFERENCE;
}
break;
}
@@ -428,8 +545,7 @@ main (int argc, char *argv[])
error (0, 0,
gettext ("%s %s differ: unequal amount of important sections"),
fname1, fname2);
- result = 1;
- goto out;
+ DIFFERENCE;
}
/* We we look at gaps, create artificial ones for the parts of the
@@ -498,8 +614,7 @@ main (int argc, char *argv[])
if (! quiet)
error (0, 0, gettext ("%s %s differ: program header %d"),
fname1, fname2, ndx);
- result = 1;
- goto out;
+ DIFFERENCE;
}
if (gaps != gaps_ignore && phdr1->p_type == PT_LOAD)
@@ -523,8 +638,8 @@ main (int argc, char *argv[])
if (!quiet)
error (0, 0, gettext ("%s %s differ: gap"),
fname1, fname2);
- result = 1;
- goto out;
+ DIFFERENCE;
+ break;
}
}
@@ -572,6 +687,10 @@ parse_opt (int key, char *arg,
quiet = true;
break;
+ case 'l':
+ verbose = true;
+ break;
+
case OPT_GAPS:
if (strcasecmp (arg, "ignore") == 0)
gaps = gaps_ignore;
@@ -592,6 +711,10 @@ parse_opt (int key, char *arg,
hash_inexact = true;
break;
+ case OPT_IGNORE_BUILD_ID:
+ ignore_build_id = true;
+ break;
+
default:
return ARGP_ERR_UNKNOWN;
}
diff --git a/src/elflint.c b/src/elflint.c
index afe8bee6..c1227355 100644
--- a/src/elflint.c
+++ b/src/elflint.c
@@ -1,5 +1,5 @@
/* Pedantic checking of ELF files compliance with gABI/psABI spec.
- Copyright (C) 2001-2010 Red Hat, Inc.
+ Copyright (C) 2001-2011 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <[email protected]>, 2001.
@@ -697,9 +697,10 @@ section [%2d] '%s': symbol %zu: invalid name value\n"),
{
if (xndxdata == NULL)
{
- ERROR (gettext ("\
+ if (!no_xndx_warned)
+ ERROR (gettext ("\
section [%2d] '%s': symbol %zu: too large section index but no extended section index section\n"),
- idx, section_name (ebl, idx), cnt);
+ idx, section_name (ebl, idx), cnt);
no_xndx_warned = true;
}
else if (xndx < SHN_LORESERVE)
@@ -1573,10 +1574,6 @@ check_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
[DT_STRSZ] = true,
[DT_SYMENT] = true
};
- GElf_Addr reladdr = 0;
- GElf_Word relsz = 0;
- GElf_Addr pltreladdr = 0;
- GElf_Word pltrelsz = 0;
memset (has_dt, '\0', sizeof (has_dt));
memset (has_val_dt, '\0', sizeof (has_val_dt));
@@ -1674,15 +1671,6 @@ section [%2d] '%s': entry %zu: level 2 tag %s used\n"),
section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"),
idx, section_name (ebl, idx), cnt);
- if (dyn->d_tag == DT_REL)
- reladdr = dyn->d_un.d_ptr;
- if (dyn->d_tag == DT_RELSZ)
- relsz = dyn->d_un.d_val;
- if (dyn->d_tag == DT_JMPREL)
- pltreladdr = dyn->d_un.d_ptr;
- if (dyn->d_tag == DT_PLTRELSZ)
- pltrelsz = dyn->d_un.d_val;
-
/* Check that addresses for entries are in loaded segments. */
switch (dyn->d_tag)
{
diff --git a/src/ldgeneric.c b/src/ldgeneric.c
index b2ea2f90..d51b54fe 100644
--- a/src/ldgeneric.c
+++ b/src/ldgeneric.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 Red Hat, Inc.
+/* Copyright (C) 2001-2011 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <[email protected]>, 2001.
@@ -285,12 +285,10 @@ static int
check_for_duplicate2 (struct usedfiles *newp, struct usedfiles *list)
{
struct usedfiles *first;
- struct usedfiles *prevp;
if (list == NULL)
return 0;
- prevp = list;
list = first = list->next;
do
{
diff --git a/src/ldscript.y b/src/ldscript.y
index 85174c7a..c2f1971a 100644
--- a/src/ldscript.y
+++ b/src/ldscript.y
@@ -1,6 +1,6 @@
%{
/* Parser for linker scripts.
- Copyright (C) 2001-2010 Red Hat, Inc.
+ Copyright (C) 2001-2011 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <[email protected]>, 2001.
@@ -802,12 +802,9 @@ add_versions (struct version *versions)
do
{
- struct version *oldp;
-
add_id_list (versions->versionname, versions->local_names, true);
add_id_list (versions->versionname, versions->global_names, false);
- oldp = versions;
versions = versions->next;
}
while (versions != NULL);
diff --git a/src/unstrip.c b/src/unstrip.c
index 443cd620..3283d736 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -1,5 +1,5 @@
/* Combine stripped files with separate symbols and debug information.
- Copyright (C) 2007-2010 Red Hat, Inc.
+ Copyright (C) 2007-2011 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Roland McGrath <[email protected]>, 2007.
@@ -1301,7 +1301,6 @@ more sections in stripped file than debug file -- arguments reversed?"));
/* Match each debuginfo section with its corresponding stripped section. */
bool check_prelink = false;
Elf_Scn *unstripped_symtab = NULL;
- size_t unstripped_strtab_ndx = SHN_UNDEF;
size_t alloc_avail = 0;
scn = NULL;
while ((scn = elf_nextscn (unstripped, scn)) != NULL)
@@ -1313,7 +1312,6 @@ more sections in stripped file than debug file -- arguments reversed?"));
if (shdr->sh_type == SHT_SYMTAB)
{
unstripped_symtab = scn;
- unstripped_strtab_ndx = shdr->sh_link;
continue;
}