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