1 // target-reloc.h -- target specific relocation support -*- C++ -*- 2 3 // Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012 4 // Free Software Foundation, Inc. 5 // Written by Ian Lance Taylor <iant@google.com>. 6 7 // This file is part of gold. 8 9 // This program is free software; you can redistribute it and/or modify 10 // it under the terms of the GNU General Public License as published by 11 // the Free Software Foundation; either version 3 of the License, or 12 // (at your option) any later version. 13 14 // This program is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 19 // You should have received a copy of the GNU General Public License 20 // along with this program; if not, write to the Free Software 21 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 22 // MA 02110-1301, USA. 23 24 #ifndef GOLD_TARGET_RELOC_H 25 #define GOLD_TARGET_RELOC_H 26 27 #include "elfcpp.h" 28 #include "symtab.h" 29 #include "object.h" 30 #include "reloc.h" 31 #include "reloc-types.h" 32 33 namespace gold 34 { 35 36 // This function implements the generic part of reloc scanning. The 37 // template parameter Scan must be a class type which provides two 38 // functions: local() and global(). Those functions implement the 39 // machine specific part of scanning. We do it this way to 40 // avoid making a function call for each relocation, and to avoid 41 // repeating the generic code for each target. 42 43 template<int size, bool big_endian, typename Target_type, int sh_type, 44 typename Scan> 45 inline void 46 scan_relocs( 47 Symbol_table* symtab, 48 Layout* layout, 49 Target_type* target, 50 Sized_relobj_file<size, big_endian>* object, 51 unsigned int data_shndx, 52 const unsigned char* prelocs, 53 size_t reloc_count, 54 Output_section* output_section, 55 bool needs_special_offset_handling, 56 size_t local_count, 57 const unsigned char* plocal_syms) 58 { 59 typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype; 60 const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size; 61 const int sym_size = elfcpp::Elf_sizes<size>::sym_size; 62 Scan scan; 63 64 for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size) 65 { 66 Reltype reloc(prelocs); 67 68 if (needs_special_offset_handling 69 && !output_section->is_input_address_mapped(object, data_shndx, 70 reloc.get_r_offset())) 71 continue; 72 73 typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info(); 74 unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info); 75 unsigned int r_type = elfcpp::elf_r_type<size>(r_info); 76 77 if (r_sym < local_count) 78 { 79 gold_assert(plocal_syms != NULL); 80 typename elfcpp::Sym<size, big_endian> lsym(plocal_syms 81 + r_sym * sym_size); 82 unsigned int shndx = lsym.get_st_shndx(); 83 bool is_ordinary; 84 shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary); 85 if (is_ordinary 86 && shndx != elfcpp::SHN_UNDEF 87 && !object->is_section_included(shndx) 88 && !symtab->is_section_folded(object, shndx)) 89 { 90 // RELOC is a relocation against a local symbol in a 91 // section we are discarding. We can ignore this 92 // relocation. It will eventually become a reloc 93 // against the value zero. 94 // 95 // FIXME: We should issue a warning if this is an 96 // allocated section; is this the best place to do it? 97 // 98 // FIXME: The old GNU linker would in some cases look 99 // for the linkonce section which caused this section to 100 // be discarded, and, if the other section was the same 101 // size, change the reloc to refer to the other section. 102 // That seems risky and weird to me, and I don't know of 103 // any case where it is actually required. 104 105 continue; 106 } 107 scan.local(symtab, layout, target, object, data_shndx, 108 output_section, reloc, r_type, lsym); 109 } 110 else 111 { 112 Symbol* gsym = object->global_symbol(r_sym); 113 gold_assert(gsym != NULL); 114 if (gsym->is_forwarder()) 115 gsym = symtab->resolve_forwards(gsym); 116 117 scan.global(symtab, layout, target, object, data_shndx, 118 output_section, reloc, r_type, gsym); 119 } 120 } 121 } 122 123 // Behavior for relocations to discarded comdat sections. 124 125 enum Comdat_behavior 126 { 127 CB_UNDETERMINED, // Not yet determined -- need to look at section name. 128 CB_PRETEND, // Attempt to map to the corresponding kept section. 129 CB_IGNORE, // Ignore the relocation. 130 CB_WARNING // Print a warning. 131 }; 132 133 // Decide what the linker should do for relocations that refer to discarded 134 // comdat sections. This decision is based on the name of the section being 135 // relocated. 136 137 inline Comdat_behavior 138 get_comdat_behavior(const char* name) 139 { 140 if (Layout::is_debug_info_section(name)) 141 return CB_PRETEND; 142 if (strcmp(name, ".eh_frame") == 0 143 || strcmp(name, ".gcc_except_table") == 0) 144 return CB_IGNORE; 145 return CB_WARNING; 146 } 147 148 // Give an error for a symbol with non-default visibility which is not 149 // defined locally. 150 151 inline void 152 visibility_error(const Symbol* sym) 153 { 154 const char* v; 155 switch (sym->visibility()) 156 { 157 case elfcpp::STV_INTERNAL: 158 v = _("internal"); 159 break; 160 case elfcpp::STV_HIDDEN: 161 v = _("hidden"); 162 break; 163 case elfcpp::STV_PROTECTED: 164 v = _("protected"); 165 break; 166 default: 167 gold_unreachable(); 168 } 169 gold_error(_("%s symbol '%s' is not defined locally"), 170 v, sym->name()); 171 } 172 173 // Return true if we are should issue an error saying that SYM is an 174 // undefined symbol. This is called if there is a relocation against 175 // SYM. 176 177 inline bool 178 issue_undefined_symbol_error(const Symbol* sym) 179 { 180 // We only report global symbols. 181 if (sym == NULL) 182 return false; 183 184 // We only report undefined symbols. 185 if (!sym->is_undefined() && !sym->is_placeholder()) 186 return false; 187 188 // We don't report weak symbols. 189 if (sym->binding() == elfcpp::STB_WEAK) 190 return false; 191 192 // We don't report symbols defined in discarded sections. 193 if (sym->is_defined_in_discarded_section()) 194 return false; 195 196 // If the target defines this symbol, don't report it here. 197 if (parameters->target().is_defined_by_abi(sym)) 198 return false; 199 200 // See if we've been told to ignore whether this symbol is 201 // undefined. 202 const char* const u = parameters->options().unresolved_symbols(); 203 if (u != NULL) 204 { 205 if (strcmp(u, "ignore-all") == 0) 206 return false; 207 if (strcmp(u, "report-all") == 0) 208 return true; 209 if (strcmp(u, "ignore-in-object-files") == 0 && !sym->in_dyn()) 210 return false; 211 if (strcmp(u, "ignore-in-shared-libs") == 0 && !sym->in_reg()) 212 return false; 213 } 214 215 // When creating a shared library, only report unresolved symbols if 216 // -z defs was used. 217 if (parameters->options().shared() && !parameters->options().defs()) 218 return false; 219 220 // Otherwise issue a warning. 221 return true; 222 } 223 224 // This function implements the generic part of relocation processing. 225 // The template parameter Relocate must be a class type which provides 226 // a single function, relocate(), which implements the machine 227 // specific part of a relocation. 228 229 // SIZE is the ELF size: 32 or 64. BIG_ENDIAN is the endianness of 230 // the data. SH_TYPE is the section type: SHT_REL or SHT_RELA. 231 // RELOCATE implements operator() to do a relocation. 232 233 // PRELOCS points to the relocation data. RELOC_COUNT is the number 234 // of relocs. OUTPUT_SECTION is the output section. 235 // NEEDS_SPECIAL_OFFSET_HANDLING is true if input offsets need to be 236 // mapped to output offsets. 237 238 // VIEW is the section data, VIEW_ADDRESS is its memory address, and 239 // VIEW_SIZE is the size. These refer to the input section, unless 240 // NEEDS_SPECIAL_OFFSET_HANDLING is true, in which case they refer to 241 // the output section. 242 243 // RELOC_SYMBOL_CHANGES is used for -fsplit-stack support. If it is 244 // not NULL, it is a vector indexed by relocation index. If that 245 // entry is not NULL, it points to a global symbol which used as the 246 // symbol for the relocation, ignoring the symbol index in the 247 // relocation. 248 249 template<int size, bool big_endian, typename Target_type, int sh_type, 250 typename Relocate> 251 inline void 252 relocate_section( 253 const Relocate_info<size, big_endian>* relinfo, 254 Target_type* target, 255 const unsigned char* prelocs, 256 size_t reloc_count, 257 Output_section* output_section, 258 bool needs_special_offset_handling, 259 unsigned char* view, 260 typename elfcpp::Elf_types<size>::Elf_Addr view_address, 261 section_size_type view_size, 262 const Reloc_symbol_changes* reloc_symbol_changes) 263 { 264 typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype; 265 const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size; 266 Relocate relocate; 267 268 Sized_relobj_file<size, big_endian>* object = relinfo->object; 269 unsigned int local_count = object->local_symbol_count(); 270 271 Comdat_behavior comdat_behavior = CB_UNDETERMINED; 272 273 for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size) 274 { 275 Reltype reloc(prelocs); 276 277 section_offset_type offset = 278 convert_to_section_size_type(reloc.get_r_offset()); 279 280 if (needs_special_offset_handling) 281 { 282 offset = output_section->output_offset(relinfo->object, 283 relinfo->data_shndx, 284 offset); 285 if (offset == -1) 286 continue; 287 } 288 289 typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info(); 290 unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info); 291 unsigned int r_type = elfcpp::elf_r_type<size>(r_info); 292 293 const Sized_symbol<size>* sym; 294 295 Symbol_value<size> symval; 296 const Symbol_value<size> *psymval; 297 bool is_defined_in_discarded_section; 298 unsigned int shndx; 299 if (r_sym < local_count 300 && (reloc_symbol_changes == NULL 301 || (*reloc_symbol_changes)[i] == NULL)) 302 { 303 sym = NULL; 304 psymval = object->local_symbol(r_sym); 305 306 // If the local symbol belongs to a section we are discarding, 307 // and that section is a debug section, try to find the 308 // corresponding kept section and map this symbol to its 309 // counterpart in the kept section. The symbol must not 310 // correspond to a section we are folding. 311 bool is_ordinary; 312 shndx = psymval->input_shndx(&is_ordinary); 313 is_defined_in_discarded_section = 314 (is_ordinary 315 && shndx != elfcpp::SHN_UNDEF 316 && !object->is_section_included(shndx) 317 && !relinfo->symtab->is_section_folded(object, shndx)); 318 } 319 else 320 { 321 const Symbol* gsym; 322 if (reloc_symbol_changes != NULL 323 && (*reloc_symbol_changes)[i] != NULL) 324 gsym = (*reloc_symbol_changes)[i]; 325 else 326 { 327 gsym = object->global_symbol(r_sym); 328 gold_assert(gsym != NULL); 329 if (gsym->is_forwarder()) 330 gsym = relinfo->symtab->resolve_forwards(gsym); 331 } 332 333 sym = static_cast<const Sized_symbol<size>*>(gsym); 334 if (sym->has_symtab_index() && sym->symtab_index() != -1U) 335 symval.set_output_symtab_index(sym->symtab_index()); 336 else 337 symval.set_no_output_symtab_entry(); 338 symval.set_output_value(sym->value()); 339 if (gsym->type() == elfcpp::STT_TLS) 340 symval.set_is_tls_symbol(); 341 else if (gsym->type() == elfcpp::STT_GNU_IFUNC) 342 symval.set_is_ifunc_symbol(); 343 psymval = &symval; 344 345 is_defined_in_discarded_section = 346 (gsym->is_defined_in_discarded_section() 347 && gsym->is_undefined()); 348 shndx = 0; 349 } 350 351 Symbol_value<size> symval2; 352 if (is_defined_in_discarded_section) 353 { 354 if (comdat_behavior == CB_UNDETERMINED) 355 { 356 std::string name = object->section_name(relinfo->data_shndx); 357 comdat_behavior = get_comdat_behavior(name.c_str()); 358 } 359 if (comdat_behavior == CB_PRETEND) 360 { 361 // FIXME: This case does not work for global symbols. 362 // We have no place to store the original section index. 363 // Fortunately this does not matter for comdat sections, 364 // only for sections explicitly discarded by a linker 365 // script. 366 bool found; 367 typename elfcpp::Elf_types<size>::Elf_Addr value = 368 object->map_to_kept_section(shndx, &found); 369 if (found) 370 symval2.set_output_value(value + psymval->input_value()); 371 else 372 symval2.set_output_value(0); 373 } 374 else 375 { 376 if (comdat_behavior == CB_WARNING) 377 gold_warning_at_location(relinfo, i, offset, 378 _("relocation refers to discarded " 379 "section")); 380 symval2.set_output_value(0); 381 } 382 symval2.set_no_output_symtab_entry(); 383 psymval = &symval2; 384 } 385 386 if (!relocate.relocate(relinfo, target, output_section, i, reloc, 387 r_type, sym, psymval, view + offset, 388 view_address + offset, view_size)) 389 continue; 390 391 if (offset < 0 || static_cast<section_size_type>(offset) >= view_size) 392 { 393 gold_error_at_location(relinfo, i, offset, 394 _("reloc has bad offset %zu"), 395 static_cast<size_t>(offset)); 396 continue; 397 } 398 399 if (issue_undefined_symbol_error(sym)) 400 gold_undefined_symbol_at_location(sym, relinfo, i, offset); 401 else if (sym != NULL 402 && sym->visibility() != elfcpp::STV_DEFAULT 403 && (sym->is_undefined() || sym->is_from_dynobj())) 404 visibility_error(sym); 405 406 if (sym != NULL && sym->has_warning()) 407 relinfo->symtab->issue_warning(sym, relinfo, i, offset); 408 } 409 } 410 411 // Apply an incremental relocation. 412 413 template<int size, bool big_endian, typename Target_type, 414 typename Relocate> 415 void 416 apply_relocation(const Relocate_info<size, big_endian>* relinfo, 417 Target_type* target, 418 typename elfcpp::Elf_types<size>::Elf_Addr r_offset, 419 unsigned int r_type, 420 typename elfcpp::Elf_types<size>::Elf_Swxword r_addend, 421 const Symbol* gsym, 422 unsigned char* view, 423 typename elfcpp::Elf_types<size>::Elf_Addr address, 424 section_size_type view_size) 425 { 426 // Construct the ELF relocation in a temporary buffer. 427 const int reloc_size = elfcpp::Elf_sizes<size>::rela_size; 428 unsigned char relbuf[reloc_size]; 429 elfcpp::Rela<size, big_endian> rel(relbuf); 430 elfcpp::Rela_write<size, big_endian> orel(relbuf); 431 orel.put_r_offset(r_offset); 432 orel.put_r_info(elfcpp::elf_r_info<size>(0, r_type)); 433 orel.put_r_addend(r_addend); 434 435 // Setup a Symbol_value for the global symbol. 436 const Sized_symbol<size>* sym = static_cast<const Sized_symbol<size>*>(gsym); 437 Symbol_value<size> symval; 438 gold_assert(sym->has_symtab_index() && sym->symtab_index() != -1U); 439 symval.set_output_symtab_index(sym->symtab_index()); 440 symval.set_output_value(sym->value()); 441 if (gsym->type() == elfcpp::STT_TLS) 442 symval.set_is_tls_symbol(); 443 else if (gsym->type() == elfcpp::STT_GNU_IFUNC) 444 symval.set_is_ifunc_symbol(); 445 446 Relocate relocate; 447 relocate.relocate(relinfo, target, NULL, -1U, rel, r_type, sym, &symval, 448 view + r_offset, address + r_offset, view_size); 449 } 450 451 // This class may be used as a typical class for the 452 // Scan_relocatable_reloc parameter to scan_relocatable_relocs. The 453 // template parameter Classify_reloc must be a class type which 454 // provides a function get_size_for_reloc which returns the number of 455 // bytes to which a reloc applies. This class is intended to capture 456 // the most typical target behaviour, while still permitting targets 457 // to define their own independent class for Scan_relocatable_reloc. 458 459 template<int sh_type, typename Classify_reloc> 460 class Default_scan_relocatable_relocs 461 { 462 public: 463 // Return the strategy to use for a local symbol which is not a 464 // section symbol, given the relocation type. 465 inline Relocatable_relocs::Reloc_strategy 466 local_non_section_strategy(unsigned int r_type, Relobj*, unsigned int r_sym) 467 { 468 // We assume that relocation type 0 is NONE. Targets which are 469 // different must override. 470 if (r_type == 0 && r_sym == 0) 471 return Relocatable_relocs::RELOC_DISCARD; 472 return Relocatable_relocs::RELOC_COPY; 473 } 474 475 // Return the strategy to use for a local symbol which is a section 476 // symbol, given the relocation type. 477 inline Relocatable_relocs::Reloc_strategy 478 local_section_strategy(unsigned int r_type, Relobj* object) 479 { 480 if (sh_type == elfcpp::SHT_RELA) 481 return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA; 482 else 483 { 484 Classify_reloc classify; 485 switch (classify.get_size_for_reloc(r_type, object)) 486 { 487 case 0: 488 return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0; 489 case 1: 490 return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_1; 491 case 2: 492 return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_2; 493 case 4: 494 return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4; 495 case 8: 496 return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_8; 497 default: 498 gold_unreachable(); 499 } 500 } 501 } 502 503 // Return the strategy to use for a global symbol, given the 504 // relocation type, the object, and the symbol index. 505 inline Relocatable_relocs::Reloc_strategy 506 global_strategy(unsigned int, Relobj*, unsigned int) 507 { return Relocatable_relocs::RELOC_COPY; } 508 }; 509 510 // Scan relocs during a relocatable link. This is a default 511 // definition which should work for most targets. 512 // Scan_relocatable_reloc must name a class type which provides three 513 // functions which return a Relocatable_relocs::Reloc_strategy code: 514 // global_strategy, local_non_section_strategy, and 515 // local_section_strategy. Most targets should be able to use 516 // Default_scan_relocatable_relocs as this class. 517 518 template<int size, bool big_endian, int sh_type, 519 typename Scan_relocatable_reloc> 520 void 521 scan_relocatable_relocs( 522 Symbol_table*, 523 Layout*, 524 Sized_relobj_file<size, big_endian>* object, 525 unsigned int data_shndx, 526 const unsigned char* prelocs, 527 size_t reloc_count, 528 Output_section* output_section, 529 bool needs_special_offset_handling, 530 size_t local_symbol_count, 531 const unsigned char* plocal_syms, 532 Relocatable_relocs* rr) 533 { 534 typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype; 535 const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size; 536 const int sym_size = elfcpp::Elf_sizes<size>::sym_size; 537 Scan_relocatable_reloc scan; 538 539 for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size) 540 { 541 Reltype reloc(prelocs); 542 543 Relocatable_relocs::Reloc_strategy strategy; 544 545 if (needs_special_offset_handling 546 && !output_section->is_input_address_mapped(object, data_shndx, 547 reloc.get_r_offset())) 548 strategy = Relocatable_relocs::RELOC_DISCARD; 549 else 550 { 551 typename elfcpp::Elf_types<size>::Elf_WXword r_info = 552 reloc.get_r_info(); 553 const unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info); 554 const unsigned int r_type = elfcpp::elf_r_type<size>(r_info); 555 556 if (r_sym >= local_symbol_count) 557 strategy = scan.global_strategy(r_type, object, r_sym); 558 else 559 { 560 gold_assert(plocal_syms != NULL); 561 typename elfcpp::Sym<size, big_endian> lsym(plocal_syms 562 + r_sym * sym_size); 563 unsigned int shndx = lsym.get_st_shndx(); 564 bool is_ordinary; 565 shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary); 566 if (is_ordinary 567 && shndx != elfcpp::SHN_UNDEF 568 && !object->is_section_included(shndx)) 569 { 570 // RELOC is a relocation against a local symbol 571 // defined in a section we are discarding. Discard 572 // the reloc. FIXME: Should we issue a warning? 573 strategy = Relocatable_relocs::RELOC_DISCARD; 574 } 575 else if (lsym.get_st_type() != elfcpp::STT_SECTION) 576 strategy = scan.local_non_section_strategy(r_type, object, 577 r_sym); 578 else 579 { 580 strategy = scan.local_section_strategy(r_type, object); 581 if (strategy != Relocatable_relocs::RELOC_DISCARD) 582 object->output_section(shndx)->set_needs_symtab_index(); 583 } 584 585 if (strategy == Relocatable_relocs::RELOC_COPY) 586 object->set_must_have_output_symtab_entry(r_sym); 587 } 588 } 589 590 rr->set_next_reloc_strategy(strategy); 591 } 592 } 593 594 // Relocate relocs during a relocatable link. This is a default 595 // definition which should work for most targets. 596 597 template<int size, bool big_endian, int sh_type> 598 void 599 relocate_for_relocatable( 600 const Relocate_info<size, big_endian>* relinfo, 601 const unsigned char* prelocs, 602 size_t reloc_count, 603 Output_section* output_section, 604 typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section, 605 const Relocatable_relocs* rr, 606 unsigned char* view, 607 typename elfcpp::Elf_types<size>::Elf_Addr view_address, 608 section_size_type view_size, 609 unsigned char* reloc_view, 610 section_size_type reloc_view_size) 611 { 612 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address; 613 typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype; 614 typedef typename Reloc_types<sh_type, size, big_endian>::Reloc_write 615 Reltype_write; 616 const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size; 617 const Address invalid_address = static_cast<Address>(0) - 1; 618 619 Sized_relobj_file<size, big_endian>* const object = relinfo->object; 620 const unsigned int local_count = object->local_symbol_count(); 621 622 unsigned char* pwrite = reloc_view; 623 624 for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size) 625 { 626 Relocatable_relocs::Reloc_strategy strategy = rr->strategy(i); 627 if (strategy == Relocatable_relocs::RELOC_DISCARD) 628 continue; 629 630 if (strategy == Relocatable_relocs::RELOC_SPECIAL) 631 { 632 // Target wants to handle this relocation. 633 Sized_target<size, big_endian>* target = 634 parameters->sized_target<size, big_endian>(); 635 target->relocate_special_relocatable(relinfo, sh_type, prelocs, 636 i, output_section, 637 offset_in_output_section, 638 view, view_address, 639 view_size, pwrite); 640 pwrite += reloc_size; 641 continue; 642 } 643 Reltype reloc(prelocs); 644 Reltype_write reloc_write(pwrite); 645 646 typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info(); 647 const unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info); 648 const unsigned int r_type = elfcpp::elf_r_type<size>(r_info); 649 650 // Get the new symbol index. 651 652 unsigned int new_symndx; 653 if (r_sym < local_count) 654 { 655 switch (strategy) 656 { 657 case Relocatable_relocs::RELOC_COPY: 658 if (r_sym == 0) 659 new_symndx = 0; 660 else 661 { 662 new_symndx = object->symtab_index(r_sym); 663 gold_assert(new_symndx != -1U); 664 } 665 break; 666 667 case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA: 668 case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0: 669 case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_1: 670 case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_2: 671 case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4: 672 case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_8: 673 case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4_UNALIGNED: 674 { 675 // We are adjusting a section symbol. We need to find 676 // the symbol table index of the section symbol for 677 // the output section corresponding to input section 678 // in which this symbol is defined. 679 gold_assert(r_sym < local_count); 680 bool is_ordinary; 681 unsigned int shndx = 682 object->local_symbol_input_shndx(r_sym, &is_ordinary); 683 gold_assert(is_ordinary); 684 Output_section* os = object->output_section(shndx); 685 gold_assert(os != NULL); 686 gold_assert(os->needs_symtab_index()); 687 new_symndx = os->symtab_index(); 688 } 689 break; 690 691 default: 692 gold_unreachable(); 693 } 694 } 695 else 696 { 697 const Symbol* gsym = object->global_symbol(r_sym); 698 gold_assert(gsym != NULL); 699 if (gsym->is_forwarder()) 700 gsym = relinfo->symtab->resolve_forwards(gsym); 701 702 gold_assert(gsym->has_symtab_index()); 703 new_symndx = gsym->symtab_index(); 704 } 705 706 // Get the new offset--the location in the output section where 707 // this relocation should be applied. 708 709 Address offset = reloc.get_r_offset(); 710 Address new_offset; 711 if (offset_in_output_section != invalid_address) 712 new_offset = offset + offset_in_output_section; 713 else 714 { 715 section_offset_type sot_offset = 716 convert_types<section_offset_type, Address>(offset); 717 section_offset_type new_sot_offset = 718 output_section->output_offset(object, relinfo->data_shndx, 719 sot_offset); 720 gold_assert(new_sot_offset != -1); 721 new_offset = new_sot_offset; 722 } 723 724 // In an object file, r_offset is an offset within the section. 725 // In an executable or dynamic object, generated by 726 // --emit-relocs, r_offset is an absolute address. 727 if (!parameters->options().relocatable()) 728 { 729 new_offset += view_address; 730 if (offset_in_output_section != invalid_address) 731 new_offset -= offset_in_output_section; 732 } 733 734 reloc_write.put_r_offset(new_offset); 735 reloc_write.put_r_info(elfcpp::elf_r_info<size>(new_symndx, r_type)); 736 737 // Handle the reloc addend based on the strategy. 738 739 if (strategy == Relocatable_relocs::RELOC_COPY) 740 { 741 if (sh_type == elfcpp::SHT_RELA) 742 Reloc_types<sh_type, size, big_endian>:: 743 copy_reloc_addend(&reloc_write, 744 &reloc); 745 } 746 else 747 { 748 // The relocation uses a section symbol in the input file. 749 // We are adjusting it to use a section symbol in the output 750 // file. The input section symbol refers to some address in 751 // the input section. We need the relocation in the output 752 // file to refer to that same address. This adjustment to 753 // the addend is the same calculation we use for a simple 754 // absolute relocation for the input section symbol. 755 756 const Symbol_value<size>* psymval = object->local_symbol(r_sym); 757 758 unsigned char* padd = view + offset; 759 switch (strategy) 760 { 761 case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA: 762 { 763 typename elfcpp::Elf_types<size>::Elf_Swxword addend; 764 addend = Reloc_types<sh_type, size, big_endian>:: 765 get_reloc_addend(&reloc); 766 addend = psymval->value(object, addend); 767 Reloc_types<sh_type, size, big_endian>:: 768 set_reloc_addend(&reloc_write, addend); 769 } 770 break; 771 772 case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0: 773 break; 774 775 case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_1: 776 Relocate_functions<size, big_endian>::rel8(padd, object, 777 psymval); 778 break; 779 780 case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_2: 781 Relocate_functions<size, big_endian>::rel16(padd, object, 782 psymval); 783 break; 784 785 case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4: 786 Relocate_functions<size, big_endian>::rel32(padd, object, 787 psymval); 788 break; 789 790 case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_8: 791 Relocate_functions<size, big_endian>::rel64(padd, object, 792 psymval); 793 break; 794 795 case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4_UNALIGNED: 796 Relocate_functions<size, big_endian>::rel32_unaligned(padd, 797 object, 798 psymval); 799 break; 800 801 default: 802 gold_unreachable(); 803 } 804 } 805 806 pwrite += reloc_size; 807 } 808 809 gold_assert(static_cast<section_size_type>(pwrite - reloc_view) 810 == reloc_view_size); 811 } 812 813 } // End namespace gold. 814 815 #endif // !defined(GOLD_TARGET_RELOC_H) 816