aboutsummaryrefslogtreecommitdiff
path: root/gold/arm.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gold/arm.cc')
-rw-r--r--gold/arm.cc230
1 files changed, 3 insertions, 227 deletions
diff --git a/gold/arm.cc b/gold/arm.cc
index 7d80d85..82782a6 100644
--- a/gold/arm.cc
+++ b/gold/arm.cc
@@ -51,7 +51,6 @@
#include "gc.h"
#include "attributes.h"
#include "arm-reloc-property.h"
-#include "nacl.h"
namespace
{
@@ -12865,8 +12864,7 @@ Target_arm<big_endian>::apply_cortex_a8_workaround(
elfcpp::Swap<16, big_endian>::writeval(wv + 1, lower_insn);
}
-// Target selector for ARM. Note this is never instantiated directly.
-// It's only used in Target_selector_arm_nacl, below.
+// Target selector for ARM.
template<bool big_endian>
class Target_selector_arm : public Target_selector
@@ -13002,229 +13000,7 @@ Target_arm<big_endian>::do_define_standard_symbols(
}
}
-// NaCl variant. It uses different PLT contents.
-
-template<bool big_endian>
-class Output_data_plt_arm_nacl;
-
-template<bool big_endian>
-class Target_arm_nacl : public Target_arm<big_endian>
-{
- public:
- Target_arm_nacl()
- : Target_arm<big_endian>(&arm_nacl_info)
- { }
-
- protected:
- virtual Output_data_plt_arm<big_endian>*
- do_make_data_plt(
- Layout* layout,
- Arm_output_data_got<big_endian>* got,
- Output_data_space* got_plt,
- Output_data_space* got_irelative)
- { return new Output_data_plt_arm_nacl<big_endian>(
- layout, got, got_plt, got_irelative); }
-
- private:
- static const Target::Target_info arm_nacl_info;
-};
-
-template<bool big_endian>
-const Target::Target_info Target_arm_nacl<big_endian>::arm_nacl_info =
-{
- 32, // size
- big_endian, // is_big_endian
- elfcpp::EM_ARM, // machine_code
- false, // has_make_symbol
- false, // has_resolve
- false, // has_code_fill
- true, // is_default_stack_executable
- false, // can_icf_inline_merge_sections
- '\0', // wrap_char
- "/lib/ld-nacl-arm.so.1", // dynamic_linker
- 0x20000, // default_text_segment_address
- 0x10000, // abi_pagesize (overridable by -z max-page-size)
- 0x10000, // common_pagesize (overridable by -z common-page-size)
- true, // isolate_execinstr
- 0x10000000, // rosegment_gap
- elfcpp::SHN_UNDEF, // small_common_shndx
- elfcpp::SHN_UNDEF, // large_common_shndx
- 0, // small_common_section_flags
- 0, // large_common_section_flags
- ".ARM.attributes", // attributes_section
- "aeabi", // attributes_vendor
- "_start", // entry_symbol_name
- 32, // hash_entry_size
- elfcpp::SHT_PROGBITS, // unwind_section_type
-};
-
-template<bool big_endian>
-class Output_data_plt_arm_nacl : public Output_data_plt_arm<big_endian>
-{
- public:
- Output_data_plt_arm_nacl(
- Layout* layout,
- Arm_output_data_got<big_endian>* got,
- Output_data_space* got_plt,
- Output_data_space* got_irelative)
- : Output_data_plt_arm<big_endian>(layout, 16, got, got_plt, got_irelative)
- { }
-
- protected:
- // Return the offset of the first non-reserved PLT entry.
- virtual unsigned int
- do_first_plt_entry_offset() const
- { return sizeof(first_plt_entry); }
-
- // Return the size of a PLT entry.
- virtual unsigned int
- do_get_plt_entry_size() const
- { return sizeof(plt_entry); }
-
- virtual void
- do_fill_first_plt_entry(unsigned char* pov,
- Arm_address got_address,
- Arm_address plt_address);
-
- virtual void
- do_fill_plt_entry(unsigned char* pov,
- Arm_address got_address,
- Arm_address plt_address,
- unsigned int got_offset,
- unsigned int plt_offset);
-
- private:
- inline uint32_t arm_movw_immediate(uint32_t value)
- {
- return (value & 0x00000fff) | ((value & 0x0000f000) << 4);
- }
-
- inline uint32_t arm_movt_immediate(uint32_t value)
- {
- return ((value & 0x0fff0000) >> 16) | ((value & 0xf0000000) >> 12);
- }
-
- // Template for the first PLT entry.
- static const uint32_t first_plt_entry[16];
-
- // Template for subsequent PLT entries.
- static const uint32_t plt_entry[4];
-};
-
-// The first entry in the PLT.
-template<bool big_endian>
-const uint32_t Output_data_plt_arm_nacl<big_endian>::first_plt_entry[16] =
-{
- // First bundle:
- 0xe300c000, // movw ip, #:lower16:&GOT[2]-.+8
- 0xe340c000, // movt ip, #:upper16:&GOT[2]-.+8
- 0xe08cc00f, // add ip, ip, pc
- 0xe52dc008, // str ip, [sp, #-8]!
- // Second bundle:
- 0xe3ccc103, // bic ip, ip, #0xc0000000
- 0xe59cc000, // ldr ip, [ip]
- 0xe3ccc13f, // bic ip, ip, #0xc000000f
- 0xe12fff1c, // bx ip
- // Third bundle:
- 0xe320f000, // nop
- 0xe320f000, // nop
- 0xe320f000, // nop
- // .Lplt_tail:
- 0xe50dc004, // str ip, [sp, #-4]
- // Fourth bundle:
- 0xe3ccc103, // bic ip, ip, #0xc0000000
- 0xe59cc000, // ldr ip, [ip]
- 0xe3ccc13f, // bic ip, ip, #0xc000000f
- 0xe12fff1c, // bx ip
-};
-
-template<bool big_endian>
-void
-Output_data_plt_arm_nacl<big_endian>::do_fill_first_plt_entry(
- unsigned char* pov,
- Arm_address got_address,
- Arm_address plt_address)
-{
- // Write first PLT entry. All but first two words are constants.
- const size_t num_first_plt_words = (sizeof(first_plt_entry)
- / sizeof(first_plt_entry[0]));
-
- int32_t got_displacement = got_address + 8 - (plt_address + 16);
-
- elfcpp::Swap<32, big_endian>::writeval
- (pov + 0, first_plt_entry[0] | arm_movw_immediate (got_displacement));
- elfcpp::Swap<32, big_endian>::writeval
- (pov + 4, first_plt_entry[1] | arm_movt_immediate (got_displacement));
-
- for (size_t i = 2; i < num_first_plt_words; ++i)
- elfcpp::Swap<32, big_endian>::writeval(pov + i * 4, first_plt_entry[i]);
-}
-
-// Subsequent entries in the PLT.
-
-template<bool big_endian>
-const uint32_t Output_data_plt_arm_nacl<big_endian>::plt_entry[4] =
-{
- 0xe300c000, // movw ip, #:lower16:&GOT[n]-.+8
- 0xe340c000, // movt ip, #:upper16:&GOT[n]-.+8
- 0xe08cc00f, // add ip, ip, pc
- 0xea000000, // b .Lplt_tail
-};
-
-template<bool big_endian>
-void
-Output_data_plt_arm_nacl<big_endian>::do_fill_plt_entry(
- unsigned char* pov,
- Arm_address got_address,
- Arm_address plt_address,
- unsigned int got_offset,
- unsigned int plt_offset)
-{
- // Calculate the displacement between the PLT slot and the
- // common tail that's part of the special initial PLT slot.
- int32_t tail_displacement = (plt_address + (11 * sizeof(uint32_t))
- - (plt_address + plt_offset
- + sizeof(plt_entry) + sizeof(uint32_t)));
- gold_assert((tail_displacement & 3) == 0);
- tail_displacement >>= 2;
-
- gold_assert ((tail_displacement & 0xff000000) == 0
- || (-tail_displacement & 0xff000000) == 0);
-
- // Calculate the displacement between the PLT slot and the entry
- // in the GOT. The offset accounts for the value produced by
- // adding to pc in the penultimate instruction of the PLT stub.
- const int32_t got_displacement = (got_address + got_offset
- - (plt_address + sizeof(plt_entry)));
-
- elfcpp::Swap<32, big_endian>::writeval
- (pov + 0, plt_entry[0] | arm_movw_immediate (got_displacement));
- elfcpp::Swap<32, big_endian>::writeval
- (pov + 4, plt_entry[1] | arm_movt_immediate (got_displacement));
- elfcpp::Swap<32, big_endian>::writeval
- (pov + 8, plt_entry[2]);
- elfcpp::Swap<32, big_endian>::writeval
- (pov + 12, plt_entry[3] | (tail_displacement & 0x00ffffff));
-}
-
-// Target selectors.
-
-template<bool big_endian>
-class Target_selector_arm_nacl
- : public Target_selector_nacl<Target_selector_arm<big_endian>,
- Target_arm_nacl<big_endian> >
-{
- public:
- Target_selector_arm_nacl()
- : Target_selector_nacl<Target_selector_arm<big_endian>,
- Target_arm_nacl<big_endian> >(
- "arm",
- big_endian ? "elf32-bigarm-nacl" : "elf32-littlearm-nacl",
- big_endian ? "armelfb_nacl" : "armelf_nacl")
- { }
-};
-
-Target_selector_arm_nacl<false> target_selector_arm;
-Target_selector_arm_nacl<true> target_selector_armbe;
+Target_selector_arm<false> target_selector_arm;
+Target_selector_arm<true> target_selector_armbe;
} // End anonymous namespace.