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