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