diff options
| author | Roland McGrath <[email protected]> | 2011-02-15 09:34:08 -0800 |
|---|---|---|
| committer | Roland McGrath <[email protected]> | 2011-02-15 09:34:08 -0800 |
| commit | db9d94008cbb190a35d4107554f7766fbaa3e40e (patch) | |
| tree | 66e655bcb90227c34dba1b83df9cc8cf7b1ddaba /src | |
| parent | a74a3171e247e6433df37a95f0d0d6404aa07594 (diff) | |
| parent | 170ecbd2b0578aa9b9408432dbca1fada0f9d80e (diff) | |
Merge commit 'elfutils-0.152' into dwarf
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 24 | ||||
| -rw-r--r-- | src/elfcmp.c | 169 | ||||
| -rw-r--r-- | src/elflint.c | 20 | ||||
| -rw-r--r-- | src/ldgeneric.c | 4 | ||||
| -rw-r--r-- | src/ldscript.y | 5 | ||||
| -rw-r--r-- | src/unstrip.c | 4 |
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, ¬e1, + &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, ¬e2, + &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; } |
