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