1 /* Combine stripped files with separate symbols and debug information. 2 Copyright (C) 2007-2012, 2014, 2015 Red Hat, Inc. 3 This file is part of elfutils. 4 Written by Roland McGrath <roland (at) redhat.com>, 2007. 5 6 This file is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 elfutils is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19 /* TODO: 20 21 * SHX_XINDEX 22 23 * prelink vs .debug_* linked addresses 24 25 */ 26 27 #ifdef HAVE_CONFIG_H 28 # include <config.h> 29 #endif 30 31 #include <argp.h> 32 #include <assert.h> 33 #include <errno.h> 34 #include <error.h> 35 #include <fcntl.h> 36 #include <fnmatch.h> 37 #include <libintl.h> 38 #include <locale.h> 39 #include <stdbool.h> 40 #include <stdio.h> 41 #include <stdio_ext.h> 42 #include <inttypes.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <unistd.h> 46 #include <sys/stat.h> 47 48 #include <gelf.h> 49 #include <libebl.h> 50 #include <libdwfl.h> 51 #include "system.h" 52 53 #ifndef _ 54 # define _(str) gettext (str) 55 #endif 56 57 /* Name and version of program. */ 58 static void print_version (FILE *stream, struct argp_state *state); 59 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; 60 61 /* Bug report address. */ 62 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; 63 64 /* Definitions of arguments for argp functions. */ 65 static const struct argp_option options[] = 66 { 67 /* Group 2 will follow group 1 from dwfl_standard_argp. */ 68 { "match-file-names", 'f', NULL, 0, 69 N_("Match MODULE against file names, not module names"), 2 }, 70 { "ignore-missing", 'i', NULL, 0, N_("Silently skip unfindable files"), 0 }, 71 72 { NULL, 0, NULL, 0, N_("Output options:"), 0 }, 73 { "output", 'o', "FILE", 0, N_("Place output into FILE"), 0 }, 74 { "output-directory", 'd', "DIRECTORY", 75 0, N_("Create multiple output files under DIRECTORY"), 0 }, 76 { "module-names", 'm', NULL, 0, N_("Use module rather than file names"), 0 }, 77 { "all", 'a', NULL, 0, 78 N_("Create output for modules that have no separate debug information"), 79 0 }, 80 { "relocate", 'R', NULL, 0, 81 N_("Apply relocations to section contents in ET_REL files"), 0 }, 82 { "list-only", 'n', NULL, 0, 83 N_("Only list module and file names, build IDs"), 0 }, 84 { "force", 'F', NULL, 0, 85 N_("Force combining files even if some ELF headers don't seem to match"), 86 0 }, 87 { NULL, 0, NULL, 0, NULL, 0 } 88 }; 89 90 struct arg_info 91 { 92 const char *output_file; 93 const char *output_dir; 94 Dwfl *dwfl; 95 char **args; 96 bool list; 97 bool all; 98 bool ignore; 99 bool modnames; 100 bool match_files; 101 bool relocate; 102 bool force; 103 }; 104 105 /* Handle program arguments. */ 106 static error_t 107 parse_opt (int key, char *arg, struct argp_state *state) 108 { 109 struct arg_info *info = state->input; 110 111 switch (key) 112 { 113 case ARGP_KEY_INIT: 114 state->child_inputs[0] = &info->dwfl; 115 break; 116 117 case 'o': 118 if (info->output_file != NULL) 119 { 120 argp_error (state, _("-o option specified twice")); 121 return EINVAL; 122 } 123 info->output_file = arg; 124 break; 125 126 case 'd': 127 if (info->output_dir != NULL) 128 { 129 argp_error (state, _("-d option specified twice")); 130 return EINVAL; 131 } 132 info->output_dir = arg; 133 break; 134 135 case 'm': 136 info->modnames = true; 137 break; 138 case 'f': 139 info->match_files = true; 140 break; 141 case 'a': 142 info->all = true; 143 break; 144 case 'i': 145 info->ignore = true; 146 break; 147 case 'n': 148 info->list = true; 149 break; 150 case 'R': 151 info->relocate = true; 152 break; 153 case 'F': 154 info->force = true; 155 break; 156 157 case ARGP_KEY_ARGS: 158 case ARGP_KEY_NO_ARGS: 159 /* We "consume" all the arguments here. */ 160 info->args = &state->argv[state->next]; 161 162 if (info->output_file != NULL && info->output_dir != NULL) 163 { 164 argp_error (state, _("only one of -o or -d allowed")); 165 return EINVAL; 166 } 167 168 if (info->list && (info->dwfl == NULL 169 || info->output_dir != NULL 170 || info->output_file != NULL)) 171 { 172 argp_error (state, 173 _("-n cannot be used with explicit files or -o or -d")); 174 return EINVAL; 175 } 176 177 if (info->output_dir != NULL) 178 { 179 struct stat st; 180 error_t fail = 0; 181 if (stat (info->output_dir, &st) < 0) 182 fail = errno; 183 else if (!S_ISDIR (st.st_mode)) 184 fail = ENOTDIR; 185 if (fail) 186 { 187 argp_failure (state, EXIT_FAILURE, fail, 188 _("output directory '%s'"), info->output_dir); 189 return fail; 190 } 191 } 192 193 if (info->dwfl == NULL) 194 { 195 if (state->next + 2 != state->argc) 196 { 197 argp_error (state, _("exactly two file arguments are required")); 198 return EINVAL; 199 } 200 201 if (info->ignore || info->all || info->modnames || info->relocate) 202 { 203 argp_error (state, _("\ 204 -m, -a, -R, and -i options not allowed with explicit files")); 205 return EINVAL; 206 } 207 208 /* Bail out immediately to prevent dwfl_standard_argp's parser 209 from defaulting to "-e a.out". */ 210 return ENOSYS; 211 } 212 else if (info->output_file == NULL && info->output_dir == NULL 213 && !info->list) 214 { 215 argp_error (state, 216 _("-o or -d is required when using implicit files")); 217 return EINVAL; 218 } 219 break; 220 221 default: 222 return ARGP_ERR_UNKNOWN; 223 } 224 return 0; 225 } 226 227 /* Print the version information. */ 228 static void 229 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 230 { 231 fprintf (stream, "unstrip (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 232 fprintf (stream, _("\ 233 Copyright (C) %s Red Hat, Inc.\n\ 234 This is free software; see the source for copying conditions. There is NO\n\ 235 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 236 "), "2012"); 237 fprintf (stream, gettext ("Written by %s.\n"), "Roland McGrath"); 238 } 239 240 #define ELF_CHECK(call, msg) \ 242 do \ 243 { \ 244 if (unlikely (!(call))) \ 245 error (EXIT_FAILURE, 0, msg, elf_errmsg (-1)); \ 246 } while (0) 247 248 /* Copy INELF to newly-created OUTELF, exit via error for any problems. */ 249 static void 250 copy_elf (Elf *outelf, Elf *inelf) 251 { 252 ELF_CHECK (gelf_newehdr (outelf, gelf_getclass (inelf)), 253 _("cannot create ELF header: %s")); 254 255 GElf_Ehdr ehdr_mem; 256 GElf_Ehdr *ehdr = gelf_getehdr (inelf, &ehdr_mem); 257 ELF_CHECK (gelf_update_ehdr (outelf, ehdr), 258 _("cannot copy ELF header: %s")); 259 260 size_t phnum; 261 ELF_CHECK (elf_getphdrnum (inelf, &phnum) == 0, 262 _("cannot get number of program headers: %s")); 263 264 if (phnum > 0) 265 { 266 ELF_CHECK (gelf_newphdr (outelf, phnum), 267 _("cannot create program headers: %s")); 268 269 GElf_Phdr phdr_mem; 270 for (size_t i = 0; i < phnum; ++i) 271 ELF_CHECK (gelf_update_phdr (outelf, i, 272 gelf_getphdr (inelf, i, &phdr_mem)), 273 _("cannot copy program header: %s")); 274 } 275 276 Elf_Scn *scn = NULL; 277 while ((scn = elf_nextscn (inelf, scn)) != NULL) 278 { 279 Elf_Scn *newscn = elf_newscn (outelf); 280 281 GElf_Shdr shdr_mem; 282 ELF_CHECK (gelf_update_shdr (newscn, gelf_getshdr (scn, &shdr_mem)), 283 _("cannot copy section header: %s")); 284 285 Elf_Data *data = elf_getdata (scn, NULL); 286 ELF_CHECK (data != NULL, _("cannot get section data: %s")); 287 Elf_Data *newdata = elf_newdata (newscn); 288 ELF_CHECK (newdata != NULL, _("cannot copy section data: %s")); 289 *newdata = *data; 290 elf_flagdata (newdata, ELF_C_SET, ELF_F_DIRTY); 291 } 292 } 293 294 /* Create directories containing PATH. */ 295 static void 296 make_directories (const char *path) 297 { 298 const char *lastslash = strrchr (path, '/'); 299 if (lastslash == NULL) 300 return; 301 302 while (lastslash > path && lastslash[-1] == '/') 303 --lastslash; 304 if (lastslash == path) 305 return; 306 307 char *dir = strndupa (path, lastslash - path); 308 while (mkdir (dir, 0777) < 0 && errno != EEXIST) 309 if (errno == ENOENT) 310 make_directories (dir); 311 else 312 error (EXIT_FAILURE, errno, _("cannot create directory '%s'"), dir); 313 } 314 315 /* Keep track of new section data we are creating, so we can free it 316 when done. */ 317 struct data_list 318 { 319 void *data; 320 struct data_list *next; 321 }; 322 323 struct data_list *new_data_list; 324 325 static void 326 record_new_data (void *data) 327 { 328 struct data_list *next = new_data_list; 329 new_data_list = xmalloc (sizeof (struct data_list)); 330 new_data_list->data = data; 331 new_data_list->next = next; 332 } 333 334 static void 335 free_new_data (void) 336 { 337 struct data_list *list = new_data_list; 338 while (list != NULL) 339 { 340 struct data_list *next = list->next; 341 free (list->data); 342 free (list); 343 list = next; 344 } 345 new_data_list = NULL; 346 } 347 348 /* The binutils linker leaves gratuitous section symbols in .symtab 349 that strip has to remove. Older linkers likewise include a 350 symbol for every section, even unallocated ones, in .dynsym. 351 Because of this, the related sections can shrink in the stripped 352 file from their original size. Older versions of strip do not 353 adjust the sh_size field in the debuginfo file's SHT_NOBITS 354 version of the section header, so it can appear larger. */ 355 static bool 356 section_can_shrink (const GElf_Shdr *shdr) 357 { 358 switch (shdr->sh_type) 359 { 360 case SHT_SYMTAB: 361 case SHT_DYNSYM: 362 case SHT_HASH: 363 case SHT_GNU_versym: 364 return true; 365 } 366 return false; 367 } 368 369 /* See if this symbol table has a leading section symbol for every single 370 section, in order. The binutils linker produces this. While we're here, 371 update each section symbol's st_value. */ 372 static size_t 373 symtab_count_leading_section_symbols (Elf *elf, Elf_Scn *scn, size_t shnum, 374 Elf_Data *newsymdata) 375 { 376 Elf_Data *data = elf_getdata (scn, NULL); 377 Elf_Data *shndxdata = NULL; /* XXX */ 378 379 for (size_t i = 1; i < shnum; ++i) 380 { 381 GElf_Sym sym_mem; 382 GElf_Word shndx = SHN_UNDEF; 383 GElf_Sym *sym = gelf_getsymshndx (data, shndxdata, i, &sym_mem, &shndx); 384 ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s")); 385 386 GElf_Shdr shdr_mem; 387 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (elf, i), &shdr_mem); 388 ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); 389 390 if (sym->st_shndx != SHN_XINDEX) 391 shndx = sym->st_shndx; 392 393 if (shndx != i || GELF_ST_TYPE (sym->st_info) != STT_SECTION) 394 return i; 395 396 sym->st_value = shdr->sh_addr; 397 if (sym->st_shndx != SHN_XINDEX) 398 shndx = SHN_UNDEF; 399 ELF_CHECK (gelf_update_symshndx (newsymdata, shndxdata, i, sym, shndx), 400 _("cannot update symbol table: %s")); 401 } 402 403 return shnum; 404 } 405 406 static void 407 update_shdr (Elf_Scn *outscn, GElf_Shdr *newshdr) 408 { 409 ELF_CHECK (gelf_update_shdr (outscn, newshdr), 410 _("cannot update section header: %s")); 411 } 412 413 /* We expanded the output section, so update its header. */ 414 static void 415 update_sh_size (Elf_Scn *outscn, const Elf_Data *data) 416 { 417 GElf_Shdr shdr_mem; 418 GElf_Shdr *newshdr = gelf_getshdr (outscn, &shdr_mem); 419 ELF_CHECK (newshdr != NULL, _("cannot get section header: %s")); 420 421 newshdr->sh_size = data->d_size; 422 423 update_shdr (outscn, newshdr); 424 } 425 426 /* Update relocation sections using the symbol table. */ 427 static void 428 adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr, 429 size_t map[], const GElf_Shdr *symshdr) 430 { 431 Elf_Data *data = elf_getdata (outscn, NULL); 432 433 inline void adjust_reloc (GElf_Xword *info) 434 { 435 size_t ndx = GELF_R_SYM (*info); 436 if (ndx != STN_UNDEF) 437 *info = GELF_R_INFO (map[ndx - 1], GELF_R_TYPE (*info)); 438 } 439 440 switch (shdr->sh_type) 441 { 442 case SHT_REL: 443 for (size_t i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i) 444 { 445 GElf_Rel rel_mem; 446 GElf_Rel *rel = gelf_getrel (data, i, &rel_mem); 447 adjust_reloc (&rel->r_info); 448 ELF_CHECK (gelf_update_rel (data, i, rel), 449 _("cannot update relocation: %s")); 450 } 451 break; 452 453 case SHT_RELA: 454 for (size_t i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i) 455 { 456 GElf_Rela rela_mem; 457 GElf_Rela *rela = gelf_getrela (data, i, &rela_mem); 458 adjust_reloc (&rela->r_info); 459 ELF_CHECK (gelf_update_rela (data, i, rela), 460 _("cannot update relocation: %s")); 461 } 462 break; 463 464 case SHT_GROUP: 465 { 466 GElf_Shdr shdr_mem; 467 GElf_Shdr *newshdr = gelf_getshdr (outscn, &shdr_mem); 468 ELF_CHECK (newshdr != NULL, _("cannot get section header: %s")); 469 if (newshdr->sh_info != STN_UNDEF) 470 { 471 newshdr->sh_info = map[newshdr->sh_info - 1]; 472 update_shdr (outscn, newshdr); 473 } 474 break; 475 } 476 477 case SHT_HASH: 478 /* We must expand the table and rejigger its contents. */ 479 { 480 const size_t nsym = symshdr->sh_size / symshdr->sh_entsize; 481 const size_t onent = shdr->sh_size / shdr->sh_entsize; 482 assert (data->d_size == shdr->sh_size); 483 484 #define CONVERT_HASH(Hash_Word) \ 485 { \ 486 const Hash_Word *const old_hash = data->d_buf; \ 487 const size_t nbucket = old_hash[0]; \ 488 const size_t nchain = old_hash[1]; \ 489 const Hash_Word *const old_bucket = &old_hash[2]; \ 490 const Hash_Word *const old_chain = &old_bucket[nbucket]; \ 491 assert (onent == 2 + nbucket + nchain); \ 492 \ 493 const size_t nent = 2 + nbucket + nsym; \ 494 Hash_Word *const new_hash = xcalloc (nent, sizeof new_hash[0]); \ 495 Hash_Word *const new_bucket = &new_hash[2]; \ 496 Hash_Word *const new_chain = &new_bucket[nbucket]; \ 497 \ 498 new_hash[0] = nbucket; \ 499 new_hash[1] = nsym; \ 500 for (size_t i = 0; i < nbucket; ++i) \ 501 if (old_bucket[i] != STN_UNDEF) \ 502 new_bucket[i] = map[old_bucket[i] - 1]; \ 503 \ 504 for (size_t i = 1; i < nchain; ++i) \ 505 if (old_chain[i] != STN_UNDEF) \ 506 new_chain[map[i - 1]] = map[old_chain[i] - 1]; \ 507 \ 508 record_new_data (new_hash); \ 509 data->d_buf = new_hash; \ 510 data->d_size = nent * sizeof new_hash[0]; \ 511 } 512 513 switch (shdr->sh_entsize) 514 { 515 case 4: 516 CONVERT_HASH (Elf32_Word); 517 break; 518 case 8: 519 CONVERT_HASH (Elf64_Xword); 520 break; 521 default: 522 abort (); 523 } 524 525 elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY); 526 update_sh_size (outscn, data); 527 528 #undef CONVERT_HASH 529 } 530 break; 531 532 case SHT_GNU_versym: 533 /* We must expand the table and move its elements around. */ 534 { 535 const size_t nent = symshdr->sh_size / symshdr->sh_entsize; 536 const size_t onent = shdr->sh_size / shdr->sh_entsize; 537 assert (nent >= onent); 538 539 /* We don't bother using gelf_update_versym because there is 540 really no conversion to be done. */ 541 assert (sizeof (Elf32_Versym) == sizeof (GElf_Versym)); 542 assert (sizeof (Elf64_Versym) == sizeof (GElf_Versym)); 543 GElf_Versym *versym = xcalloc (nent, sizeof versym[0]); 544 545 for (size_t i = 1; i < onent; ++i) 546 { 547 GElf_Versym *v = gelf_getversym (data, i, &versym[map[i - 1]]); 548 ELF_CHECK (v != NULL, _("cannot get symbol version: %s")); 549 } 550 551 record_new_data (versym); 552 data->d_buf = versym; 553 data->d_size = nent * shdr->sh_entsize; 554 elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY); 555 update_sh_size (outscn, data); 556 } 557 break; 558 559 default: 560 error (EXIT_FAILURE, 0, 561 _("unexpected section type in [%zu] with sh_link to symtab"), 562 elf_ndxscn (inscn)); 563 } 564 } 565 566 /* Adjust all the relocation sections in the file. */ 567 static void 568 adjust_all_relocs (Elf *elf, Elf_Scn *symtab, const GElf_Shdr *symshdr, 569 size_t map[]) 570 { 571 size_t new_sh_link = elf_ndxscn (symtab); 572 Elf_Scn *scn = NULL; 573 while ((scn = elf_nextscn (elf, scn)) != NULL) 574 if (scn != symtab) 575 { 576 GElf_Shdr shdr_mem; 577 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 578 ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); 579 if (shdr->sh_type != SHT_NOBITS && shdr->sh_link == new_sh_link) 580 adjust_relocs (scn, scn, shdr, map, symshdr); 581 } 582 } 583 584 /* The original file probably had section symbols for all of its 585 sections, even the unallocated ones. To match it as closely as 586 possible, add in section symbols for the added sections. */ 587 static Elf_Data * 588 add_new_section_symbols (Elf_Scn *old_symscn, size_t old_shnum, 589 Elf *elf, bool rel, Elf_Scn *symscn, size_t shnum) 590 { 591 const size_t added = shnum - old_shnum; 592 593 GElf_Shdr shdr_mem; 594 GElf_Shdr *shdr = gelf_getshdr (symscn, &shdr_mem); 595 ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); 596 597 const size_t nsym = shdr->sh_size / shdr->sh_entsize; 598 size_t symndx_map[nsym - 1]; 599 600 shdr->sh_info += added; 601 shdr->sh_size += added * shdr->sh_entsize; 602 update_shdr (symscn, shdr); 603 604 Elf_Data *symdata = elf_getdata (symscn, NULL); 605 Elf_Data *shndxdata = NULL; /* XXX */ 606 607 symdata->d_size = shdr->sh_size; 608 symdata->d_buf = xmalloc (symdata->d_size); 609 record_new_data (symdata->d_buf); 610 611 /* Copy the existing section symbols. */ 612 Elf_Data *old_symdata = elf_getdata (old_symscn, NULL); 613 for (size_t i = 0; i < old_shnum; ++i) 614 { 615 GElf_Sym sym_mem; 616 GElf_Word shndx = SHN_UNDEF; 617 GElf_Sym *sym = gelf_getsymshndx (old_symdata, shndxdata, 618 i, &sym_mem, &shndx); 619 ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, i, 620 sym, shndx), 621 _("cannot update symbol table: %s")); 622 623 if (i > 0) 624 symndx_map[i - 1] = i; 625 } 626 627 /* Add in the new section symbols. */ 628 for (size_t i = old_shnum; i < shnum; ++i) 629 { 630 GElf_Shdr i_shdr_mem; 631 GElf_Shdr *i_shdr = gelf_getshdr (elf_getscn (elf, i), &i_shdr_mem); 632 ELF_CHECK (i_shdr != NULL, _("cannot get section header: %s")); 633 GElf_Sym sym = 634 { 635 .st_value = rel ? 0 : i_shdr->sh_addr, 636 .st_info = GELF_ST_INFO (STB_LOCAL, STT_SECTION), 637 .st_shndx = i < SHN_LORESERVE ? i : SHN_XINDEX 638 }; 639 GElf_Word shndx = i < SHN_LORESERVE ? SHN_UNDEF : i; 640 ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, i, 641 &sym, shndx), 642 _("cannot update symbol table: %s")); 643 } 644 645 /* Now copy the rest of the existing symbols. */ 646 for (size_t i = old_shnum; i < nsym; ++i) 647 { 648 GElf_Sym sym_mem; 649 GElf_Word shndx = SHN_UNDEF; 650 GElf_Sym *sym = gelf_getsymshndx (old_symdata, shndxdata, 651 i, &sym_mem, &shndx); 652 ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, 653 i + added, sym, shndx), 654 _("cannot update symbol table: %s")); 655 656 symndx_map[i - 1] = i + added; 657 } 658 659 /* Adjust any relocations referring to the old symbol table. */ 660 adjust_all_relocs (elf, symscn, shdr, symndx_map); 661 662 return symdata; 663 } 664 665 /* This has the side effect of updating STT_SECTION symbols' values, 666 in case of prelink adjustments. */ 667 static Elf_Data * 668 check_symtab_section_symbols (Elf *elf, bool rel, Elf_Scn *scn, 669 size_t shnum, size_t shstrndx, 670 Elf_Scn *oscn, size_t oshnum, size_t oshstrndx, 671 size_t debuglink) 672 { 673 size_t n = symtab_count_leading_section_symbols (elf, oscn, oshnum, 674 elf_getdata (scn, NULL)); 675 676 if (n == oshnum) 677 return add_new_section_symbols (oscn, n, elf, rel, scn, shnum); 678 679 if (n == oshstrndx || (n == debuglink && n == oshstrndx - 1)) 680 return add_new_section_symbols (oscn, n, elf, rel, scn, shstrndx); 681 682 return NULL; 683 } 684 685 struct section 687 { 688 Elf_Scn *scn; 689 const char *name; 690 Elf_Scn *outscn; 691 struct Ebl_Strent *strent; 692 GElf_Shdr shdr; 693 }; 694 695 static int 696 compare_alloc_sections (const struct section *s1, const struct section *s2, 697 bool rel) 698 { 699 if (!rel) 700 { 701 /* Sort by address. */ 702 if (s1->shdr.sh_addr < s2->shdr.sh_addr) 703 return -1; 704 if (s1->shdr.sh_addr > s2->shdr.sh_addr) 705 return 1; 706 } 707 708 /* At the same address, preserve original section order. */ 709 return (ssize_t) elf_ndxscn (s1->scn) - (ssize_t) elf_ndxscn (s2->scn); 710 } 711 712 static int 713 compare_unalloc_sections (const GElf_Shdr *shdr1, const GElf_Shdr *shdr2, 714 const char *name1, const char *name2) 715 { 716 /* Sort by sh_flags as an arbitrary ordering. */ 717 if (shdr1->sh_flags < shdr2->sh_flags) 718 return -1; 719 if (shdr1->sh_flags > shdr2->sh_flags) 720 return 1; 721 722 /* Sort by name as last resort. */ 723 return strcmp (name1, name2); 724 } 725 726 static int 727 compare_sections (const void *a, const void *b, bool rel) 728 { 729 const struct section *s1 = a; 730 const struct section *s2 = b; 731 732 /* Sort all non-allocated sections last. */ 733 if ((s1->shdr.sh_flags ^ s2->shdr.sh_flags) & SHF_ALLOC) 734 return (s1->shdr.sh_flags & SHF_ALLOC) ? -1 : 1; 735 736 return ((s1->shdr.sh_flags & SHF_ALLOC) 737 ? compare_alloc_sections (s1, s2, rel) 738 : compare_unalloc_sections (&s1->shdr, &s2->shdr, 739 s1->name, s2->name)); 740 } 741 742 static int 743 compare_sections_rel (const void *a, const void *b) 744 { 745 return compare_sections (a, b, true); 746 } 747 748 static int 749 compare_sections_nonrel (const void *a, const void *b) 750 { 751 return compare_sections (a, b, false); 752 } 753 754 755 struct symbol 756 { 757 size_t *map; 758 759 union 760 { 761 const char *name; 762 struct Ebl_Strent *strent; 763 }; 764 union 765 { 766 struct 767 { 768 GElf_Addr value; 769 GElf_Xword size; 770 GElf_Word shndx; 771 union 772 { 773 struct 774 { 775 uint8_t info; 776 uint8_t other; 777 } info; 778 int16_t compare; 779 }; 780 }; 781 782 /* For a symbol discarded after first sort, this matches its better's 783 map pointer. */ 784 size_t *duplicate; 785 }; 786 }; 787 788 /* Collect input symbols into our internal form. */ 789 static void 790 collect_symbols (Elf *outelf, bool rel, Elf_Scn *symscn, Elf_Scn *strscn, 791 const size_t nent, const GElf_Addr bias, 792 const size_t scnmap[], struct symbol *table, size_t *map, 793 struct section *split_bss) 794 { 795 Elf_Data *symdata = elf_getdata (symscn, NULL); 796 Elf_Data *strdata = elf_getdata (strscn, NULL); 797 Elf_Data *shndxdata = NULL; /* XXX */ 798 799 for (size_t i = 1; i < nent; ++i) 800 { 801 GElf_Sym sym_mem; 802 GElf_Word shndx = SHN_UNDEF; 803 GElf_Sym *sym = gelf_getsymshndx (symdata, shndxdata, i, 804 &sym_mem, &shndx); 805 ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s")); 806 if (sym->st_shndx != SHN_XINDEX) 807 shndx = sym->st_shndx; 808 809 if (sym->st_name >= strdata->d_size) 810 error (EXIT_FAILURE, 0, 811 _("invalid string offset in symbol [%zu]"), i); 812 813 struct symbol *s = &table[i - 1]; 814 s->map = &map[i - 1]; 815 s->name = strdata->d_buf + sym->st_name; 816 s->value = sym->st_value + bias; 817 s->size = sym->st_size; 818 s->shndx = shndx; 819 s->info.info = sym->st_info; 820 s->info.other = sym->st_other; 821 822 if (scnmap != NULL && shndx != SHN_UNDEF && shndx < SHN_LORESERVE) 823 s->shndx = scnmap[shndx - 1]; 824 825 if (GELF_ST_TYPE (s->info.info) == STT_SECTION && !rel) 826 { 827 /* Update the value to match the output section. */ 828 GElf_Shdr shdr_mem; 829 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (outelf, s->shndx), 830 &shdr_mem); 831 ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); 832 s->value = shdr->sh_addr; 833 } 834 else if (split_bss != NULL 835 && s->value < split_bss->shdr.sh_addr 836 && s->value >= split_bss[-1].shdr.sh_addr 837 && shndx == elf_ndxscn (split_bss->outscn)) 838 /* This symbol was in .bss and was split into .dynbss. */ 839 s->shndx = elf_ndxscn (split_bss[-1].outscn); 840 } 841 } 842 843 844 #define CMP(value) \ 845 if (s1->value < s2->value) \ 846 return -1; \ 847 if (s1->value > s2->value) \ 848 return 1 849 850 /* Compare symbols with a consistent ordering, 851 but one only meaningful for equality. */ 852 static int 853 compare_symbols (const void *a, const void *b) 854 { 855 const struct symbol *s1 = a; 856 const struct symbol *s2 = b; 857 858 CMP (value); 859 CMP (size); 860 CMP (shndx); 861 862 return (s1->compare - s2->compare) ?: strcmp (s1->name, s2->name); 863 } 864 865 /* Compare symbols for output order after slots have been assigned. */ 866 static int 867 compare_symbols_output (const void *a, const void *b) 868 { 869 const struct symbol *s1 = a; 870 const struct symbol *s2 = b; 871 int cmp; 872 873 /* Sort discarded symbols last. */ 874 cmp = (s1->name == NULL) - (s2->name == NULL); 875 876 if (cmp == 0) 877 /* Local symbols must come first. */ 878 cmp = ((GELF_ST_BIND (s2->info.info) == STB_LOCAL) 879 - (GELF_ST_BIND (s1->info.info) == STB_LOCAL)); 880 881 if (cmp == 0) 882 /* binutils always puts section symbols first. */ 883 cmp = ((GELF_ST_TYPE (s2->info.info) == STT_SECTION) 884 - (GELF_ST_TYPE (s1->info.info) == STT_SECTION)); 885 886 if (cmp == 0) 887 { 888 if (GELF_ST_TYPE (s1->info.info) == STT_SECTION) 889 { 890 /* binutils always puts section symbols in section index order. */ 891 CMP (shndx); 892 else 893 assert (s1 == s2); 894 } 895 896 /* Nothing really matters, so preserve the original order. */ 897 CMP (map); 898 else 899 assert (s1 == s2); 900 } 901 902 return cmp; 903 } 904 905 #undef CMP 906 907 /* Return true if the flags of the sections match, ignoring the SHF_INFO_LINK 908 flag if the section contains relocation information. */ 909 static bool 910 sections_flags_match (Elf64_Xword sh_flags1, Elf64_Xword sh_flags2, 911 Elf64_Word sh_type) 912 { 913 if (sh_type == SHT_REL || sh_type == SHT_RELA) 914 { 915 sh_flags1 &= ~SHF_INFO_LINK; 916 sh_flags2 &= ~SHF_INFO_LINK; 917 } 918 919 return sh_flags1 == sh_flags2; 920 } 921 922 /* Return true iff the flags, size, and name match. */ 923 static bool 924 sections_match (const struct section *sections, size_t i, 925 const GElf_Shdr *shdr, const char *name) 926 { 927 return (sections_flags_match (sections[i].shdr.sh_flags, shdr->sh_flags, 928 sections[i].shdr.sh_type) 929 && (sections[i].shdr.sh_size == shdr->sh_size 930 || (sections[i].shdr.sh_size < shdr->sh_size 931 && section_can_shrink (§ions[i].shdr))) 932 && !strcmp (sections[i].name, name)); 933 } 934 935 /* Locate a matching allocated section in SECTIONS. */ 936 static struct section * 937 find_alloc_section (const GElf_Shdr *shdr, GElf_Addr bias, const char *name, 938 struct section sections[], size_t nalloc) 939 { 940 const GElf_Addr addr = shdr->sh_addr + bias; 941 size_t l = 0, u = nalloc; 942 while (l < u) 943 { 944 size_t i = (l + u) / 2; 945 if (addr < sections[i].shdr.sh_addr) 946 u = i; 947 else if (addr > sections[i].shdr.sh_addr) 948 l = i + 1; 949 else 950 { 951 /* We've found allocated sections with this address. 952 Find one with matching size, flags, and name. */ 953 while (i > 0 && sections[i - 1].shdr.sh_addr == addr) 954 --i; 955 for (; i < nalloc && sections[i].shdr.sh_addr == addr; 956 ++i) 957 if (sections_match (sections, i, shdr, name)) 958 return §ions[i]; 959 break; 960 } 961 } 962 return NULL; 963 } 964 965 static inline const char * 966 get_section_name (size_t ndx, const GElf_Shdr *shdr, const Elf_Data *shstrtab) 967 { 968 if (shdr->sh_name >= shstrtab->d_size) 969 error (EXIT_FAILURE, 0, _("cannot read section [%zu] name: %s"), 970 ndx, elf_errmsg (-1)); 971 return shstrtab->d_buf + shdr->sh_name; 972 } 973 974 /* Fix things up when prelink has moved some allocated sections around 975 and the debuginfo file's section headers no longer match up. 976 This fills in SECTIONS[0..NALLOC-1].outscn or exits. 977 If there was a .bss section that was split into two sections 978 with the new one preceding it in sh_addr, we return that pointer. */ 979 static struct section * 980 find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab, 981 Elf *main, const GElf_Ehdr *main_ehdr, 982 Elf_Data *main_shstrtab, GElf_Addr bias, 983 struct section *sections, 984 size_t nalloc, size_t nsections) 985 { 986 Elf_Scn *undo = NULL; 987 for (size_t i = nalloc; i < nsections; ++i) 988 { 989 const struct section *sec = §ions[i]; 990 if (sec->shdr.sh_type == SHT_PROGBITS 991 && !(sec->shdr.sh_flags & SHF_ALLOC) 992 && !strcmp (sec->name, ".gnu.prelink_undo")) 993 { 994 undo = sec->scn; 995 break; 996 } 997 } 998 999 /* Find the original allocated sections before prelinking. */ 1000 struct section *undo_sections = NULL; 1001 size_t undo_nalloc = 0; 1002 if (undo != NULL) 1003 { 1004 /* Clear assignments that might have been bogus. */ 1005 for (size_t i = 0; i < nalloc; ++i) 1006 sections[i].outscn = NULL; 1007 1008 Elf_Data *undodata = elf_rawdata (undo, NULL); 1009 ELF_CHECK (undodata != NULL, 1010 _("cannot read '.gnu.prelink_undo' section: %s")); 1011 1012 union 1013 { 1014 Elf32_Ehdr e32; 1015 Elf64_Ehdr e64; 1016 } ehdr; 1017 Elf_Data dst = 1018 { 1019 .d_buf = &ehdr, 1020 .d_size = sizeof ehdr, 1021 .d_type = ELF_T_EHDR, 1022 .d_version = EV_CURRENT 1023 }; 1024 Elf_Data src = *undodata; 1025 src.d_size = gelf_fsize (main, ELF_T_EHDR, 1, EV_CURRENT); 1026 src.d_type = ELF_T_EHDR; 1027 ELF_CHECK (gelf_xlatetom (main, &dst, &src, 1028 main_ehdr->e_ident[EI_DATA]) != NULL, 1029 _("cannot read '.gnu.prelink_undo' section: %s")); 1030 1031 uint_fast16_t phnum; 1032 uint_fast16_t shnum; 1033 if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32) 1034 { 1035 phnum = ehdr.e32.e_phnum; 1036 shnum = ehdr.e32.e_shnum; 1037 } 1038 else 1039 { 1040 phnum = ehdr.e64.e_phnum; 1041 shnum = ehdr.e64.e_shnum; 1042 } 1043 1044 size_t phsize = gelf_fsize (main, ELF_T_PHDR, phnum, EV_CURRENT); 1045 src.d_buf += src.d_size + phsize; 1046 src.d_size = gelf_fsize (main, ELF_T_SHDR, shnum - 1, EV_CURRENT); 1047 src.d_type = ELF_T_SHDR; 1048 if ((size_t) (src.d_buf - undodata->d_buf) > undodata->d_size 1049 || undodata->d_size - (src.d_buf - undodata->d_buf) != src.d_size) 1050 error (EXIT_FAILURE, 0, _("invalid contents in '%s' section"), 1051 ".gnu.prelink_undo"); 1052 1053 bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32; 1054 size_t shsize = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr); 1055 if (unlikely ((shnum - 1) > SIZE_MAX / shsize)) 1056 error (EXIT_FAILURE, 0, _("overflow with shnum = %zu in '%s' section"), 1057 (size_t) shnum, ".gnu.prelink_undo"); 1058 const size_t shdr_bytes = (shnum - 1) * shsize; 1059 void *shdr = xmalloc (shdr_bytes); 1060 dst.d_buf = shdr; 1061 dst.d_size = shdr_bytes; 1062 ELF_CHECK (gelf_xlatetom (main, &dst, &src, 1063 main_ehdr->e_ident[EI_DATA]) != NULL, 1064 _("cannot read '.gnu.prelink_undo' section: %s")); 1065 1066 undo_sections = xmalloc ((shnum - 1) * sizeof undo_sections[0]); 1067 for (size_t i = 0; i < shnum - 1; ++i) 1068 { 1069 struct section *sec = &undo_sections[undo_nalloc]; 1070 Elf32_Shdr (*s32)[shnum - 1] = shdr; 1071 Elf64_Shdr (*s64)[shnum - 1] = shdr; 1072 if (class32) 1073 { 1074 #define COPY(field) sec->shdr.field = (*s32)[i].field 1075 COPY (sh_name); 1076 COPY (sh_type); 1077 COPY (sh_flags); 1078 COPY (sh_addr); 1079 COPY (sh_offset); 1080 COPY (sh_size); 1081 COPY (sh_link); 1082 COPY (sh_info); 1083 COPY (sh_addralign); 1084 COPY (sh_entsize); 1085 #undef COPY 1086 } 1087 else 1088 sec->shdr = (*s64)[i]; 1089 if (sec->shdr.sh_flags & SHF_ALLOC) 1090 { 1091 sec->shdr.sh_addr += bias; 1092 sec->name = get_section_name (i + 1, &sec->shdr, main_shstrtab); 1093 sec->scn = elf_getscn (main, i + 1); /* Really just for ndx. */ 1094 sec->outscn = NULL; 1095 sec->strent = NULL; 1096 ++undo_nalloc; 1097 } 1098 } 1099 qsort (undo_sections, undo_nalloc, 1100 sizeof undo_sections[0], compare_sections_nonrel); 1101 free (shdr); 1102 } 1103 1104 bool fail = false; 1105 inline void check_match (bool match, Elf_Scn *scn, const char *name) 1106 { 1107 if (!match) 1108 { 1109 fail = true; 1110 error (0, 0, _("cannot find matching section for [%zu] '%s'"), 1111 elf_ndxscn (scn), name); 1112 } 1113 } 1114 1115 Elf_Scn *scn = NULL; 1116 while ((scn = elf_nextscn (debug, scn)) != NULL) 1117 { 1118 GElf_Shdr shdr_mem; 1119 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1120 ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); 1121 1122 if (!(shdr->sh_flags & SHF_ALLOC)) 1123 continue; 1124 1125 const char *name = get_section_name (elf_ndxscn (scn), shdr, 1126 debug_shstrtab); 1127 1128 if (undo_sections != NULL) 1129 { 1130 struct section *sec = find_alloc_section (shdr, 0, name, 1131 undo_sections, 1132 undo_nalloc); 1133 if (sec != NULL) 1134 { 1135 sec->outscn = scn; 1136 continue; 1137 } 1138 } 1139 1140 /* If there is no prelink info, we are just here to find 1141 the sections to give error messages about. */ 1142 for (size_t i = 0; shdr != NULL && i < nalloc; ++i) 1143 if (sections[i].outscn == scn) 1144 shdr = NULL; 1145 check_match (shdr == NULL, scn, name); 1146 } 1147 1148 if (fail) 1149 exit (EXIT_FAILURE); 1150 1151 /* Now we have lined up output sections for each of the original sections 1152 before prelinking. Translate those to the prelinked sections. 1153 This matches what prelink's undo_sections does. */ 1154 struct section *split_bss = NULL; 1155 for (size_t i = 0; i < undo_nalloc; ++i) 1156 { 1157 const struct section *undo_sec = &undo_sections[i]; 1158 1159 const char *name = undo_sec->name; 1160 scn = undo_sec->scn; /* This is just for elf_ndxscn. */ 1161 1162 for (size_t j = 0; j < nalloc; ++j) 1163 { 1164 struct section *sec = §ions[j]; 1165 #define RELA_SCALED(field) \ 1166 (2 * sec->shdr.field == 3 * undo_sec->shdr.field) 1167 if (sec->outscn == NULL 1168 && sec->shdr.sh_name == undo_sec->shdr.sh_name 1169 && sec->shdr.sh_flags == undo_sec->shdr.sh_flags 1170 && sec->shdr.sh_addralign == undo_sec->shdr.sh_addralign 1171 && (((sec->shdr.sh_type == undo_sec->shdr.sh_type 1172 && sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize 1173 && (sec->shdr.sh_size == undo_sec->shdr.sh_size 1174 || (sec->shdr.sh_size > undo_sec->shdr.sh_size 1175 && main_ehdr->e_type == ET_EXEC 1176 && !strcmp (sec->name, ".dynstr")))) 1177 || (sec->shdr.sh_size == undo_sec->shdr.sh_size 1178 && ((sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize 1179 && undo_sec->shdr.sh_type == SHT_NOBITS) 1180 || undo_sec->shdr.sh_type == SHT_PROGBITS) 1181 && !strcmp (sec->name, ".plt"))) 1182 || (sec->shdr.sh_type == SHT_RELA 1183 && undo_sec->shdr.sh_type == SHT_REL 1184 && RELA_SCALED (sh_entsize) && RELA_SCALED (sh_size)) 1185 || (sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize 1186 && (sec->shdr.sh_type == undo_sec->shdr.sh_type 1187 || (sec->shdr.sh_type == SHT_PROGBITS 1188 && undo_sec->shdr.sh_type == SHT_NOBITS)) 1189 && sec->shdr.sh_size <= undo_sec->shdr.sh_size 1190 && (!strcmp (sec->name, ".bss") 1191 || !strcmp (sec->name, ".sbss")) 1192 && (sec->shdr.sh_size == undo_sec->shdr.sh_size 1193 || (split_bss = sec) > sections)))) 1194 { 1195 sec->outscn = undo_sec->outscn; 1196 undo_sec = NULL; 1197 break; 1198 } 1199 } 1200 1201 check_match (undo_sec == NULL, scn, name); 1202 } 1203 1204 free (undo_sections); 1205 1206 if (fail) 1207 exit (EXIT_FAILURE); 1208 1209 return split_bss; 1210 } 1211 1212 /* Create new .shstrtab contents, subroutine of copy_elided_sections. 1213 This can't be open coded there and still use variable-length auto arrays, 1214 since the end of our block would free other VLAs too. */ 1215 static Elf_Data * 1216 new_shstrtab (Elf *unstripped, size_t unstripped_shnum, 1217 Elf_Data *shstrtab, size_t unstripped_shstrndx, 1218 struct section *sections, size_t stripped_shnum, 1219 struct Ebl_Strtab *strtab) 1220 { 1221 if (strtab == NULL) 1222 return NULL; 1223 1224 struct Ebl_Strent *unstripped_strent[unstripped_shnum - 1]; 1225 memset (unstripped_strent, 0, sizeof unstripped_strent); 1226 for (struct section *sec = sections; 1227 sec < §ions[stripped_shnum - 1]; 1228 ++sec) 1229 if (sec->outscn != NULL) 1230 { 1231 if (sec->strent == NULL) 1232 { 1233 sec->strent = ebl_strtabadd (strtab, sec->name, 0); 1234 ELF_CHECK (sec->strent != NULL, 1235 _("cannot add section name to string table: %s")); 1236 } 1237 unstripped_strent[elf_ndxscn (sec->outscn) - 1] = sec->strent; 1238 } 1239 1240 /* Add names of sections we aren't touching. */ 1241 for (size_t i = 0; i < unstripped_shnum - 1; ++i) 1242 if (unstripped_strent[i] == NULL) 1243 { 1244 Elf_Scn *scn = elf_getscn (unstripped, i + 1); 1245 GElf_Shdr shdr_mem; 1246 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1247 const char *name = get_section_name (i + 1, shdr, shstrtab); 1248 unstripped_strent[i] = ebl_strtabadd (strtab, name, 0); 1249 ELF_CHECK (unstripped_strent[i] != NULL, 1250 _("cannot add section name to string table: %s")); 1251 } 1252 else 1253 unstripped_strent[i] = NULL; 1254 1255 /* Now finalize the string table so we can get offsets. */ 1256 Elf_Data *strtab_data = elf_getdata (elf_getscn (unstripped, 1257 unstripped_shstrndx), NULL); 1258 ELF_CHECK (elf_flagdata (strtab_data, ELF_C_SET, ELF_F_DIRTY), 1259 _("cannot update section header string table data: %s")); 1260 ebl_strtabfinalize (strtab, strtab_data); 1261 1262 /* Update the sh_name fields of sections we aren't modifying later. */ 1263 for (size_t i = 0; i < unstripped_shnum - 1; ++i) 1264 if (unstripped_strent[i] != NULL) 1265 { 1266 Elf_Scn *scn = elf_getscn (unstripped, i + 1); 1267 GElf_Shdr shdr_mem; 1268 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1269 shdr->sh_name = ebl_strtaboffset (unstripped_strent[i]); 1270 if (i + 1 == unstripped_shstrndx) 1271 shdr->sh_size = strtab_data->d_size; 1272 update_shdr (scn, shdr); 1273 } 1274 1275 return strtab_data; 1276 } 1277 1278 /* Fill in any SHT_NOBITS sections in UNSTRIPPED by 1279 copying their contents and sh_type from STRIPPED. */ 1280 static void 1281 copy_elided_sections (Elf *unstripped, Elf *stripped, 1282 const GElf_Ehdr *stripped_ehdr, GElf_Addr bias) 1283 { 1284 size_t unstripped_shstrndx; 1285 ELF_CHECK (elf_getshdrstrndx (unstripped, &unstripped_shstrndx) == 0, 1286 _("cannot get section header string table section index: %s")); 1287 1288 size_t stripped_shstrndx; 1289 ELF_CHECK (elf_getshdrstrndx (stripped, &stripped_shstrndx) == 0, 1290 _("cannot get section header string table section index: %s")); 1291 1292 size_t unstripped_shnum; 1293 ELF_CHECK (elf_getshdrnum (unstripped, &unstripped_shnum) == 0, 1294 _("cannot get section count: %s")); 1295 1296 size_t stripped_shnum; 1297 ELF_CHECK (elf_getshdrnum (stripped, &stripped_shnum) == 0, 1298 _("cannot get section count: %s")); 1299 1300 if (unlikely (stripped_shnum > unstripped_shnum)) 1301 error (EXIT_FAILURE, 0, _("\ 1302 more sections in stripped file than debug file -- arguments reversed?")); 1303 1304 /* Cache the stripped file's section details. */ 1305 struct section sections[stripped_shnum - 1]; 1306 Elf_Scn *scn = NULL; 1307 while ((scn = elf_nextscn (stripped, scn)) != NULL) 1308 { 1309 size_t i = elf_ndxscn (scn) - 1; 1310 GElf_Shdr *shdr = gelf_getshdr (scn, §ions[i].shdr); 1311 ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); 1312 sections[i].name = elf_strptr (stripped, stripped_shstrndx, 1313 shdr->sh_name); 1314 if (sections[i].name == NULL) 1315 error (EXIT_FAILURE, 0, _("cannot read section [%zu] name: %s"), 1316 elf_ndxscn (scn), elf_errmsg (-1)); 1317 sections[i].scn = scn; 1318 sections[i].outscn = NULL; 1319 sections[i].strent = NULL; 1320 } 1321 1322 const struct section *stripped_symtab = NULL; 1323 1324 /* Sort the sections, allocated by address and others after. */ 1325 qsort (sections, stripped_shnum - 1, sizeof sections[0], 1326 stripped_ehdr->e_type == ET_REL 1327 ? compare_sections_rel : compare_sections_nonrel); 1328 size_t nalloc = stripped_shnum - 1; 1329 while (nalloc > 0 && !(sections[nalloc - 1].shdr.sh_flags & SHF_ALLOC)) 1330 { 1331 --nalloc; 1332 if (sections[nalloc].shdr.sh_type == SHT_SYMTAB) 1333 stripped_symtab = §ions[nalloc]; 1334 } 1335 1336 /* Locate a matching unallocated section in SECTIONS. */ 1337 inline struct section *find_unalloc_section (const GElf_Shdr *shdr, 1338 const char *name) 1339 { 1340 size_t l = nalloc, u = stripped_shnum - 1; 1341 while (l < u) 1342 { 1343 size_t i = (l + u) / 2; 1344 struct section *sec = §ions[i]; 1345 int cmp = compare_unalloc_sections (shdr, &sec->shdr, 1346 name, sec->name); 1347 if (cmp < 0) 1348 u = i; 1349 else if (cmp > 0) 1350 l = i + 1; 1351 else 1352 return sec; 1353 } 1354 return NULL; 1355 } 1356 1357 Elf_Data *shstrtab = elf_getdata (elf_getscn (unstripped, 1358 unstripped_shstrndx), NULL); 1359 ELF_CHECK (shstrtab != NULL, 1360 _("cannot read section header string table: %s")); 1361 1362 /* Match each debuginfo section with its corresponding stripped section. */ 1363 bool check_prelink = false; 1364 Elf_Scn *unstripped_symtab = NULL; 1365 size_t alloc_avail = 0; 1366 scn = NULL; 1367 while ((scn = elf_nextscn (unstripped, scn)) != NULL) 1368 { 1369 GElf_Shdr shdr_mem; 1370 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1371 ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); 1372 1373 if (shdr->sh_type == SHT_SYMTAB) 1374 { 1375 unstripped_symtab = scn; 1376 continue; 1377 } 1378 1379 const size_t ndx = elf_ndxscn (scn); 1380 if (ndx == unstripped_shstrndx) 1381 continue; 1382 1383 const char *name = get_section_name (ndx, shdr, shstrtab); 1384 1385 struct section *sec = NULL; 1386 if (shdr->sh_flags & SHF_ALLOC) 1387 { 1388 if (stripped_ehdr->e_type != ET_REL) 1389 { 1390 /* Look for the section that matches. */ 1391 sec = find_alloc_section (shdr, bias, name, sections, nalloc); 1392 if (sec == NULL) 1393 { 1394 /* We couldn't figure it out. It may be a prelink issue. */ 1395 check_prelink = true; 1396 continue; 1397 } 1398 } 1399 else 1400 { 1401 /* The sh_addr of allocated sections does not help us, 1402 but the order usually matches. */ 1403 if (likely (sections_match (sections, alloc_avail, shdr, name))) 1404 sec = §ions[alloc_avail++]; 1405 else 1406 for (size_t i = alloc_avail + 1; i < nalloc; ++i) 1407 if (sections_match (sections, i, shdr, name)) 1408 { 1409 sec = §ions[i]; 1410 break; 1411 } 1412 } 1413 } 1414 else 1415 { 1416 /* Look for the section that matches. */ 1417 sec = find_unalloc_section (shdr, name); 1418 if (sec == NULL) 1419 { 1420 /* An additional unallocated section is fine if not SHT_NOBITS. 1421 We looked it up anyway in case it's an unallocated section 1422 copied in both files (e.g. SHT_NOTE), and don't keep both. */ 1423 if (shdr->sh_type != SHT_NOBITS) 1424 continue; 1425 1426 /* Somehow some old .debug files wound up with SHT_NOBITS 1427 .comment sections, so let those pass. */ 1428 if (!strcmp (name, ".comment")) 1429 continue; 1430 } 1431 } 1432 1433 if (sec == NULL) 1434 error (EXIT_FAILURE, 0, 1435 _("cannot find matching section for [%zu] '%s'"), 1436 elf_ndxscn (scn), name); 1437 1438 sec->outscn = scn; 1439 } 1440 1441 /* If that failed due to changes made by prelink, we take another tack. 1442 We keep track of a .bss section that was partly split into .dynbss 1443 so that collect_symbols can update symbols' st_shndx fields. */ 1444 struct section *split_bss = NULL; 1445 if (check_prelink) 1446 { 1447 Elf_Data *data = elf_getdata (elf_getscn (stripped, stripped_shstrndx), 1448 NULL); 1449 ELF_CHECK (data != NULL, 1450 _("cannot read section header string table: %s")); 1451 split_bss = find_alloc_sections_prelink (unstripped, shstrtab, 1452 stripped, stripped_ehdr, 1453 data, bias, sections, 1454 nalloc, stripped_shnum - 1); 1455 } 1456 1457 /* Make sure each main file section has a place to go. */ 1458 const struct section *stripped_dynsym = NULL; 1459 size_t debuglink = SHN_UNDEF; 1460 size_t ndx_section[stripped_shnum - 1]; 1461 struct Ebl_Strtab *strtab = NULL; 1462 for (struct section *sec = sections; 1463 sec < §ions[stripped_shnum - 1]; 1464 ++sec) 1465 { 1466 size_t secndx = elf_ndxscn (sec->scn); 1467 1468 if (sec->outscn == NULL) 1469 { 1470 /* We didn't find any corresponding section for this. */ 1471 1472 if (secndx == stripped_shstrndx) 1473 { 1474 /* We only need one .shstrtab. */ 1475 ndx_section[secndx - 1] = unstripped_shstrndx; 1476 continue; 1477 } 1478 1479 if (unstripped_symtab != NULL && sec == stripped_symtab) 1480 { 1481 /* We don't need a second symbol table. */ 1482 ndx_section[secndx - 1] = elf_ndxscn (unstripped_symtab); 1483 continue; 1484 } 1485 1486 if (unstripped_symtab != NULL && stripped_symtab != NULL 1487 && secndx == stripped_symtab->shdr.sh_link) 1488 { 1489 /* ... nor its string table. */ 1490 GElf_Shdr shdr_mem; 1491 GElf_Shdr *shdr = gelf_getshdr (unstripped_symtab, &shdr_mem); 1492 ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); 1493 ndx_section[secndx - 1] = shdr->sh_link; 1494 continue; 1495 } 1496 1497 if (!(sec->shdr.sh_flags & SHF_ALLOC) 1498 && !strcmp (sec->name, ".gnu_debuglink")) 1499 { 1500 /* This was created by stripping. We don't want it. */ 1501 debuglink = secndx; 1502 ndx_section[secndx - 1] = SHN_UNDEF; 1503 continue; 1504 } 1505 1506 sec->outscn = elf_newscn (unstripped); 1507 Elf_Data *newdata = elf_newdata (sec->outscn); 1508 ELF_CHECK (newdata != NULL && gelf_update_shdr (sec->outscn, 1509 &sec->shdr), 1510 _("cannot add new section: %s")); 1511 1512 if (strtab == NULL) 1513 strtab = ebl_strtabinit (true); 1514 sec->strent = ebl_strtabadd (strtab, sec->name, 0); 1515 ELF_CHECK (sec->strent != NULL, 1516 _("cannot add section name to string table: %s")); 1517 } 1518 1519 /* Cache the mapping of original section indices to output sections. */ 1520 ndx_section[secndx - 1] = elf_ndxscn (sec->outscn); 1521 } 1522 1523 /* We added some sections, so we need a new shstrtab. */ 1524 Elf_Data *strtab_data = new_shstrtab (unstripped, unstripped_shnum, 1525 shstrtab, unstripped_shstrndx, 1526 sections, stripped_shnum, 1527 strtab); 1528 1529 /* Get the updated section count. */ 1530 ELF_CHECK (elf_getshdrnum (unstripped, &unstripped_shnum) == 0, 1531 _("cannot get section count: %s")); 1532 1533 bool placed[unstripped_shnum - 1]; 1534 memset (placed, 0, sizeof placed); 1535 1536 /* Now update the output sections and copy in their data. */ 1537 GElf_Off offset = 0; 1538 for (const struct section *sec = sections; 1539 sec < §ions[stripped_shnum - 1]; 1540 ++sec) 1541 if (sec->outscn != NULL) 1542 { 1543 GElf_Shdr shdr_mem; 1544 GElf_Shdr *shdr = gelf_getshdr (sec->outscn, &shdr_mem); 1545 ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); 1546 1547 /* In an ET_REL file under --relocate, the sh_addr of SHF_ALLOC 1548 sections will have been set nonzero by relocation. This 1549 touched the shdrs of whichever file had the symtab. sh_addr 1550 is still zero in the corresponding shdr. The relocated 1551 address is what we want to use. */ 1552 if (stripped_ehdr->e_type != ET_REL 1553 || !(shdr_mem.sh_flags & SHF_ALLOC) 1554 || shdr_mem.sh_addr == 0) 1555 shdr_mem.sh_addr = sec->shdr.sh_addr; 1556 1557 shdr_mem.sh_type = sec->shdr.sh_type; 1558 shdr_mem.sh_size = sec->shdr.sh_size; 1559 shdr_mem.sh_info = sec->shdr.sh_info; 1560 shdr_mem.sh_link = sec->shdr.sh_link; 1561 1562 /* Buggy binutils objdump might have stripped the SHF_INFO_LINK 1563 put it back if necessary. */ 1564 if ((sec->shdr.sh_type == SHT_REL || sec->shdr.sh_type == SHT_RELA) 1565 && sec->shdr.sh_flags != shdr_mem.sh_flags 1566 && (sec->shdr.sh_flags & SHF_INFO_LINK) != 0) 1567 shdr_mem.sh_flags |= SHF_INFO_LINK; 1568 1569 if (sec->shdr.sh_link != SHN_UNDEF) 1570 shdr_mem.sh_link = ndx_section[sec->shdr.sh_link - 1]; 1571 if (SH_INFO_LINK_P (&sec->shdr) && sec->shdr.sh_info != 0) 1572 shdr_mem.sh_info = ndx_section[sec->shdr.sh_info - 1]; 1573 1574 if (strtab != NULL) 1575 shdr_mem.sh_name = ebl_strtaboffset (sec->strent); 1576 1577 Elf_Data *indata = elf_getdata (sec->scn, NULL); 1578 ELF_CHECK (indata != NULL, _("cannot get section data: %s")); 1579 Elf_Data *outdata = elf_getdata (sec->outscn, NULL); 1580 ELF_CHECK (outdata != NULL, _("cannot copy section data: %s")); 1581 *outdata = *indata; 1582 elf_flagdata (outdata, ELF_C_SET, ELF_F_DIRTY); 1583 1584 /* Preserve the file layout of the allocated sections. */ 1585 if (stripped_ehdr->e_type != ET_REL && (shdr_mem.sh_flags & SHF_ALLOC)) 1586 { 1587 shdr_mem.sh_offset = sec->shdr.sh_offset; 1588 placed[elf_ndxscn (sec->outscn) - 1] = true; 1589 1590 const GElf_Off end_offset = (shdr_mem.sh_offset 1591 + (shdr_mem.sh_type == SHT_NOBITS 1592 ? 0 : shdr_mem.sh_size)); 1593 if (end_offset > offset) 1594 offset = end_offset; 1595 } 1596 1597 update_shdr (sec->outscn, &shdr_mem); 1598 1599 if (shdr_mem.sh_type == SHT_SYMTAB || shdr_mem.sh_type == SHT_DYNSYM) 1600 { 1601 /* We must adjust all the section indices in the symbol table. */ 1602 1603 Elf_Data *shndxdata = NULL; /* XXX */ 1604 1605 for (size_t i = 1; i < shdr_mem.sh_size / shdr_mem.sh_entsize; ++i) 1606 { 1607 GElf_Sym sym_mem; 1608 GElf_Word shndx = SHN_UNDEF; 1609 GElf_Sym *sym = gelf_getsymshndx (outdata, shndxdata, 1610 i, &sym_mem, &shndx); 1611 ELF_CHECK (sym != NULL, 1612 _("cannot get symbol table entry: %s")); 1613 if (sym->st_shndx != SHN_XINDEX) 1614 shndx = sym->st_shndx; 1615 1616 if (shndx != SHN_UNDEF && shndx < SHN_LORESERVE) 1617 { 1618 if (shndx >= stripped_shnum) 1619 error (EXIT_FAILURE, 0, 1620 _("symbol [%zu] has invalid section index"), i); 1621 1622 shndx = ndx_section[shndx - 1]; 1623 if (shndx < SHN_LORESERVE) 1624 { 1625 sym->st_shndx = shndx; 1626 shndx = SHN_UNDEF; 1627 } 1628 else 1629 sym->st_shndx = SHN_XINDEX; 1630 1631 ELF_CHECK (gelf_update_symshndx (outdata, shndxdata, 1632 i, sym, shndx), 1633 _("cannot update symbol table: %s")); 1634 } 1635 } 1636 1637 if (shdr_mem.sh_type == SHT_SYMTAB) 1638 stripped_symtab = sec; 1639 if (shdr_mem.sh_type == SHT_DYNSYM) 1640 stripped_dynsym = sec; 1641 } 1642 } 1643 1644 /* We may need to update the symbol table. */ 1645 Elf_Data *symdata = NULL; 1646 struct Ebl_Strtab *symstrtab = NULL; 1647 Elf_Data *symstrdata = NULL; 1648 if (unstripped_symtab != NULL && (stripped_symtab != NULL 1649 || check_prelink /* Section adjustments. */ 1650 || (stripped_ehdr->e_type != ET_REL 1651 && bias != 0))) 1652 { 1653 /* Merge the stripped file's symbol table into the unstripped one. */ 1654 const size_t stripped_nsym = (stripped_symtab == NULL ? 1 1655 : (stripped_symtab->shdr.sh_size 1656 / stripped_symtab->shdr.sh_entsize)); 1657 1658 GElf_Shdr shdr_mem; 1659 GElf_Shdr *shdr = gelf_getshdr (unstripped_symtab, &shdr_mem); 1660 ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); 1661 const size_t unstripped_nsym = shdr->sh_size / shdr->sh_entsize; 1662 1663 /* First collect all the symbols from both tables. */ 1664 1665 const size_t total_syms = stripped_nsym - 1 + unstripped_nsym - 1; 1666 struct symbol symbols[total_syms]; 1667 size_t symndx_map[total_syms]; 1668 1669 if (stripped_symtab != NULL) 1670 collect_symbols (unstripped, stripped_ehdr->e_type == ET_REL, 1671 stripped_symtab->scn, 1672 elf_getscn (stripped, stripped_symtab->shdr.sh_link), 1673 stripped_nsym, 0, ndx_section, 1674 symbols, symndx_map, NULL); 1675 1676 Elf_Scn *unstripped_strtab = elf_getscn (unstripped, shdr->sh_link); 1677 collect_symbols (unstripped, stripped_ehdr->e_type == ET_REL, 1678 unstripped_symtab, unstripped_strtab, unstripped_nsym, 1679 stripped_ehdr->e_type == ET_REL ? 0 : bias, NULL, 1680 &symbols[stripped_nsym - 1], 1681 &symndx_map[stripped_nsym - 1], split_bss); 1682 1683 /* Next, sort our array of all symbols. */ 1684 qsort (symbols, total_syms, sizeof symbols[0], compare_symbols); 1685 1686 /* Now we can weed out the duplicates. Assign remaining symbols 1687 new slots, collecting a map from old indices to new. */ 1688 size_t nsym = 0; 1689 for (struct symbol *s = symbols; s < &symbols[total_syms]; ++s) 1690 { 1691 /* Skip a section symbol for a removed section. */ 1692 if (s->shndx == SHN_UNDEF 1693 && GELF_ST_TYPE (s->info.info) == STT_SECTION) 1694 { 1695 s->name = NULL; /* Mark as discarded. */ 1696 *s->map = STN_UNDEF; 1697 s->duplicate = NULL; 1698 continue; 1699 } 1700 1701 struct symbol *n = s; 1702 while (n + 1 < &symbols[total_syms] && !compare_symbols (s, n + 1)) 1703 ++n; 1704 1705 while (s < n) 1706 { 1707 /* This is a duplicate. Its twin will get the next slot. */ 1708 s->name = NULL; /* Mark as discarded. */ 1709 s->duplicate = n->map; 1710 ++s; 1711 } 1712 1713 /* Allocate the next slot. */ 1714 *s->map = ++nsym; 1715 } 1716 1717 /* Now we sort again, to determine the order in the output. */ 1718 qsort (symbols, total_syms, sizeof symbols[0], compare_symbols_output); 1719 1720 if (nsym < total_syms) 1721 /* The discarded symbols are now at the end of the table. */ 1722 assert (symbols[nsym].name == NULL); 1723 1724 /* Now a final pass updates the map with the final order, 1725 and builds up the new string table. */ 1726 symstrtab = ebl_strtabinit (true); 1727 for (size_t i = 0; i < nsym; ++i) 1728 { 1729 assert (symbols[i].name != NULL); 1730 assert (*symbols[i].map != 0); 1731 *symbols[i].map = 1 + i; 1732 symbols[i].strent = ebl_strtabadd (symstrtab, symbols[i].name, 0); 1733 } 1734 1735 /* Scan the discarded symbols too, just to update their slots 1736 in SYMNDX_MAP to refer to their live duplicates. */ 1737 for (size_t i = nsym; i < total_syms; ++i) 1738 { 1739 assert (symbols[i].name == NULL); 1740 if (symbols[i].duplicate == NULL) 1741 assert (*symbols[i].map == STN_UNDEF); 1742 else 1743 { 1744 assert (*symbols[i].duplicate != STN_UNDEF); 1745 *symbols[i].map = *symbols[i].duplicate; 1746 } 1747 } 1748 1749 /* Now we are ready to write the new symbol table. */ 1750 symdata = elf_getdata (unstripped_symtab, NULL); 1751 symstrdata = elf_getdata (unstripped_strtab, NULL); 1752 Elf_Data *shndxdata = NULL; /* XXX */ 1753 1754 /* If symtab and the section header table share the string table 1755 add the section names to the strtab and then (after finalizing) 1756 fixup the section header sh_names. Also dispose of the old data. */ 1757 struct Ebl_Strent *unstripped_strent[unstripped_shnum - 1]; 1758 if (unstripped_shstrndx == elf_ndxscn (unstripped_strtab)) 1759 { 1760 for (size_t i = 0; i < unstripped_shnum - 1; ++i) 1761 { 1762 Elf_Scn *sec = elf_getscn (unstripped, i + 1); 1763 GElf_Shdr mem; 1764 GElf_Shdr *hdr = gelf_getshdr (sec, &mem); 1765 const char *name = get_section_name (i + 1, hdr, shstrtab); 1766 unstripped_strent[i + 1] = ebl_strtabadd (symstrtab, name, 0); 1767 ELF_CHECK (unstripped_strent[i + 1] != NULL, 1768 _("cannot add section name to string table: %s")); 1769 } 1770 1771 if (strtab != NULL) 1772 { 1773 ebl_strtabfree (strtab); 1774 free (strtab_data->d_buf); 1775 strtab = NULL; 1776 } 1777 } 1778 1779 ebl_strtabfinalize (symstrtab, symstrdata); 1780 elf_flagdata (symstrdata, ELF_C_SET, ELF_F_DIRTY); 1781 1782 /* And update the section header names if necessary. */ 1783 if (unstripped_shstrndx == elf_ndxscn (unstripped_strtab)) 1784 { 1785 for (size_t i = 0; i < unstripped_shnum - 1; ++i) 1786 { 1787 Elf_Scn *sec = elf_getscn (unstripped, i + 1); 1788 GElf_Shdr mem; 1789 GElf_Shdr *hdr = gelf_getshdr (sec, &mem); 1790 shdr->sh_name = ebl_strtaboffset (unstripped_strent[i + 1]); 1791 update_shdr (sec, hdr); 1792 } 1793 } 1794 1795 /* Now update the symtab shdr. Reload symtab shdr because sh_name 1796 might have changed above. */ 1797 shdr = gelf_getshdr (unstripped_symtab, &shdr_mem); 1798 ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); 1799 1800 shdr->sh_size = symdata->d_size = (1 + nsym) * shdr->sh_entsize; 1801 symdata->d_buf = xmalloc (symdata->d_size); 1802 record_new_data (symdata->d_buf); 1803 1804 GElf_Sym sym; 1805 memset (&sym, 0, sizeof sym); 1806 ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, 0, &sym, SHN_UNDEF), 1807 _("cannot update symbol table: %s")); 1808 1809 shdr->sh_info = 1; 1810 for (size_t i = 0; i < nsym; ++i) 1811 { 1812 struct symbol *s = &symbols[i]; 1813 1814 /* Fill in the symbol details. */ 1815 sym.st_name = ebl_strtaboffset (s->strent); 1816 sym.st_value = s->value; /* Already biased to output address. */ 1817 sym.st_size = s->size; 1818 sym.st_shndx = s->shndx; /* Already mapped to output index. */ 1819 sym.st_info = s->info.info; 1820 sym.st_other = s->info.other; 1821 1822 /* Keep track of the number of leading local symbols. */ 1823 if (GELF_ST_BIND (sym.st_info) == STB_LOCAL) 1824 { 1825 assert (shdr->sh_info == 1 + i); 1826 shdr->sh_info = 1 + i + 1; 1827 } 1828 1829 ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, 1 + i, 1830 &sym, SHN_UNDEF), 1831 _("cannot update symbol table: %s")); 1832 1833 } 1834 elf_flagdata (symdata, ELF_C_SET, ELF_F_DIRTY); 1835 update_shdr (unstripped_symtab, shdr); 1836 1837 if (stripped_symtab != NULL) 1838 { 1839 /* Adjust any relocations referring to the old symbol table. */ 1840 const size_t old_sh_link = elf_ndxscn (stripped_symtab->scn); 1841 for (const struct section *sec = sections; 1842 sec < §ions[stripped_shnum - 1]; 1843 ++sec) 1844 if (sec->outscn != NULL && sec->shdr.sh_link == old_sh_link) 1845 adjust_relocs (sec->outscn, sec->scn, &sec->shdr, 1846 symndx_map, shdr); 1847 } 1848 1849 /* Also adjust references to the other old symbol table. */ 1850 adjust_all_relocs (unstripped, unstripped_symtab, shdr, 1851 &symndx_map[stripped_nsym - 1]); 1852 } 1853 else if (stripped_symtab != NULL && stripped_shnum != unstripped_shnum) 1854 check_symtab_section_symbols (unstripped, 1855 stripped_ehdr->e_type == ET_REL, 1856 stripped_symtab->scn, 1857 unstripped_shnum, unstripped_shstrndx, 1858 stripped_symtab->outscn, 1859 stripped_shnum, stripped_shstrndx, 1860 debuglink); 1861 1862 if (stripped_dynsym != NULL) 1863 (void) check_symtab_section_symbols (unstripped, 1864 stripped_ehdr->e_type == ET_REL, 1865 stripped_dynsym->outscn, 1866 unstripped_shnum, 1867 unstripped_shstrndx, 1868 stripped_dynsym->scn, stripped_shnum, 1869 stripped_shstrndx, debuglink); 1870 1871 /* We need to preserve the layout of the stripped file so the 1872 phdrs will match up. This requires us to do our own layout of 1873 the added sections. We do manual layout even for ET_REL just 1874 so we can try to match what the original probably had. */ 1875 1876 elf_flagelf (unstripped, ELF_C_SET, ELF_F_LAYOUT); 1877 1878 if (offset == 0) 1879 /* For ET_REL we are starting the layout from scratch. */ 1880 offset = gelf_fsize (unstripped, ELF_T_EHDR, 1, EV_CURRENT); 1881 1882 bool skip_reloc = false; 1883 do 1884 { 1885 skip_reloc = !skip_reloc; 1886 for (size_t i = 0; i < unstripped_shnum - 1; ++i) 1887 if (!placed[i]) 1888 { 1889 scn = elf_getscn (unstripped, 1 + i); 1890 1891 GElf_Shdr shdr_mem; 1892 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1893 ELF_CHECK (shdr != NULL, _("cannot get section header: %s")); 1894 1895 /* We must make sure we have read in the data of all sections 1896 beforehand and marked them to be written out. When we're 1897 modifying the existing file in place, we might overwrite 1898 this part of the file before we get to handling the section. */ 1899 1900 ELF_CHECK (elf_flagdata (elf_getdata (scn, NULL), 1901 ELF_C_SET, ELF_F_DIRTY), 1902 _("cannot read section data: %s")); 1903 1904 if (skip_reloc 1905 && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)) 1906 continue; 1907 1908 GElf_Off align = shdr->sh_addralign ?: 1; 1909 offset = (offset + align - 1) & -align; 1910 shdr->sh_offset = offset; 1911 if (shdr->sh_type != SHT_NOBITS) 1912 offset += shdr->sh_size; 1913 1914 update_shdr (scn, shdr); 1915 1916 if (unstripped_shstrndx == 1 + i) 1917 { 1918 /* Place the section headers immediately after 1919 .shstrtab, and update the ELF header. */ 1920 1921 GElf_Ehdr ehdr_mem; 1922 GElf_Ehdr *ehdr = gelf_getehdr (unstripped, &ehdr_mem); 1923 ELF_CHECK (ehdr != NULL, _("cannot get ELF header: %s")); 1924 1925 GElf_Off sh_align = gelf_getclass (unstripped) * 4; 1926 offset = (offset + sh_align - 1) & -sh_align; 1927 ehdr->e_shnum = unstripped_shnum; 1928 ehdr->e_shoff = offset; 1929 offset += unstripped_shnum * ehdr->e_shentsize; 1930 ELF_CHECK (gelf_update_ehdr (unstripped, ehdr), 1931 _("cannot update ELF header: %s")); 1932 } 1933 1934 placed[i] = true; 1935 } 1936 } 1937 while (skip_reloc); 1938 1939 size_t phnum; 1940 ELF_CHECK (elf_getphdrnum (stripped, &phnum) == 0, 1941 _("cannot get number of program headers: %s")); 1942 1943 if (phnum > 0) 1944 ELF_CHECK (gelf_newphdr (unstripped, phnum), 1945 _("cannot create program headers: %s")); 1946 1947 /* Copy each program header from the stripped file. */ 1948 for (size_t i = 0; i < phnum; ++i) 1949 { 1950 GElf_Phdr phdr_mem; 1951 GElf_Phdr *phdr = gelf_getphdr (stripped, i, &phdr_mem); 1952 ELF_CHECK (phdr != NULL, _("cannot get program header: %s")); 1953 1954 ELF_CHECK (gelf_update_phdr (unstripped, i, phdr), 1955 _("cannot update program header: %s")); 1956 } 1957 1958 /* Finally, write out the file. */ 1959 ELF_CHECK (elf_update (unstripped, ELF_C_WRITE) > 0, 1960 _("cannot write output file: %s")); 1961 1962 if (strtab != NULL) 1963 { 1964 ebl_strtabfree (strtab); 1965 free (strtab_data->d_buf); 1966 } 1967 1968 if (symstrtab != NULL) 1969 { 1970 ebl_strtabfree (symstrtab); 1971 free (symstrdata->d_buf); 1972 } 1973 free_new_data (); 1974 } 1975 1976 /* Process one pair of files, already opened. */ 1977 static void 1978 handle_file (const char *output_file, bool create_dirs, 1979 Elf *stripped, const GElf_Ehdr *stripped_ehdr, 1980 Elf *unstripped) 1981 { 1982 size_t phnum; 1983 ELF_CHECK (elf_getphdrnum (stripped, &phnum) == 0, 1984 _("cannot get number of program headers: %s")); 1985 1986 /* Determine the address bias between the debuginfo file and the main 1987 file, which may have been modified by prelinking. */ 1988 GElf_Addr bias = 0; 1989 if (unstripped != NULL) 1990 for (size_t i = 0; i < phnum; ++i) 1991 { 1992 GElf_Phdr phdr_mem; 1993 GElf_Phdr *phdr = gelf_getphdr (stripped, i, &phdr_mem); 1994 ELF_CHECK (phdr != NULL, _("cannot get program header: %s")); 1995 if (phdr->p_type == PT_LOAD) 1996 { 1997 GElf_Phdr unstripped_phdr_mem; 1998 GElf_Phdr *unstripped_phdr = gelf_getphdr (unstripped, i, 1999 &unstripped_phdr_mem); 2000 ELF_CHECK (unstripped_phdr != NULL, 2001 _("cannot get program header: %s")); 2002 bias = phdr->p_vaddr - unstripped_phdr->p_vaddr; 2003 break; 2004 } 2005 } 2006 2007 /* One day we could adjust all the DWARF data (like prelink itself does). */ 2008 if (bias != 0) 2009 { 2010 if (output_file == NULL) 2011 error (0, 0, _("\ 2012 DWARF data not adjusted for prelinking bias; consider prelink -u")); 2013 else 2014 error (0, 0, _("\ 2015 DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"), 2016 output_file); 2017 } 2018 2019 if (output_file == NULL) 2020 /* Modify the unstripped file in place. */ 2021 copy_elided_sections (unstripped, stripped, stripped_ehdr, bias); 2022 else 2023 { 2024 if (create_dirs) 2025 make_directories (output_file); 2026 2027 /* Copy the unstripped file and then modify it. */ 2028 int outfd = open (output_file, O_RDWR | O_CREAT, 2029 stripped_ehdr->e_type == ET_REL ? 0666 : 0777); 2030 if (outfd < 0) 2031 error (EXIT_FAILURE, errno, _("cannot open '%s'"), output_file); 2032 Elf *outelf = elf_begin (outfd, ELF_C_WRITE, NULL); 2033 ELF_CHECK (outelf != NULL, _("cannot create ELF descriptor: %s")); 2034 2035 if (unstripped == NULL) 2036 { 2037 /* Actually, we are just copying out the main file as it is. */ 2038 copy_elf (outelf, stripped); 2039 if (stripped_ehdr->e_type != ET_REL) 2040 elf_flagelf (outelf, ELF_C_SET, ELF_F_LAYOUT); 2041 ELF_CHECK (elf_update (outelf, ELF_C_WRITE) > 0, 2042 _("cannot write output file: %s")); 2043 } 2044 else 2045 { 2046 copy_elf (outelf, unstripped); 2047 copy_elided_sections (outelf, stripped, stripped_ehdr, bias); 2048 } 2049 2050 elf_end (outelf); 2051 close (outfd); 2052 } 2053 } 2054 2055 static int 2056 open_file (const char *file, bool writable) 2057 { 2058 int fd = open (file, writable ? O_RDWR : O_RDONLY); 2059 if (fd < 0) 2060 error (EXIT_FAILURE, errno, _("cannot open '%s'"), file); 2061 return fd; 2062 } 2063 2064 /* Handle a pair of files we need to open by name. */ 2065 static void 2066 handle_explicit_files (const char *output_file, bool create_dirs, bool force, 2067 const char *stripped_file, const char *unstripped_file) 2068 { 2069 2070 /* Warn, and exit if not forced to continue, if some ELF header 2071 sanity check for the stripped and unstripped files failed. */ 2072 void warn (const char *msg) 2073 { 2074 error (force ? 0 : EXIT_FAILURE, 0, "%s'%s' and '%s' %s%s.", 2075 force ? _("WARNING: ") : "", 2076 stripped_file, unstripped_file, msg, 2077 force ? "" : _(", use --force")); 2078 } 2079 2080 int stripped_fd = open_file (stripped_file, false); 2081 Elf *stripped = elf_begin (stripped_fd, ELF_C_READ, NULL); 2082 GElf_Ehdr stripped_ehdr; 2083 ELF_CHECK (gelf_getehdr (stripped, &stripped_ehdr), 2084 _("cannot create ELF descriptor: %s")); 2085 2086 int unstripped_fd = -1; 2087 Elf *unstripped = NULL; 2088 if (unstripped_file != NULL) 2089 { 2090 unstripped_fd = open_file (unstripped_file, output_file == NULL); 2091 unstripped = elf_begin (unstripped_fd, 2092 (output_file == NULL ? ELF_C_RDWR : ELF_C_READ), 2093 NULL); 2094 GElf_Ehdr unstripped_ehdr; 2095 ELF_CHECK (gelf_getehdr (unstripped, &unstripped_ehdr), 2096 _("cannot create ELF descriptor: %s")); 2097 2098 if (memcmp (stripped_ehdr.e_ident, 2099 unstripped_ehdr.e_ident, EI_NIDENT) != 0) 2100 warn (_("ELF header identification (e_ident) different")); 2101 2102 if (stripped_ehdr.e_type != unstripped_ehdr.e_type) 2103 warn (_("ELF header type (e_type) different")); 2104 2105 if (stripped_ehdr.e_machine != unstripped_ehdr.e_machine) 2106 warn (_("ELF header machine type (e_machine) different")); 2107 2108 if (stripped_ehdr.e_phnum < unstripped_ehdr.e_phnum) 2109 warn (_("stripped program header (e_phnum) smaller than unstripped")); 2110 } 2111 2112 handle_file (output_file, create_dirs, stripped, &stripped_ehdr, unstripped); 2113 2114 elf_end (stripped); 2115 close (stripped_fd); 2116 2117 elf_end (unstripped); 2118 close (unstripped_fd); 2119 } 2120 2121 2122 /* Handle a pair of files opened implicitly by libdwfl for one module. */ 2123 static void 2124 handle_dwfl_module (const char *output_file, bool create_dirs, bool force, 2125 Dwfl_Module *mod, bool all, bool ignore, bool relocate) 2126 { 2127 GElf_Addr bias; 2128 Elf *stripped = dwfl_module_getelf (mod, &bias); 2129 if (stripped == NULL) 2130 { 2131 if (ignore) 2132 return; 2133 2134 const char *file; 2135 const char *modname = dwfl_module_info (mod, NULL, NULL, NULL, 2136 NULL, NULL, &file, NULL); 2137 if (file == NULL) 2138 error (EXIT_FAILURE, 0, 2139 _("cannot find stripped file for module '%s': %s"), 2140 modname, dwfl_errmsg (-1)); 2141 else 2142 error (EXIT_FAILURE, 0, 2143 _("cannot open stripped file '%s' for module '%s': %s"), 2144 modname, file, dwfl_errmsg (-1)); 2145 } 2146 2147 Elf *debug = dwarf_getelf (dwfl_module_getdwarf (mod, &bias)); 2148 if (debug == NULL && !all) 2149 { 2150 if (ignore) 2151 return; 2152 2153 const char *file; 2154 const char *modname = dwfl_module_info (mod, NULL, NULL, NULL, 2155 NULL, NULL, NULL, &file); 2156 if (file == NULL) 2157 error (EXIT_FAILURE, 0, 2158 _("cannot find debug file for module '%s': %s"), 2159 modname, dwfl_errmsg (-1)); 2160 else 2161 error (EXIT_FAILURE, 0, 2162 _("cannot open debug file '%s' for module '%s': %s"), 2163 modname, file, dwfl_errmsg (-1)); 2164 } 2165 2166 if (debug == stripped) 2167 { 2168 if (all) 2169 debug = NULL; 2170 else 2171 { 2172 const char *file; 2173 const char *modname = dwfl_module_info (mod, NULL, NULL, NULL, 2174 NULL, NULL, &file, NULL); 2175 error (EXIT_FAILURE, 0, _("module '%s' file '%s' is not stripped"), 2176 modname, file); 2177 } 2178 } 2179 2180 GElf_Ehdr stripped_ehdr; 2181 ELF_CHECK (gelf_getehdr (stripped, &stripped_ehdr), 2182 _("cannot create ELF descriptor: %s")); 2183 2184 if (stripped_ehdr.e_type == ET_REL) 2185 { 2186 if (!relocate) 2187 { 2188 /* We can't use the Elf handles already open, 2189 because the DWARF sections have been relocated. */ 2190 2191 const char *stripped_file = NULL; 2192 const char *unstripped_file = NULL; 2193 (void) dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, 2194 &stripped_file, &unstripped_file); 2195 2196 handle_explicit_files (output_file, create_dirs, force, 2197 stripped_file, unstripped_file); 2198 return; 2199 } 2200 2201 /* Relocation is what we want! This ensures that all sections that can 2202 get sh_addr values assigned have them, even ones not used in DWARF. 2203 They might still be used in the symbol table. */ 2204 if (dwfl_module_relocations (mod) < 0) 2205 error (EXIT_FAILURE, 0, 2206 _("cannot cache section addresses for module '%s': %s"), 2207 dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, NULL, NULL), 2208 dwfl_errmsg (-1)); 2209 } 2210 2211 handle_file (output_file, create_dirs, stripped, &stripped_ehdr, debug); 2212 } 2213 2214 /* Handle one module being written to the output directory. */ 2215 static void 2216 handle_output_dir_module (const char *output_dir, Dwfl_Module *mod, bool force, 2217 bool all, bool ignore, bool modnames, bool relocate) 2218 { 2219 if (! modnames) 2220 { 2221 /* Make sure we've searched for the ELF file. */ 2222 GElf_Addr bias; 2223 (void) dwfl_module_getelf (mod, &bias); 2224 } 2225 2226 const char *file; 2227 const char *name = dwfl_module_info (mod, NULL, NULL, NULL, 2228 NULL, NULL, &file, NULL); 2229 2230 if (file == NULL && ignore) 2231 return; 2232 2233 char *output_file; 2234 if (asprintf (&output_file, "%s/%s", output_dir, modnames ? name : file) < 0) 2235 error (EXIT_FAILURE, 0, _("memory exhausted")); 2236 2237 handle_dwfl_module (output_file, true, force, mod, all, ignore, relocate); 2238 } 2239 2240 2241 static void 2242 list_module (Dwfl_Module *mod) 2243 { 2244 /* Make sure we have searched for the files. */ 2245 GElf_Addr bias; 2246 bool have_elf = dwfl_module_getelf (mod, &bias) != NULL; 2247 bool have_dwarf = dwfl_module_getdwarf (mod, &bias) != NULL; 2248 2249 const char *file; 2250 const char *debug; 2251 Dwarf_Addr start; 2252 Dwarf_Addr end; 2253 const char *name = dwfl_module_info (mod, NULL, &start, &end, 2254 NULL, NULL, &file, &debug); 2255 if (file != NULL && debug != NULL && (debug == file || !strcmp (debug, file))) 2256 debug = "."; 2257 2258 const unsigned char *id; 2259 GElf_Addr id_vaddr; 2260 int id_len = dwfl_module_build_id (mod, &id, &id_vaddr); 2261 2262 printf ("%#" PRIx64 "+%#" PRIx64 " ", start, end - start); 2263 2264 if (id_len > 0) 2265 { 2266 do 2267 printf ("%02" PRIx8, *id++); 2268 while (--id_len > 0); 2269 if (id_vaddr != 0) 2270 printf ("@%#" PRIx64, id_vaddr); 2271 } 2272 else 2273 putchar ('-'); 2274 2275 printf (" %s %s %s\n", 2276 file ?: have_elf ? "." : "-", 2277 debug ?: have_dwarf ? "." : "-", 2278 name); 2279 } 2280 2281 2282 struct match_module_info 2283 { 2284 char **patterns; 2285 Dwfl_Module *found; 2286 bool match_files; 2287 }; 2288 2289 static int 2290 match_module (Dwfl_Module *mod, 2291 void **userdata __attribute__ ((unused)), 2292 const char *name, 2293 Dwarf_Addr start __attribute__ ((unused)), 2294 void *arg) 2295 { 2296 struct match_module_info *info = arg; 2297 2298 if (info->patterns[0] == NULL) /* Match all. */ 2299 { 2300 match: 2301 info->found = mod; 2302 return DWARF_CB_ABORT; 2303 } 2304 2305 if (info->match_files) 2306 { 2307 /* Make sure we've searched for the ELF file. */ 2308 GElf_Addr bias; 2309 (void) dwfl_module_getelf (mod, &bias); 2310 2311 const char *file; 2312 const char *check = dwfl_module_info (mod, NULL, NULL, NULL, 2313 NULL, NULL, &file, NULL); 2314 assert (check == name); 2315 if (file == NULL) 2316 return DWARF_CB_OK; 2317 2318 name = file; 2319 } 2320 2321 for (char **p = info->patterns; *p != NULL; ++p) 2322 if (fnmatch (*p, name, 0) == 0) 2323 goto match; 2324 2325 return DWARF_CB_OK; 2326 } 2327 2328 /* Handle files opened implicitly via libdwfl. */ 2329 static void 2330 handle_implicit_modules (const struct arg_info *info) 2331 { 2332 struct match_module_info mmi = { info->args, NULL, info->match_files }; 2333 inline ptrdiff_t next (ptrdiff_t offset) 2334 { 2335 return dwfl_getmodules (info->dwfl, &match_module, &mmi, offset); 2336 } 2337 ptrdiff_t offset = next (0); 2338 if (offset == 0) 2339 error (EXIT_FAILURE, 0, _("no matching modules found")); 2340 2341 if (info->list) 2342 do 2343 list_module (mmi.found); 2344 while ((offset = next (offset)) > 0); 2345 else if (info->output_dir == NULL) 2346 { 2347 if (next (offset) != 0) 2348 error (EXIT_FAILURE, 0, _("matched more than one module")); 2349 handle_dwfl_module (info->output_file, false, info->force, mmi.found, 2350 info->all, info->ignore, info->relocate); 2351 } 2352 else 2353 do 2354 handle_output_dir_module (info->output_dir, mmi.found, info->force, 2355 info->all, info->ignore, 2356 info->modnames, info->relocate); 2357 while ((offset = next (offset)) > 0); 2358 } 2359 2360 int 2362 main (int argc, char **argv) 2363 { 2364 /* We use no threads here which can interfere with handling a stream. */ 2365 __fsetlocking (stdin, FSETLOCKING_BYCALLER); 2366 __fsetlocking (stdout, FSETLOCKING_BYCALLER); 2367 __fsetlocking (stderr, FSETLOCKING_BYCALLER); 2368 2369 /* Set locale. */ 2370 setlocale (LC_ALL, ""); 2371 2372 /* Make sure the message catalog can be found. */ 2373 bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); 2374 2375 /* Initialize the message catalog. */ 2376 textdomain (PACKAGE_TARNAME); 2377 2378 /* Parse and process arguments. */ 2379 const struct argp_child argp_children[] = 2380 { 2381 { 2382 .argp = dwfl_standard_argp (), 2383 .header = N_("Input selection options:"), 2384 .group = 1, 2385 }, 2386 { .argp = NULL }, 2387 }; 2388 const struct argp argp = 2389 { 2390 .options = options, 2391 .parser = parse_opt, 2392 .children = argp_children, 2393 .args_doc = N_("STRIPPED-FILE DEBUG-FILE\n[MODULE...]"), 2394 .doc = N_("\ 2395 Combine stripped files with separate symbols and debug information.\v\ 2396 The first form puts the result in DEBUG-FILE if -o was not given.\n\ 2397 \n\ 2398 MODULE arguments give file name patterns matching modules to process.\n\ 2399 With -f these match the file name of the main (stripped) file \ 2400 (slashes are never special), otherwise they match the simple module names. \ 2401 With no arguments, process all modules found.\n\ 2402 \n\ 2403 Multiple modules are written to files under OUTPUT-DIRECTORY, \ 2404 creating subdirectories as needed. \ 2405 With -m these files have simple module names, otherwise they have the \ 2406 name of the main file complete with directory underneath OUTPUT-DIRECTORY.\n\ 2407 \n\ 2408 With -n no files are written, but one line to standard output for each module:\ 2409 \n\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n\ 2410 START and SIZE are hexadecimal giving the address bounds of the module. \ 2411 BUILDID is hexadecimal for the build ID bits, or - if no ID is known; \ 2412 the hexadecimal may be followed by @0xADDR giving the address where the \ 2413 ID resides if that is known. \ 2414 FILE is the file name found for the module, or - if none was found, \ 2415 or . if an ELF image is available but not from any named file. \ 2416 DEBUGFILE is the separate debuginfo file name, \ 2417 or - if no debuginfo was found, or . if FILE contains the debug information.\ 2418 ") 2419 }; 2420 2421 int remaining; 2422 struct arg_info info = { .args = NULL }; 2423 error_t result = argp_parse (&argp, argc, argv, 0, &remaining, &info); 2424 if (result == ENOSYS) 2425 assert (info.dwfl == NULL); 2426 else if (result) 2427 return EXIT_FAILURE; 2428 assert (info.args != NULL); 2429 2430 /* Tell the library which version we are expecting. */ 2431 elf_version (EV_CURRENT); 2432 2433 if (info.dwfl == NULL) 2434 { 2435 assert (result == ENOSYS); 2436 2437 if (info.output_dir != NULL) 2438 { 2439 char *file; 2440 if (asprintf (&file, "%s/%s", info.output_dir, info.args[0]) < 0) 2441 error (EXIT_FAILURE, 0, _("memory exhausted")); 2442 handle_explicit_files (file, true, info.force, 2443 info.args[0], info.args[1]); 2444 free (file); 2445 } 2446 else 2447 handle_explicit_files (info.output_file, false, info.force, 2448 info.args[0], info.args[1]); 2449 } 2450 else 2451 { 2452 /* parse_opt checked this. */ 2453 assert (info.output_file != NULL || info.output_dir != NULL || info.list); 2454 2455 handle_implicit_modules (&info); 2456 2457 dwfl_end (info.dwfl); 2458 } 2459 2460 return 0; 2461 } 2462 2463 2464 #include "debugpred.h" 2465