This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi Cary, thanks. All done in below. Attached modified patch - relaxation.patch2. Also attached the diff from patch2 to patch1 for ease of review. Thanks, Han On Fri, Oct 10, 2014 at 4:28 PM, Cary Coutant <ccoutant@google.com> wrote: > > > Here we have the patch for gold aarch64 backend to support relaxation. > > > > In short relaxation is the linker's generation of stubs that fixes the > > out-of-range jumps/branches in the original object file. > > > > With this implementation, we are able to link a 456MB aarch64 application > > (correctness of the result file, though, hasn't been verified.) > > Thanks. Here are my comments... > > -cary > > > + struct > + { > + // For a global symbol, the symbol itself. > + Symbol* symbol; > + } global; > + struct > + { > + // For a local symbol, the object defining object. > > I know this is actually unchanged code from before, but this > comment looks wrong. Should probably be "the defining object" > or "the object defining the symbol". Done > > > + // Do not change the value of the enums, they are used to index into > + // stub_insns array. > > In that case, you should probably assign values explicitly to each > enum constant. Enum constants like this should generally be all > upper case (like macros and static constants). Done - Changed to all upper case and explicitly assigned values to them. > > > + // Determine the stub type for a certain relocation or st_none, if no stub is > + // needed. > + static Stub_type > + stub_type_for_reloc(unsigned int r_type, AArch64_address address, > + AArch64_address target); > + > + public: > > Unnecessary: everything above this was also public. Done > > > + // The key class used to index the stub instance in the stub > table's stub map. > + class Key > + { > + public: > > "public" should be indented one space. Done > > > + // Return a hash value. > + size_t > + hash_value() const > + { > + return (this->stub_type_ > + ^ this->r_sym_ > + ^ gold::string_hash<char>( > + (this->r_sym_ != Reloc_stub::invalid_index) > + ? this->u_.relobj->name().c_str() > + : this->u_.symbol->name()) > + ^ this->addend_); > > I know this is just copied from arm.cc, but it looks to me like > this hash function might be a bit weak. In particular, > stub_type_, r_sym_, and addend_ might easily cancel one another > out, causing some preventable collisions. r_sym_ is also > unnecessary (but harmless, I guess), when it's equal to > invalid_index. I'd suggest at least shifting stub_type_, r_sym_, > and addend_ by different amounts, or applying a different > multiplier to each to distribute the bits around more, and > applying r_sym_ only when it's a local symbol index. Done by placing name hash at bit 0-19, stub_type 20-21, r_sym 22-26 (even if it's a invalid_index) and addend 27-31. > > > + struct equal_to > + { > + bool > + operator()(const Key& k1, const Key& k2) const > + { return k1.eq(k2); } > + }; > + > + private: > > "private" should be indented one space. Done. > > > + // Initialize look-up tables. > + Stub_table_list empty_stub_table_list(this->shnum(), NULL); > + this->stub_tables_.swap(empty_stub_table_list); > > It's simpler to just use resize(this->shnum()). The "swap" idiom > is useful when you need to release memory, but not necessary for > initialization. Done > > > + // Call parent to relocate sections. > + Sized_relobj_file<size, big_endian>::do_relocate_sections(symtab, layout, > + pshdrs, of, pviews); > > Indentation is off by one. Done. > > > + unsigned int reloc_size; > + if (sh_type == elfcpp::SHT_RELA) > + reloc_size = elfcpp::Elf_sizes<size>::rela_size; > > For REL sections, reloc_size will be left uninitialized here. > If you don't expect REL sections, you should assert that. Done. > > > + const unsigned int shdr_size = elfcpp::Elf_sizes<size>::shdr_size; > + const elfcpp::Shdr<size, big_endian> text_shdr(pshdrs + index * shdr_size); > + return this->section_is_scannable(text_shdr, index, > + out_sections[index], symtab); > > The naming doesn't really make it clear that > section_needs_reloc_stub_scanning is looking at the REL/RELA > section, while section_is_scannable is looking at the PROGBITS > section that is being relocated. You've used text_shdr for the > section header, so I'd suggest using text_shndx instead of index, > and text_section_is_scannable for the function name. Done. > > > + // Currently this only happens for a relaxed section. > + const Output_relaxed_input_section* poris = > + out_sections[index]->find_relaxed_input_section(this, index); > > This continuation line needs indentation (4 spaces). Done. > > > + // Get the section contents. This does work for the case in which > + // we modify the contents of an input section. We need to pass the > + // output view under such circumstances. > > Should the comment read "This does *not* work ..."? > > I don't see you handling the case where you modify the contents, > so maybe that last sentence is not necessary? Done by removing the confusing last 2 sentences. > > > +// Create a stub group for input sections from BEGIN to END. OWNER > +// points to the input section to be the owner a new stub table. > > "OWNER points to the input section that will be the owner of the > stub table." Done. > > > + // Currently we convert ordinary input sections into relaxed sections only > + // at this point but we may want to support creating relaxed input section > + // very early. So we check here to see if owner is already a relaxed > + // section. > + gold_assert(!owner->is_relaxed_input_section()); > + > + The_aarch64_input_section* input_section; > + if (owner->is_relaxed_input_section()) > + { > + input_section = static_cast<The_aarch64_input_section*>( > + owner->relaxed_input_section()); > + } > > Given the assert above, this code can't be reached. If you want to > leave it in as a stub for the future, I'd suggest removing the above > assert, and replacing the then clause with gold_unreachable(). Done by replacing gold_assert by gold_unreachable inside the if clause also updated the comments. > > > + do > + { > + if (p->is_input_section() || p->is_relaxed_input_section()) > + { > + // The stub table information for input sections live > + // in their objects. > + The_aarch64_relobj* aarch64_relobj = > + static_cast<The_aarch64_relobj*>(p->relobj()); > + aarch64_relobj->set_stub_table(p->shndx(), stub_table); > + } > + prev_p = p++; > + } > + while (prev_p != end); > > Suggest renaming begin/end to maybe first/last? It took me a minute > to understand that "end" doesn't refer to the same "end" that an > iterator would test against, and that you intended this to be an > inclusive range. Done renaming. > > > Why not just "do { ... } while (p++ != last);"? Done. > > > +// Group input sections for stub generation. GROUP_SIZE is roughly the limit > +// of stub groups. We grow a stub group by adding input section until the > +// size is just below GROUP_SIZE. The last input section will be converted > +// into a stub table. If STUB_ALWAYS_AFTER_BRANCH is false, we also add > +// input section after the stub table, effectively double the group size. > > Do you mean "the last input section will be converted into a stub > table *owner*"? > > And "we also add input section*s* after the stub table, effectively > *doubling* the group size." Done. > > > + case HAS_STUB_SECTION: > + // Adding this section makes the post stub-section group larger > + // than GROUP_SIZE. > + gold_assert(false); > > You can just use gold_unreachable() here. > > + // ET_EXEC files are valid input for --just-symbols/-R, > + // and we treat them as relocatable objects. > > For --just-symbols, shouldn't you use the base implementation > of do_make_elf_object? Done by invoking parent implementation. > > > +// This function scans a relocation sections for stub generation. > > s/sections/section/ Done. > > > + // An error should never aroused in the above step. If so, please > + // An error should never arouse, it is an "_NC" relocation. > > "arise". > > + gold_error(_("Stub is too far away, try use a smaller value " > + "for '--stub-group-size'. For example, 0x2000000.")); > > Either "try using" or "try to use" or just "try a smaller value". Done. -- Han Shen | Software Engineer | shenhan@google.com | +1-650-440-3330
Attachment:
relaxation.patch2
Description: Binary data
diff --git a/gold/aarch64.cc b/gold/aarch64.cc index 79f153a..a1b4011 100644 --- a/gold/aarch64.cc +++ b/gold/aarch64.cc @@ -286,11 +286,11 @@ class Output_data_got_aarch64 : public Output_data_got<size, big_endian> // For a global symbol, the symbol itself. Symbol* symbol; } global; struct { - // For a local symbol, the object defining object. + // For a local symbol, the object defining the symbol. Sized_relobj_file<size, big_endian>* relobj; // For a local symbol, the symbol index. unsigned int index; } local; } u_; @@ -319,24 +319,24 @@ class Reloc_stub // Do not change the value of the enums, they are used to index into // stub_insns array. typedef enum { - st_none, + ST_NONE = 0, // Using adrp/add pair, 4 insns (including alignment) without mem access, // the fastest stub. This has a limited jump distance, which is tested by // aarch64_valid_for_adrp_p. - st_adrp_branch, + ST_ADRP_BRANCH = 1, // Using ldr-absolute-address/br-register, 4 insns with 1 mem access, // unlimited in jump distance. - st_long_branch_abs, + ST_LONG_BRANCH_ABS = 2, // Using ldr/calculate-pcrel/jump, 8 insns (including alignment) with 1 mem // access, slowest one. Only used in position independent executables. - st_long_branch_pcrel, + ST_LONG_BRANCH_PCREL = 3, } Stub_type; // Branch range. This is used to calculate the section group size, as well as // determine whether a stub is needed. @@ -363,17 +363,16 @@ class Reloc_stub typedef AArch64_relocate_functions<size, big_endian> Reloc; int64_t adrp_imm = (Reloc::Page(dest) - Reloc::Page(location)) >> 12; return adrp_imm >= MIN_ADRP_IMM && adrp_imm <= MAX_ADRP_IMM; } - // Determine the stub type for a certain relocation or st_none, if no stub is + // Determine the stub type for a certain relocation or ST_NONE, if no stub is // needed. static Stub_type stub_type_for_reloc(unsigned int r_type, AArch64_address address, AArch64_address target); - public: Reloc_stub(Stub_type stub_type) : stub_type_(stub_type), offset_(invalid_offset), destination_address_(invalid_address) { } @@ -440,11 +439,11 @@ class Reloc_stub { this->do_write(view, view_size); } // The key class used to index the stub instance in the stub table's stub map. class Key { - public: + public: Key(Stub_type stub_type, const Symbol* symbol, const Relobj* relobj, unsigned int r_sym, int32_t addend) : stub_type_(stub_type), addend_(addend) { if (symbol != NULL) @@ -497,17 +496,26 @@ class Reloc_stub // Return a hash value. size_t hash_value() const { - return (this->stub_type_ - ^ this->r_sym_ - ^ gold::string_hash<char>( - (this->r_sym_ != Reloc_stub::invalid_index) - ? this->u_.relobj->name().c_str() - : this->u_.symbol->name()) - ^ this->addend_); + // This will occupy the lowest 20 bits in the final hash value. + size_t name_hash_value = 0XFFFFFF & gold::string_hash<char>( + (this->r_sym_ != Reloc_stub::invalid_index) + ? this->u_.relobj->name().c_str() + : this->u_.symbol->name()); + // We only have 4 stub types, so we allocate 2 bits for it in the final + // hash value, and they will occupy bit 21 - 22. + size_t stub_type_hash_value = 0x03 & this->stub_type_; + // 5 bits for r_sym_, even if it's a invalid_index. + size_t r_sym_hash_value = this->r_sym_ & 0x1F; + // 5 bits for addend_. + size_t addend_hash_value = this->addend_ & 0x1F; + return name_hash_value + | (stub_type_hash_value << 20) + | (r_sym_hash_value << 22) + | (addend_hash_value << 27); } // Functors for STL associative containers. struct hash { @@ -521,11 +529,11 @@ class Reloc_stub bool operator()(const Key& k1, const Key& k2) const { return k1.eq(k2); } }; - private: + private: // Stub type. const Stub_type stub_type_; // If this is a local symbol, this is the index in the defining object. // Otherwise, it is invalid_index for a global symbol. unsigned int r_sym_; @@ -586,34 +594,34 @@ template<int size, bool big_endian> const uint32_t Reloc_stub<size, big_endian>::stub_insns_[][10] = { // The first element of each group is the num of the insns. - // st_none + // ST_NONE {0, 0}, - // st_adrp_branch + // ST_ADRP_BRANCH { 4, 0x90000010, /* adrp ip0, X */ /* ADR_PREL_PG_HI21(X) */ 0x91000210, /* add ip0, ip0, :lo12:X */ /* ADD_ABS_LO12_NC(X) */ 0xd61f0200, /* br ip0 */ 0x00000000, /* alignment padding */ }, - // st_long_branch_abs + // ST_LONG_BRANCH_ABS { 4, 0x58000050, /* ldr ip0, 0x8 */ 0xd61f0200, /* br ip0 */ 0x00000000, /* address field */ 0x00000000, /* address fields */ }, - // st_long_branch_pcrel + // ST_LONG_BRANCH_PCREL { 8, 0x58000090, /* ldr ip0, 0x10 */ 0x10000011, /* adr ip1, #0 */ 0x8b110210, /* add ip0, ip0, ip1 */ @@ -624,11 +632,11 @@ Reloc_stub<size, big_endian>::stub_insns_[][10] = 0x00000000, /* alignment padding */ } }; -// Determine the stub type for a certain relocation or st_none, if no stub is +// Determine the stub type for a certain relocation or ST_NONE, if no stub is // needed. template<int size, bool big_endian> inline typename Reloc_stub<size, big_endian>::Stub_type @@ -645,20 +653,20 @@ Reloc_stub<size, big_endian>::stub_type_for_reloc( default: gold_assert(false); } if (aarch64_valid_branch_offset_p(branch_offset)) - return st_none; + return ST_NONE; if (aarch64_valid_for_adrp_p(location, dest)) - return st_adrp_branch; + return ST_ADRP_BRANCH; if (parameters->options().output_is_position_independent() && parameters->options().output_is_executable()) - return st_long_branch_pcrel; + return ST_LONG_BRANCH_PCREL; - return st_long_branch_abs; + return ST_LONG_BRANCH_ABS; } // A class to hold stubs for the ARM target. template<int size, bool big_endian> @@ -919,12 +927,12 @@ class AArch64_relobj : public Sized_relobj_file<size, big_endian> scan_sections_for_stubs(The_target_aarch64*, const Symbol_table*, const Layout*); // Whether a section is a scannable text section. bool - section_is_scannable(const elfcpp::Shdr<size, big_endian>&, unsigned int, - const Output_section*, const Symbol_table*); + text_section_is_scannable(const elfcpp::Shdr<size, big_endian>&, unsigned int, + const Output_section*, const Symbol_table*); // Convert regular input section with index SHNDX to a relaxed section. void convert_input_section_to_relaxed_section(unsigned /* shndx */) { @@ -940,12 +948,11 @@ class AArch64_relobj : public Sized_relobj_file<size, big_endian> { // Call parent's setup method. Sized_relobj_file<size, big_endian>::do_setup(); // Initialize look-up tables. - Stub_table_list empty_stub_table_list(this->shnum(), NULL); - this->stub_tables_.swap(empty_stub_table_list); + this->stub_tables_.resize(this->shnum()); } virtual void do_relocate_sections( const Symbol_table* symtab, const Layout* layout, @@ -973,11 +980,11 @@ AArch64_relobj<size, big_endian>::do_relocate_sections( const unsigned char* pshdrs, Output_file* of, typename Sized_relobj_file<size, big_endian>::Views* pviews) { // Call parent to relocate sections. Sized_relobj_file<size, big_endian>::do_relocate_sections(symtab, layout, - pshdrs, of, pviews); + pshdrs, of, pviews); // We do not generate stubs if doing a relocatable link. if (parameters->options().relocatable()) return; @@ -1027,37 +1034,33 @@ AArch64_relobj<size, big_endian>::do_relocate_sections( // section for the input section and SYMTAB is the global symbol table used to // look up ICF information. template<int size, bool big_endian> bool -AArch64_relobj<size, big_endian>::section_is_scannable( - const elfcpp::Shdr<size, big_endian>& shdr, - unsigned int shndx, +AArch64_relobj<size, big_endian>::text_section_is_scannable( + const elfcpp::Shdr<size, big_endian>& text_shdr, + unsigned int text_shndx, const Output_section* os, const Symbol_table* symtab) { // Skip any empty sections, unallocated sections or sections whose // type are not SHT_PROGBITS. - if (shdr.get_sh_size() == 0 - || (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0 - || shdr.get_sh_type() != elfcpp::SHT_PROGBITS) + if (text_shdr.get_sh_size() == 0 + || (text_shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0 + || text_shdr.get_sh_type() != elfcpp::SHT_PROGBITS) return false; // Skip any discarded or ICF'ed sections. - if (os == NULL || symtab->is_section_folded(this, shndx)) + if (os == NULL || symtab->is_section_folded(this, text_shndx)) return false; - // If this requires special offset handling, check to see if it is - // a relaxed section. If this is not, then it is a merged section that - // we cannot handle. - if (this->is_output_section_offset_invalid(shndx)) - { - const Output_relaxed_input_section* poris = - os->find_relaxed_input_section(this, shndx); - if (poris == NULL) - return false; - } + // Skip exception frame. + if (strcmp(os->name(), ".eh_frame") == 0) + return false ; + + gold_assert(!this->is_output_section_offset_invalid(text_shndx) || + os->find_relaxed_input_section(this, text_shndx) != NULL); return true; } @@ -1084,29 +1087,29 @@ AArch64_relobj<size, big_endian>::section_needs_reloc_stub_scanning( // Ignore reloc section with unexpected symbol table. The // error will be reported in the final link. if (this->adjust_shndx(shdr.get_sh_link()) != this->symtab_shndx()) return false; - unsigned int reloc_size; - if (sh_type == elfcpp::SHT_RELA) - reloc_size = elfcpp::Elf_sizes<size>::rela_size; + gold_assert(sh_type == elfcpp::SHT_RELA); + unsigned int reloc_size = elfcpp::Elf_sizes<size>::rela_size; // Ignore reloc section with unexpected entsize or uneven size. // The error will be reported in the final link. if (reloc_size != shdr.get_sh_entsize() || sh_size % reloc_size != 0) return false; // Ignore reloc section with bad info. This error will be // reported in the final link. - unsigned int index = this->adjust_shndx(shdr.get_sh_info()); - if (index >= this->shnum()) + unsigned int text_shndx = this->adjust_shndx(shdr.get_sh_info()); + if (text_shndx >= this->shnum()) return false; const unsigned int shdr_size = elfcpp::Elf_sizes<size>::shdr_size; - const elfcpp::Shdr<size, big_endian> text_shdr(pshdrs + index * shdr_size); - return this->section_is_scannable(text_shdr, index, - out_sections[index], symtab); + const elfcpp::Shdr<size, big_endian> text_shdr(pshdrs + + text_shndx * shdr_size); + return this->text_section_is_scannable(text_shdr, text_shndx, + out_sections[text_shndx], symtab); } // Scan relocations for stub generation. @@ -1154,23 +1157,21 @@ AArch64_relobj<size, big_endian>::scan_sections_for_stubs( } else { // Currently this only happens for a relaxed section. const Output_relaxed_input_section* poris = - out_sections[index]->find_relaxed_input_section(this, index); + out_sections[index]->find_relaxed_input_section(this, index); gold_assert(poris != NULL); output_address = poris->address(); } // Get the relocations. const unsigned char* prelocs = this->get_view(shdr.get_sh_offset(), shdr.get_sh_size(), true, false); - // Get the section contents. This does work for the case in which - // we modify the contents of an input section. We need to pass the - // output view under such circumstances. + // Get the section contents. section_size_type input_view_size = 0; const unsigned char* input_view = this->section_contents(index, &input_view_size, false); relinfo.reloc_shndx = i; @@ -1431,34 +1432,27 @@ class AArch64_output_section : public Output_section std::vector<Output_relaxed_input_section*>&, const Task*); }; // End of AArch64_output_section -// Create a stub group for input sections from BEGIN to END. OWNER -// points to the input section to be the owner a new stub table. +// Create a stub group for input sections from FIRST to LAST. OWNER points to +// the input section that will be the owner of the stub table. template<int size, bool big_endian> void AArch64_output_section<size, big_endian>::create_stub_group( - Input_section_list::const_iterator begin, - Input_section_list::const_iterator end, + Input_section_list::const_iterator first, + Input_section_list::const_iterator last, Input_section_list::const_iterator owner, The_target_aarch64* target, std::vector<Output_relaxed_input_section*>& new_relaxed_sections, const Task* task) { // Currently we convert ordinary input sections into relaxed sections only - // at this point but we may want to support creating relaxed input section - // very early. So we check here to see if owner is already a relaxed - // section. - gold_assert(!owner->is_relaxed_input_section()); - + // at this point. The_aarch64_input_section* input_section; if (owner->is_relaxed_input_section()) - { - input_section = static_cast<The_aarch64_input_section*>( - owner->relaxed_input_section()); - } + gold_unreachable(); else { gold_assert(owner->is_input_section()); // Create a new relaxed input section. We need to lock the original // file. @@ -1472,34 +1466,32 @@ AArch64_output_section<size, big_endian>::create_stub_group( The_stub_table* stub_table = target->new_stub_table(input_section); input_section->set_stub_table(stub_table); - Input_section_list::const_iterator p = begin; - Input_section_list::const_iterator prev_p; - // Look for input sections or relaxed input sections in [begin ... end]. + Input_section_list::const_iterator p = first; + // Look for input sections or relaxed input sections in [first ... last]. do { if (p->is_input_section() || p->is_relaxed_input_section()) { // The stub table information for input sections live // in their objects. The_aarch64_relobj* aarch64_relobj = static_cast<The_aarch64_relobj*>(p->relobj()); aarch64_relobj->set_stub_table(p->shndx(), stub_table); } - prev_p = p++; } - while (prev_p != end); + while (p++ != last); } -// Group input sections for stub generation. GROUP_SIZE is roughly the limit -// of stub groups. We grow a stub group by adding input section until the -// size is just below GROUP_SIZE. The last input section will be converted -// into a stub table. If STUB_ALWAYS_AFTER_BRANCH is false, we also add -// input section after the stub table, effectively double the group size. +// Group input sections for stub generation. GROUP_SIZE is roughly the limit of +// stub groups. We grow a stub group by adding input section until the size is +// just below GROUP_SIZE. The last input section will be converted into a stub +// table owner. If STUB_ALWAYS_AFTER_BRANCH is false, we also add input sectiond +// after the stub table, effectively doubling the group size. // // This is similar to the group_sections() function in elf32-arm.c but is // implemented differently. template<int size, bool big_endian> @@ -1567,12 +1559,12 @@ void AArch64_output_section<size, big_endian>::group_sections( break; case HAS_STUB_SECTION: // Adding this section makes the post stub-section group larger // than GROUP_SIZE. - gold_assert(false); - // NOT SUPPORTED YET. + gold_unreachable(); + // NOT SUPPORTED YET. For completeness only. if (section_end_offset - stub_table_end_offset >= group_size) { gold_assert(group_end != this->input_sections().end()); this->create_stub_group(group_begin, group_end, stub_table, target, new_relaxed_sections, task); @@ -2469,12 +2461,14 @@ Target_aarch64<size, big_endian>::do_make_elf_object( off_t offset, const elfcpp::Ehdr<size, big_endian>& ehdr) { int et = ehdr.get_e_type(); // ET_EXEC files are valid input for --just-symbols/-R, // and we treat them as relocatable objects. - if (et == elfcpp::ET_REL - || (et == elfcpp::ET_EXEC && input_file->just_symbols())) + if (et == elfcpp::ET_EXEC && input_file->just_symbols()) + return Sized_target<size, big_endian>::do_make_elf_object( + name, input_file, offset, ehdr); + else if (et == elfcpp::ET_REL) { AArch64_relobj<size, big_endian>* obj = new AArch64_relobj<size, big_endian>(name, input_file, offset, ehdr); obj->setup(); return obj; @@ -2545,11 +2539,11 @@ Target_aarch64<size, big_endian>::scan_reloc_for_stub( gold_assert(false); } typename The_reloc_stub::Stub_type stub_type = The_reloc_stub:: stub_type_for_reloc(r_type, address, destination); - if (stub_type == The_reloc_stub::st_none) + if (stub_type == The_reloc_stub::ST_NONE) return ; The_stub_table* stub_table = aarch64_relobj->stub_table(relinfo->data_shndx); gold_assert(stub_table != NULL); @@ -2562,11 +2556,11 @@ Target_aarch64<size, big_endian>::scan_reloc_for_stub( } stub->set_destination_address(destination); } // End of Target_aarch64::scan_reloc_for_stub -// This function scans a relocation sections for stub generation. +// This function scans a relocation section for stub generation. // The template parameter Relocate must be a class type which provides // a single function, relocate(), which implements the machine // specific part of a relocation. // BIG_ENDIAN is the endianness of the data. SH_TYPE is the section type: @@ -2812,37 +2806,37 @@ relocate_stub(The_reloc_stub* stub, Address dest = stub->destination_address(); switch(stub->stub_type()) { - case The_reloc_stub::st_adrp_branch: + case The_reloc_stub::ST_ADRP_BRANCH: { // 1st reloc is ADR_PREL_PG_HI21 The_reloc_functions_status status = The_reloc_functions::adrp(view, dest, address); - // An error should never aroused in the above step. If so, please + // An error should never arise in the above step. If so, please // check 'aarch64_valid_for_adrp_p'. gold_assert(status == The_reloc_functions::STATUS_OKAY); // 2nd reloc is ADD_ABS_LO12_NC const AArch64_reloc_property* arp = aarch64_reloc_property_table->get_reloc_property( elfcpp::R_AARCH64_ADD_ABS_LO12_NC); gold_assert(arp != NULL); status = The_reloc_functions::template rela_general<32>(view + 4, dest, 0, arp); - // An error should never arouse, it is an "_NC" relocation. + // An error should never arise, it is an "_NC" relocation. gold_assert(status == The_reloc_functions::STATUS_OKAY); } break; - case The_reloc_stub::st_long_branch_abs: + case The_reloc_stub::ST_LONG_BRANCH_ABS: // 1st reloc is R_AARCH64_PREL64, at offset 8 elfcpp::Swap<64,big_endian>::writeval(view + 8, dest); break; - case The_reloc_stub::st_long_branch_pcrel: + case The_reloc_stub::ST_LONG_BRANCH_PCREL: { // "PC" calculation is the 2nd insn in the stub. uint64_t offset = dest - (address + 4); // Offset is placed at offset 4 and 5. elfcpp::Swap<64,big_endian>::writeval(view + 16, offset); @@ -4084,11 +4078,11 @@ maybe_apply_stub(unsigned int r_type, typename elfcpp::Elf_types<size>::Elf_Swxword addend = rela.get_r_addend(); Address branch_target = psymval->value(object, 0) + addend; The_reloc_stub_type stub_type = The_reloc_stub:: stub_type_for_reloc(r_type, address, branch_target); - if (stub_type == The_reloc_stub::st_none) + if (stub_type == The_reloc_stub::ST_NONE) return false; const The_aarch64_relobj* aarch64_relobj = static_cast<const The_aarch64_relobj*>(object); The_stub_table* stub_table = aarch64_relobj->stub_table(relinfo->data_shndx); @@ -4106,11 +4100,11 @@ maybe_apply_stub(unsigned int r_type, aarch64_reloc_property_table->get_reloc_property(r_type); gold_assert(arp != NULL); This::Status status = This::template rela_general<32>(view, branch_offset, 0, arp); if (status != This::STATUS_OKAY) - gold_error(_("Stub is too far away, try use a smaller value " + gold_error(_("Stub is too far away, try a smaller value " "for '--stub-group-size'. For example, 0x2000000.")); return true; } @@ -5439,18 +5433,21 @@ Target_aarch64<size, big_endian>::Relocate::relocate( break; case elfcpp::R_AARCH64_PREL64: reloc_status = Reloc::template pcrela_ua<64>( view, object, psymval, addend, address, reloc_property); + break; case elfcpp::R_AARCH64_PREL32: reloc_status = Reloc::template pcrela_ua<32>( view, object, psymval, addend, address, reloc_property); + break; case elfcpp::R_AARCH64_PREL16: reloc_status = Reloc::template pcrela_ua<16>( view, object, psymval, addend, address, reloc_property); + break; case elfcpp::R_AARCH64_ADR_PREL_PG_HI21_NC: case elfcpp::R_AARCH64_ADR_PREL_PG_HI21: reloc_status = Reloc::adrp(view, object, psymval, addend, address, reloc_property);
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |