summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2018-07-21 17:07:12 +0200
committerMark Wielaard <mark@klomp.org>2018-07-24 09:56:34 +0200
commited62996defc619d0def86a5ed223a48486b97a70 (patch)
treed43df5ecb934d8bed99879604611408c0a62fc57
parentdf9053f67c637fd240771705bb926a6d0e3381cf (diff)
elfcompress: Don't rewrite file if no section data needs to be updated.
If the input and output file are the same and no section needs to be updated we really don't need to rewrite the file. Check whether any matching section is already compressed or decompressed. Skip the section if it doesn't need to be changed. If no section data needs updating end with success without rewriting/updating file. With --force the file will still always be updated/rewritten even if no section data needs to be (de)compressed. Acked-by: Igor Gnatenko <ignatenkobrain@fedoraproject.org> Signed-off-by: Mark Wielaard <mark@klomp.org>
-rw-r--r--src/ChangeLog7
-rw-r--r--src/elfcompress.c45
2 files changed, 49 insertions, 3 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 0e9ab301..39214c39 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,12 @@
2018-07-21 Mark Wielaard <mark@klomp.org>
+ * elfcompress.c (get_sections): New function.
+ (process_file): Check whether section needs to change. Don't rewrite
+ file if no section data needs changing.
+ (main): Update 'force' help text.
+
+2018-07-21 Mark Wielaard <mark@klomp.org>
+
* elfcompress.c (process_file): Swap fchmod and fchown calls.
2018-07-04 Mark Wielaard <mark@klomp.org>
diff --git a/src/elfcompress.c b/src/elfcompress.c
index 1a0f9845..6ba6af41 100644
--- a/src/elfcompress.c
+++ b/src/elfcompress.c
@@ -1,5 +1,5 @@
/* Compress or decompress an ELF file.
- Copyright (C) 2015, 2016 Red Hat, Inc.
+ Copyright (C) 2015, 2016, 2018 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -286,6 +286,15 @@ process_file (const char *fname)
return (sections[ndx / WORD_BITS] & (1U << (ndx % WORD_BITS))) != 0;
}
+ /* How many sections are we going to change? */
+ size_t get_sections (void)
+ {
+ size_t s = 0;
+ for (size_t i = 0; i < shnum / WORD_BITS + 1; i++)
+ s += __builtin_popcount (sections[i]);
+ return s;
+ }
+
int cleanup (int res)
{
elf_end (elf);
@@ -422,6 +431,9 @@ process_file (const char *fname)
names change and whether there is a symbol table that might need
to be adjusted be if the section header name table is changed.
+ If nothing needs changing, and the input and output file are the
+ same, we are done.
+
Second a collection pass that creates the Elf sections and copies
the data. This pass will compress/decompress section data when
needed. And it will collect all data needed if we'll need to
@@ -464,7 +476,26 @@ process_file (const char *fname)
if (section_name_matches (sname))
{
- if (shdr->sh_type != SHT_NOBITS
+ if (!force && type == T_DECOMPRESS
+ && (shdr->sh_flags & SHF_COMPRESSED) == 0
+ && strncmp (sname, ".zdebug", strlen (".zdebug")) != 0)
+ {
+ if (verbose > 0)
+ printf ("[%zd] %s already decompressed\n", ndx, sname);
+ }
+ else if (!force && type == T_COMPRESS_ZLIB
+ && (shdr->sh_flags & SHF_COMPRESSED) != 0)
+ {
+ if (verbose > 0)
+ printf ("[%zd] %s already compressed\n", ndx, sname);
+ }
+ else if (!force && type == T_COMPRESS_GNU
+ && strncmp (sname, ".zdebug", strlen (".zdebug")) == 0)
+ {
+ if (verbose > 0)
+ printf ("[%zd] %s already GNU compressed\n", ndx, sname);
+ }
+ else if (shdr->sh_type != SHT_NOBITS
&& (shdr->sh_flags & SHF_ALLOC) == 0)
{
set_section (ndx);
@@ -518,6 +549,14 @@ process_file (const char *fname)
}
}
+ if (foutput == NULL && get_sections () == 0)
+ {
+ if (verbose > 0)
+ printf ("Nothing to do.\n");
+ fnew = NULL;
+ return cleanup (0);
+ }
+
if (adjust_names)
{
names = dwelf_strtab_init (true);
@@ -1279,7 +1318,7 @@ main (int argc, char **argv)
N_("Print a message for each section being (de)compressed"),
0 },
{ "force", 'f', NULL, 0,
- N_("Force compression of section even if it would become larger"),
+ N_("Force compression of section even if it would become larger or update/rewrite the file even if no section would be (de)compressed"),
0 },
{ "permissive", 'p', NULL, 0,
N_("Relax a few rules to handle slightly broken ELF files"),