summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2011-02-11 10:42:45 -0800
committerRoland McGrath <roland@redhat.com>2011-02-11 10:42:45 -0800
commit4a14ef7b9a4b274fd45d17512cf0da42956b672b (patch)
treed51079286140f54937b2bcc2e259dcf2dcf49349
parent1fb9c917a55fa30c5f6b27c30727a796f9b1e804 (diff)
downloadelfutils-4a14ef7b9a4b274fd45d17512cf0da42956b672b.tar.gz
elfcmp: Add --l/--verbose flag.
-rw-r--r--NEWS1
-rw-r--r--src/ChangeLog4
-rw-r--r--src/elfcmp.c82
3 files changed, 51 insertions, 36 deletions
diff --git a/NEWS b/NEWS
index 989572b0..2a04daa4 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ Various build and warning nits fixed for newest GCC and Autoconf.
libdwfl: Yet another prelink-related fix for another regression.
elfcmp: New flag --ignore-build-id to ignore differing build ID bits.
+ New flag -l/--verbose to print all differences.
Version 0.151
diff --git a/src/ChangeLog b/src/ChangeLog
index 9ce621fa..d3d45b09 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,9 @@
2011-02-11 Roland McGrath <roland@redhat.com>
+ * 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
diff --git a/src/elfcmp.c b/src/elfcmp.c
index e1aec2bd..b589dda8 100644
--- a/src/elfcmp.c
+++ b/src/elfcmp.c
@@ -68,6 +68,8 @@ ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
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 },
@@ -115,6 +117,9 @@ 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;
@@ -148,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
@@ -179,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
@@ -194,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;
@@ -210,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;
@@ -227,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
@@ -283,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. */
@@ -307,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)
@@ -369,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
@@ -413,8 +429,7 @@ main (int argc, char *argv[])
error (0, 0, gettext ("\
%s %s differ: section [%zu] '%s' number of notes"),
fname1, fname2, elf_ndxscn (scn1), sname1);
- result = 1;
- goto out;
+ DIFFERENCE;
}
off2 = gelf_getnote (data2, off2, &note2,
&name_offset, &desc_offset);
@@ -432,8 +447,7 @@ cannot read note section [%zu] '%s' in '%s': %s"),
error (0, 0, gettext ("\
%s %s differ: section [%zu] '%s' note name"),
fname1, fname2, elf_ndxscn (scn1), sname1);
- result = 1;
- goto out;
+ DIFFERENCE;
}
if (note1.n_type != note2.n_type)
{
@@ -441,8 +455,7 @@ cannot read note section [%zu] '%s' in '%s': %s"),
error (0, 0, gettext ("\
%s %s differ: section [%zu] '%s' note '%s' type"),
fname1, fname2, elf_ndxscn (scn1), sname1, name1);
- result = 1;
- goto out;
+ DIFFERENCE;
}
if (note1.n_descsz != note2.n_descsz
|| memcmp (desc1, desc2, note1.n_descsz))
@@ -457,8 +470,7 @@ cannot read note section [%zu] '%s' in '%s': %s"),
error (0, 0, gettext ("\
%s %s differ: build ID length"),
fname1, fname2);
- result = 1;
- goto out;
+ DIFFERENCE;
}
else if (! ignore_build_id)
{
@@ -466,8 +478,7 @@ cannot read note section [%zu] '%s' in '%s': %s"),
error (0, 0, gettext ("\
%s %s differ: build ID content"),
fname1, fname2);
- result = 1;
- goto out;
+ DIFFERENCE;
}
}
else
@@ -477,8 +488,7 @@ cannot read note section [%zu] '%s' in '%s': %s"),
%s %s differ: section [%zu] '%s' note '%s' content"),
fname1, fname2, elf_ndxscn (scn1), sname1,
name1);
- result = 1;
- goto out;
+ DIFFERENCE;
}
}
}
@@ -488,8 +498,7 @@ cannot read note section [%zu] '%s' in '%s': %s"),
error (0, 0, gettext ("\
%s %s differ: section [%zu] '%s' number of notes"),
fname1, fname2, elf_ndxscn (scn1), sname1);
- result = 1;
- goto out;
+ DIFFERENCE;
}
}
break;
@@ -524,8 +533,7 @@ cannot read note section [%zu] '%s' in '%s': %s"),
fname1, fname2, elf_ndxscn (scn1),
elf_ndxscn (scn2), sname1);
}
- result = 1;
- goto out;
+ DIFFERENCE;
}
break;
}
@@ -537,8 +545,7 @@ cannot read note section [%zu] '%s' in '%s': %s"),
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
@@ -607,8 +614,7 @@ cannot read note section [%zu] '%s' in '%s': %s"),
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)
@@ -632,8 +638,8 @@ cannot read note section [%zu] '%s' in '%s': %s"),
if (!quiet)
error (0, 0, gettext ("%s %s differ: gap"),
fname1, fname2);
- result = 1;
- goto out;
+ DIFFERENCE;
+ break;
}
}
@@ -681,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;