xref: /aosp_15_r20/external/elfutils/src/elfcompress.c (revision 7304104da70ce23c86437a01be71edd1a2d7f37e)
1 /* Compress or decompress an ELF file.
2    Copyright (C) 2015, 2016, 2018 Red Hat, Inc.
3    This file is part of elfutils.
4 
5    This file is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9 
10    elfutils is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17 
18 #include <config.h>
19 #include <assert.h>
20 #include <argp.h>
21 #include <stdbool.h>
22 #include <stdlib.h>
23 #include <inttypes.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <locale.h>
27 #include <fcntl.h>
28 #include <fnmatch.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include ELFUTILS_HEADER(elf)
33 #include ELFUTILS_HEADER(ebl)
34 #include ELFUTILS_HEADER(dwelf)
35 #include <gelf.h>
36 #include "system.h"
37 #include "libeu.h"
38 #include "printversion.h"
39 
40 /* Name and version of program.  */
41 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
42 
43 /* Bug report address.  */
44 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
45 
46 static int verbose = 0; /* < 0, no warnings, > 0 extra verbosity.  */
47 static bool force = false;
48 static bool permissive = false;
49 static const char *foutput = NULL;
50 
51 /* Compression algorithm, where all legal values for ch_type
52    (compression algorithm) do match the following enum.  */
53 enum ch_type
54 {
55   UNSET = -1,
56   NONE,
57   ZLIB,
58   ZSTD,
59 
60   /* Maximal supported ch_type.  */
61   MAXIMAL_CH_TYPE = ZSTD,
62 
63   ZLIB_GNU = 1 << 16
64 };
65 
66 #define WORD_BITS (8U * sizeof (unsigned int))
67 
68 static enum ch_type type = UNSET;
69 
70 struct section_pattern
71 {
72   char *pattern;
73   struct section_pattern *next;
74 };
75 
76 static struct section_pattern *patterns = NULL;
77 
78 static void
add_pattern(const char * pattern)79 add_pattern (const char *pattern)
80 {
81   struct section_pattern *p = xmalloc (sizeof *p);
82   p->pattern = xstrdup (pattern);
83   p->next = patterns;
84   patterns = p;
85 }
86 
87 static void
free_patterns(void)88 free_patterns (void)
89 {
90   struct section_pattern *pattern = patterns;
91   while (pattern != NULL)
92     {
93       struct section_pattern *p = pattern;
94       pattern = p->next;
95       free (p->pattern);
96       free (p);
97     }
98 }
99 
100 static error_t
parse_opt(int key,char * arg,struct argp_state * state)101 parse_opt (int key, char *arg __attribute__ ((unused)),
102 	   struct argp_state *state __attribute__ ((unused)))
103 {
104   switch (key)
105     {
106     case 'v':
107       verbose++;
108       break;
109 
110     case 'q':
111       verbose--;
112       break;
113 
114     case 'f':
115       force = true;
116       break;
117 
118     case 'p':
119       permissive = true;
120       break;
121 
122     case 'n':
123       add_pattern (arg);
124       break;
125 
126     case 'o':
127       if (foutput != NULL)
128 	argp_error (state, N_("-o option specified twice"));
129       else
130 	foutput = arg;
131       break;
132 
133     case 't':
134       if (type != UNSET)
135 	argp_error (state, N_("-t option specified twice"));
136 
137       if (strcmp ("none", arg) == 0)
138 	type = NONE;
139       else if (strcmp ("zlib", arg) == 0 || strcmp ("zlib-gabi", arg) == 0)
140 	type = ZLIB;
141       else if (strcmp ("zlib-gnu", arg) == 0 || strcmp ("gnu", arg) == 0)
142 	type = ZLIB_GNU;
143       else if (strcmp ("zstd", arg) == 0)
144 #ifdef USE_ZSTD_COMPRESS
145 	type = ZSTD;
146 #else
147 	argp_error (state, N_("ZSTD support is not enabled"));
148 #endif
149       else
150 	argp_error (state, N_("unknown compression type '%s'"), arg);
151       break;
152 
153     case ARGP_KEY_SUCCESS:
154       if (type == UNSET)
155 	type = ZLIB;
156       if (patterns == NULL)
157 	add_pattern (".?(z)debug*");
158       break;
159 
160     case ARGP_KEY_NO_ARGS:
161       /* We need at least one input file.  */
162       argp_error (state, N_("No input file given"));
163       break;
164 
165     case ARGP_KEY_ARGS:
166       if (foutput != NULL && state->argc - state->next > 1)
167 	argp_error (state,
168 		    N_("Only one input file allowed together with '-o'"));
169       /* We only use this for checking the number of arguments, we don't
170 	 actually want to consume them.  */
171       FALLTHROUGH;
172     default:
173       return ARGP_ERR_UNKNOWN;
174     }
175   return 0;
176 }
177 
178 static bool
section_name_matches(const char * name)179 section_name_matches (const char *name)
180 {
181   struct section_pattern *pattern = patterns;
182   while (pattern != NULL)
183     {
184       if (fnmatch (pattern->pattern, name, FNM_EXTMATCH) == 0)
185 	return true;
186       pattern = pattern->next;
187     }
188   return false;
189 }
190 
191 static int
setshdrstrndx(Elf * elf,GElf_Ehdr * ehdr,size_t ndx)192 setshdrstrndx (Elf *elf, GElf_Ehdr *ehdr, size_t ndx)
193 {
194   if (ndx < SHN_LORESERVE)
195     ehdr->e_shstrndx = ndx;
196   else
197     {
198       ehdr->e_shstrndx = SHN_XINDEX;
199       Elf_Scn *zscn = elf_getscn (elf, 0);
200       GElf_Shdr zshdr_mem;
201       GElf_Shdr *zshdr = gelf_getshdr (zscn, &zshdr_mem);
202       if (zshdr == NULL)
203 	return -1;
204       zshdr->sh_link = ndx;
205       if (gelf_update_shdr (zscn, zshdr) == 0)
206 	return -1;
207     }
208 
209   if (gelf_update_ehdr (elf, ehdr) == 0)
210     return -1;
211 
212   return 0;
213 }
214 
215 static int
compress_section(Elf_Scn * scn,size_t orig_size,const char * name,const char * newname,size_t ndx,enum ch_type schtype,enum ch_type dchtype,bool report_verbose)216 compress_section (Elf_Scn *scn, size_t orig_size, const char *name,
217 		  const char *newname, size_t ndx,
218 		  enum ch_type schtype, enum ch_type dchtype,
219 		  bool report_verbose)
220 {
221   /* We either compress or decompress.  */
222   assert (schtype == NONE || dchtype == NONE);
223   bool compress = dchtype != NONE;
224 
225   int res;
226   unsigned int flags = compress && force ? ELF_CHF_FORCE : 0;
227   if (schtype == ZLIB_GNU || dchtype == ZLIB_GNU)
228     res = elf_compress_gnu (scn, compress ? 1 : 0, flags);
229   else
230     res = elf_compress (scn, dchtype, flags);
231 
232   if (res < 0)
233     error (0, 0, "Couldn't %s section [%zd] %s: %s",
234 	   compress ? "compress" : "decompress",
235 	   ndx, name, elf_errmsg (-1));
236   else
237     {
238       if (compress && res == 0)
239 	{
240 	  if (verbose >= 0)
241 	    printf ("[%zd] %s NOT compressed, wouldn't be smaller\n",
242 		    ndx, name);
243 	}
244 
245       if (report_verbose && res > 0)
246 	{
247 	  printf ("[%zd] %s %s", ndx, name,
248 		  compress ? "compressed" : "decompressed");
249 	  if (newname != NULL)
250 	    printf (" -> %s", newname);
251 
252 	  /* Reload shdr, it has changed.  */
253 	  GElf_Shdr shdr_mem;
254 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
255 	  if (shdr == NULL)
256 	    {
257 	      error (0, 0, "Couldn't get shdr for section [%zd]", ndx);
258 	      return -1;
259 	    }
260 	  float new = shdr->sh_size;
261 	  float orig = orig_size ?: 1;
262 	  printf (" (%zu => %" PRIu64 " %.2f%%)\n",
263 		  orig_size, shdr->sh_size, (new / orig) * 100);
264 	}
265     }
266 
267   return res;
268 }
269 
270 static void
set_section(unsigned int * sections,size_t ndx)271 set_section (unsigned int *sections, size_t ndx)
272 {
273   sections[ndx / WORD_BITS] |= (1U << (ndx % WORD_BITS));
274 }
275 
276 static bool
get_section(unsigned int * sections,size_t ndx)277 get_section (unsigned int *sections, size_t ndx)
278 {
279   return (sections[ndx / WORD_BITS] & (1U << (ndx % WORD_BITS))) != 0;
280 }
281 
282 /* How many sections are we going to change?  */
283 static size_t
get_sections(unsigned int * sections,size_t shnum)284 get_sections (unsigned int *sections, size_t shnum)
285 {
286   size_t s = 0;
287   for (size_t i = 0; i < shnum / WORD_BITS + 1; i++)
288     s += __builtin_popcount (sections[i]);
289   return s;
290 }
291 
292 /* Return compression type of a given section SHDR.  */
293 
294 static enum ch_type
get_section_chtype(Elf_Scn * scn,GElf_Shdr * shdr,const char * sname,size_t ndx)295 get_section_chtype (Elf_Scn *scn, GElf_Shdr *shdr, const char *sname,
296 		    size_t ndx)
297 {
298   enum ch_type chtype = UNSET;
299   if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
300     {
301       GElf_Chdr chdr;
302       if (gelf_getchdr (scn, &chdr) != NULL)
303 	{
304 	  chtype = (enum ch_type)chdr.ch_type;
305 	  if (chtype == NONE)
306 	    {
307 	      error (0, 0, "Compression type for section %zd"
308 		     " can't be zero ", ndx);
309 	      chtype = UNSET;
310 	    }
311 	  else if (chtype > MAXIMAL_CH_TYPE)
312 	    {
313 	      error (0, 0, "Compression type (%d) for section %zd"
314 		     " is unsupported ", chtype, ndx);
315 	      chtype = UNSET;
316 	    }
317 	}
318       else
319 	error (0, 0, "Couldn't get chdr for section %zd", ndx);
320     }
321   /* Set ZLIB_GNU compression manually for .zdebug* sections.  */
322   else if (startswith (sname, ".zdebug"))
323     chtype = ZLIB_GNU;
324   else
325     chtype = NONE;
326 
327   return chtype;
328 }
329 
330 static int
process_file(const char * fname)331 process_file (const char *fname)
332 {
333   if (verbose > 0)
334     printf ("processing: %s\n", fname);
335 
336   /* The input ELF.  */
337   int fd = -1;
338   Elf *elf = NULL;
339 
340   /* The output ELF.  */
341   char *fnew = NULL;
342   int fdnew = -1;
343   Elf *elfnew = NULL;
344 
345   /* Buffer for (one) new section name if necessary.  */
346   char *snamebuf = NULL;
347 
348   /* String table (and symbol table), if section names need adjusting.  */
349   Dwelf_Strtab *names = NULL;
350   Dwelf_Strent **scnstrents = NULL;
351   Dwelf_Strent **symstrents = NULL;
352   char **scnnames = NULL;
353 
354   /* Section data from names.  */
355   void *namesbuf = NULL;
356 
357   /* Which sections match and need to be (un)compressed.  */
358   unsigned int *sections = NULL;
359 
360   /* How many sections are we talking about?  */
361   size_t shnum = 0;
362   int res = 1;
363 
364   fd = open (fname, O_RDONLY);
365   if (fd < 0)
366     {
367       error (0, errno, "Couldn't open %s\n", fname);
368       goto cleanup;
369     }
370 
371   elf = elf_begin (fd, ELF_C_READ, NULL);
372   if (elf == NULL)
373     {
374       error (0, 0, "Couldn't open ELF file %s for reading: %s",
375 	     fname, elf_errmsg (-1));
376       goto cleanup;
377     }
378 
379   /* We don't handle ar files (or anything else), we probably should.  */
380   Elf_Kind kind = elf_kind (elf);
381   if (kind != ELF_K_ELF)
382     {
383       if (kind == ELF_K_AR)
384 	error (0, 0, "Cannot handle ar files: %s", fname);
385       else
386 	error (0, 0, "Unknown file type: %s", fname);
387       goto cleanup;
388     }
389 
390   struct stat st;
391   if (fstat (fd, &st) != 0)
392     {
393       error (0, errno, "Couldn't fstat %s", fname);
394       goto cleanup;
395     }
396 
397   GElf_Ehdr ehdr;
398   if (gelf_getehdr (elf, &ehdr) == NULL)
399     {
400       error (0, 0, "Couldn't get ehdr for %s: %s", fname, elf_errmsg (-1));
401       goto cleanup;
402     }
403 
404   /* Get the section header string table.  */
405   size_t shdrstrndx;
406   if (elf_getshdrstrndx (elf, &shdrstrndx) != 0)
407     {
408       error (0, 0, "Couldn't get section header string table index in %s: %s",
409 	     fname, elf_errmsg (-1));
410       goto cleanup;
411     }
412 
413   /* How many sections are we talking about?  */
414   if (elf_getshdrnum (elf, &shnum) != 0)
415     {
416       error (0, 0, "Couldn't get number of sections in %s: %s",
417 	     fname, elf_errmsg (1));
418       goto cleanup;
419     }
420 
421   if (shnum == 0)
422     {
423       error (0, 0, "ELF file %s has no sections", fname);
424       goto cleanup;
425     }
426 
427   sections = xcalloc (shnum / 8 + 1, sizeof (unsigned int));
428 
429   size_t phnum;
430   if (elf_getphdrnum (elf, &phnum) != 0)
431     {
432       error (0, 0, "Couldn't get phdrnum: %s", elf_errmsg (-1));
433       goto cleanup;
434     }
435 
436   /* Whether we need to adjust any section names (going to/from GNU
437      naming).  If so we'll need to build a new section header string
438      table.  */
439   bool adjust_names = false;
440 
441   /* If there are phdrs we want to maintain the layout of the
442      allocated sections in the file.  */
443   bool layout = phnum != 0;
444 
445   /* While going through all sections keep track of last section data
446      offset if needed to keep the layout.  We are responsible for
447      adding the section offsets and headers (e_shoff) in that case
448      (which we will place after the last section).  */
449   GElf_Off last_offset = 0;
450   if (layout)
451     last_offset = (ehdr.e_phoff
452 		   + gelf_fsize (elf, ELF_T_PHDR, phnum, EV_CURRENT));
453 
454   /* Which section, if any, is a symbol table that shares a string
455      table with the section header string table?  */
456   size_t symtabndx = 0;
457 
458   /* We do three passes over all sections.
459 
460      First an inspection pass over the old Elf to see which section
461      data needs to be copied and/or transformed, which sections need a
462      names change and whether there is a symbol table that might need
463      to be adjusted be if the section header name table is changed.
464 
465      If nothing needs changing, and the input and output file are the
466      same, we are done.
467 
468      Second a collection pass that creates the Elf sections and copies
469      the data.  This pass will compress/decompress section data when
470      needed.  And it will collect all data needed if we'll need to
471      construct a new string table. Afterwards the new string table is
472      constructed.
473 
474      Third a fixup/adjustment pass over the new Elf that will adjust
475      any section references (names) and adjust the layout based on the
476      new sizes of the sections if necessary.  This pass is optional if
477      we aren't responsible for the layout and the section header
478      string table hasn't been changed.  */
479 
480   /* Inspection pass.  */
481   size_t maxnamelen = 0;
482   Elf_Scn *scn = NULL;
483   while ((scn = elf_nextscn (elf, scn)) != NULL)
484     {
485       size_t ndx = elf_ndxscn (scn);
486       if (ndx > shnum)
487 	{
488 	  error (0, 0, "Unexpected section number %zd, expected only %zd",
489 		 ndx, shnum);
490 	  goto cleanup;
491 	}
492 
493       GElf_Shdr shdr_mem;
494       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
495       if (shdr == NULL)
496 	{
497 	  error (0, 0, "Couldn't get shdr for section %zd", ndx);
498 	  goto cleanup;
499 	}
500 
501       const char *sname = elf_strptr (elf, shdrstrndx, shdr->sh_name);
502       if (sname == NULL)
503 	{
504 	  error (0, 0, "Couldn't get name for section %zd", ndx);
505 	  goto cleanup;
506 	}
507 
508       if (section_name_matches (sname))
509 	{
510 	  enum ch_type schtype = get_section_chtype (scn, shdr, sname, ndx);
511 	  if (!force && verbose > 0)
512 	    {
513 	      /* The current compression matches the final one.  */
514 	      if (type == schtype)
515 		switch (type)
516 		  {
517 		  case NONE:
518 		    printf ("[%zd] %s already decompressed\n", ndx, sname);
519 		    break;
520 		  case ZLIB:
521 		  case ZSTD:
522 		    printf ("[%zd] %s already compressed\n", ndx, sname);
523 		    break;
524 		  case ZLIB_GNU:
525 		    printf ("[%zd] %s already GNU compressed\n", ndx, sname);
526 		    break;
527 		  default:
528 		    abort ();
529 		  }
530 	    }
531 
532 	  if (force || type != schtype)
533 	    {
534 	      if (shdr->sh_type != SHT_NOBITS
535 		  && (shdr->sh_flags & SHF_ALLOC) == 0)
536 		{
537 		  set_section (sections, ndx);
538 		  /* Check if we might want to change this section name.  */
539 		  if (! adjust_names
540 		      && ((type != ZLIB_GNU
541 			   && startswith (sname, ".zdebug"))
542 			  || (type == ZLIB_GNU
543 			      && startswith (sname, ".debug"))))
544 		    adjust_names = true;
545 
546 		  /* We need a buffer this large if we change the names.  */
547 		  if (adjust_names)
548 		    {
549 		      size_t slen = strlen (sname);
550 		      if (slen > maxnamelen)
551 			maxnamelen = slen;
552 		    }
553 		}
554 	      else
555 		if (verbose >= 0)
556 		  printf ("[%zd] %s ignoring %s section\n", ndx, sname,
557 			  (shdr->sh_type == SHT_NOBITS ? "no bits" : "allocated"));
558 	    }
559 	}
560 
561       if (shdr->sh_type == SHT_SYMTAB)
562 	{
563 	  /* Check if we might have to adjust the symbol name indexes.  */
564 	  if (shdr->sh_link == shdrstrndx)
565 	    {
566 	      if (symtabndx != 0)
567 		{
568 		  error (0, 0,
569 			 "Multiple symbol tables (%zd, %zd) using the same string table unsupported", symtabndx, ndx);
570 		  goto cleanup;
571 		}
572 	      symtabndx = ndx;
573 	    }
574 	}
575 
576       /* Keep track of last allocated data offset.  */
577       if (layout)
578 	if ((shdr->sh_flags & SHF_ALLOC) != 0)
579 	  {
580 	    GElf_Off off = shdr->sh_offset + (shdr->sh_type != SHT_NOBITS
581 					      ? shdr->sh_size : 0);
582 	    if (last_offset < off)
583 	      last_offset = off;
584 	  }
585     }
586 
587   if (foutput == NULL && get_sections (sections, shnum) == 0)
588     {
589       if (verbose > 0)
590 	printf ("Nothing to do.\n");
591       res = 0;
592       goto cleanup;
593     }
594 
595   if (adjust_names)
596     {
597       names = dwelf_strtab_init (true);
598       if (names == NULL)
599 	{
600 	  error (0, 0, "Not enough memory for new strtab");
601 	  goto cleanup;
602 	}
603       scnstrents = xmalloc (shnum
604 			    * sizeof (Dwelf_Strent *));
605       scnnames = xcalloc (shnum, sizeof (char *));
606     }
607 
608   /* Create a new (temporary) ELF file for the result.  */
609   if (foutput == NULL)
610     {
611       size_t fname_len = strlen (fname);
612       fnew = xmalloc (fname_len + sizeof (".XXXXXX"));
613       strcpy (mempcpy (fnew, fname, fname_len), ".XXXXXX");
614       fdnew = mkstemp (fnew);
615     }
616   else
617     {
618       fnew = xstrdup (foutput);
619       fdnew = open (fnew, O_WRONLY | O_CREAT, st.st_mode & ALLPERMS);
620     }
621 
622   if (fdnew < 0)
623     {
624       error (0, errno, "Couldn't create output file %s", fnew);
625       /* Since we didn't create it we don't want to try to unlink it.  */
626       free (fnew);
627       fnew = NULL;
628       goto cleanup;
629     }
630 
631   elfnew = elf_begin (fdnew, ELF_C_WRITE, NULL);
632   if (elfnew == NULL)
633     {
634       error (0, 0, "Couldn't open new ELF %s for writing: %s",
635 	     fnew, elf_errmsg (-1));
636       goto cleanup;
637     }
638 
639   /* Create the new ELF header and copy over all the data.  */
640   if (gelf_newehdr (elfnew, gelf_getclass (elf)) == 0)
641     {
642       error (0, 0, "Couldn't create new ehdr: %s", elf_errmsg (-1));
643       goto cleanup;
644     }
645 
646   GElf_Ehdr newehdr;
647   if (gelf_getehdr (elfnew, &newehdr) == NULL)
648     {
649       error (0, 0, "Couldn't get new ehdr: %s", elf_errmsg (-1));
650       goto cleanup;
651     }
652 
653   newehdr.e_ident[EI_DATA] = ehdr.e_ident[EI_DATA];
654   newehdr.e_type = ehdr.e_type;
655   newehdr.e_machine = ehdr.e_machine;
656   newehdr.e_version = ehdr.e_version;
657   newehdr.e_entry = ehdr.e_entry;
658   newehdr.e_flags = ehdr.e_flags;
659 
660   if (gelf_update_ehdr (elfnew, &newehdr) == 0)
661     {
662       error (0, 0, "Couldn't update ehdr: %s", elf_errmsg (-1));
663       goto cleanup;
664     }
665 
666   /* Copy over the phdrs as is.  */
667   if (phnum != 0)
668     {
669       if (gelf_newphdr (elfnew, phnum) == 0)
670 	{
671 	  error (0, 0, "Couldn't create phdrs: %s", elf_errmsg (-1));
672 	  goto cleanup;
673 	}
674 
675       for (size_t cnt = 0; cnt < phnum; ++cnt)
676 	{
677 	  GElf_Phdr phdr_mem;
678 	  GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
679 	  if (phdr == NULL)
680 	    {
681 	      error (0, 0, "Couldn't get phdr %zd: %s", cnt, elf_errmsg (-1));
682 	      goto cleanup;
683 	    }
684 	  if (gelf_update_phdr (elfnew, cnt, phdr) == 0)
685 	    {
686 	      error (0, 0, "Couldn't create phdr %zd: %s", cnt,
687 		     elf_errmsg (-1));
688 	      goto cleanup;
689 	    }
690 	}
691     }
692 
693   /* Possibly add a 'z' and zero terminator.  */
694   if (maxnamelen > 0)
695     snamebuf = xmalloc (maxnamelen + 2);
696 
697   /* We might want to read/adjust the section header strings and
698      symbol tables.  If so, and those sections are to be compressed
699      then we will have to decompress it during the collection pass and
700      compress it again in the fixup pass.  Don't compress unnecessary
701      and keep track of whether or not to compress them (later in the
702      fixup pass).  Also record the original size, so we can report the
703      difference later when we do compress.  */
704   enum ch_type shstrtab_compressed = UNSET;
705   size_t shstrtab_size = 0;
706   char *shstrtab_name = NULL;
707   char *shstrtab_newname = NULL;
708   enum ch_type symtab_compressed = UNSET;
709   size_t symtab_size = 0;
710   char *symtab_name = NULL;
711   char *symtab_newname = NULL;
712 
713   /* Collection pass.  Copy over the sections, (de)compresses matching
714      sections, collect names of sections and symbol table if
715      necessary.  */
716   scn = NULL;
717   while ((scn = elf_nextscn (elf, scn)) != NULL)
718     {
719       size_t ndx = elf_ndxscn (scn);
720       assert (ndx < shnum);
721 
722       /* (de)compress if section matched.  */
723       char *sname = NULL;
724       char *newname = NULL;
725       if (get_section (sections, ndx))
726 	{
727 	  GElf_Shdr shdr_mem;
728 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
729 	  if (shdr == NULL)
730 	    {
731 	      error (0, 0, "Couldn't get shdr for section %zd", ndx);
732 	      goto cleanup;
733 	    }
734 
735 	  uint64_t size = shdr->sh_size;
736 	  sname = elf_strptr (elf, shdrstrndx, shdr->sh_name);
737 	  if (sname == NULL)
738 	    {
739 	      error (0, 0, "Couldn't get name for section %zd", ndx);
740 	      goto cleanup;
741 	    }
742 
743 	  /* strdup sname, the shdrstrndx section itself might be
744 	     (de)compressed, invalidating the string pointers.  */
745 	  sname = xstrdup (sname);
746 
747 
748 	  /* Detect source compression that is how is the section compressed
749 	     now.  */
750 	  enum ch_type schtype = get_section_chtype (scn, shdr, sname, ndx);
751 	  if (schtype == UNSET)
752 	    goto cleanup;
753 
754 	  /* We might want to decompress (and rename), but not
755 	     compress during this pass since we might need the section
756 	     data in later passes.  Skip those sections for now and
757 	     compress them in the fixup pass.  */
758 	  bool skip_compress_section = (adjust_names
759 					&& (ndx == shdrstrndx
760 					    || ndx == symtabndx));
761 
762 	  switch (type)
763 	    {
764 	    case NONE:
765 	      if (schtype != NONE)
766 		{
767 		  if (schtype == ZLIB_GNU)
768 		    {
769 		      snamebuf[0] = '.';
770 		      strcpy (&snamebuf[1], &sname[2]);
771 		      newname = snamebuf;
772 		    }
773 		  if (compress_section (scn, size, sname, NULL, ndx,
774 					schtype, NONE, verbose > 0) < 0)
775 		    goto cleanup;
776 		}
777 	      else if (verbose > 0)
778 		printf ("[%zd] %s already decompressed\n", ndx, sname);
779 	      break;
780 
781 	    case ZLIB_GNU:
782 	      if (startswith (sname, ".debug"))
783 		{
784 		  if (schtype == ZLIB || schtype == ZSTD)
785 		    {
786 		      /* First decompress to recompress GNU style.
787 			 Don't report even when verbose.  */
788 		      if (compress_section (scn, size, sname, NULL, ndx,
789 					    schtype, NONE, false) < 0)
790 			goto cleanup;
791 		    }
792 
793 		  snamebuf[0] = '.';
794 		  snamebuf[1] = 'z';
795 		  strcpy (&snamebuf[2], &sname[1]);
796 		  newname = snamebuf;
797 
798 		  if (skip_compress_section)
799 		    {
800 		      if (ndx == shdrstrndx)
801 			{
802 			  shstrtab_size = size;
803 			  shstrtab_compressed = ZLIB_GNU;
804 			  if (shstrtab_name != NULL
805 			      || shstrtab_newname != NULL)
806 			    {
807 			      error (0, 0, "Internal error,"
808 					   " shstrtab_name already set,"
809 					   " while handling section [%zd] %s",
810 				     ndx, sname);
811 			      goto cleanup;
812 			    }
813 			  shstrtab_name = xstrdup (sname);
814 			  shstrtab_newname = xstrdup (newname);
815 			}
816 		      else
817 			{
818 			  symtab_size = size;
819 			  symtab_compressed = ZLIB_GNU;
820 			  symtab_name = xstrdup (sname);
821 			  symtab_newname = xstrdup (newname);
822 			}
823 		    }
824 		  else
825 		    {
826 		      int result = compress_section (scn, size, sname, newname,
827 						     ndx, NONE, type,
828 						     verbose > 0);
829 		      if (result < 0)
830 			goto cleanup;
831 
832 		      if (result == 0)
833 			newname = NULL;
834 		    }
835 		}
836 	      else if (verbose >= 0)
837 		{
838 		  if (schtype == ZLIB_GNU)
839 		    printf ("[%zd] %s unchanged, already GNU compressed\n",
840 			    ndx, sname);
841 		  else
842 		    printf ("[%zd] %s cannot GNU compress section not starting with .debug\n",
843 			    ndx, sname);
844 		}
845 	      break;
846 
847 	    case ZLIB:
848 	    case ZSTD:
849 	      if (schtype != type)
850 		{
851 		  if (schtype != NONE)
852 		    {
853 		      /* Decompress first.  */
854 		      if (compress_section (scn, size, sname, NULL, ndx,
855 					    schtype, NONE, false) < 0)
856 			goto cleanup;
857 
858 		      if (schtype == ZLIB_GNU)
859 			{
860 			  snamebuf[0] = '.';
861 			  strcpy (&snamebuf[1], &sname[2]);
862 			  newname = snamebuf;
863 			}
864 		    }
865 
866 		  if (skip_compress_section)
867 		    {
868 		      if (ndx == shdrstrndx)
869 			{
870 			  shstrtab_size = size;
871 			  shstrtab_compressed = type;
872 			  if (shstrtab_name != NULL
873 			      || shstrtab_newname != NULL)
874 			    {
875 			      error (0, 0, "Internal error,"
876 					   " shstrtab_name already set,"
877 					   " while handling section [%zd] %s",
878 				     ndx, sname);
879 			      goto cleanup;
880 			    }
881 			  shstrtab_name = xstrdup (sname);
882 			  shstrtab_newname = (newname == NULL
883 					      ? NULL : xstrdup (newname));
884 			}
885 		      else
886 			{
887 			  symtab_size = size;
888 			  symtab_compressed = type;
889 			  symtab_name = xstrdup (sname);
890 			  symtab_newname = (newname == NULL
891 					    ? NULL : xstrdup (newname));
892 			}
893 		    }
894 		  else if (compress_section (scn, size, sname, newname, ndx,
895 					     NONE, type, verbose > 0) < 0)
896 		    goto cleanup;
897 		}
898 	      else if (verbose > 0)
899 		printf ("[%zd] %s already compressed\n", ndx, sname);
900 	      break;
901 
902 	    case UNSET:
903 	      break;
904 	    }
905 
906 	  free (sname);
907 	}
908 
909       Elf_Scn *newscn = elf_newscn (elfnew);
910       if (newscn == NULL)
911 	{
912 	  error (0, 0, "Couldn't create new section %zd", ndx);
913 	  goto cleanup;
914 	}
915 
916       GElf_Shdr shdr_mem;
917       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
918       if (shdr == NULL)
919 	{
920 	  error (0, 0, "Couldn't get shdr for section %zd", ndx);
921 	  goto cleanup;
922 	}
923 
924       if (gelf_update_shdr (newscn, shdr) == 0)
925         {
926 	  error (0, 0, "Couldn't update section header %zd", ndx);
927 	  goto cleanup;
928 	}
929 
930       /* Except for the section header string table all data can be
931 	 copied as is.  The section header string table will be
932 	 created later and the symbol table might be fixed up if
933 	 necessary.  */
934       if (! adjust_names || ndx != shdrstrndx)
935 	{
936 	  Elf_Data *data = elf_getdata (scn, NULL);
937 	  if (data == NULL)
938 	    {
939 	      error (0, 0, "Couldn't get data from section %zd", ndx);
940 	      goto cleanup;
941 	    }
942 
943 	  Elf_Data *newdata = elf_newdata (newscn);
944 	  if (newdata == NULL)
945 	    {
946 	      error (0, 0, "Couldn't create new data for section %zd", ndx);
947 	      goto cleanup;
948 	    }
949 
950 	  *newdata = *data;
951 	}
952 
953       /* Keep track of the (new) section names.  */
954       if (adjust_names)
955 	{
956 	  char *name;
957 	  if (newname != NULL)
958 	    name = newname;
959 	  else
960 	    {
961 	      name = elf_strptr (elf, shdrstrndx, shdr->sh_name);
962 	      if (name == NULL)
963 		{
964 		  error (0, 0, "Couldn't get name for section [%zd]", ndx);
965 		  goto cleanup;
966 		}
967 	    }
968 
969 	  /* We need to keep a copy of the name till the strtab is done.  */
970 	  name = scnnames[ndx] = xstrdup (name);
971 	  if ((scnstrents[ndx] = dwelf_strtab_add (names, name)) == NULL)
972 	    {
973 	      error (0, 0, "No memory to add section name string table");
974 	      goto cleanup;
975 	    }
976 
977 	  /* If the symtab shares strings then add those too.  */
978 	  if (ndx == symtabndx)
979 	    {
980 	      /* If the section is (still) compressed we'll need to
981 		 uncompress it first to adjust the data, then
982 		 recompress it in the fixup pass.  */
983 	      if (symtab_compressed == UNSET)
984 		{
985 		  size_t size = shdr->sh_size;
986 		  if ((shdr->sh_flags == SHF_COMPRESSED) != 0)
987 		    {
988 		      /* Don't report the (internal) uncompression.  */
989 		      if (compress_section (newscn, size, sname, NULL, ndx,
990 					    ZLIB, NONE, false) < 0)
991 			goto cleanup;
992 
993 		      symtab_size = size;
994 		      symtab_compressed = ZLIB;
995 		    }
996 		  else if (startswith (name, ".zdebug"))
997 		    {
998 		      /* Don't report the (internal) uncompression.  */
999 		      if (compress_section (newscn, size, sname, NULL, ndx,
1000 					    ZLIB_GNU, NONE, false) < 0)
1001 			goto cleanup;
1002 
1003 		      symtab_size = size;
1004 		      symtab_compressed = ZLIB_GNU;
1005 		    }
1006 		}
1007 
1008 	      Elf_Data *symd = elf_getdata (newscn, NULL);
1009 	      if (symd == NULL)
1010 		{
1011 		  error (0, 0, "Couldn't get symtab data for section [%zd] %s",
1012 			 ndx, name);
1013 		  goto cleanup;
1014 		}
1015 	      size_t elsize = gelf_fsize (elfnew, ELF_T_SYM, 1, EV_CURRENT);
1016 	      size_t syms = symd->d_size / elsize;
1017 	      if (symstrents != NULL)
1018 		{
1019 		  error (0, 0, "Internal error, symstrents already set,"
1020 			 " while handling section [%zd] %s", ndx, name);
1021 		  goto cleanup;
1022 		}
1023 	      symstrents = xmalloc (syms * sizeof (Dwelf_Strent *));
1024 	      for (size_t i = 0; i < syms; i++)
1025 		{
1026 		  GElf_Sym sym_mem;
1027 		  GElf_Sym *sym = gelf_getsym (symd, i, &sym_mem);
1028 		  if (sym == NULL)
1029 		    {
1030 		      error (0, 0, "Couldn't get symbol %zd", i);
1031 		      goto cleanup;
1032 		    }
1033 		  if (sym->st_name != 0)
1034 		    {
1035 		      /* Note we take the name from the original ELF,
1036 			 since the new one will not have setup the
1037 			 strtab yet.  */
1038 		      const char *symname = elf_strptr (elf, shdrstrndx,
1039 							sym->st_name);
1040 		      if (symname == NULL)
1041 			{
1042 			  error (0, 0, "Couldn't get symbol %zd name", i);
1043 			  goto cleanup;
1044 			}
1045 		      symstrents[i] = dwelf_strtab_add (names, symname);
1046 		      if (symstrents[i] == NULL)
1047 			{
1048 			  error (0, 0, "No memory to add to symbol name");
1049 			  goto cleanup;
1050 			}
1051 		    }
1052 		}
1053 	    }
1054 	}
1055     }
1056 
1057   if (adjust_names)
1058     {
1059       /* We got all needed strings, put the new data in the shstrtab.  */
1060       if (verbose > 0)
1061 	printf ("[%zd] Updating section string table\n", shdrstrndx);
1062 
1063       scn = elf_getscn (elfnew, shdrstrndx);
1064       if (scn == NULL)
1065 	{
1066 	  error (0, 0, "Couldn't get new section header string table [%zd]",
1067 		 shdrstrndx);
1068 	  goto cleanup;
1069 	}
1070 
1071       Elf_Data *data = elf_newdata (scn);
1072       if (data == NULL)
1073 	{
1074 	  error (0, 0, "Couldn't create new section header string table data");
1075 	  goto cleanup;
1076 	}
1077       if (dwelf_strtab_finalize (names, data) == NULL)
1078 	{
1079 	  error (0, 0, "Not enough memory to create string table");
1080 	  goto cleanup;
1081 	}
1082       namesbuf = data->d_buf;
1083 
1084       GElf_Shdr shdr_mem;
1085       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1086       if (shdr == NULL)
1087 	{
1088 	  error (0, 0, "Couldn't get shdr for new section strings %zd",
1089 		 shdrstrndx);
1090 	  goto cleanup;
1091 	}
1092 
1093       /* Note that we also might have to compress and possibly set
1094 	 sh_off below */
1095       shdr->sh_name = dwelf_strent_off (scnstrents[shdrstrndx]);
1096       shdr->sh_type = SHT_STRTAB;
1097       shdr->sh_flags = 0;
1098       shdr->sh_addr = 0;
1099       shdr->sh_offset = 0;
1100       shdr->sh_size = data->d_size;
1101       shdr->sh_link = SHN_UNDEF;
1102       shdr->sh_info = SHN_UNDEF;
1103       shdr->sh_addralign = 1;
1104       shdr->sh_entsize = 0;
1105 
1106       if (gelf_update_shdr (scn, shdr) == 0)
1107 	{
1108 	  error (0, 0, "Couldn't update new section strings [%zd]",
1109 		 shdrstrndx);
1110 	  goto cleanup;
1111 	}
1112 
1113       /* We might have to compress the data if the user asked us to,
1114 	 or if the section was already compressed (and the user didn't
1115 	 ask for decompression).  Note somewhat identical code for
1116 	 symtab below.  */
1117       if (shstrtab_compressed == UNSET)
1118 	{
1119 	  /* The user didn't ask for compression, but maybe it was
1120 	     compressed in the original ELF file.  */
1121 	  Elf_Scn *oldscn = elf_getscn (elf, shdrstrndx);
1122 	  if (oldscn == NULL)
1123 	    {
1124 	      error (0, 0, "Couldn't get section header string table [%zd]",
1125 		     shdrstrndx);
1126 	      goto cleanup;
1127 	    }
1128 
1129 	  shdr = gelf_getshdr (oldscn, &shdr_mem);
1130 	  if (shdr == NULL)
1131 	    {
1132 	      error (0, 0, "Couldn't get shdr for old section strings [%zd]",
1133 		     shdrstrndx);
1134 	      goto cleanup;
1135 	    }
1136 
1137 	  shstrtab_name = elf_strptr (elf, shdrstrndx, shdr->sh_name);
1138 	  if (shstrtab_name == NULL)
1139 	    {
1140 	      error (0, 0, "Couldn't get name for old section strings [%zd]",
1141 		     shdrstrndx);
1142 	      goto cleanup;
1143 	    }
1144 
1145 	  shstrtab_size = shdr->sh_size;
1146 	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1147 	    shstrtab_compressed = ZLIB;
1148 	  else if (startswith (shstrtab_name, ".zdebug"))
1149 	    shstrtab_compressed = ZLIB_GNU;
1150 	}
1151 
1152       /* Should we (re)compress?  */
1153       if (shstrtab_compressed != UNSET)
1154 	{
1155 	  if (compress_section (scn, shstrtab_size, shstrtab_name,
1156 				shstrtab_newname, shdrstrndx,
1157 				NONE, shstrtab_compressed,
1158 				verbose > 0) < 0)
1159 	    goto cleanup;
1160 	}
1161     }
1162 
1163   /* Make sure to re-get the new ehdr.  Adding phdrs and shdrs will
1164      have changed it.  */
1165   if (gelf_getehdr (elfnew, &newehdr) == NULL)
1166     {
1167       error (0, 0, "Couldn't re-get new ehdr: %s", elf_errmsg (-1));
1168       goto cleanup;
1169     }
1170 
1171   /* Set this after the sections have been created, otherwise section
1172      zero might not exist yet.  */
1173   if (setshdrstrndx (elfnew, &newehdr, shdrstrndx) != 0)
1174     {
1175       error (0, 0, "Couldn't set new shdrstrndx: %s", elf_errmsg (-1));
1176       goto cleanup;
1177     }
1178 
1179   /* Fixup pass.  Adjust string table references, symbol table and
1180      layout if necessary.  */
1181   if (layout || adjust_names)
1182     {
1183       scn = NULL;
1184       while ((scn = elf_nextscn (elfnew, scn)) != NULL)
1185 	{
1186 	  size_t ndx = elf_ndxscn (scn);
1187 
1188 	  GElf_Shdr shdr_mem;
1189 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1190 	  if (shdr == NULL)
1191 	    {
1192 	      error (0, 0, "Couldn't get shdr for section %zd", ndx);
1193 	      goto cleanup;
1194 	    }
1195 
1196 	  /* Keep the offset of allocated sections so they are at the
1197 	     same place in the file. Add (possibly changed)
1198 	     unallocated ones after the allocated ones.  */
1199 	  if ((shdr->sh_flags & SHF_ALLOC) == 0)
1200 	    {
1201 	      /* Zero means one.  No alignment constraints.  */
1202 	      size_t addralign = shdr->sh_addralign ?: 1;
1203 	      last_offset = (last_offset + addralign - 1) & ~(addralign - 1);
1204 	      shdr->sh_offset = last_offset;
1205 	      if (shdr->sh_type != SHT_NOBITS)
1206 		last_offset += shdr->sh_size;
1207 	    }
1208 
1209 	  if (adjust_names)
1210 	    shdr->sh_name = dwelf_strent_off (scnstrents[ndx]);
1211 
1212 	  if (gelf_update_shdr (scn, shdr) == 0)
1213 	    {
1214 	      error (0, 0, "Couldn't update section header %zd", ndx);
1215 	      goto cleanup;
1216 	    }
1217 
1218 	  if (adjust_names && ndx == symtabndx)
1219 	    {
1220 	      if (verbose > 0)
1221 		printf ("[%zd] Updating symbol table\n", symtabndx);
1222 
1223 	      Elf_Data *symd = elf_getdata (scn, NULL);
1224 	      if (symd == NULL)
1225 		{
1226 		  error (0, 0, "Couldn't get new symtab data section [%zd]",
1227 			 ndx);
1228 		  goto cleanup;
1229 		}
1230 	      size_t elsize = gelf_fsize (elfnew, ELF_T_SYM, 1, EV_CURRENT);
1231 	      size_t syms = symd->d_size / elsize;
1232 	      for (size_t i = 0; i < syms; i++)
1233 		{
1234 		  GElf_Sym sym_mem;
1235 		  GElf_Sym *sym = gelf_getsym (symd, i, &sym_mem);
1236 		  if (sym == NULL)
1237 		    {
1238 		      error (0, 0, "2 Couldn't get symbol %zd", i);
1239 		      goto cleanup;
1240 		    }
1241 
1242 		  if (sym->st_name != 0)
1243 		    {
1244 		      sym->st_name = dwelf_strent_off (symstrents[i]);
1245 
1246 		      if (gelf_update_sym (symd, i, sym) == 0)
1247 			{
1248 			  error (0, 0, "Couldn't update symbol %zd", i);
1249 			  goto cleanup;
1250 			}
1251 		    }
1252 		}
1253 
1254 	      /* We might have to compress the data if the user asked
1255 		 us to, or if the section was already compressed (and
1256 		 the user didn't ask for decompression).  Note
1257 		 somewhat identical code for shstrtab above.  */
1258 	      if (symtab_compressed == UNSET)
1259 		{
1260 		  /* The user didn't ask for compression, but maybe it was
1261 		     compressed in the original ELF file.  */
1262 		  Elf_Scn *oldscn = elf_getscn (elf, symtabndx);
1263 		  if (oldscn == NULL)
1264 		    {
1265 		      error (0, 0, "Couldn't get symbol table [%zd]",
1266 			     symtabndx);
1267 		      goto cleanup;
1268 		    }
1269 
1270 		  shdr = gelf_getshdr (oldscn, &shdr_mem);
1271 		  if (shdr == NULL)
1272 		    {
1273 		      error (0, 0, "Couldn't get old symbol table shdr [%zd]",
1274 			     symtabndx);
1275 		      goto cleanup;
1276 		    }
1277 
1278 		  symtab_name = elf_strptr (elf, shdrstrndx, shdr->sh_name);
1279 		  if (symtab_name == NULL)
1280 		    {
1281 		      error (0, 0, "Couldn't get old symbol table name [%zd]",
1282 			     symtabndx);
1283 		      goto cleanup;
1284 		    }
1285 
1286 		  symtab_size = shdr->sh_size;
1287 		  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1288 		    symtab_compressed = ZLIB;
1289 		  else if (startswith (symtab_name, ".zdebug"))
1290 		    symtab_compressed = ZLIB_GNU;
1291 		}
1292 
1293 	      /* Should we (re)compress?  */
1294 	      if (symtab_compressed != UNSET)
1295 		{
1296 		  if (compress_section (scn, symtab_size, symtab_name,
1297 					symtab_newname, symtabndx,
1298 					NONE, symtab_compressed,
1299 					verbose > 0) < 0)
1300 		    goto cleanup;
1301 		}
1302 	    }
1303 	}
1304     }
1305 
1306   /* If we have phdrs we want elf_update to layout the SHF_ALLOC
1307      sections precisely as in the original file.  In that case we are
1308      also responsible for setting phoff and shoff */
1309   if (layout)
1310     {
1311       if (gelf_getehdr (elfnew, &newehdr) == NULL)
1312 	{
1313 	  error (0, 0, "Couldn't get ehdr: %s", elf_errmsg (-1));
1314 	  goto cleanup;
1315 	}
1316 
1317       /* Position the shdrs after the last (unallocated) section.  */
1318       const size_t offsize = gelf_fsize (elfnew, ELF_T_OFF, 1, EV_CURRENT);
1319       newehdr.e_shoff = ((last_offset + offsize - 1)
1320 			 & ~((GElf_Off) (offsize - 1)));
1321 
1322       /* The phdrs go in the same place as in the original file.
1323 	 Normally right after the ELF header.  */
1324       newehdr.e_phoff = ehdr.e_phoff;
1325 
1326       if (gelf_update_ehdr (elfnew, &newehdr) == 0)
1327 	{
1328 	  error (0, 0, "Couldn't update ehdr: %s", elf_errmsg (-1));
1329 	  goto cleanup;
1330 	}
1331     }
1332 
1333   elf_flagelf (elfnew, ELF_C_SET, ((layout ? ELF_F_LAYOUT : 0)
1334 				   | (permissive ? ELF_F_PERMISSIVE : 0)));
1335 
1336   if (elf_update (elfnew, ELF_C_WRITE) < 0)
1337     {
1338       error (0, 0, "Couldn't write %s: %s", fnew, elf_errmsg (-1));
1339       goto cleanup;
1340     }
1341 
1342   elf_end (elfnew);
1343   elfnew = NULL;
1344 
1345   /* Try to match mode and owner.group of the original file.
1346      Note to set suid bits we have to make sure the owner is setup
1347      correctly first. Otherwise fchmod will drop them silently
1348      or fchown may clear them.  */
1349   if (fchown (fdnew, st.st_uid, st.st_gid) != 0)
1350     if (verbose >= 0)
1351       error (0, errno, "Couldn't fchown %s", fnew);
1352   if (fchmod (fdnew, st.st_mode & ALLPERMS) != 0)
1353     if (verbose >= 0)
1354       error (0, errno, "Couldn't fchmod %s", fnew);
1355 
1356   /* Finally replace the old file with the new file.  */
1357   if (foutput == NULL)
1358     if (rename (fnew, fname) != 0)
1359       {
1360 	error (0, errno, "Couldn't rename %s to %s", fnew, fname);
1361 	goto cleanup;
1362       }
1363 
1364   /* We are finally done with the new file, don't unlink it now.  */
1365   free (fnew);
1366   fnew = NULL;
1367   res = 0;
1368 
1369 cleanup:
1370   elf_end (elf);
1371   close (fd);
1372 
1373   elf_end (elfnew);
1374   close (fdnew);
1375 
1376   if (fnew != NULL)
1377     {
1378       unlink (fnew);
1379       free (fnew);
1380       fnew = NULL;
1381     }
1382 
1383   free (snamebuf);
1384   if (names != NULL)
1385     {
1386       dwelf_strtab_free (names);
1387       free (scnstrents);
1388       free (symstrents);
1389       free (namesbuf);
1390       if (scnnames != NULL)
1391 	{
1392 	  for (size_t n = 0; n < shnum; n++)
1393 	    free (scnnames[n]);
1394 	  free (scnnames);
1395 	}
1396     }
1397 
1398   free (sections);
1399   return res;
1400 }
1401 
1402 int
main(int argc,char ** argv)1403 main (int argc, char **argv)
1404 {
1405   const struct argp_option options[] =
1406     {
1407       { "output", 'o', "FILE", 0,
1408 	N_("Place (de)compressed output into FILE"),
1409 	0 },
1410       { "type", 't', "TYPE", 0,
1411 	N_("What type of compression to apply. TYPE can be 'none' (decompress), 'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias), "
1412 	   "'zlib-gnu' (.zdebug GNU style compression, 'gnu' is an alias) or 'zstd' (ELF ZSTD compression)"),
1413 	0 },
1414       { "name", 'n', "SECTION", 0,
1415 	N_("SECTION name to (de)compress, SECTION is an extended wildcard pattern (defaults to '.?(z)debug*')"),
1416 	0 },
1417       { "verbose", 'v', NULL, 0,
1418 	N_("Print a message for each section being (de)compressed"),
1419 	0 },
1420       { "force", 'f', NULL, 0,
1421 	N_("Force compression of section even if it would become larger or update/rewrite the file even if no section would be (de)compressed"),
1422 	0 },
1423       { "permissive", 'p', NULL, 0,
1424 	N_("Relax a few rules to handle slightly broken ELF files"),
1425 	0 },
1426       { "quiet", 'q', NULL, 0,
1427 	N_("Be silent when a section cannot be compressed"),
1428 	0 },
1429       { NULL, 0, NULL, 0, NULL, 0 }
1430     };
1431 
1432   const struct argp argp =
1433     {
1434       .options = options,
1435       .parser = parse_opt,
1436       .args_doc = N_("FILE..."),
1437       .doc = N_("Compress or decompress sections in an ELF file.")
1438     };
1439 
1440   int remaining;
1441   if (argp_parse (&argp, argc, argv, 0, &remaining, NULL) != 0)
1442     return EXIT_FAILURE;
1443 
1444   /* Should already be handled by ARGP_KEY_NO_ARGS case above,
1445      just sanity check.  */
1446   if (remaining >= argc)
1447     error_exit (0, N_("No input file given"));
1448 
1449   /* Likewise for the ARGP_KEY_ARGS case above, an extra sanity check.  */
1450   if (foutput != NULL && remaining + 1 < argc)
1451     error_exit (0, N_("Only one input file allowed together with '-o'"));
1452 
1453   elf_version (EV_CURRENT);
1454 
1455   /* Process all the remaining files.  */
1456   int result = 0;
1457   do
1458     result |= process_file (argv[remaining]);
1459   while (++remaining < argc);
1460 
1461   free_patterns ();
1462   return result;
1463 }
1464