diff options
-rw-r--r-- | src/ChangeLog | 7 | ||||
-rw-r--r-- | src/elfcompress.c | 45 |
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"), |