diff options
Diffstat (limited to 'gold')
-rw-r--r-- | gold/Makefile.am | 2 | ||||
-rw-r--r-- | gold/Makefile.in | 18 | ||||
-rw-r--r-- | gold/aarch64.cc | 1 | ||||
-rw-r--r-- | gold/aclocal.m4 | 29 | ||||
-rw-r--r-- | gold/arm.cc | 230 | ||||
-rwxr-xr-x | gold/configure | 1 | ||||
-rw-r--r-- | gold/configure.ac | 5 | ||||
-rw-r--r-- | gold/i386.cc | 342 | ||||
-rw-r--r-- | gold/mips.cc | 67 | ||||
-rw-r--r-- | gold/nacl.cc | 47 | ||||
-rw-r--r-- | gold/nacl.h | 243 | ||||
-rw-r--r-- | gold/po/POTFILES.in | 2 | ||||
-rw-r--r-- | gold/x86_64.cc | 379 |
13 files changed, 24 insertions, 1342 deletions
diff --git a/gold/Makefile.am b/gold/Makefile.am index 8607d3c..e756fcc 100644 --- a/gold/Makefile.am +++ b/gold/Makefile.am @@ -89,7 +89,6 @@ CCFILES = \ layout.cc \ mapfile.cc \ merge.cc \ - nacl.cc \ object.cc \ options.cc \ output.cc \ @@ -138,7 +137,6 @@ HFILES = \ layout.h \ mapfile.h \ merge.h \ - nacl.h \ object.h \ options.h \ output.h \ diff --git a/gold/Makefile.in b/gold/Makefile.in index 02df538..e8146c8 100644 --- a/gold/Makefile.in +++ b/gold/Makefile.in @@ -173,14 +173,13 @@ am__objects_1 = archive.$(OBJEXT) attributes.$(OBJEXT) \ gdb-index.$(OBJEXT) gold.$(OBJEXT) gold-threads.$(OBJEXT) \ icf.$(OBJEXT) incremental.$(OBJEXT) int_encoding.$(OBJEXT) \ layout.$(OBJEXT) mapfile.$(OBJEXT) merge.$(OBJEXT) \ - nacl.$(OBJEXT) object.$(OBJEXT) options.$(OBJEXT) \ - output.$(OBJEXT) parameters.$(OBJEXT) plugin.$(OBJEXT) \ - readsyms.$(OBJEXT) reduced_debug_output.$(OBJEXT) \ - reloc.$(OBJEXT) resolve.$(OBJEXT) script-sections.$(OBJEXT) \ - script.$(OBJEXT) stringpool.$(OBJEXT) symtab.$(OBJEXT) \ - target.$(OBJEXT) target-select.$(OBJEXT) timer.$(OBJEXT) \ - version.$(OBJEXT) workqueue.$(OBJEXT) \ - workqueue-threads.$(OBJEXT) + object.$(OBJEXT) options.$(OBJEXT) output.$(OBJEXT) \ + parameters.$(OBJEXT) plugin.$(OBJEXT) readsyms.$(OBJEXT) \ + reduced_debug_output.$(OBJEXT) reloc.$(OBJEXT) \ + resolve.$(OBJEXT) script-sections.$(OBJEXT) script.$(OBJEXT) \ + stringpool.$(OBJEXT) symtab.$(OBJEXT) target.$(OBJEXT) \ + target-select.$(OBJEXT) timer.$(OBJEXT) version.$(OBJEXT) \ + workqueue.$(OBJEXT) workqueue-threads.$(OBJEXT) am__objects_2 = am__objects_3 = yyscript.$(OBJEXT) am_libgold_a_OBJECTS = $(am__objects_1) $(am__objects_2) \ @@ -736,7 +735,6 @@ CCFILES = \ layout.cc \ mapfile.cc \ merge.cc \ - nacl.cc \ object.cc \ options.cc \ output.cc \ @@ -785,7 +783,6 @@ HFILES = \ layout.h \ mapfile.h \ merge.h \ - nacl.h \ object.h \ options.h \ output.h \ @@ -1113,7 +1110,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mapfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/merge.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mips.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nacl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/output.Po@am__quote@ diff --git a/gold/aarch64.cc b/gold/aarch64.cc index fb29a09..0976292 100644 --- a/gold/aarch64.cc +++ b/gold/aarch64.cc @@ -41,7 +41,6 @@ #include "target-select.h" #include "tls.h" #include "freebsd.h" -#include "nacl.h" #include "gc.h" #include "icf.h" #include "aarch64-reloc-property.h" diff --git a/gold/aclocal.m4 b/gold/aclocal.m4 index d0455aa..a8512a2 100644 --- a/gold/aclocal.m4 +++ b/gold/aclocal.m4 @@ -751,35 +751,6 @@ else fi ]) -# -*- Autoconf -*- -# Obsolete and "removed" macros, that must however still report explicit -# error messages when used, to smooth transition. -# -# Copyright (C) 1996-2017 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -AC_DEFUN([AM_CONFIG_HEADER], -[AC_DIAGNOSE([obsolete], -['$0': this macro is obsolete. -You should use the 'AC][_CONFIG_HEADERS' macro instead.])dnl -AC_CONFIG_HEADERS($@)]) - -AC_DEFUN([AM_PROG_CC_STDC], -[AC_PROG_CC -am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc -AC_DIAGNOSE([obsolete], -['$0': this macro is obsolete. -You should simply use the 'AC][_PROG_CC' macro instead. -Also, your code should no longer depend upon 'am_cv_prog_cc_stdc', -but upon 'ac_cv_prog_cc_stdc'.])]) - -AC_DEFUN([AM_C_PROTOTYPES], - [AC_FATAL([automatic de-ANSI-fication support has been removed])]) -AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES]) - # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. 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. diff --git a/gold/configure b/gold/configure index f4cb3f8..a81a04f 100755 --- a/gold/configure +++ b/gold/configure @@ -13590,6 +13590,7 @@ DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= +U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' diff --git a/gold/configure.ac b/gold/configure.ac index 90e51de..597788d 100644 --- a/gold/configure.ac +++ b/gold/configure.ac @@ -25,7 +25,7 @@ AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([no-dist parallel-tests]) AM_SILENT_RULES([yes]) -AM_CONFIG_HEADER(config.h:config.in) +AC_CONFIG_HEADERS([config.h:config.in]) AC_USE_SYSTEM_EXTENSIONS @@ -737,4 +737,5 @@ AM_LC_MESSAGES AM_MAINTAINER_MODE -AC_OUTPUT(Makefile testsuite/Makefile po/Makefile.in:po/Make-in) +AC_CONFIG_FILES([Makefile testsuite/Makefile po/Makefile.in:po/Make-in]) +AC_OUTPUT diff --git a/gold/i386.cc b/gold/i386.cc index d7d8f87..f9ae4ad 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -39,7 +39,6 @@ #include "target-select.h" #include "tls.h" #include "freebsd.h" -#include "nacl.h" #include "gc.h" namespace @@ -4046,8 +4045,7 @@ Target_i386::do_calls_non_split(Relobj* object, unsigned int shndx, *to = "__morestack_non_split"; } -// The selector for i386 object files. Note this is never instantiated -// directly. It's only used in Target_selector_i386_nacl, below. +// The selector for i386 object files. class Target_selector_i386 : public Target_selector_freebsd { @@ -4063,343 +4061,7 @@ public: { return new Target_i386(); } }; -// NaCl variant. It uses different PLT contents. - -class Output_data_plt_i386_nacl : public Output_data_plt_i386 -{ - public: - Output_data_plt_i386_nacl(Layout* layout, - Output_data_got_plt_i386* got_plt, - Output_data_space* got_irelative) - : Output_data_plt_i386(layout, plt_entry_size, got_plt, got_irelative) - { } - - protected: - virtual unsigned int - do_get_plt_entry_size() const - { return plt_entry_size; } - - virtual void - do_add_eh_frame(Layout* layout) - { - layout->add_eh_frame_for_plt(this, plt_eh_frame_cie, plt_eh_frame_cie_size, - plt_eh_frame_fde, plt_eh_frame_fde_size); - } - - // The size of an entry in the PLT. - static const int plt_entry_size = 64; - - // The .eh_frame unwind information for the PLT. - static const int plt_eh_frame_fde_size = 32; - static const unsigned char plt_eh_frame_fde[plt_eh_frame_fde_size]; -}; - -class Output_data_plt_i386_nacl_exec : public Output_data_plt_i386_nacl -{ -public: - Output_data_plt_i386_nacl_exec(Layout* layout, - Output_data_got_plt_i386* got_plt, - Output_data_space* got_irelative) - : Output_data_plt_i386_nacl(layout, got_plt, got_irelative) - { } - - protected: - virtual void - do_fill_first_plt_entry(unsigned char* pov, - elfcpp::Elf_types<32>::Elf_Addr got_address); - - virtual unsigned int - do_fill_plt_entry(unsigned char* pov, - elfcpp::Elf_types<32>::Elf_Addr got_address, - unsigned int got_offset, - unsigned int plt_offset, - unsigned int plt_rel_offset); - - private: - // The first entry in the PLT for an executable. - static const unsigned char first_plt_entry[plt_entry_size]; - - // Other entries in the PLT for an executable. - static const unsigned char plt_entry[plt_entry_size]; -}; - -class Output_data_plt_i386_nacl_dyn : public Output_data_plt_i386_nacl -{ - public: - Output_data_plt_i386_nacl_dyn(Layout* layout, - Output_data_got_plt_i386* got_plt, - Output_data_space* got_irelative) - : Output_data_plt_i386_nacl(layout, got_plt, got_irelative) - { } - - protected: - virtual void - do_fill_first_plt_entry(unsigned char* pov, elfcpp::Elf_types<32>::Elf_Addr); - - virtual unsigned int - do_fill_plt_entry(unsigned char* pov, - elfcpp::Elf_types<32>::Elf_Addr, - unsigned int got_offset, - unsigned int plt_offset, - unsigned int plt_rel_offset); - - private: - // The first entry in the PLT for a shared object. - static const unsigned char first_plt_entry[plt_entry_size]; - - // Other entries in the PLT for a shared object. - static const unsigned char plt_entry[plt_entry_size]; -}; - -class Target_i386_nacl : public Target_i386 -{ - public: - Target_i386_nacl() - : Target_i386(&i386_nacl_info) - { } - - protected: - virtual Output_data_plt_i386* - do_make_data_plt(Layout* layout, - Output_data_got_plt_i386* got_plt, - Output_data_space* got_irelative, - bool dyn) - { - if (dyn) - return new Output_data_plt_i386_nacl_dyn(layout, got_plt, got_irelative); - else - return new Output_data_plt_i386_nacl_exec(layout, got_plt, got_irelative); - } - - virtual std::string - do_code_fill(section_size_type length) const; - - private: - static const Target::Target_info i386_nacl_info; -}; - -const Target::Target_info Target_i386_nacl::i386_nacl_info = -{ - 32, // size - false, // is_big_endian - elfcpp::EM_386, // machine_code - false, // has_make_symbol - false, // has_resolve - true, // has_code_fill - true, // is_default_stack_executable - true, // can_icf_inline_merge_sections - '\0', // wrap_char - "/lib/ld-nacl-x86-32.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 - NULL, // attributes_section - NULL, // attributes_vendor - "_start", // entry_symbol_name - 32, // hash_entry_size - elfcpp::SHT_PROGBITS, // unwind_section_type -}; - -#define NACLMASK 0xe0 // 32-byte alignment mask - -const unsigned char -Output_data_plt_i386_nacl_exec::first_plt_entry[plt_entry_size] = -{ - 0xff, 0x35, // pushl contents of memory address - 0, 0, 0, 0, // replaced with address of .got + 4 - 0x8b, 0x0d, // movl contents of address, %ecx - 0, 0, 0, 0, // replaced with address of .got + 8 - 0x83, 0xe1, NACLMASK, // andl $NACLMASK, %ecx - 0xff, 0xe1, // jmp *%ecx - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90 -}; - -void -Output_data_plt_i386_nacl_exec::do_fill_first_plt_entry( - unsigned char* pov, - elfcpp::Elf_types<32>::Elf_Addr got_address) -{ - memcpy(pov, first_plt_entry, plt_entry_size); - elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_address + 4); - elfcpp::Swap<32, false>::writeval(pov + 8, got_address + 8); -} - -// The first entry in the PLT for a shared object. - -const unsigned char -Output_data_plt_i386_nacl_dyn::first_plt_entry[plt_entry_size] = -{ - 0xff, 0xb3, 4, 0, 0, 0, // pushl 4(%ebx) - 0x8b, 0x4b, 0x08, // mov 0x8(%ebx), %ecx - 0x83, 0xe1, NACLMASK, // andl $NACLMASK, %ecx - 0xff, 0xe1, // jmp *%ecx - 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90, // nops - 0x90, 0x90, 0x90, 0x90, 0x90 // nops -}; - -void -Output_data_plt_i386_nacl_dyn::do_fill_first_plt_entry( - unsigned char* pov, - elfcpp::Elf_types<32>::Elf_Addr) -{ - memcpy(pov, first_plt_entry, plt_entry_size); -} - -// Subsequent entries in the PLT for an executable. - -const unsigned char -Output_data_plt_i386_nacl_exec::plt_entry[plt_entry_size] = -{ - 0x8b, 0x0d, // movl contents of address, %ecx */ - 0, 0, 0, 0, // replaced with address of symbol in .got - 0x83, 0xe1, NACLMASK, // andl $NACLMASK, %ecx - 0xff, 0xe1, // jmp *%ecx - - // Pad to the next 32-byte boundary with nop instructions. - 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - - // Lazy GOT entries point here (32-byte aligned). - 0x68, // pushl immediate - 0, 0, 0, 0, // replaced with offset into relocation table - 0xe9, // jmp relative - 0, 0, 0, 0, // replaced with offset to start of .plt - - // Pad to the next 32-byte boundary with nop instructions. - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90 -}; - -unsigned int -Output_data_plt_i386_nacl_exec::do_fill_plt_entry( - unsigned char* pov, - elfcpp::Elf_types<32>::Elf_Addr got_address, - unsigned int got_offset, - unsigned int plt_offset, - unsigned int plt_rel_offset) -{ - memcpy(pov, plt_entry, plt_entry_size); - elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, - got_address + got_offset); - elfcpp::Swap_unaligned<32, false>::writeval(pov + 33, plt_rel_offset); - elfcpp::Swap<32, false>::writeval(pov + 38, - (plt_offset + 38 + 4)); - return 32; -} - -// Subsequent entries in the PLT for a shared object. - -const unsigned char -Output_data_plt_i386_nacl_dyn::plt_entry[plt_entry_size] = -{ - 0x8b, 0x8b, // movl offset(%ebx), %ecx - 0, 0, 0, 0, // replaced with offset of symbol in .got - 0x83, 0xe1, 0xe0, // andl $NACLMASK, %ecx - 0xff, 0xe1, // jmp *%ecx - - // Pad to the next 32-byte boundary with nop instructions. - 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - - // Lazy GOT entries point here (32-byte aligned). - 0x68, // pushl immediate - 0, 0, 0, 0, // replaced with offset into relocation table. - 0xe9, // jmp relative - 0, 0, 0, 0, // replaced with offset to start of .plt. - - // Pad to the next 32-byte boundary with nop instructions. - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90 -}; - -unsigned int -Output_data_plt_i386_nacl_dyn::do_fill_plt_entry( - unsigned char* pov, - elfcpp::Elf_types<32>::Elf_Addr, - unsigned int got_offset, - unsigned int plt_offset, - unsigned int plt_rel_offset) -{ - memcpy(pov, plt_entry, plt_entry_size); - elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, got_offset); - elfcpp::Swap_unaligned<32, false>::writeval(pov + 33, plt_rel_offset); - elfcpp::Swap<32, false>::writeval(pov + 38, - (plt_offset + 38 + 4)); - return 32; -} - -const unsigned char -Output_data_plt_i386_nacl::plt_eh_frame_fde[plt_eh_frame_fde_size] = -{ - 0, 0, 0, 0, // Replaced with offset to .plt. - 0, 0, 0, 0, // Replaced with size of .plt. - 0, // Augmentation size. - elfcpp::DW_CFA_def_cfa_offset, 8, // DW_CFA_def_cfa_offset: 8. - elfcpp::DW_CFA_advance_loc + 6, // Advance 6 to __PLT__ + 6. - elfcpp::DW_CFA_def_cfa_offset, 12, // DW_CFA_def_cfa_offset: 12. - elfcpp::DW_CFA_advance_loc + 58, // Advance 58 to __PLT__ + 64. - elfcpp::DW_CFA_def_cfa_expression, // DW_CFA_def_cfa_expression. - 13, // Block length. - elfcpp::DW_OP_breg4, 4, // Push %esp + 4. - elfcpp::DW_OP_breg8, 0, // Push %eip. - elfcpp::DW_OP_const1u, 63, // Push 0x3f. - elfcpp::DW_OP_and, // & (%eip & 0x3f). - elfcpp::DW_OP_const1u, 37, // Push 0x25. - elfcpp::DW_OP_ge, // >= ((%eip & 0x3f) >= 0x25) - elfcpp::DW_OP_lit2, // Push 2. - elfcpp::DW_OP_shl, // << (((%eip & 0x3f) >= 0x25) << 2) - elfcpp::DW_OP_plus, // + ((((%eip&0x3f)>=0x25)<<2)+%esp+4 - elfcpp::DW_CFA_nop, // Align to 32 bytes. - elfcpp::DW_CFA_nop -}; - -// Return a string used to fill a code section with nops. -// For NaCl, long NOPs are only valid if they do not cross -// bundle alignment boundaries, so keep it simple with one-byte NOPs. -std::string -Target_i386_nacl::do_code_fill(section_size_type length) const -{ - return std::string(length, static_cast<char>(0x90)); -} - -// The selector for i386-nacl object files. - -class Target_selector_i386_nacl - : public Target_selector_nacl<Target_selector_i386, Target_i386_nacl> -{ - public: - Target_selector_i386_nacl() - : Target_selector_nacl<Target_selector_i386, - Target_i386_nacl>("x86-32", - "elf32-i386-nacl", - "elf_i386_nacl") - { } -}; - -Target_selector_i386_nacl target_selector_i386; +Target_selector_i386 target_selector_i386; // IAMCU variant. It uses EM_IAMCU, not EM_386. diff --git a/gold/mips.cc b/gold/mips.cc index 38e517a..4f609dc 100644 --- a/gold/mips.cc +++ b/gold/mips.cc @@ -45,7 +45,6 @@ #include "errors.h" #include "gc.h" #include "attributes.h" -#include "nacl.h" namespace { @@ -12664,49 +12663,7 @@ const Target::Target_info Target_mips<size, big_endian>::mips_info = elfcpp::SHT_PROGBITS, // unwind_section_type }; -template<int size, bool big_endian> -class Target_mips_nacl : public Target_mips<size, big_endian> -{ - public: - Target_mips_nacl() - : Target_mips<size, big_endian>(&mips_nacl_info) - { } - - private: - static const Target::Target_info mips_nacl_info; -}; - -template<int size, bool big_endian> -const Target::Target_info Target_mips_nacl<size, big_endian>::mips_nacl_info = -{ - size, // size - big_endian, // is_big_endian - elfcpp::EM_MIPS, // machine_code - true, // 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.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 - NULL, // attributes_section - NULL, // attributes_vendor - "_start", // entry_symbol_name - 32, // hash_entry_size - elfcpp::SHT_PROGBITS, // unwind_section_type -}; - -// Target selector for Mips. Note this is never instantiated directly. -// It's only used in Target_selector_mips_nacl, below. +// Target selector for Mips. template<int size, bool big_endian> class Target_selector_mips : public Target_selector @@ -12726,23 +12683,9 @@ public: { return new Target_mips<size, big_endian>(); } }; -template<int size, bool big_endian> -class Target_selector_mips_nacl - : public Target_selector_nacl<Target_selector_mips<size, big_endian>, - Target_mips_nacl<size, big_endian> > -{ - public: - Target_selector_mips_nacl() - : Target_selector_nacl<Target_selector_mips<size, big_endian>, - Target_mips_nacl<size, big_endian> >( - // NaCl currently supports only MIPS32 little-endian. - "mipsel", "elf32-tradlittlemips-nacl", "elf32-tradlittlemips-nacl") - { } -}; - -Target_selector_mips_nacl<32, true> target_selector_mips32; -Target_selector_mips_nacl<32, false> target_selector_mips32el; -Target_selector_mips_nacl<64, true> target_selector_mips64; -Target_selector_mips_nacl<64, false> target_selector_mips64el; +Target_selector_mips<32, true> target_selector_mips32; +Target_selector_mips<32, false> target_selector_mips32el; +Target_selector_mips<64, true> target_selector_mips64; +Target_selector_mips<64, false> target_selector_mips64el; } // End anonymous namespace. diff --git a/gold/nacl.cc b/gold/nacl.cc deleted file mode 100644 index 60c32df..0000000 --- a/gold/nacl.cc +++ /dev/null @@ -1,47 +0,0 @@ -// nacl.cc -- Native Client support for gold - -// Copyright (C) 2012-2025 Free Software Foundation, Inc. - -// 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. - -#include "gold.h" - -#include <cstdio> -#include "libiberty.h" - -#include "nacl.h" -#include "elfcpp.h" - -namespace gold -{ - -// Copied from object.cc:Object::error. -void -Sniff_file::error(const char* format, ...) const -{ - va_list args; - va_start(args, format); - char* buf = NULL; - if (vasprintf(&buf, format, args) < 0) - gold_nomem(); - va_end(args); - gold_error(_("%s: %s"), this->file_.filename().c_str(), buf); - free(buf); -} - -} // end namespace gold diff --git a/gold/nacl.h b/gold/nacl.h deleted file mode 100644 index 4357500..0000000 --- a/gold/nacl.h +++ /dev/null @@ -1,243 +0,0 @@ -// nacl.h -- Native Client support for gold -*- C++ -*- - -// Copyright (C) 2012-2025 Free Software Foundation, Inc. - -// 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. - -#include "elfcpp_file.h" -#include "fileread.h" -#include "layout.h" -#include "target-select.h" -#include "target.h" - -#ifndef GOLD_NACL_H -#define GOLD_NACL_H - -namespace gold -{ - -class Sniff_file -{ - public: - Sniff_file(Input_file* input_file, off_t offset) - : file_(input_file->file()), offset_(offset) - { } - - class Location - { - public: - Location(off_t file_offset, off_t data_size) - : offset_(file_offset), size_(data_size) - { } - - inline off_t offset() const - { return this->offset_; } - - inline section_size_type size() const - { return this->size_; } - - private: - off_t offset_; - section_size_type size_; - }; - - class View - { - public: - View(File_read& file, off_t file_offset, off_t data_size) - : data_(file.get_view(file_offset, 0, data_size, true, false)) - { } - - const unsigned char* data() - { return this->data_; } - - private: - const unsigned char* data_; - }; - - View view(off_t file_offset, off_t data_size) - { - return View(this->file_, this->offset_ + file_offset, data_size); - } - - View view(Location loc) - { - return this->view(loc.offset(), loc.size()); - } - - // Report an error. - void - error(const char* format, ...) const ATTRIBUTE_PRINTF_2; - - private: - File_read& file_; - off_t offset_; -}; - - -template<class base_selector, class nacl_target> -class Target_selector_nacl : public base_selector -{ - public: - Target_selector_nacl(const char* nacl_abi_name, - const char* bfd_name, const char* emulation) - : base_selector(), is_nacl_(false), nacl_abi_name_(nacl_abi_name), - bfd_name_(bfd_name), emulation_(emulation) - { } - - protected: - virtual Target* - do_instantiate_target() - { - if (this->is_nacl_) - return new nacl_target(); - return this->base_selector::do_instantiate_target(); - } - - virtual Target* - do_recognize(Input_file* file, off_t offset, - int machine, int osabi, int abiversion) - { - this->is_nacl_ = file != NULL && this->recognize_nacl_file(file, offset); - if (this->is_nacl_) - return this->instantiate_target(); - return this->base_selector::do_recognize(file, offset, - machine, osabi, abiversion); - } - - virtual Target* - do_recognize_by_bfd_name(const char* name) - { - gold_assert(this->bfd_name_ != NULL); - this->is_nacl_ = strcmp(name, this->bfd_name_) == 0; - if (this->is_nacl_) - return this->instantiate_target(); - return this->base_selector::do_recognize_by_bfd_name(name); - } - - virtual void - do_supported_bfd_names(std::vector<const char*>* names) - { - gold_assert(this->bfd_name_ != NULL); - this->base_selector::do_supported_bfd_names(names); - names->push_back(this->bfd_name_); - } - - virtual void - do_supported_emulations(std::vector<const char*>* emulations) - { - gold_assert(this->emulation_ != NULL); - this->base_selector::do_supported_emulations(emulations); - emulations->push_back(this->emulation_); - } - - virtual const char* - do_target_bfd_name(const Target* target) - { - return (!this->is_our_target(target) - ? NULL - : (this->is_nacl_ - ? this->bfd_name_ - : base_selector::do_target_bfd_name(target))); - } - - private: - bool - recognize_nacl_file(Input_file* input_file, off_t offset) - { - if (this->is_big_endian()) - { -#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG) -# ifdef HAVE_TARGET_32_BIG - if (this->get_size() == 32) - return do_recognize_nacl_file<32, true>(input_file, offset); -# endif -# ifdef HAVE_TARGET_64_BIG - if (this->get_size() == 64) - return do_recognize_nacl_file<64, true>(input_file, offset); -# endif -#endif - gold_unreachable(); - } - else - { -#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE) -# ifdef HAVE_TARGET_32_LITTLE - if (this->get_size() == 32) - return do_recognize_nacl_file<32, false>(input_file, offset); -# endif -# ifdef HAVE_TARGET_64_LITTLE - if (this->get_size() == 64) - return do_recognize_nacl_file<64, false>(input_file, offset); -# endif -#endif - gold_unreachable(); - } - } - - template<int size, bool big_endian> - bool - do_recognize_nacl_file(Input_file* input_file, off_t offset) - { - Sniff_file file(input_file, offset); - elfcpp::Elf_file<size, big_endian, Sniff_file> elf_file(&file); - const unsigned int shnum = elf_file.shnum(); - for (unsigned int shndx = 1; shndx < shnum; ++shndx) - { - if (elf_file.section_type(shndx) == elfcpp::SHT_NOTE) - { - Sniff_file::Location loc = elf_file.section_contents(shndx); - if (loc.size() < (3 * 4 - + align_address(sizeof "NaCl", 4) - + align_address(nacl_abi_name_.size() + 1, 4))) - continue; - Sniff_file::View view(file.view(loc)); - const unsigned char* note_data = view.data(); - if ((elfcpp::Swap<32, big_endian>::readval(note_data + 0) - == sizeof "NaCl") - && (elfcpp::Swap<32, big_endian>::readval(note_data + 4) - == nacl_abi_name_.size() + 1) - && (elfcpp::Swap<32, big_endian>::readval(note_data + 8) - == elfcpp::NT_VERSION)) - { - const unsigned char* name = note_data + 12; - const unsigned char* desc = (name - + align_address(sizeof "NaCl", 4)); - if (memcmp(name, "NaCl", sizeof "NaCl") == 0 - && memcmp(desc, nacl_abi_name_.c_str(), - nacl_abi_name_.size() + 1) == 0) - return true; - } - } - } - return false; - } - - // Whether we decided this was the NaCl target variant. - bool is_nacl_; - // The string found in the NaCl ABI note. - std::string nacl_abi_name_; - // BFD name of NaCl target, for compatibility. - const char* const bfd_name_; - // GNU linker emulation for this NaCl target, for compatibility. - const char* const emulation_; -}; - -} // end namespace gold - -#endif // !defined(GOLD_NACL_H) diff --git a/gold/po/POTFILES.in b/gold/po/POTFILES.in index 585b79b..b5ec048 100644 --- a/gold/po/POTFILES.in +++ b/gold/po/POTFILES.in @@ -57,8 +57,6 @@ mapfile.h merge.cc merge.h mips.cc -nacl.cc -nacl.h object.cc object.h options.cc diff --git a/gold/x86_64.cc b/gold/x86_64.cc index 5c6157d..f23330e 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -39,7 +39,6 @@ #include "target-select.h" #include "tls.h" #include "freebsd.h" -#include "nacl.h" #include "gc.h" #include "icf.h" @@ -5792,8 +5791,7 @@ Target_x86_64<size>::do_calls_non_split(Relobj* object, unsigned int shndx, *to = "__morestack_non_split"; } -// The selector for x86_64 object files. Note this is never instantiated -// directly. It's only used in Target_selector_x86_64_nacl, below. +// The selector for x86_64 object files. template<int size> class Target_selector_x86_64 : public Target_selector_freebsd @@ -5815,378 +5813,7 @@ public: }; -// NaCl variant. It uses different PLT contents. - -template<int size> -class Output_data_plt_x86_64_nacl : public Output_data_plt_x86_64<size> -{ - public: - Output_data_plt_x86_64_nacl(Layout* layout, - Output_data_got<64, false>* got, - Output_data_got_plt_x86_64* got_plt, - Output_data_space* got_irelative) - : Output_data_plt_x86_64<size>(layout, plt_entry_size, - got, got_plt, got_irelative) - { } - - Output_data_plt_x86_64_nacl(Layout* layout, - Output_data_got<64, false>* got, - Output_data_got_plt_x86_64* got_plt, - Output_data_space* got_irelative, - unsigned int plt_count) - : Output_data_plt_x86_64<size>(layout, plt_entry_size, - got, got_plt, got_irelative, - plt_count) - { } - - protected: - virtual unsigned int - do_get_plt_entry_size() const - { return plt_entry_size; } - - virtual void - do_add_eh_frame(Layout* layout) - { - layout->add_eh_frame_for_plt(this, - this->plt_eh_frame_cie, - this->plt_eh_frame_cie_size, - plt_eh_frame_fde, - plt_eh_frame_fde_size); - } - - virtual void - do_fill_first_plt_entry(unsigned char* pov, - typename elfcpp::Elf_types<size>::Elf_Addr got_addr, - typename elfcpp::Elf_types<size>::Elf_Addr plt_addr); - - virtual unsigned int - do_fill_plt_entry(unsigned char* pov, - typename elfcpp::Elf_types<size>::Elf_Addr got_address, - typename elfcpp::Elf_types<size>::Elf_Addr plt_address, - unsigned int got_offset, - unsigned int plt_offset, - unsigned int plt_index); - - virtual void - do_fill_tlsdesc_entry(unsigned char* pov, - typename elfcpp::Elf_types<size>::Elf_Addr got_address, - typename elfcpp::Elf_types<size>::Elf_Addr plt_address, - typename elfcpp::Elf_types<size>::Elf_Addr got_base, - unsigned int tlsdesc_got_offset, - unsigned int plt_offset); - - private: - // The size of an entry in the PLT. - static const int plt_entry_size = 64; - - // The first entry in the PLT. - static const unsigned char first_plt_entry[plt_entry_size]; - - // Other entries in the PLT for an executable. - static const unsigned char plt_entry[plt_entry_size]; - - // The reserved TLSDESC entry in the PLT for an executable. - static const unsigned char tlsdesc_plt_entry[plt_entry_size]; - - // The .eh_frame unwind information for the PLT. - static const int plt_eh_frame_fde_size = 32; - static const unsigned char plt_eh_frame_fde[plt_eh_frame_fde_size]; -}; - -template<int size> -class Target_x86_64_nacl : public Target_x86_64<size> -{ - public: - Target_x86_64_nacl() - : Target_x86_64<size>(&x86_64_nacl_info) - { } - - virtual Output_data_plt_x86_64<size>* - do_make_data_plt(Layout* layout, - Output_data_got<64, false>* got, - Output_data_got_plt_x86_64* got_plt, - Output_data_space* got_irelative) - { - return new Output_data_plt_x86_64_nacl<size>(layout, got, got_plt, - got_irelative); - } - - virtual Output_data_plt_x86_64<size>* - do_make_data_plt(Layout* layout, - Output_data_got<64, false>* got, - Output_data_got_plt_x86_64* got_plt, - Output_data_space* got_irelative, - unsigned int plt_count) - { - return new Output_data_plt_x86_64_nacl<size>(layout, got, got_plt, - got_irelative, - plt_count); - } - - virtual std::string - do_code_fill(section_size_type length) const; - - private: - static const Target::Target_info x86_64_nacl_info; -}; - -template<> -const Target::Target_info Target_x86_64_nacl<64>::x86_64_nacl_info = -{ - 64, // size - false, // is_big_endian - elfcpp::EM_X86_64, // machine_code - false, // has_make_symbol - false, // has_resolve - true, // has_code_fill - true, // is_default_stack_executable - true, // can_icf_inline_merge_sections - '\0', // wrap_char - "/lib64/ld-nacl-x86-64.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_X86_64_LCOMMON, // large_common_shndx - 0, // small_common_section_flags - elfcpp::SHF_X86_64_LARGE, // large_common_section_flags - NULL, // attributes_section - NULL, // attributes_vendor - "_start", // entry_symbol_name - 32, // hash_entry_size - elfcpp::SHT_X86_64_UNWIND, // unwind_section_type -}; - -template<> -const Target::Target_info Target_x86_64_nacl<32>::x86_64_nacl_info = -{ - 32, // size - false, // is_big_endian - elfcpp::EM_X86_64, // machine_code - false, // has_make_symbol - false, // has_resolve - true, // has_code_fill - true, // is_default_stack_executable - true, // can_icf_inline_merge_sections - '\0', // wrap_char - "/lib/ld-nacl-x86-64.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_X86_64_LCOMMON, // large_common_shndx - 0, // small_common_section_flags - elfcpp::SHF_X86_64_LARGE, // large_common_section_flags - NULL, // attributes_section - NULL, // attributes_vendor - "_start", // entry_symbol_name - 32, // hash_entry_size - elfcpp::SHT_X86_64_UNWIND, // unwind_section_type -}; - -#define NACLMASK 0xe0 // 32-byte alignment mask. - -// The first entry in the PLT. - -template<int size> -const unsigned char -Output_data_plt_x86_64_nacl<size>::first_plt_entry[plt_entry_size] = -{ - 0xff, 0x35, // pushq contents of memory address - 0, 0, 0, 0, // replaced with address of .got + 8 - 0x4c, 0x8b, 0x1d, // mov GOT+16(%rip), %r11 - 0, 0, 0, 0, // replaced with address of .got + 16 - 0x41, 0x83, 0xe3, NACLMASK, // and $-32, %r11d - 0x4d, 0x01, 0xfb, // add %r15, %r11 - 0x41, 0xff, 0xe3, // jmpq *%r11 - - // 9-byte nop sequence to pad out to the next 32-byte boundary. - 0x66, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, // nopw 0x0(%rax,%rax,1) - - // 32 bytes of nop to pad out to the standard size - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, // excess data32 prefixes - 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, // nopw %cs:0x0(%rax,%rax,1) - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, // excess data32 prefixes - 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, // nopw %cs:0x0(%rax,%rax,1) - 0x66, // excess data32 prefix - 0x90 // nop -}; - -template<int size> -void -Output_data_plt_x86_64_nacl<size>::do_fill_first_plt_entry( - unsigned char* pov, - typename elfcpp::Elf_types<size>::Elf_Addr got_address, - typename elfcpp::Elf_types<size>::Elf_Addr plt_address) -{ - memcpy(pov, first_plt_entry, plt_entry_size); - elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, - (got_address + 8 - - (plt_address + 2 + 4))); - elfcpp::Swap_unaligned<32, false>::writeval(pov + 9, - (got_address + 16 - - (plt_address + 9 + 4))); -} - -// Subsequent entries in the PLT. - -template<int size> -const unsigned char -Output_data_plt_x86_64_nacl<size>::plt_entry[plt_entry_size] = -{ - 0x4c, 0x8b, 0x1d, // mov name@GOTPCREL(%rip),%r11 - 0, 0, 0, 0, // replaced with address of symbol in .got - 0x41, 0x83, 0xe3, NACLMASK, // and $-32, %r11d - 0x4d, 0x01, 0xfb, // add %r15, %r11 - 0x41, 0xff, 0xe3, // jmpq *%r11 - - // 15-byte nop sequence to pad out to the next 32-byte boundary. - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, // excess data32 prefixes - 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, // nopw %cs:0x0(%rax,%rax,1) - - // Lazy GOT entries point here (32-byte aligned). - 0x68, // pushq immediate - 0, 0, 0, 0, // replaced with index into relocation table - 0xe9, // jmp relative - 0, 0, 0, 0, // replaced with offset to start of .plt0 - - // 22 bytes of nop to pad out to the standard size. - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, // excess data32 prefixes - 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, // nopw %cs:0x0(%rax,%rax,1) - 0x0f, 0x1f, 0x80, 0, 0, 0, 0, // nopl 0x0(%rax) -}; - -template<int size> -unsigned int -Output_data_plt_x86_64_nacl<size>::do_fill_plt_entry( - unsigned char* pov, - typename elfcpp::Elf_types<size>::Elf_Addr got_address, - typename elfcpp::Elf_types<size>::Elf_Addr plt_address, - unsigned int got_offset, - unsigned int plt_offset, - unsigned int plt_index) -{ - memcpy(pov, plt_entry, plt_entry_size); - elfcpp::Swap_unaligned<32, false>::writeval(pov + 3, - (got_address + got_offset - - (plt_address + plt_offset - + 3 + 4))); - - elfcpp::Swap_unaligned<32, false>::writeval(pov + 33, plt_index); - elfcpp::Swap_unaligned<32, false>::writeval(pov + 38, - - (plt_offset + 38 + 4)); - - return 32; -} - -// The reserved TLSDESC entry in the PLT. - -template<int size> -const unsigned char -Output_data_plt_x86_64_nacl<size>::tlsdesc_plt_entry[plt_entry_size] = -{ - 0xff, 0x35, // pushq x(%rip) - 0, 0, 0, 0, // replaced with address of linkmap GOT entry (at PLTGOT + 8) - 0x4c, 0x8b, 0x1d, // mov y(%rip),%r11 - 0, 0, 0, 0, // replaced with offset of reserved TLSDESC_GOT entry - 0x41, 0x83, 0xe3, NACLMASK, // and $-32, %r11d - 0x4d, 0x01, 0xfb, // add %r15, %r11 - 0x41, 0xff, 0xe3, // jmpq *%r11 - - // 41 bytes of nop to pad out to the standard size. - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, // excess data32 prefixes - 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, // nopw %cs:0x0(%rax,%rax,1) - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, // excess data32 prefixes - 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, // nopw %cs:0x0(%rax,%rax,1) - 0x66, 0x66, // excess data32 prefixes - 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, // nopw %cs:0x0(%rax,%rax,1) -}; - -template<int size> -void -Output_data_plt_x86_64_nacl<size>::do_fill_tlsdesc_entry( - unsigned char* pov, - typename elfcpp::Elf_types<size>::Elf_Addr got_address, - typename elfcpp::Elf_types<size>::Elf_Addr plt_address, - typename elfcpp::Elf_types<size>::Elf_Addr got_base, - unsigned int tlsdesc_got_offset, - unsigned int plt_offset) -{ - memcpy(pov, tlsdesc_plt_entry, plt_entry_size); - elfcpp::Swap_unaligned<32, false>::writeval(pov + 2, - (got_address + 8 - - (plt_address + plt_offset - + 2 + 4))); - elfcpp::Swap_unaligned<32, false>::writeval(pov + 9, - (got_base - + tlsdesc_got_offset - - (plt_address + plt_offset - + 9 + 4))); -} - -// The .eh_frame unwind information for the PLT. - -template<int size> -const unsigned char -Output_data_plt_x86_64_nacl<size>::plt_eh_frame_fde[plt_eh_frame_fde_size] = -{ - 0, 0, 0, 0, // Replaced with offset to .plt. - 0, 0, 0, 0, // Replaced with size of .plt. - 0, // Augmentation size. - elfcpp::DW_CFA_def_cfa_offset, 16, // DW_CFA_def_cfa_offset: 16. - elfcpp::DW_CFA_advance_loc + 6, // Advance 6 to __PLT__ + 6. - elfcpp::DW_CFA_def_cfa_offset, 24, // DW_CFA_def_cfa_offset: 24. - elfcpp::DW_CFA_advance_loc + 58, // Advance 58 to __PLT__ + 64. - elfcpp::DW_CFA_def_cfa_expression, // DW_CFA_def_cfa_expression. - 13, // Block length. - elfcpp::DW_OP_breg7, 8, // Push %rsp + 8. - elfcpp::DW_OP_breg16, 0, // Push %rip. - elfcpp::DW_OP_const1u, 63, // Push 0x3f. - elfcpp::DW_OP_and, // & (%rip & 0x3f). - elfcpp::DW_OP_const1u, 37, // Push 0x25. - elfcpp::DW_OP_ge, // >= ((%rip & 0x3f) >= 0x25) - elfcpp::DW_OP_lit3, // Push 3. - elfcpp::DW_OP_shl, // << (((%rip & 0x3f) >= 0x25) << 3) - elfcpp::DW_OP_plus, // + ((((%rip&0x3f)>=0x25)<<3)+%rsp+8 - elfcpp::DW_CFA_nop, // Align to 32 bytes. - elfcpp::DW_CFA_nop -}; - -// Return a string used to fill a code section with nops. -// For NaCl, long NOPs are only valid if they do not cross -// bundle alignment boundaries, so keep it simple with one-byte NOPs. -template<int size> -std::string -Target_x86_64_nacl<size>::do_code_fill(section_size_type length) const -{ - return std::string(length, static_cast<char>(0x90)); -} - -// The selector for x86_64-nacl object files. - -template<int size> -class Target_selector_x86_64_nacl - : public Target_selector_nacl<Target_selector_x86_64<size>, - Target_x86_64_nacl<size> > -{ - public: - Target_selector_x86_64_nacl() - : Target_selector_nacl<Target_selector_x86_64<size>, - Target_x86_64_nacl<size> >("x86-64", - size == 64 - ? "elf64-x86-64-nacl" - : "elf32-x86-64-nacl", - size == 64 - ? "elf_x86_64_nacl" - : "elf32_x86_64_nacl") - { } -}; - -Target_selector_x86_64_nacl<64> target_selector_x86_64; -Target_selector_x86_64_nacl<32> target_selector_x32; +Target_selector_x86_64<64> target_selector_x86_64; +Target_selector_x86_64<32> target_selector_x32; } // End anonymous namespace. |