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