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