diff options
-rw-r--r-- | gold/Makefile.am | 1 | ||||
-rw-r--r-- | gold/Makefile.in | 1 | ||||
-rw-r--r-- | gold/i386.cc | 259 | ||||
-rw-r--r-- | gold/po/POTFILES.in | 1 | ||||
-rw-r--r-- | gold/po/gold.pot | 58 | ||||
-rw-r--r-- | gold/tls.h | 89 |
6 files changed, 253 insertions, 156 deletions
diff --git a/gold/Makefile.am b/gold/Makefile.am index 87bde55..e9508de 100644 --- a/gold/Makefile.am +++ b/gold/Makefile.am @@ -75,6 +75,7 @@ HFILES = \ target.h \ target-reloc.h \ target-select.h \ + tls.h \ workqueue.h YFILES = \ diff --git a/gold/Makefile.in b/gold/Makefile.in index 13a3536..9d9ff8c 100644 --- a/gold/Makefile.in +++ b/gold/Makefile.in @@ -326,6 +326,7 @@ HFILES = \ target.h \ target-reloc.h \ target-select.h \ + tls.h \ workqueue.h YFILES = \ diff --git a/gold/i386.cc b/gold/i386.cc index 033a9b9..ce4d961 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -35,6 +35,7 @@ #include "target.h" #include "target-reloc.h" #include "target-select.h" +#include "tls.h" namespace { @@ -112,6 +113,13 @@ class Target_i386 : public Sized_target<32, false> unsigned int data_shndx, const elfcpp::Rel<32, false>& reloc, unsigned int r_type, Symbol* gsym); + + static void + unsupported_reloc_local(Sized_relobj<32, false>*, unsigned int r_type); + + static void + unsupported_reloc_global(Sized_relobj<32, false>*, unsigned int r_type, + Symbol*); }; // The class which implements relocation. @@ -180,16 +188,6 @@ class Target_i386 : public Sized_target<32, false> unsigned char* view, off_t view_size); - // Check the range for a TLS relocation. - static inline void - check_range(const Relocate_info<32, false>*, size_t relnum, - const elfcpp::Rel<32, false>&, off_t, off_t); - - // Check the validity of a TLS relocation. This is like assert. - static inline void - check_tls(const Relocate_info<32, false>*, size_t relnum, - const elfcpp::Rel<32, false>&, bool); - // We need to keep track of which type of local dynamic relocation // we have seen, so that we can optimize R_386_TLS_LDO_32 correctly. enum Local_dynamic_type @@ -209,7 +207,7 @@ class Target_i386 : public Sized_target<32, false> // Adjust TLS relocation type based on the options and whether this // is a local symbol. - static unsigned int + static tls::Tls_optimization optimize_tls_reloc(bool is_final, int r_type); // Get the GOT section, creating it if necessary. @@ -667,13 +665,13 @@ Target_i386::copy_reloc(const General_options* options, // symbol. IS_FINAL is true if the final address of this symbol is // known at link time. -unsigned int +tls::Tls_optimization Target_i386::optimize_tls_reloc(bool is_final, int r_type) { // If we are generating a shared library, then we can't do anything // in the linker. if (parameters->output_is_shared()) - return r_type; + return tls::TLSOPT_NONE; switch (r_type) { @@ -685,20 +683,18 @@ Target_i386::optimize_tls_reloc(bool is_final, int r_type) // we can convert this to Initial-Exec. If we also know that // this is a local symbol, we can further switch to Local-Exec. if (is_final) - return elfcpp::R_386_TLS_LE_32; - return elfcpp::R_386_TLS_IE_32; + return tls::TLSOPT_TO_LE; + return tls::TLSOPT_TO_IE; case elfcpp::R_386_TLS_LDM: // This is Local-Dynamic, which refers to a local symbol in the // dynamic TLS block. Since we know that we generating an // executable, we can switch to Local-Exec. - return elfcpp::R_386_TLS_LE_32; + return tls::TLSOPT_TO_LE; case elfcpp::R_386_TLS_LDO_32: - // Another type of Local-Dynamic relocation. We return a - // different value as we need to negate the thread segment - // offset. FIXME: Returning reloc types makes no sense. - return elfcpp::R_386_TLS_LE; + // Another type of Local-Dynamic relocation. + return tls::TLSOPT_TO_LE; case elfcpp::R_386_TLS_IE: case elfcpp::R_386_TLS_GOTIE: @@ -708,20 +704,30 @@ Target_i386::optimize_tls_reloc(bool is_final, int r_type) // local symbol, we can switch to Local-Exec, which links the // thread offset into the instruction. if (is_final) - return elfcpp::R_386_TLS_LE_32; - return r_type; + return tls::TLSOPT_TO_LE; + return tls::TLSOPT_NONE; case elfcpp::R_386_TLS_LE: case elfcpp::R_386_TLS_LE_32: // When we already have Local-Exec, there is nothing further we // can do. - return r_type; + return tls::TLSOPT_NONE; default: gold_unreachable(); } } +// Report an unsupported relocation against a local symbol. + +void +Target_i386::Scan::unsupported_reloc_local(Sized_relobj<32, false>* object, + unsigned int r_type) +{ + fprintf(stderr, _("%s: %s: unsupported reloc %u against local symbol\n"), + program_name, object->name().c_str(), r_type); +} + // Scan a relocation for a local symbol. inline void @@ -761,12 +767,12 @@ Target_i386::Scan::local(const General_options&, target->got_section(symtab, layout); break; + // These are relocations which should only be seen by the + // dynamic linker, and should never be seen here. case elfcpp::R_386_COPY: case elfcpp::R_386_GLOB_DAT: case elfcpp::R_386_JUMP_SLOT: case elfcpp::R_386_RELATIVE: - // These are outstanding tls relocs, which are unexpected when - // linking. case elfcpp::R_386_TLS_TPOFF: case elfcpp::R_386_TLS_DTPMOD32: case elfcpp::R_386_TLS_DTPOFF32: @@ -777,7 +783,7 @@ Target_i386::Scan::local(const General_options&, gold_exit(false); break; - // These are initial tls relocs, which are expected when + // These are initial TLS relocs, which are expected when // linking. case elfcpp::R_386_TLS_IE: case elfcpp::R_386_TLS_GOTIE: @@ -791,8 +797,8 @@ Target_i386::Scan::local(const General_options&, case elfcpp::R_386_TLS_DESC_CALL: { bool output_is_shared = parameters->output_is_shared(); - r_type = Target_i386::optimize_tls_reloc(!output_is_shared, - r_type); + const tls::Tls_optimization optimized_type + = Target_i386::optimize_tls_reloc(!output_is_shared, r_type); switch (r_type) { case elfcpp::R_386_TLS_LE: @@ -802,20 +808,36 @@ Target_i386::Scan::local(const General_options&, gold_assert(!output_is_shared); break; + case elfcpp::R_386_TLS_IE: + case elfcpp::R_386_TLS_IE_32: + case elfcpp::R_386_TLS_GOTIE: + // FIXME: If not relaxing to LE, we need to generate a + // TPOFF or TPOFF32 reloc. + if (optimized_type != tls::TLSOPT_TO_LE) + unsupported_reloc_local(object, r_type); + break; + case elfcpp::R_386_TLS_LDM: + // FIXME: If not relaxing to LE, we need to generate a + // DTPMOD32 reloc. + if (optimized_type != tls::TLSOPT_TO_LE) + unsupported_reloc_local(object, r_type); + break; + case elfcpp::R_386_TLS_LDO_32: break; - case elfcpp::R_386_TLS_IE: - case elfcpp::R_386_TLS_GOTIE: case elfcpp::R_386_TLS_GD: - case elfcpp::R_386_TLS_IE_32: case elfcpp::R_386_TLS_GOTDESC: case elfcpp::R_386_TLS_DESC_CALL: - fprintf(stderr, - _("%s: %s: unsupported reloc %u against local symbol\n"), - program_name, object->name().c_str(), r_type); + // FIXME: If not relaxing to LE, we need to generate + // DTPMOD32 and DTPOFF32 relocs. + if (optimized_type != tls::TLSOPT_TO_LE) + unsupported_reloc_local(object, r_type); break; + + default: + gold_unreachable(); } } break; @@ -833,12 +855,23 @@ Target_i386::Scan::local(const General_options&, case elfcpp::R_386_TLS_LDM_POP: case elfcpp::R_386_USED_BY_INTEL_200: default: - fprintf(stderr, _("%s: %s: unsupported reloc %u against local symbol\n"), - program_name, object->name().c_str(), r_type); + unsupported_reloc_local(object, r_type); break; } } +// Report an unsupported relocation against a global symbol. + +void +Target_i386::Scan::unsupported_reloc_global(Sized_relobj<32, false>* object, + unsigned int r_type, + Symbol* gsym) +{ + fprintf(stderr, + _("%s: %s: unsupported reloc %u against global symbol %s\n"), + program_name, object->name().c_str(), r_type, gsym->name()); +} + // Scan a relocation for a global symbol. inline void @@ -928,12 +961,12 @@ Target_i386::Scan::global(const General_options& options, target->got_section(symtab, layout); break; + // These are relocations which should only be seen by the + // dynamic linker, and should never be seen here. case elfcpp::R_386_COPY: case elfcpp::R_386_GLOB_DAT: case elfcpp::R_386_JUMP_SLOT: case elfcpp::R_386_RELATIVE: - // These are outstanding tls relocs, which are unexpected when - // linking. case elfcpp::R_386_TLS_TPOFF: case elfcpp::R_386_TLS_DTPMOD32: case elfcpp::R_386_TLS_DTPOFF32: @@ -958,7 +991,8 @@ Target_i386::Scan::global(const General_options& options, case elfcpp::R_386_TLS_DESC_CALL: { const bool is_final = gsym->final_value_is_known(); - r_type = Target_i386::optimize_tls_reloc(is_final, r_type); + const tls::Tls_optimization optimized_type + = Target_i386::optimize_tls_reloc(is_final, r_type); switch (r_type) { case elfcpp::R_386_TLS_LE: @@ -968,22 +1002,36 @@ Target_i386::Scan::global(const General_options& options, gold_assert(!parameters->output_is_shared()); break; + case elfcpp::R_386_TLS_IE: + case elfcpp::R_386_TLS_IE_32: + case elfcpp::R_386_TLS_GOTIE: + // FIXME: If not relaxing to LE, we need to generate a + // TPOFF or TPOFF32 reloc. + if (optimized_type != tls::TLSOPT_TO_LE) + unsupported_reloc_global(object, r_type, gsym); + break; + case elfcpp::R_386_TLS_LDM: + // FIXME: If not relaxing to LE, we need to generate a + // DTPMOD32 reloc. + if (optimized_type != tls::TLSOPT_TO_LE) + unsupported_reloc_global(object, r_type, gsym); + break; + case elfcpp::R_386_TLS_LDO_32: break; - case elfcpp::R_386_TLS_IE: - case elfcpp::R_386_TLS_GOTIE: case elfcpp::R_386_TLS_GD: - case elfcpp::R_386_TLS_IE_32: case elfcpp::R_386_TLS_GOTDESC: case elfcpp::R_386_TLS_DESC_CALL: - fprintf(stderr, - _("%s: %s: unsupported reloc %u " - "against global symbol %s\n"), - program_name, object->name().c_str(), r_type, - gsym->name()); + // FIXME: If not relaxing to LE, we need to generate + // DTPMOD32 and DTPOFF32 relocs. + if (optimized_type != tls::TLSOPT_TO_LE) + unsupported_reloc_global(object, r_type, gsym); break; + + default: + gold_unreachable(); } } break; @@ -999,9 +1047,7 @@ Target_i386::Scan::global(const General_options& options, case elfcpp::R_386_TLS_LDM_POP: case elfcpp::R_386_USED_BY_INTEL_200: default: - fprintf(stderr, - _("%s: %s: unsupported reloc %u against global symbol %s\n"), - program_name, object->name().c_str(), r_type, gsym->name()); + unsupported_reloc_global(object, r_type, gsym); break; } } @@ -1279,8 +1325,8 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, const bool is_final = (gsym == NULL ? !parameters->output_is_shared() : gsym->final_value_is_known()); - const unsigned int opt_r_type = - Target_i386::optimize_tls_reloc(is_final, r_type); + const tls::Tls_optimization optimized_type + = Target_i386::optimize_tls_reloc(is_final, r_type); switch (r_type) { case elfcpp::R_386_TLS_LE_32: @@ -1296,14 +1342,14 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, case elfcpp::R_386_TLS_IE: case elfcpp::R_386_TLS_GOTIE: case elfcpp::R_386_TLS_IE_32: - if (opt_r_type == elfcpp::R_386_TLS_LE_32) + if (optimized_type == tls::TLSOPT_TO_LE) { Target_i386::Relocate::tls_ie_to_le(relinfo, relnum, tls_segment, rel, r_type, value, view, view_size); break; } - fprintf(stderr, _("%s: %s: unsupported reloc type %u\n"), + fprintf(stderr, _("%s: %s: unsupported reloc %u\n"), program_name, relinfo->location(relnum, rel.get_r_offset()).c_str(), r_type); @@ -1311,7 +1357,7 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, break; case elfcpp::R_386_TLS_GD: - if (opt_r_type == elfcpp::R_386_TLS_LE_32) + if (optimized_type == tls::TLSOPT_TO_LE) { this->tls_gd_to_le(relinfo, relnum, tls_segment, rel, r_type, value, view, @@ -1335,7 +1381,7 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, gold_exit(false); } this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU; - if (opt_r_type == elfcpp::R_386_TLS_LE_32) + if (optimized_type == tls::TLSOPT_TO_LE) { this->tls_ld_to_le(relinfo, relnum, tls_segment, rel, r_type, value, view, view_size); @@ -1352,7 +1398,7 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, // This reloc can appear in debugging sections, in which case we // won't see the TLS_LDM reloc. The local_dynamic_type field // tells us this. - if (opt_r_type == elfcpp::R_386_TLS_LDO_32 + if (optimized_type != tls::TLSOPT_TO_LE || this->local_dynamic_type_ == LOCAL_DYNAMIC_NONE) value = value - tls_segment->vaddr(); else if (this->local_dynamic_type_ == LOCAL_DYNAMIC_GNU) @@ -1394,8 +1440,8 @@ Target_i386::Relocate::tls_ie_to_le(const Relocate_info<32, false>* relinfo, // movl %gs:XX,%eax ==> movl $YY,%eax // movl %gs:XX,%reg ==> movl $YY,%reg // addl %gs:XX,%reg ==> addl $YY,%reg - Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, -1); - Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, 4); + tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -1); + tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4); unsigned char op1 = view[-1]; if (op1 == 0xa1) @@ -1405,28 +1451,27 @@ Target_i386::Relocate::tls_ie_to_le(const Relocate_info<32, false>* relinfo, } else { - Target_i386::Relocate::check_range(relinfo, relnum, rel, - view_size, -2); + tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2); unsigned char op2 = view[-2]; if (op2 == 0x8b) { // movl XX,%reg ==> movl $YY,%reg - Target_i386::Relocate::check_tls(relinfo, relnum, rel, - (op1 & 0xc7) == 0x05); + tls::check_tls(relinfo, relnum, rel.get_r_offset(), + (op1 & 0xc7) == 0x05); view[-2] = 0xc7; view[-1] = 0xc0 | ((op1 >> 3) & 7); } else if (op2 == 0x03) { // addl XX,%reg ==> addl $YY,%reg - Target_i386::Relocate::check_tls(relinfo, relnum, rel, - (op1 & 0xc7) == 0x05); + tls::check_tls(relinfo, relnum, rel.get_r_offset(), + (op1 & 0xc7) == 0x05); view[-2] = 0x81; view[-1] = 0xc0 | ((op1 >> 3) & 7); } else - Target_i386::Relocate::check_tls(relinfo, relnum, rel, 0); + tls::check_tls(relinfo, relnum, rel.get_r_offset(), 0); } } else @@ -1434,13 +1479,13 @@ Target_i386::Relocate::tls_ie_to_le(const Relocate_info<32, false>* relinfo, // subl %gs:XX(%reg1),%reg2 ==> subl $YY,%reg2 // movl %gs:XX(%reg1),%reg2 ==> movl $YY,%reg2 // addl %gs:XX(%reg1),%reg2 ==> addl $YY,$reg2 - Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, -2); - Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, 4); + tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2); + tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4); unsigned char op1 = view[-1]; unsigned char op2 = view[-2]; - Target_i386::Relocate::check_tls(relinfo, relnum, rel, - (op1 & 0xc0) == 0x80 && (op1 & 7) != 4); + tls::check_tls(relinfo, relnum, rel.get_r_offset(), + (op1 & 0xc0) == 0x80 && (op1 & 7) != 4); if (op2 == 0x8b) { // movl %gs:XX(%reg1),%reg2 ==> movl $YY,%reg2 @@ -1460,7 +1505,7 @@ Target_i386::Relocate::tls_ie_to_le(const Relocate_info<32, false>* relinfo, view[-1] = 0xc0 | ((op1 >> 3) & 7); } else - Target_i386::Relocate::check_tls(relinfo, relnum, rel, 0); + tls::check_tls(relinfo, relnum, rel.get_r_offset(), 0); } value = tls_segment->vaddr() + tls_segment->memsz() - value; @@ -1488,33 +1533,30 @@ Target_i386::Relocate::tls_gd_to_le(const Relocate_info<32, false>* relinfo, // leal foo(%reg),%eax; call ___tls_get_addr // ==> movl %gs:0,%eax; subl $foo@tpoff,%eax - Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, -2); - Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, 9); + tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2); + tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 9); unsigned char op1 = view[-1]; unsigned char op2 = view[-2]; - Target_i386::Relocate::check_tls(relinfo, relnum, rel, - op2 == 0x8d || op2 == 0x04); - Target_i386::Relocate::check_tls(relinfo, relnum, rel, - view[4] == 0xe8); + tls::check_tls(relinfo, relnum, rel.get_r_offset(), + op2 == 0x8d || op2 == 0x04); + tls::check_tls(relinfo, relnum, rel.get_r_offset(), view[4] == 0xe8); int roff = 5; if (op2 == 0x04) { - Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, -3); - Target_i386::Relocate::check_tls(relinfo, relnum, rel, - view[-3] == 0x8d); - Target_i386::Relocate::check_tls(relinfo, relnum, rel, - ((op1 & 0xc7) == 0x05 - && op1 != (4 << 3))); + tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -3); + tls::check_tls(relinfo, relnum, rel.get_r_offset(), view[-3] == 0x8d); + tls::check_tls(relinfo, relnum, rel.get_r_offset(), + ((op1 & 0xc7) == 0x05 && op1 != (4 << 3))); memcpy(view - 3, "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12); } else { - Target_i386::Relocate::check_tls(relinfo, relnum, rel, - (op1 & 0xf8) == 0x80 && (op1 & 7) != 4); + tls::check_tls(relinfo, relnum, rel.get_r_offset(), + (op1 & 0xf8) == 0x80 && (op1 & 7) != 4); if (static_cast<off_t>(rel.get_r_offset() + 9) < view_size && view[9] == 0x90) { @@ -1553,15 +1595,14 @@ Target_i386::Relocate::tls_ld_to_le(const Relocate_info<32, false>* relinfo, // leal foo(%reg), %eax; call ___tls_get_addr // ==> movl %gs:0,%eax; nop; leal 0(%esi,1),%esi - Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, -2); - Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, 9); + tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2); + tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 9); // FIXME: Does this test really always pass? - Target_i386::Relocate::check_tls(relinfo, relnum, rel, - view[-2] == 0x8d && view[-1] == 0x83); + tls::check_tls(relinfo, relnum, rel.get_r_offset(), + view[-2] == 0x8d && view[-1] == 0x83); - Target_i386::Relocate::check_tls(relinfo, relnum, rel, - view[4] == 0xe8); + tls::check_tls(relinfo, relnum, rel.get_r_offset(), view[4] == 0xe8); memcpy(view - 2, "\x65\xa1\0\0\0\0\x90\x8d\x74\x26\0", 11); @@ -1570,42 +1611,6 @@ Target_i386::Relocate::tls_ld_to_le(const Relocate_info<32, false>* relinfo, this->skip_call_tls_get_addr_ = true; } -// Check the range for a TLS relocation. - -inline void -Target_i386::Relocate::check_range(const Relocate_info<32, false>* relinfo, - size_t relnum, - const elfcpp::Rel<32, false>& rel, - off_t view_size, off_t off) -{ - off_t offset = rel.get_r_offset() + off; - if (offset < 0 || offset > view_size) - { - fprintf(stderr, _("%s: %s: TLS relocation out of range\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str()); - gold_exit(false); - } -} - -// Check the validity of a TLS relocation. This is like assert. - -inline void -Target_i386::Relocate::check_tls(const Relocate_info<32, false>* relinfo, - size_t relnum, - const elfcpp::Rel<32, false>& rel, - bool valid) -{ - if (!valid) - { - fprintf(stderr, - _("%s: %s: TLS relocation against invalid instruction\n"), - program_name, - relinfo->location(relnum, rel.get_r_offset()).c_str()); - gold_exit(false); - } -} - // Relocate section data. void diff --git a/gold/po/POTFILES.in b/gold/po/POTFILES.in index 9628afa..a65d3a5 100644 --- a/gold/po/POTFILES.in +++ b/gold/po/POTFILES.in @@ -46,6 +46,7 @@ target.h target-reloc.h target-select.cc target-select.h +tls.h version.cc workqueue.cc workqueue.h diff --git a/gold/po/gold.pot b/gold/po/gold.pot index cf5aea9..20bada8 100644 --- a/gold/po/gold.pot +++ b/gold/po/gold.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-10-07 11:04-0700\n" +"POT-Creation-Date: 2007-10-07 22:11-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -270,68 +270,53 @@ msgid "pthread_cond_signal failed" msgstr "" #. FIXME: This needs to specify the location somehow. -#: i386.cc:131 x86_64.cc:146 +#: i386.cc:139 x86_64.cc:146 #, c-format msgid "%s: missing expected TLS relocation\n" msgstr "" -#: i386.cc:775 i386.cc:942 i386.cc:1210 x86_64.cc:737 x86_64.cc:898 -#: x86_64.cc:1215 +#: i386.cc:727 x86_64.cc:766 x86_64.cc:782 #, c-format -msgid "%s: %s: unexpected reloc %u in object file\n" +msgid "%s: %s: unsupported reloc %u against local symbol\n" msgstr "" -#: i386.cc:816 i386.cc:836 x86_64.cc:766 x86_64.cc:782 +#: i386.cc:781 i386.cc:975 i386.cc:1256 x86_64.cc:737 x86_64.cc:898 +#: x86_64.cc:1215 #, c-format -msgid "%s: %s: unsupported reloc %u against local symbol\n" +msgid "%s: %s: unexpected reloc %u in object file\n" msgstr "" -#: i386.cc:982 i386.cc:1003 x86_64.cc:927 x86_64.cc:940 +#: i386.cc:871 x86_64.cc:927 x86_64.cc:940 #, c-format msgid "%s: %s: unsupported reloc %u against global symbol %s\n" msgstr "" -#: i386.cc:1026 +#: i386.cc:1072 #, c-format msgid "%s: %s: unsupported RELA reloc section\n" msgstr "" -#: i386.cc:1116 x86_64.cc:1053 +#: i386.cc:1162 x86_64.cc:1053 #, c-format msgid "%s: %s: missing expected TLS relocation\n" msgstr "" -#: i386.cc:1244 i386.cc:1321 i386.cc:1344 i386.cc:1367 x86_64.cc:1237 -#: x86_64.cc:1307 x86_64.cc:1315 +#: i386.cc:1290 i386.cc:1352 i386.cc:1367 i386.cc:1390 i386.cc:1413 +#: x86_64.cc:1237 x86_64.cc:1307 x86_64.cc:1315 #, c-format msgid "%s: %s: unsupported reloc %u\n" msgstr "" -#: i386.cc:1271 x86_64.cc:1264 +#: i386.cc:1317 x86_64.cc:1264 #, c-format msgid "%s: %s: TLS reloc but no TLS segment\n" msgstr "" -#: i386.cc:1306 x86_64.cc:1292 -#, c-format -msgid "%s: %s: unsupported reloc type %u\n" -msgstr "" - -#: i386.cc:1332 +#: i386.cc:1378 #, c-format msgid "%s: %s: both SUN and GNU model TLS relocations\n" msgstr "" -#: i386.cc:1584 x86_64.cc:1463 -#, c-format -msgid "%s: %s: TLS relocation out of range\n" -msgstr "" - -#: i386.cc:1602 x86_64.cc:1481 -#, c-format -msgid "%s: %s: TLS relocation against invalid instruction\n" -msgstr "" - #: merge.cc:247 #, c-format msgid "" @@ -751,6 +736,16 @@ msgstr "" msgid "%s: %s: undefined reference to '%s'\n" msgstr "" +#: tls.h:58 x86_64.cc:1463 +#, c-format +msgid "%s: %s: TLS relocation out of range\n" +msgstr "" + +#: tls.h:77 x86_64.cc:1481 +#, c-format +msgid "%s: %s: TLS relocation against invalid instruction\n" +msgstr "" + #. This output is intended to follow the GNU standards. #: version.cc:50 #, c-format @@ -770,3 +765,8 @@ msgstr "" #, c-format msgid "%s: %s: unsupported REL reloc section\n" msgstr "" + +#: x86_64.cc:1292 +#, c-format +msgid "%s: %s: unsupported reloc type %u\n" +msgstr "" diff --git a/gold/tls.h b/gold/tls.h new file mode 100644 index 0000000..9324701c --- /dev/null +++ b/gold/tls.h @@ -0,0 +1,89 @@ +// tls.h -- Thread-Local Storage utility routines for gold -*- C++ -*- + +// Copyright 2006, 2007 Free Software Foundation, Inc. +// Written by Ian Lance Taylor <iant@google.com>. + +// This file is part of gold. + +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +// MA 02110-1301, USA. + +#ifndef GOLD_TLS_H +#define GOLD_TLS_H + +#include "elfcpp.h" +#include "reloc.h" + +namespace gold +{ + +namespace tls +{ + +// This is used for relocations that can be converted to a different, +// more efficient type of relocation. + +enum Tls_optimization +{ + TLSOPT_NONE, // Can not convert this relocation to a more efficient one. + TLSOPT_TO_LD, // Can convert General Dynamic to Local Dynamic. + TLSOPT_TO_LE, // Can convert GD or LD to Local-Exec. + TLSOPT_TO_IE, // Can convert GD or LD or LE to Initial-Exec. +}; + +// Check the range for a TLS relocation. This is inlined for efficiency. + +template<int size, bool big_endian> +inline void +check_range(const Relocate_info<size, big_endian>* relinfo, + size_t relnum, + typename elfcpp::Elf_types<size>::Elf_Addr rel_offset, + off_t view_size, off_t off) +{ + off_t offset = rel_offset + off; + if (offset < 0 || offset > view_size) + { + fprintf(stderr, _("%s: %s: TLS relocation out of range\n"), + program_name, + relinfo->location(relnum, rel_offset).c_str()); + gold_exit(false); + } +} + +// Check the validity of a TLS relocation. This is like assert. + +template<int size, bool big_endian> +inline void +check_tls(const Relocate_info<size, big_endian>* relinfo, + size_t relnum, + typename elfcpp::Elf_types<size>::Elf_Addr rel_offset, + bool valid) +{ + if (!valid) + { + fprintf(stderr, + _("%s: %s: TLS relocation against invalid instruction\n"), + program_name, + relinfo->location(relnum, rel_offset).c_str()); + gold_exit(false); + } +} + + +} // End namespace tls. + +} // End namespace gold. + +#endif // !defined(GOLD_TLS_H) |