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