Home | History | Annotate | Download | only in tests
      1 /* Merge string sections.
      2    Copyright (C) 2015 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 
     20 #include <assert.h>
     21 #include <errno.h>
     22 #include <stdlib.h>
     23 #include <string.h>
     24 #include <sys/types.h>
     25 #include <sys/stat.h>
     26 #include <fcntl.h>
     27 #include <error.h>
     28 #include <stdio.h>
     29 #include <inttypes.h>
     30 #include <unistd.h>
     31 
     32 #include <gelf.h>
     33 #include ELFUTILS_HEADER(ebl)
     34 
     35 /* The original ELF file.  */
     36 static int fd = -1;
     37 static Elf *elf = NULL;
     38 static bool replace;
     39 
     40 /* The new ELF file.  */
     41 static char *fnew = NULL;
     42 static int fdnew = -1;
     43 static Elf *elfnew = NULL;
     44 
     45 /* The merged string table.  */
     46 static struct Ebl_Strtab *strings = NULL;
     47 
     48 /* Section name strents.  */
     49 static struct Ebl_Strent **scnstrents = NULL;
     50 
     51 /* Symbol name strends.  */
     52 static struct Ebl_Strent **symstrents = NULL;
     53 
     54 /* New ELF file buffers.  */
     55 static Elf_Data newstrtabdata = { .d_buf = NULL };
     56 static size_t newshnums = 0;
     57 static void **newscnbufs = NULL;
     58 
     59 /* Release all files and resources allocated.  */
     60 static void
     61 release (void)
     62 {
     63   /* The new string table.  */
     64   if (strings != NULL)
     65     ebl_strtabfree (strings);
     66 
     67   free (scnstrents);
     68   free (symstrents);
     69   free (newstrtabdata.d_buf);
     70 
     71   /* Any new data buffers allocated.  */
     72   for (size_t i = 0; i < newshnums; i++)
     73     free (newscnbufs[i]);
     74   free (newscnbufs);
     75 
     76   /* The new ELF file.  */
     77   if (fdnew != -1)
     78     {
     79       unlink (fnew);
     80       elf_end (elfnew);
     81       close (fdnew);
     82     }
     83   // Don't release, we might need it in the error message.
     84   // if (replace)
     85   //   free (fnew);
     86 
     87   /* The original ELF file.  */
     88   elf_end (elf);
     89   close (fd);
     90 }
     91 
     92 /* The various ways we can fail... Cleanup and show some message to
     93    the user.  The file name may be NULL.  */
     94 static void __attribute__ ((noreturn))
     95 fail (const char *msg, const char *fname)
     96 {
     97   release ();
     98   if (fname != NULL)
     99     error (1, 0, "%s: %s", fname, msg);
    100   else
    101     error (1, 0, "%s", msg);
    102   abort();
    103 }
    104 
    105 static void __attribute__ ((noreturn))
    106 fail_errno (const char *msg, const char *fname)
    107 {
    108   release ();
    109   if (fname != NULL)
    110     error (1, errno, "%s: %s", fname, msg);
    111   else
    112     error (1, errno, "%s", msg);
    113   abort();
    114 }
    115 
    116 static void __attribute__ ((noreturn))
    117 fail_idx (const char *msg, const char *fname, size_t idx)
    118 {
    119   release ();
    120   if (fname != NULL)
    121     error (1, 0, "%s: %s %zd", fname, msg, idx);
    122   else
    123     error (1, 0, "%s %zd", msg, idx);
    124   abort();
    125 }
    126 
    127 static void __attribute__ ((noreturn))
    128 fail_elf (const char *msg, const char *fname)
    129 {
    130   release ();
    131   if (fname != NULL)
    132     error (1, 0, "%s: %s: %s", fname, msg, elf_errmsg (-1));
    133   else
    134     error (1, 0, "%s: %s", msg, elf_errmsg (-1));
    135   abort();
    136 }
    137 
    138 static void __attribute__ ((noreturn))
    139 fail_elf_idx (const char *msg, const char *fname, size_t idx)
    140 {
    141   release ();
    142   if (fname != NULL)
    143     error (1, 0, "%s: %s %zd: %s", fname, msg, idx, elf_errmsg (-1));
    144   else
    145     error (1, 0, "%s %zd: %s", msg, idx, elf_errmsg (-1));
    146   abort();
    147 }
    148 
    149 int
    150 main (int argc, char **argv)
    151 {
    152   elf_version (EV_CURRENT);
    153 
    154   /* Basic command line handling.  Need to replace the input file?  */
    155   if ((argc != 2 && argc != 4)
    156       || (argc == 4 && strcmp (argv[1], "-o") != 0))
    157     fail ("Usage argument: [-o <outputfile>] <inputfile>", NULL);
    158   replace = argc == 2;
    159 
    160   /* Get the ELF file.  */
    161   const char *fname;
    162   if (replace)
    163     fname = argv[1];
    164   else
    165     fname = argv[3];
    166   fd = open (fname, O_RDONLY);
    167   if (fd < 0)
    168     fail_errno ("couldn't open", fname);
    169 
    170   elf = elf_begin (fd, ELF_C_READ, NULL);
    171   if (elf == NULL)
    172     fail_elf ("couldn't open ELF file for reading", fname);
    173 
    174   GElf_Ehdr ehdr;
    175   if (gelf_getehdr (elf, &ehdr) == NULL)
    176     fail_elf ("Couldn't get ehdr", fname);
    177 
    178   /* Get the section header string table.  */
    179   size_t shdrstrndx;
    180   if (elf_getshdrstrndx (elf, &shdrstrndx) != 0)
    181     fail_elf ("couldn't get section header string table index", fname);
    182 
    183   Elf_Scn *shdrstrscn = elf_getscn (elf, shdrstrndx);
    184   GElf_Shdr shdrstrshdr_mem;
    185   GElf_Shdr *shdrstrshdr = gelf_getshdr (shdrstrscn, &shdrstrshdr_mem);
    186   if (shdrstrshdr == NULL)
    187     fail_elf ("couldn't get section header string table section", fname);
    188 
    189   if ((shdrstrshdr->sh_flags & SHF_ALLOC) != 0)
    190     fail ("section header string table is an allocated section", fname);
    191 
    192   /* Get the symtab section.  */
    193   size_t symtabndx = 0;
    194   Elf_Scn *symtabscn = NULL;
    195   GElf_Shdr symtabshdr_mem;
    196   GElf_Shdr *symtabshdr;
    197   while ((symtabscn = elf_nextscn (elf, symtabscn)) != NULL)
    198     {
    199       symtabshdr = gelf_getshdr (symtabscn, &symtabshdr_mem);
    200       if (symtabshdr == NULL)
    201 	fail_elf ("couldn't get shdr", fname);
    202 
    203       if (symtabshdr->sh_type == SHT_SYMTAB)
    204 	{
    205 	  /* Just pick the first, we don't expect more than one. */
    206 	  symtabndx = elf_ndxscn (symtabscn);
    207 	  break;
    208 	}
    209     }
    210 
    211   if (symtabndx == 0)
    212     fail ("No symtab found", fname);
    213 
    214   if ((symtabshdr->sh_flags & SHF_ALLOC) != 0)
    215     fail ("symtab is an allocated section", fname);
    216 
    217   /* Get the strtab of the symtab.  */
    218   size_t strtabndx = symtabshdr->sh_link;
    219   Elf_Scn *strtabscn = elf_getscn (elf, strtabndx);
    220   GElf_Shdr strtabshdr_mem;
    221   GElf_Shdr *strtabshdr = gelf_getshdr (strtabscn, &strtabshdr_mem);
    222   if (strtabshdr == NULL)
    223     fail_elf ("Couldn't get strtab section", fname);
    224 
    225   if (shdrstrndx == strtabndx)
    226     {
    227       error (0, 0, "%s: Nothing to do, shstrtab == strtab", fname);
    228       release ();
    229       return 0;
    230     }
    231 
    232   if ((strtabshdr->sh_flags & SHF_ALLOC) != 0)
    233     fail ("strtab is an allocated section", fname);
    234 
    235   size_t phnum;
    236   if (elf_getphdrnum (elf, &phnum) != 0)
    237     fail_elf ("Couldn't get number of phdrs", fname);
    238 
    239   /* If there are phdrs we want to maintain the layout of the
    240      allocated sections in the file.  */
    241   bool layout = phnum != 0;
    242 
    243   /* Create a new merged strings table that starts with the empty string.  */
    244   strings = ebl_strtabinit (true);
    245   if (strings == NULL)
    246     fail ("No memory to create merged string table", NULL);
    247 
    248   /* Add the strings from all the sections.  */
    249   size_t shdrnum;
    250   if (elf_getshdrnum (elf, &shdrnum) != 0)
    251     fail_elf ("Couldn't get number of sections", fname);
    252   scnstrents = malloc (shdrnum * sizeof (struct Ebl_Strent *));
    253   if (scnstrents == NULL)
    254     fail ("couldn't allocate memory for section strings", NULL);
    255 
    256   /* While going through all sections keep track of last allocated
    257      offset if needed to keep the layout.  We'll put any unallocated
    258      sections behind those (strtab is unallocated and will change
    259      size).  */
    260   GElf_Off last_offset = 0;
    261   if (layout)
    262     last_offset = (ehdr.e_phoff
    263 		   + gelf_fsize (elf, ELF_T_PHDR, phnum, EV_CURRENT));
    264   Elf_Scn *scn = NULL;
    265   while ((scn = elf_nextscn (elf, scn)) != NULL)
    266     {
    267       size_t scnnum = elf_ndxscn (scn);
    268       GElf_Shdr shdr_mem;
    269       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
    270       if (shdr == NULL)
    271 	fail_elf_idx ("couldn't get shdr", fname, scnnum);
    272       /* Don't add the .shstrtab section itself, we'll not use it.  */
    273       if (shdr->sh_name != 0 && scnnum != shdrstrndx)
    274 	{
    275 	  const char *sname = elf_strptr (elf, shdrstrndx, shdr->sh_name);
    276 	  if (sname == NULL)
    277 	    fail_elf_idx ("couldn't get section name", fname, scnnum);
    278 	  if ((scnstrents[scnnum] = ebl_strtabadd (strings, sname, 0)) == NULL)
    279 	    fail ("No memory to add to  merged string table", NULL);
    280 	}
    281 
    282       if (layout)
    283 	if ((shdr->sh_flags & SHF_ALLOC) != 0)
    284 	  {
    285 	    GElf_Off off = shdr->sh_offset + (shdr->sh_type != SHT_NOBITS
    286 					      ? shdr->sh_size : 0);
    287 	    if (last_offset < off)
    288 	      last_offset = off;
    289 	  }
    290     }
    291 
    292   /* Add the strings from all the symbols.  */
    293   size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
    294   Elf_Data *symd = elf_getdata (symtabscn, NULL);
    295   if (symd == NULL)
    296     fail_elf ("couldn't get symtab data", fname);
    297   size_t symsnum = symd->d_size / elsize;
    298   symstrents = malloc (symsnum * sizeof (struct Ebl_Strent *));
    299   if (symstrents == NULL)
    300     fail_errno ("Couldn't allocate memory for symbol strings", NULL);
    301   for (size_t i = 0; i < symsnum; i++)
    302     {
    303       GElf_Sym sym_mem;
    304       GElf_Sym *sym = gelf_getsym (symd, i, &sym_mem);
    305       if (sym == NULL)
    306 	fail_elf_idx ("Couldn't get symbol", fname, i);
    307       if (sym->st_name != 0)
    308 	{
    309 	  const char *sname = elf_strptr (elf, strtabndx, sym->st_name);
    310 	  if (sname == NULL)
    311 	    fail_elf_idx ("Couldn't get symbol name", fname, i);
    312 	  if ((symstrents[i] = ebl_strtabadd (strings, sname, 0)) == NULL)
    313 	    fail_idx ("No memory to add to merged string table symbol",
    314 		      fname, i);
    315 	}
    316     }
    317 
    318   /* We got all strings, build the new string table and store it as
    319      new strtab.  */
    320   ebl_strtabfinalize (strings, &newstrtabdata);
    321 
    322   /* We share at least the empty string so the result is at least 1
    323      byte smaller.  */
    324   if (newstrtabdata.d_size >= shdrstrshdr->sh_size + strtabshdr->sh_size)
    325     fail ("Impossible, merged string table is larger", fname);
    326 
    327   /* section index mapping and sanity checking.  */
    328   size_t newsecndx (size_t secndx, const char *what, size_t widx,
    329 		    const char *member, size_t midx)
    330   {
    331     if (unlikely (secndx == 0 || secndx == shdrstrndx || secndx >= shdrnum))
    332       {
    333 	/* Don't use fail... too specialized messages.  Call release
    334 	   outselves and then error.  Ignores midx if widx is
    335 	   zero.  */
    336 	release ();
    337 	if (widx == 0)
    338 	  error (1, 0, "%s: bad section index %zd in %s for %s",
    339 		 fname, secndx, what, member);
    340 	else if (midx == 0)
    341 	  error (1, 0, "%s: bad section index %zd in %s %zd for %s",
    342 		 fname, secndx, what, widx, member);
    343 	else
    344 	  error (1, 0, "%s: bad section index %zd in %s %zd for %s %zd",
    345 		 fname, secndx, what, widx, member, midx);
    346       }
    347 
    348     return secndx < shdrstrndx ? secndx : secndx - 1;
    349   }
    350 
    351   struct stat st;
    352   if (fstat (fd, &st) != 0)
    353     fail_errno("Couldn't fstat", fname);
    354 
    355   /* Create a new (temporary) ELF file for the result.  */
    356   if (replace)
    357     {
    358       size_t fname_len = strlen (fname);
    359       fnew = malloc (fname_len + sizeof (".XXXXXX"));
    360       if (fnew == NULL)
    361 	fail_errno ("couldn't allocate memory for new file name", NULL);
    362       strcpy (mempcpy (fnew, fname, fname_len), ".XXXXXX");
    363 
    364       fdnew = mkstemp (fnew);
    365     }
    366   else
    367     {
    368       fnew = argv[2];
    369       fdnew = open (fnew, O_WRONLY | O_CREAT, st.st_mode & ALLPERMS);
    370     }
    371 
    372   if (fdnew < 0)
    373     fail_errno ("couldn't create output file", fnew);
    374 
    375   elfnew = elf_begin (fdnew, ELF_C_WRITE, NULL);
    376   if (elfnew == NULL)
    377     fail_elf ("couldn't open new ELF for writing", fnew);
    378 
    379   /* Create the new ELF header and copy over all the data.  */
    380   if (gelf_newehdr (elfnew, gelf_getclass (elf)) == 0)
    381     fail_elf ("Couldn't create new ehdr", fnew);
    382   GElf_Ehdr newehdr;
    383   if (gelf_getehdr (elfnew, &newehdr) == NULL)
    384     fail_elf ("Couldn't get ehdr", fnew);
    385 
    386   newehdr.e_ident[EI_DATA] = ehdr.e_ident[EI_DATA];
    387   newehdr.e_type = ehdr.e_type;
    388   newehdr.e_machine = ehdr.e_machine;
    389   newehdr.e_version = ehdr.e_version;
    390   newehdr.e_entry = ehdr.e_entry;
    391   newehdr.e_flags = ehdr.e_flags;
    392 
    393   /* The new file uses the new strtab as shstrtab.  */
    394   size_t newstrtabndx = newsecndx (strtabndx, "ehdr", 0, "e_shstrndx", 0);
    395   if (newstrtabndx < SHN_LORESERVE)
    396     newehdr.e_shstrndx = newstrtabndx;
    397   else
    398     {
    399       Elf_Scn *zscn = elf_getscn (elfnew, 0);
    400       GElf_Shdr zshdr_mem;
    401       GElf_Shdr *zshdr = gelf_getshdr (zscn, &zshdr_mem);
    402       if (zshdr == NULL)
    403 	fail_elf ("Couldn't get section zero", fnew);
    404       zshdr->sh_link = strtabndx;
    405       if (gelf_update_shdr (zscn, zshdr) == 0)
    406 	fail_elf ("Couldn't update section zero", fnew);
    407       newehdr.e_shstrndx = SHN_XINDEX;
    408     }
    409 
    410   if (gelf_update_ehdr (elfnew, &newehdr) == 0)
    411     fail ("Couldn't update ehdr", fnew);
    412 
    413   /* Copy the program headers if any.  */
    414   if (phnum != 0)
    415     {
    416       if (gelf_newphdr (elfnew, phnum) == 0)
    417 	fail_elf ("Couldn't create phdrs", fnew);
    418 
    419       for (size_t cnt = 0; cnt < phnum; ++cnt)
    420 	{
    421 	  GElf_Phdr phdr_mem;
    422 	  GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
    423 	  if (phdr == NULL)
    424 	    fail_elf_idx ("Couldn't get phdr", fname, cnt);
    425 	  if (gelf_update_phdr (elfnew, cnt, phdr) == 0)
    426 	    fail_elf_idx ("Couldn't create phdr", fnew, cnt);
    427 	}
    428     }
    429 
    430   newshnums = shdrnum - 1;
    431   newscnbufs = calloc (sizeof (void *), newshnums);
    432   if (newscnbufs == NULL)
    433     fail_errno ("Couldn't allocate memory for new section buffers", NULL);
    434 
    435   /* Copy the sections, except the shstrtab, fill the strtab with the
    436      combined strings and adjust section references.  */
    437   while ((scn = elf_nextscn (elf, scn)) != NULL)
    438     {
    439       size_t ndx = elf_ndxscn (scn);
    440 
    441       GElf_Shdr shdr_mem;
    442       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
    443       if (shdr == NULL)
    444 	fail_elf_idx ("Couldn't get shdr", fname, ndx);
    445 
    446       /* Section zero is always created.  Skip the shtrtab.  */
    447       if (ndx == 0 || ndx == shdrstrndx)
    448 	continue;
    449 
    450       Elf_Scn *newscn = elf_newscn (elfnew);
    451       if (newscn == NULL)
    452 	fail_elf_idx ("couldn't create new section", fnew, ndx);
    453 
    454       GElf_Shdr newshdr;
    455       newshdr.sh_name = (shdr->sh_name != 0
    456 			 ? ebl_strtaboffset (scnstrents[ndx]) : 0);
    457       newshdr.sh_type = shdr->sh_type;
    458       newshdr.sh_flags = shdr->sh_flags;
    459       newshdr.sh_addr = shdr->sh_addr;
    460       newshdr.sh_size = shdr->sh_size;
    461       if (shdr->sh_link != 0)
    462 	newshdr.sh_link = newsecndx (shdr->sh_link, "shdr", ndx, "sh_link", 0);
    463       else
    464 	newshdr.sh_link = 0;
    465       if (SH_INFO_LINK_P (shdr) && shdr->sh_info != 0)
    466 	newshdr.sh_info = newsecndx (shdr->sh_info, "shdr", ndx, "sh_info", 0);
    467       else
    468 	newshdr.sh_info = shdr->sh_info;
    469       newshdr.sh_entsize = shdr->sh_entsize;
    470 
    471       /* Some sections need a new data buffer because they need to
    472 	 manipulate the original data.  Allocate and check here, so we
    473 	 have a list of all data buffers we might need to release when
    474 	 done.  */
    475       void new_data_buf (Elf_Data *d)
    476       {
    477 	size_t s = d->d_size;
    478 	if (s == 0)
    479 	  fail_idx ("Expected data in section", fname, ndx);
    480 	void *b = malloc (d->d_size);
    481 	if (b == NULL)
    482 	  fail_idx ("Couldn't allocated buffer for section", NULL, ndx);
    483 	newscnbufs[newsecndx (ndx, "section", ndx, "d_buf", 0)] = d->d_buf = b;
    484       }
    485 
    486       Elf_Data *newdata = elf_newdata (newscn);
    487       if (newdata == NULL)
    488 	fail_elf_idx ("Couldn't create new data for section", fnew, ndx);
    489       if (ndx == strtabndx)
    490 	*newdata = newstrtabdata;
    491       else
    492 	{
    493 	  /* The symtab, dynsym, group and symtab_shndx sections
    494 	     contain section indexes. Symbol tables (symtab and
    495 	     dynsym) contain indexes to strings. Update both if
    496 	     necessary.  */
    497 	  Elf_Data *data = elf_getdata (scn, NULL);
    498 	  if (data == NULL)
    499 	    fail_elf_idx ("Couldn't get data from section", fname, ndx);
    500 	  *newdata = *data;
    501 	  switch (shdr->sh_type)
    502 	    {
    503 	    case SHT_SYMTAB:
    504 	    case SHT_DYNSYM:
    505 	      {
    506 		/* We need to update the section numbers of the
    507 		   symbols and if this symbol table uses the strtab
    508 		   section also the name indexes.  */
    509 		const bool update_name = shdr->sh_link == strtabndx;
    510 		if (update_name && ndx != symtabndx)
    511 		  fail ("Only one symbol table using strtab expected", fname);
    512 		new_data_buf (newdata);
    513 		size_t syms = (data->d_size
    514 			       / gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT));
    515 		for (size_t i = 0; i < syms; i++)
    516 		  {
    517 		    GElf_Sym sym;
    518 		    if (gelf_getsym (data, i, &sym) == NULL)
    519 		      fail_elf_idx ("Couldn't get symbol", fname, i);
    520 
    521 		    if (GELF_ST_TYPE (sym.st_info) == STT_SECTION
    522 			&& sym.st_shndx == shdrstrndx)
    523 		      fprintf (stderr, "WARNING:"
    524 			       " symbol table [%zd] contains section symbol %zd"
    525 			       " for old shdrstrndx %zd\n", ndx, i, shdrstrndx);
    526 		    else if (sym.st_shndx != SHN_UNDEF
    527 			     && sym.st_shndx < SHN_LORESERVE)
    528 		      sym.st_shndx = newsecndx (sym.st_shndx, "section", ndx,
    529 						"symbol", i);
    530 		    if (update_name && sym.st_name != 0)
    531 		      sym.st_name = ebl_strtaboffset (symstrents[i]);
    532 
    533 		    /* We explicitly don't update the SHNDX table at
    534 		       the same time, we do that below.  */
    535 		    if (gelf_update_sym (newdata, i, &sym) == 0)
    536 		      fail_elf_idx ("Couldn't update symbol", fnew, i);
    537 		  }
    538 	      }
    539 	      break;
    540 
    541 	    case SHT_GROUP:
    542 	      {
    543 		new_data_buf (newdata);
    544 		/* A section group contains Elf32_Words. The first
    545 		   word is a falg value, the rest of the words are
    546 		   indexes of the sections belonging to the group.  */
    547 		Elf32_Word *group = (Elf32_Word *) data->d_buf;
    548 		Elf32_Word *newgroup = (Elf32_Word *) newdata->d_buf;
    549 		size_t words = data->d_size / sizeof (Elf32_Word);
    550 		if (words == 0)
    551 		  fail_idx ("Not enough data in group section", fname, ndx);
    552 		newgroup[0] = group[0];
    553 		for (size_t i = 1; i < words; i++)
    554 		  newgroup[i] = newsecndx (group[i], "section", ndx,
    555 					   "group", i);
    556 	      }
    557 	      break;
    558 
    559 	    case SHT_SYMTAB_SHNDX:
    560 	      {
    561 		new_data_buf (newdata);
    562 		/* A SHNDX just contains an array of section indexes
    563 		   for the corresponding symbol table.  The entry is
    564 		   SHN_UNDEF unless the corresponding symbol is
    565 		   SHN_XINDEX.  */
    566 		Elf32_Word *shndx = (Elf32_Word *) data->d_buf;
    567 		Elf32_Word *newshndx = (Elf32_Word *) newdata->d_buf;
    568 		size_t words = data->d_size / sizeof (Elf32_Word);
    569 		for (size_t i = 0; i < words; i++)
    570 		  if (shndx[i] == SHN_UNDEF)
    571 		    newshndx[i] = SHN_UNDEF;
    572 		  else
    573 		    newshndx[i] = newsecndx (shndx[i], "section", ndx,
    574 					     "shndx", i);
    575 	      }
    576 	      break;
    577 
    578 	    case SHT_DYNAMIC:
    579 	      /* Fallthrough.  There are string indexes in here, but
    580 		 they (should) point to a allocated string table,
    581 		 which we don't alter.  */
    582 	    default:
    583 	      /* Nothing to do.  Section data doesn't contain section
    584 		 or strtab indexes.  */
    585 	      break;
    586 	    }
    587 	}
    588 
    589       /* When we are responsible for the layout explicitly set
    590 	 sh_addralign, sh_size and sh_offset.  Otherwise libelf will
    591 	 calculate those from the Elf_Data.  */
    592       if (layout)
    593 	{
    594 	  /* We have just one Elf_Data.  */
    595 	  newshdr.sh_size = newdata->d_size;
    596 	  newshdr.sh_addralign = newdata->d_align;
    597 
    598 	  /* Keep the offset of allocated sections so they are at the
    599 	     same place in the file. Add unallocated ones after the
    600 	     allocated ones.  */
    601 	  if ((shdr->sh_flags & SHF_ALLOC) != 0)
    602 	    newshdr.sh_offset = shdr->sh_offset;
    603 	  else
    604 	    {
    605 	      /* Zero means one.  No alignment constraints.  */
    606 	      size_t addralign = newshdr.sh_addralign ?: 1;
    607 	      last_offset = (last_offset + addralign - 1) & ~(addralign - 1);
    608 	      newshdr.sh_offset = last_offset;
    609 	      if (newshdr.sh_type != SHT_NOBITS)
    610 		last_offset += newshdr.sh_size;
    611 	    }
    612 	}
    613       else
    614 	{
    615 	  newshdr.sh_addralign = 0;
    616 	  newshdr.sh_size = 0;
    617 	  newshdr.sh_offset = 0;
    618 	}
    619 
    620       if (gelf_update_shdr (newscn, &newshdr) == 0)
    621 	fail_elf_idx ("Couldn't update section header", fnew, ndx);
    622     }
    623 
    624   /* If we have phdrs we want elf_update to layout the SHF_ALLOC
    625      sections precisely as in the original file.  In that case we are
    626      also responsible for setting phoff and shoff */
    627   if (layout)
    628     {
    629       /* Position the shdrs after the last (unallocated) section.  */
    630       if (gelf_getehdr (elfnew, &newehdr) == NULL)
    631 	fail_elf ("Couldn't get ehdr", fnew);
    632       const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT);
    633       newehdr.e_shoff = ((last_offset + offsize - 1)
    634 			 & ~((GElf_Off) (offsize - 1)));
    635 
    636       /* The phdrs go in the same place as in the original file.
    637 	 Normally right after the ELF header.  */
    638       newehdr.e_phoff = ehdr.e_phoff;
    639 
    640       if (gelf_update_ehdr (elfnew, &newehdr) == 0)
    641 	fail_elf ("Couldn't update ehdr", fnew);
    642 
    643       elf_flagelf (elfnew, ELF_C_SET, ELF_F_LAYOUT);
    644     }
    645 
    646   if (elf_update (elfnew, ELF_C_WRITE) == -1)
    647     fail_elf ("Couldn't write ELF", fnew);
    648 
    649   elf_end (elfnew);
    650   elfnew = NULL;
    651 
    652   /* Try to match mode and owner.group of the original file.  */
    653   if (fchmod (fdnew, st.st_mode & ALLPERMS) != 0)
    654     error (0, errno, "Couldn't fchmod %s", fnew);
    655   if (fchown (fdnew, st.st_uid, st.st_gid) != 0)
    656     error (0, errno, "Couldn't fchown %s", fnew);
    657 
    658   /* Finally replace the old file with the new merged strings file.  */
    659   if (replace)
    660     if (rename (fnew, fname) != 0)
    661       fail_errno ("rename", fnew);
    662 
    663   /* We are finally done with the new file, don't unlink it now.  */
    664   close (fdnew);
    665   if (replace)
    666     free (fnew);
    667   fnew = NULL;
    668   fdnew = -1;
    669 
    670   release ();
    671   return 0;
    672 }
    673