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