[GOLD][PATCH] Handle 32-bit initial TLS relocations for ARM target.
Doug Kwan (關振德)
dougkwan@google.com
Wed Feb 17 19:34:00 GMT 2010
Hi,
This patch adds some support for initial TLS relocations for the
ARM target. It is required for running the gold test suite on an ARM
system running Ubuntu. It is not yet complete. There are known
issues:
-TLS relocations in static output objects do not work.
-12-bit TLS relocations not supported.
-TLS optimization not supported.
-Additional TLS relocations defined in
http://www.lsd.ic.unicamp.br/~oliva/writeups/TLS/RFC-TLSDESC-ARM.txt
not supported.
These will be fixed or implemented later. This patch allows most of
the tests in the test suite to build.
-Doug
2010-02-18 Doug Kwan <dougkwan@google.com>
* arm-reloc.def: Mark R_ARM_TLS_GD32, R_ARM_TLS_LDM32,
R_ARM_TLS_LDO32, R_ARM_TLS_IE32 and R_ARM_TLS_LE32 are implemented.
* arm.cc (Arm_relocation_functions): New forward declaration.
(Target_arm::Target_arm): Initialize new data members
got_mod_index_offset_ and tls_base_symbol_defined_.
(Target_arm::Relocate::relocate_tls): New method.
(Target_arm::optimize_tls_reloc, Target_arm::define_tls_base_symbol,
Target_arm::got_mod_index_entry, Target_arm::rel_tls_desc_section):
New methods.
(Target_arm::Got_type): Add GOT_TYPE_TLS_NOFFSET, GOT_TYPE_OFFSET,
GOT_TYPE_TLS_PAIR and GOT_TYPE_TLS_DESC.
(Target_arm::got_mod_index_offset_,
Target_arm::tls_base_symbol_defined_): New data members.
(Target_arm::Scan::local, Target::Scan::global,
Target_arm::Relocate::relocate): Handle 32-bit initial TLS
relocations.
-------------- next part --------------
Index: gold/arm.cc
===================================================================
RCS file: /cvs/src/src/gold/arm.cc,v
retrieving revision 1.81
diff -u -u -p -r1.81 arm.cc
--- gold/arm.cc 13 Feb 2010 02:04:20 -0000 1.81
+++ gold/arm.cc 17 Feb 2010 00:32:49 -0000
@@ -2437,7 +2437,11 @@ class Target_arm : public Sized_target<3
// The types of GOT entries needed for this platform.
enum Got_type
{
- GOT_TYPE_STANDARD = 0 // GOT entry for a regular symbol
+ GOT_TYPE_STANDARD = 0, // GOT entry for a regular symbol
+ GOT_TYPE_TLS_NOFFSET = 1, // GOT entry for negative TLS offset
+ GOT_TYPE_TLS_OFFSET = 2, // GOT entry for positive TLS offset
+ GOT_TYPE_TLS_PAIR = 3, // GOT entry for TLS module/offset pair
+ GOT_TYPE_TLS_DESC = 4 // GOT entry for TLS_DESC pair
};
typedef typename std::vector<Stub_table<big_endian>*> Stub_table_list;
@@ -6755,6 +6759,19 @@ Target_arm<big_endian>::Scan::local(Symb
}
break;
+ case elfcpp::R_ARM_TLS_IE32:
+ {
+ layout->set_has_static_tls();
+ // Create a GOT entry for the tp-relative offset.
+ Output_data_got<32, big_endian>* got =
+ target->got_section(symtab, layout);
+ unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
+ got->add_local_with_rel(object, r_sym, GOT_TYPE_TLS_OFFSET,
+ target->rel_dyn_section(layout),
+ elfcpp::R_ARM_TLS_TPOFF32);
+ }
+ break;
+
case elfcpp::R_ARM_TARGET1:
case elfcpp::R_ARM_TARGET2:
// This should have been mapped to another type already.
@@ -7004,6 +7021,18 @@ Target_arm<big_endian>::Scan::global(Sym
}
break;
+ case elfcpp::R_ARM_TLS_IE32:
+ {
+ layout->set_has_static_tls();
+ // Create a GOT entry for the tp-relative offset.
+ Output_data_got<32, big_endian>* got
+ = target->got_section(symtab, layout);
+ got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
+ target->rel_dyn_section(layout),
+ elfcpp::R_ARM_TLS_TPOFF32);
+ }
+ break;
+
case elfcpp::R_ARM_TARGET1:
case elfcpp::R_ARM_TARGET2:
// These should have been mapped to other types already.
@@ -7720,6 +7749,29 @@ Target_arm<big_endian>::Relocate::reloca
relative_address_base);
break;
+ case elfcpp::R_ARM_TLS_IE32:
+ {
+ // Relocate the field with the offset of the GOT entry for
+ // the tp-relative offset of the symbol.
+ const unsigned int got_type = GOT_TYPE_TLS_OFFSET;
+ unsigned int got_offset;
+ if (gsym != NULL)
+ {
+ gold_assert(gsym->has_got_offset(got_type));
+ got_offset = gsym->got_offset(got_type);
+ }
+ else
+ {
+ unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
+ gold_assert(object->local_has_got_offset(r_sym, got_type));
+ got_offset = object->local_got_offset(r_sym, got_type);
+ }
+ // All GOT offsets are relative to the end of the GOT.
+ got_offset -= target->got_size();
+ Relocate_functions<32, false>::rel32(view, got_offset);
+ }
+ break;
+
default:
gold_unreachable();
}
More information about the Binutils
mailing list