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