00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "bfd.h"
00026 #include "sysdep.h"
00027 #include "libbfd.h"
00028 #include "elf-bfd.h"
00029 #include "opcode/sparc.h"
00030
00031
00032
00033
00034
00035
00036 #include "elf/sparc.h"
00037
00038
00039 #define MINUS_ONE (~ (bfd_vma) 0)
00040
00041 static struct bfd_link_hash_table * sparc64_elf_bfd_link_hash_table_create
00042 PARAMS ((bfd *));
00043 static bfd_boolean create_got_section
00044 PARAMS ((bfd *, struct bfd_link_info *));
00045 static bfd_boolean sparc64_elf_create_dynamic_sections
00046 PARAMS ((bfd *, struct bfd_link_info *));
00047 static bfd_reloc_status_type init_insn_reloc
00048 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *,
00049 bfd *, bfd_vma *, bfd_vma *));
00050 static reloc_howto_type *sparc64_elf_reloc_type_lookup
00051 PARAMS ((bfd *, bfd_reloc_code_real_type));
00052 static void sparc64_elf_info_to_howto
00053 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
00054
00055 static void sparc64_elf_build_plt
00056 PARAMS ((bfd *, unsigned char *, int));
00057 static bfd_vma sparc64_elf_plt_entry_offset
00058 PARAMS ((bfd_vma));
00059 static bfd_vma sparc64_elf_plt_ptr_offset
00060 PARAMS ((bfd_vma, bfd_vma));
00061
00062 static bfd_boolean sparc64_elf_check_relocs
00063 PARAMS ((bfd *, struct bfd_link_info *, asection *sec,
00064 const Elf_Internal_Rela *));
00065 static bfd_boolean sparc64_elf_adjust_dynamic_symbol
00066 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
00067 static bfd_boolean sparc64_elf_omit_section_dynsym
00068 PARAMS ((bfd *, struct bfd_link_info *, asection *));
00069 static bfd_boolean sparc64_elf_size_dynamic_sections
00070 PARAMS ((bfd *, struct bfd_link_info *));
00071 static int sparc64_elf_get_symbol_type
00072 PARAMS (( Elf_Internal_Sym *, int));
00073 static bfd_boolean sparc64_elf_add_symbol_hook
00074 PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
00075 const char **, flagword *, asection **, bfd_vma *));
00076 static bfd_boolean sparc64_elf_output_arch_syms
00077 PARAMS ((bfd *, struct bfd_link_info *, PTR,
00078 bfd_boolean (*) (PTR, const char *, Elf_Internal_Sym *,
00079 asection *, struct elf_link_hash_entry *)));
00080 static void sparc64_elf_symbol_processing
00081 PARAMS ((bfd *, asymbol *));
00082
00083 static bfd_boolean sparc64_elf_merge_private_bfd_data
00084 PARAMS ((bfd *, bfd *));
00085
00086 static bfd_boolean sparc64_elf_fake_sections
00087 PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
00088
00089 static const char *sparc64_elf_print_symbol_all
00090 PARAMS ((bfd *, PTR, asymbol *));
00091 static bfd_boolean sparc64_elf_new_section_hook
00092 PARAMS ((bfd *, asection *));
00093 static bfd_boolean sparc64_elf_relax_section
00094 PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
00095 static bfd_boolean sparc64_elf_relocate_section
00096 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
00097 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
00098 static bfd_boolean sparc64_elf_finish_dynamic_symbol
00099 PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
00100 Elf_Internal_Sym *));
00101 static bfd_boolean sparc64_elf_finish_dynamic_sections
00102 PARAMS ((bfd *, struct bfd_link_info *));
00103 static bfd_boolean sparc64_elf_object_p PARAMS ((bfd *));
00104 static long sparc64_elf_get_reloc_upper_bound PARAMS ((bfd *, asection *));
00105 static long sparc64_elf_get_dynamic_reloc_upper_bound PARAMS ((bfd *));
00106 static bfd_boolean sparc64_elf_slurp_one_reloc_table
00107 PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, asymbol **, bfd_boolean));
00108 static bfd_boolean sparc64_elf_slurp_reloc_table
00109 PARAMS ((bfd *, asection *, asymbol **, bfd_boolean));
00110 static long sparc64_elf_canonicalize_reloc
00111 PARAMS ((bfd *, asection *, arelent **, asymbol **));
00112 static long sparc64_elf_canonicalize_dynamic_reloc
00113 PARAMS ((bfd *, arelent **, asymbol **));
00114 static void sparc64_elf_write_relocs PARAMS ((bfd *, asection *, PTR));
00115 static enum elf_reloc_type_class sparc64_elf_reloc_type_class
00116 PARAMS ((const Elf_Internal_Rela *));
00117
00118
00119
00120 static bfd_reloc_status_type sparc_elf_notsup_reloc
00121 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00122 static bfd_reloc_status_type sparc_elf_wdisp16_reloc
00123 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00124 static bfd_reloc_status_type sparc_elf_hix22_reloc
00125 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00126 static bfd_reloc_status_type sparc_elf_lox10_reloc
00127 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00128
00129 static reloc_howto_type sparc64_elf_howto_table[] =
00130 {
00131 HOWTO(R_SPARC_NONE, 0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", FALSE,0,0x00000000,TRUE),
00132 HOWTO(R_SPARC_8, 0,0, 8,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_8", FALSE,0,0x000000ff,TRUE),
00133 HOWTO(R_SPARC_16, 0,1,16,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_16", FALSE,0,0x0000ffff,TRUE),
00134 HOWTO(R_SPARC_32, 0,2,32,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_32", FALSE,0,0xffffffff,TRUE),
00135 HOWTO(R_SPARC_DISP8, 0,0, 8,TRUE, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP8", FALSE,0,0x000000ff,TRUE),
00136 HOWTO(R_SPARC_DISP16, 0,1,16,TRUE, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP16", FALSE,0,0x0000ffff,TRUE),
00137 HOWTO(R_SPARC_DISP32, 0,2,32,TRUE, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP32", FALSE,0,0xffffffff,TRUE),
00138 HOWTO(R_SPARC_WDISP30, 2,2,30,TRUE, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP30", FALSE,0,0x3fffffff,TRUE),
00139 HOWTO(R_SPARC_WDISP22, 2,2,22,TRUE, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP22", FALSE,0,0x003fffff,TRUE),
00140 HOWTO(R_SPARC_HI22, 10,2,22,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HI22", FALSE,0,0x003fffff,TRUE),
00141 HOWTO(R_SPARC_22, 0,2,22,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_22", FALSE,0,0x003fffff,TRUE),
00142 HOWTO(R_SPARC_13, 0,2,13,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_13", FALSE,0,0x00001fff,TRUE),
00143 HOWTO(R_SPARC_LO10, 0,2,10,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LO10", FALSE,0,0x000003ff,TRUE),
00144 HOWTO(R_SPARC_GOT10, 0,2,10,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT10", FALSE,0,0x000003ff,TRUE),
00145 HOWTO(R_SPARC_GOT13, 0,2,13,FALSE,0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_GOT13", FALSE,0,0x00001fff,TRUE),
00146 HOWTO(R_SPARC_GOT22, 10,2,22,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT22", FALSE,0,0x003fffff,TRUE),
00147 HOWTO(R_SPARC_PC10, 0,2,10,TRUE, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_PC10", FALSE,0,0x000003ff,TRUE),
00148 HOWTO(R_SPARC_PC22, 10,2,22,TRUE, 0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_PC22", FALSE,0,0x003fffff,TRUE),
00149 HOWTO(R_SPARC_WPLT30, 2,2,30,TRUE, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WPLT30", FALSE,0,0x3fffffff,TRUE),
00150 HOWTO(R_SPARC_COPY, 0,0,00,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_COPY", FALSE,0,0x00000000,TRUE),
00151 HOWTO(R_SPARC_GLOB_DAT, 0,0,00,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_DAT",FALSE,0,0x00000000,TRUE),
00152 HOWTO(R_SPARC_JMP_SLOT, 0,0,00,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_JMP_SLOT",FALSE,0,0x00000000,TRUE),
00153 HOWTO(R_SPARC_RELATIVE, 0,0,00,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_RELATIVE",FALSE,0,0x00000000,TRUE),
00154 HOWTO(R_SPARC_UA32, 0,2,32,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_UA32", FALSE,0,0xffffffff,TRUE),
00155 #ifndef SPARC64_OLD_RELOCS
00156 HOWTO(R_SPARC_PLT32, 0,2,32,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_PLT32", FALSE,0,0xffffffff,TRUE),
00157
00158 HOWTO(R_SPARC_HIPLT22, 0,0,00,FALSE,0,complain_overflow_dont, sparc_elf_notsup_reloc, "R_SPARC_HIPLT22", FALSE,0,0x00000000,TRUE),
00159 HOWTO(R_SPARC_LOPLT10, 0,0,00,FALSE,0,complain_overflow_dont, sparc_elf_notsup_reloc, "R_SPARC_LOPLT10", FALSE,0,0x00000000,TRUE),
00160 HOWTO(R_SPARC_PCPLT32, 0,0,00,FALSE,0,complain_overflow_dont, sparc_elf_notsup_reloc, "R_SPARC_PCPLT32", FALSE,0,0x00000000,TRUE),
00161 HOWTO(R_SPARC_PCPLT22, 0,0,00,FALSE,0,complain_overflow_dont, sparc_elf_notsup_reloc, "R_SPARC_PCPLT22", FALSE,0,0x00000000,TRUE),
00162 HOWTO(R_SPARC_PCPLT10, 0,0,00,FALSE,0,complain_overflow_dont, sparc_elf_notsup_reloc, "R_SPARC_PCPLT10", FALSE,0,0x00000000,TRUE),
00163 #endif
00164 HOWTO(R_SPARC_10, 0,2,10,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_10", FALSE,0,0x000003ff,TRUE),
00165 HOWTO(R_SPARC_11, 0,2,11,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_11", FALSE,0,0x000007ff,TRUE),
00166 HOWTO(R_SPARC_64, 0,4,64,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_64", FALSE,0,MINUS_ONE, TRUE),
00167 HOWTO(R_SPARC_OLO10, 0,2,13,FALSE,0,complain_overflow_signed, sparc_elf_notsup_reloc, "R_SPARC_OLO10", FALSE,0,0x00001fff,TRUE),
00168 HOWTO(R_SPARC_HH22, 42,2,22,FALSE,0,complain_overflow_unsigned,bfd_elf_generic_reloc, "R_SPARC_HH22", FALSE,0,0x003fffff,TRUE),
00169 HOWTO(R_SPARC_HM10, 32,2,10,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HM10", FALSE,0,0x000003ff,TRUE),
00170 HOWTO(R_SPARC_LM22, 10,2,22,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LM22", FALSE,0,0x003fffff,TRUE),
00171 HOWTO(R_SPARC_PC_HH22, 42,2,22,TRUE, 0,complain_overflow_unsigned,bfd_elf_generic_reloc, "R_SPARC_PC_HH22", FALSE,0,0x003fffff,TRUE),
00172 HOWTO(R_SPARC_PC_HM10, 32,2,10,TRUE, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_PC_HM10", FALSE,0,0x000003ff,TRUE),
00173 HOWTO(R_SPARC_PC_LM22, 10,2,22,TRUE, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_PC_LM22", FALSE,0,0x003fffff,TRUE),
00174 HOWTO(R_SPARC_WDISP16, 2,2,16,TRUE, 0,complain_overflow_signed, sparc_elf_wdisp16_reloc,"R_SPARC_WDISP16", FALSE,0,0x00000000,TRUE),
00175 HOWTO(R_SPARC_WDISP19, 2,2,19,TRUE, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP19", FALSE,0,0x0007ffff,TRUE),
00176 HOWTO(R_SPARC_UNUSED_42, 0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_UNUSED_42",FALSE,0,0x00000000,TRUE),
00177 HOWTO(R_SPARC_7, 0,2, 7,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_7", FALSE,0,0x0000007f,TRUE),
00178 HOWTO(R_SPARC_5, 0,2, 5,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_5", FALSE,0,0x0000001f,TRUE),
00179 HOWTO(R_SPARC_6, 0,2, 6,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_6", FALSE,0,0x0000003f,TRUE),
00180 HOWTO(R_SPARC_DISP64, 0,4,64,TRUE, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP64", FALSE,0,MINUS_ONE, TRUE),
00181 HOWTO(R_SPARC_PLT64, 0,4,64,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_PLT64", FALSE,0,MINUS_ONE, TRUE),
00182 HOWTO(R_SPARC_HIX22, 0,4, 0,FALSE,0,complain_overflow_bitfield,sparc_elf_hix22_reloc, "R_SPARC_HIX22", FALSE,0,MINUS_ONE, FALSE),
00183 HOWTO(R_SPARC_LOX10, 0,4, 0,FALSE,0,complain_overflow_dont, sparc_elf_lox10_reloc, "R_SPARC_LOX10", FALSE,0,MINUS_ONE, FALSE),
00184 HOWTO(R_SPARC_H44, 22,2,22,FALSE,0,complain_overflow_unsigned,bfd_elf_generic_reloc, "R_SPARC_H44", FALSE,0,0x003fffff,FALSE),
00185 HOWTO(R_SPARC_M44, 12,2,10,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_M44", FALSE,0,0x000003ff,FALSE),
00186 HOWTO(R_SPARC_L44, 0,2,13,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_L44", FALSE,0,0x00000fff,FALSE),
00187 HOWTO(R_SPARC_REGISTER, 0,4, 0,FALSE,0,complain_overflow_bitfield,sparc_elf_notsup_reloc, "R_SPARC_REGISTER",FALSE,0,MINUS_ONE, FALSE),
00188 HOWTO(R_SPARC_UA64, 0,4,64,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_UA64", FALSE,0,MINUS_ONE, TRUE),
00189 HOWTO(R_SPARC_UA16, 0,1,16,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_UA16", FALSE,0,0x0000ffff,TRUE),
00190 HOWTO(R_SPARC_TLS_GD_HI22,10,2,22,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_GD_HI22",FALSE,0,0x003fffff,TRUE),
00191 HOWTO(R_SPARC_TLS_GD_LO10,0,2,10,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_GD_LO10",FALSE,0,0x000003ff,TRUE),
00192 HOWTO(R_SPARC_TLS_GD_ADD,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_GD_ADD",FALSE,0,0x00000000,TRUE),
00193 HOWTO(R_SPARC_TLS_GD_CALL,2,2,30,TRUE,0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_TLS_GD_CALL",FALSE,0,0x3fffffff,TRUE),
00194 HOWTO(R_SPARC_TLS_LDM_HI22,10,2,22,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_LDM_HI22",FALSE,0,0x003fffff,TRUE),
00195 HOWTO(R_SPARC_TLS_LDM_LO10,0,2,10,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_LDM_LO10",FALSE,0,0x000003ff,TRUE),
00196 HOWTO(R_SPARC_TLS_LDM_ADD,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_LDM_ADD",FALSE,0,0x00000000,TRUE),
00197 HOWTO(R_SPARC_TLS_LDM_CALL,2,2,30,TRUE,0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_TLS_LDM_CALL",FALSE,0,0x3fffffff,TRUE),
00198 HOWTO(R_SPARC_TLS_LDO_HIX22,0,2,0,FALSE,0,complain_overflow_bitfield,sparc_elf_hix22_reloc,"R_SPARC_TLS_LDO_HIX22",FALSE,0,0x003fffff, FALSE),
00199 HOWTO(R_SPARC_TLS_LDO_LOX10,0,2,0,FALSE,0,complain_overflow_dont, sparc_elf_lox10_reloc, "R_SPARC_TLS_LDO_LOX10",FALSE,0,0x000003ff, FALSE),
00200 HOWTO(R_SPARC_TLS_LDO_ADD,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_LDO_ADD",FALSE,0,0x00000000,TRUE),
00201 HOWTO(R_SPARC_TLS_IE_HI22,10,2,22,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_IE_HI22",FALSE,0,0x003fffff,TRUE),
00202 HOWTO(R_SPARC_TLS_IE_LO10,0,2,10,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_IE_LO10",FALSE,0,0x000003ff,TRUE),
00203 HOWTO(R_SPARC_TLS_IE_LD,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_IE_LD",FALSE,0,0x00000000,TRUE),
00204 HOWTO(R_SPARC_TLS_IE_LDX,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_IE_LDX",FALSE,0,0x00000000,TRUE),
00205 HOWTO(R_SPARC_TLS_IE_ADD,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_IE_ADD",FALSE,0,0x00000000,TRUE),
00206 HOWTO(R_SPARC_TLS_LE_HIX22,0,2,0,FALSE,0,complain_overflow_bitfield,sparc_elf_hix22_reloc, "R_SPARC_TLS_LE_HIX22",FALSE,0,0x003fffff, FALSE),
00207 HOWTO(R_SPARC_TLS_LE_LOX10,0,2,0,FALSE,0,complain_overflow_dont, sparc_elf_lox10_reloc, "R_SPARC_TLS_LE_LOX10",FALSE,0,0x000003ff, FALSE),
00208 HOWTO(R_SPARC_TLS_DTPMOD32,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_DTPMOD32",FALSE,0,0x00000000,TRUE),
00209 HOWTO(R_SPARC_TLS_DTPMOD64,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_DTPMOD64",FALSE,0,0x00000000,TRUE),
00210 HOWTO(R_SPARC_TLS_DTPOFF32,0,2,32,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_TLS_DTPOFF32",FALSE,0,0xffffffff,TRUE),
00211 HOWTO(R_SPARC_TLS_DTPOFF64,0,4,64,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_TLS_DTPOFF64",FALSE,0,MINUS_ONE,TRUE),
00212 HOWTO(R_SPARC_TLS_TPOFF32,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_TPOFF32",FALSE,0,0x00000000,TRUE),
00213 HOWTO(R_SPARC_TLS_TPOFF64,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_TPOFF64",FALSE,0,0x00000000,TRUE)
00214 };
00215
00216 struct elf_reloc_map {
00217 bfd_reloc_code_real_type bfd_reloc_val;
00218 unsigned char elf_reloc_val;
00219 };
00220
00221 static const struct elf_reloc_map sparc_reloc_map[] =
00222 {
00223 { BFD_RELOC_NONE, R_SPARC_NONE, },
00224 { BFD_RELOC_16, R_SPARC_16, },
00225 { BFD_RELOC_16_PCREL, R_SPARC_DISP16 },
00226 { BFD_RELOC_8, R_SPARC_8 },
00227 { BFD_RELOC_8_PCREL, R_SPARC_DISP8 },
00228 { BFD_RELOC_CTOR, R_SPARC_64 },
00229 { BFD_RELOC_32, R_SPARC_32 },
00230 { BFD_RELOC_32_PCREL, R_SPARC_DISP32 },
00231 { BFD_RELOC_HI22, R_SPARC_HI22 },
00232 { BFD_RELOC_LO10, R_SPARC_LO10, },
00233 { BFD_RELOC_32_PCREL_S2, R_SPARC_WDISP30 },
00234 { BFD_RELOC_64_PCREL, R_SPARC_DISP64 },
00235 { BFD_RELOC_SPARC22, R_SPARC_22 },
00236 { BFD_RELOC_SPARC13, R_SPARC_13 },
00237 { BFD_RELOC_SPARC_GOT10, R_SPARC_GOT10 },
00238 { BFD_RELOC_SPARC_GOT13, R_SPARC_GOT13 },
00239 { BFD_RELOC_SPARC_GOT22, R_SPARC_GOT22 },
00240 { BFD_RELOC_SPARC_PC10, R_SPARC_PC10 },
00241 { BFD_RELOC_SPARC_PC22, R_SPARC_PC22 },
00242 { BFD_RELOC_SPARC_WPLT30, R_SPARC_WPLT30 },
00243 { BFD_RELOC_SPARC_COPY, R_SPARC_COPY },
00244 { BFD_RELOC_SPARC_GLOB_DAT, R_SPARC_GLOB_DAT },
00245 { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT },
00246 { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE },
00247 { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 },
00248 { BFD_RELOC_SPARC_UA16, R_SPARC_UA16 },
00249 { BFD_RELOC_SPARC_UA32, R_SPARC_UA32 },
00250 { BFD_RELOC_SPARC_UA64, R_SPARC_UA64 },
00251 { BFD_RELOC_SPARC_10, R_SPARC_10 },
00252 { BFD_RELOC_SPARC_11, R_SPARC_11 },
00253 { BFD_RELOC_SPARC_64, R_SPARC_64 },
00254 { BFD_RELOC_SPARC_OLO10, R_SPARC_OLO10 },
00255 { BFD_RELOC_SPARC_HH22, R_SPARC_HH22 },
00256 { BFD_RELOC_SPARC_HM10, R_SPARC_HM10 },
00257 { BFD_RELOC_SPARC_LM22, R_SPARC_LM22 },
00258 { BFD_RELOC_SPARC_PC_HH22, R_SPARC_PC_HH22 },
00259 { BFD_RELOC_SPARC_PC_HM10, R_SPARC_PC_HM10 },
00260 { BFD_RELOC_SPARC_PC_LM22, R_SPARC_PC_LM22 },
00261 { BFD_RELOC_SPARC_WDISP16, R_SPARC_WDISP16 },
00262 { BFD_RELOC_SPARC_WDISP19, R_SPARC_WDISP19 },
00263 { BFD_RELOC_SPARC_7, R_SPARC_7 },
00264 { BFD_RELOC_SPARC_5, R_SPARC_5 },
00265 { BFD_RELOC_SPARC_6, R_SPARC_6 },
00266 { BFD_RELOC_SPARC_DISP64, R_SPARC_DISP64 },
00267 { BFD_RELOC_SPARC_TLS_GD_HI22, R_SPARC_TLS_GD_HI22 },
00268 { BFD_RELOC_SPARC_TLS_GD_LO10, R_SPARC_TLS_GD_LO10 },
00269 { BFD_RELOC_SPARC_TLS_GD_ADD, R_SPARC_TLS_GD_ADD },
00270 { BFD_RELOC_SPARC_TLS_GD_CALL, R_SPARC_TLS_GD_CALL },
00271 { BFD_RELOC_SPARC_TLS_LDM_HI22, R_SPARC_TLS_LDM_HI22 },
00272 { BFD_RELOC_SPARC_TLS_LDM_LO10, R_SPARC_TLS_LDM_LO10 },
00273 { BFD_RELOC_SPARC_TLS_LDM_ADD, R_SPARC_TLS_LDM_ADD },
00274 { BFD_RELOC_SPARC_TLS_LDM_CALL, R_SPARC_TLS_LDM_CALL },
00275 { BFD_RELOC_SPARC_TLS_LDO_HIX22, R_SPARC_TLS_LDO_HIX22 },
00276 { BFD_RELOC_SPARC_TLS_LDO_LOX10, R_SPARC_TLS_LDO_LOX10 },
00277 { BFD_RELOC_SPARC_TLS_LDO_ADD, R_SPARC_TLS_LDO_ADD },
00278 { BFD_RELOC_SPARC_TLS_IE_HI22, R_SPARC_TLS_IE_HI22 },
00279 { BFD_RELOC_SPARC_TLS_IE_LO10, R_SPARC_TLS_IE_LO10 },
00280 { BFD_RELOC_SPARC_TLS_IE_LD, R_SPARC_TLS_IE_LD },
00281 { BFD_RELOC_SPARC_TLS_IE_LDX, R_SPARC_TLS_IE_LDX },
00282 { BFD_RELOC_SPARC_TLS_IE_ADD, R_SPARC_TLS_IE_ADD },
00283 { BFD_RELOC_SPARC_TLS_LE_HIX22, R_SPARC_TLS_LE_HIX22 },
00284 { BFD_RELOC_SPARC_TLS_LE_LOX10, R_SPARC_TLS_LE_LOX10 },
00285 { BFD_RELOC_SPARC_TLS_DTPMOD32, R_SPARC_TLS_DTPMOD32 },
00286 { BFD_RELOC_SPARC_TLS_DTPMOD64, R_SPARC_TLS_DTPMOD64 },
00287 { BFD_RELOC_SPARC_TLS_DTPOFF32, R_SPARC_TLS_DTPOFF32 },
00288 { BFD_RELOC_SPARC_TLS_DTPOFF64, R_SPARC_TLS_DTPOFF64 },
00289 { BFD_RELOC_SPARC_TLS_TPOFF32, R_SPARC_TLS_TPOFF32 },
00290 { BFD_RELOC_SPARC_TLS_TPOFF64, R_SPARC_TLS_TPOFF64 },
00291 #ifndef SPARC64_OLD_RELOCS
00292 { BFD_RELOC_SPARC_PLT32, R_SPARC_PLT32 },
00293 #endif
00294 { BFD_RELOC_SPARC_PLT64, R_SPARC_PLT64 },
00295 { BFD_RELOC_SPARC_HIX22, R_SPARC_HIX22 },
00296 { BFD_RELOC_SPARC_LOX10, R_SPARC_LOX10 },
00297 { BFD_RELOC_SPARC_H44, R_SPARC_H44 },
00298 { BFD_RELOC_SPARC_M44, R_SPARC_M44 },
00299 { BFD_RELOC_SPARC_L44, R_SPARC_L44 },
00300 { BFD_RELOC_SPARC_REGISTER, R_SPARC_REGISTER }
00301 };
00302
00303 static reloc_howto_type *
00304 sparc64_elf_reloc_type_lookup (abfd, code)
00305 bfd *abfd ATTRIBUTE_UNUSED;
00306 bfd_reloc_code_real_type code;
00307 {
00308 unsigned int i;
00309 for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct elf_reloc_map); i++)
00310 {
00311 if (sparc_reloc_map[i].bfd_reloc_val == code)
00312 return &sparc64_elf_howto_table[(int) sparc_reloc_map[i].elf_reloc_val];
00313 }
00314 return 0;
00315 }
00316
00317 static void
00318 sparc64_elf_info_to_howto (abfd, cache_ptr, dst)
00319 bfd *abfd ATTRIBUTE_UNUSED;
00320 arelent *cache_ptr;
00321 Elf_Internal_Rela *dst;
00322 {
00323 BFD_ASSERT (ELF64_R_TYPE_ID (dst->r_info) < (unsigned int) R_SPARC_max_std);
00324 cache_ptr->howto = &sparc64_elf_howto_table[ELF64_R_TYPE_ID (dst->r_info)];
00325 }
00326
00327 struct sparc64_elf_section_data
00328 {
00329 struct bfd_elf_section_data elf;
00330 unsigned int do_relax, reloc_count;
00331 };
00332
00333 #define sec_do_relax(sec) \
00334 ((struct sparc64_elf_section_data *) elf_section_data (sec))->do_relax
00335 #define canon_reloc_count(sec) \
00336 ((struct sparc64_elf_section_data *) elf_section_data (sec))->reloc_count
00337
00338
00339
00340
00341
00342 static long
00343 sparc64_elf_get_reloc_upper_bound (abfd, sec)
00344 bfd *abfd ATTRIBUTE_UNUSED;
00345 asection *sec;
00346 {
00347 return (sec->reloc_count * 2 + 1) * sizeof (arelent *);
00348 }
00349
00350 static long
00351 sparc64_elf_get_dynamic_reloc_upper_bound (abfd)
00352 bfd *abfd;
00353 {
00354 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 2;
00355 }
00356
00357
00358
00359
00360
00361
00362 static bfd_boolean
00363 sparc64_elf_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols, dynamic)
00364 bfd *abfd;
00365 asection *asect;
00366 Elf_Internal_Shdr *rel_hdr;
00367 asymbol **symbols;
00368 bfd_boolean dynamic;
00369 {
00370 PTR allocated = NULL;
00371 bfd_byte *native_relocs;
00372 arelent *relent;
00373 unsigned int i;
00374 int entsize;
00375 bfd_size_type count;
00376 arelent *relents;
00377
00378 allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
00379 if (allocated == NULL)
00380 goto error_return;
00381
00382 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
00383 || bfd_bread (allocated, rel_hdr->sh_size, abfd) != rel_hdr->sh_size)
00384 goto error_return;
00385
00386 native_relocs = (bfd_byte *) allocated;
00387
00388 relents = asect->relocation + canon_reloc_count (asect);
00389
00390 entsize = rel_hdr->sh_entsize;
00391 BFD_ASSERT (entsize == sizeof (Elf64_External_Rela));
00392
00393 count = rel_hdr->sh_size / entsize;
00394
00395 for (i = 0, relent = relents; i < count;
00396 i++, relent++, native_relocs += entsize)
00397 {
00398 Elf_Internal_Rela rela;
00399
00400 bfd_elf64_swap_reloca_in (abfd, native_relocs, &rela);
00401
00402
00403
00404
00405
00406 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
00407 relent->address = rela.r_offset;
00408 else
00409 relent->address = rela.r_offset - asect->vma;
00410
00411 if (ELF64_R_SYM (rela.r_info) == 0)
00412 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
00413 else
00414 {
00415 asymbol **ps, *s;
00416
00417 ps = symbols + ELF64_R_SYM (rela.r_info) - 1;
00418 s = *ps;
00419
00420
00421 if ((s->flags & BSF_SECTION_SYM) == 0)
00422 relent->sym_ptr_ptr = ps;
00423 else
00424 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
00425 }
00426
00427 relent->addend = rela.r_addend;
00428
00429 BFD_ASSERT (ELF64_R_TYPE_ID (rela.r_info) < (unsigned int) R_SPARC_max_std);
00430 if (ELF64_R_TYPE_ID (rela.r_info) == R_SPARC_OLO10)
00431 {
00432 relent->howto = &sparc64_elf_howto_table[R_SPARC_LO10];
00433 relent[1].address = relent->address;
00434 relent++;
00435 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
00436 relent->addend = ELF64_R_TYPE_DATA (rela.r_info);
00437 relent->howto = &sparc64_elf_howto_table[R_SPARC_13];
00438 }
00439 else
00440 relent->howto = &sparc64_elf_howto_table[ELF64_R_TYPE_ID (rela.r_info)];
00441 }
00442
00443 canon_reloc_count (asect) += relent - relents;
00444
00445 if (allocated != NULL)
00446 free (allocated);
00447
00448 return TRUE;
00449
00450 error_return:
00451 if (allocated != NULL)
00452 free (allocated);
00453 return FALSE;
00454 }
00455
00456
00457
00458 static bfd_boolean
00459 sparc64_elf_slurp_reloc_table (abfd, asect, symbols, dynamic)
00460 bfd *abfd;
00461 asection *asect;
00462 asymbol **symbols;
00463 bfd_boolean dynamic;
00464 {
00465 struct bfd_elf_section_data * const d = elf_section_data (asect);
00466 Elf_Internal_Shdr *rel_hdr;
00467 Elf_Internal_Shdr *rel_hdr2;
00468 bfd_size_type amt;
00469
00470 if (asect->relocation != NULL)
00471 return TRUE;
00472
00473 if (! dynamic)
00474 {
00475 if ((asect->flags & SEC_RELOC) == 0
00476 || asect->reloc_count == 0)
00477 return TRUE;
00478
00479 rel_hdr = &d->rel_hdr;
00480 rel_hdr2 = d->rel_hdr2;
00481
00482 BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
00483 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
00484 }
00485 else
00486 {
00487
00488
00489
00490
00491 if (asect->size == 0)
00492 return TRUE;
00493
00494 rel_hdr = &d->this_hdr;
00495 asect->reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
00496 rel_hdr2 = NULL;
00497 }
00498
00499 amt = asect->reloc_count;
00500 amt *= 2 * sizeof (arelent);
00501 asect->relocation = (arelent *) bfd_alloc (abfd, amt);
00502 if (asect->relocation == NULL)
00503 return FALSE;
00504
00505
00506
00507 canon_reloc_count (asect) = 0;
00508
00509 if (!sparc64_elf_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols,
00510 dynamic))
00511 return FALSE;
00512
00513 if (rel_hdr2
00514 && !sparc64_elf_slurp_one_reloc_table (abfd, asect, rel_hdr2, symbols,
00515 dynamic))
00516 return FALSE;
00517
00518 return TRUE;
00519 }
00520
00521
00522
00523 static long
00524 sparc64_elf_canonicalize_reloc (abfd, section, relptr, symbols)
00525 bfd *abfd;
00526 sec_ptr section;
00527 arelent **relptr;
00528 asymbol **symbols;
00529 {
00530 arelent *tblptr;
00531 unsigned int i;
00532 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
00533
00534 if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
00535 return -1;
00536
00537 tblptr = section->relocation;
00538 for (i = 0; i < canon_reloc_count (section); i++)
00539 *relptr++ = tblptr++;
00540
00541 *relptr = NULL;
00542
00543 return canon_reloc_count (section);
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 static long
00557 sparc64_elf_canonicalize_dynamic_reloc (abfd, storage, syms)
00558 bfd *abfd;
00559 arelent **storage;
00560 asymbol **syms;
00561 {
00562 asection *s;
00563 long ret;
00564
00565 if (elf_dynsymtab (abfd) == 0)
00566 {
00567 bfd_set_error (bfd_error_invalid_operation);
00568 return -1;
00569 }
00570
00571 ret = 0;
00572 for (s = abfd->sections; s != NULL; s = s->next)
00573 {
00574 if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
00575 && (elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
00576 {
00577 arelent *p;
00578 long count, i;
00579
00580 if (! sparc64_elf_slurp_reloc_table (abfd, s, syms, TRUE))
00581 return -1;
00582 count = canon_reloc_count (s);
00583 p = s->relocation;
00584 for (i = 0; i < count; i++)
00585 *storage++ = p++;
00586 ret += count;
00587 }
00588 }
00589
00590 *storage = NULL;
00591
00592 return ret;
00593 }
00594
00595
00596
00597 static void
00598 sparc64_elf_write_relocs (abfd, sec, data)
00599 bfd *abfd;
00600 asection *sec;
00601 PTR data;
00602 {
00603 bfd_boolean *failedp = (bfd_boolean *) data;
00604 Elf_Internal_Shdr *rela_hdr;
00605 Elf64_External_Rela *outbound_relocas, *src_rela;
00606 unsigned int idx, count;
00607 asymbol *last_sym = 0;
00608 int last_sym_idx = 0;
00609
00610
00611 if (*failedp)
00612 return;
00613
00614 if ((sec->flags & SEC_RELOC) == 0)
00615 return;
00616
00617
00618
00619
00620
00621 if (sec->reloc_count == 0)
00622 return;
00623
00624
00625
00626
00627 count = 0;
00628 for (idx = 0; idx < sec->reloc_count; idx++)
00629 {
00630 bfd_vma addr;
00631
00632 ++count;
00633
00634 addr = sec->orelocation[idx]->address;
00635 if (sec->orelocation[idx]->howto->type == R_SPARC_LO10
00636 && idx < sec->reloc_count - 1)
00637 {
00638 arelent *r = sec->orelocation[idx + 1];
00639
00640 if (r->howto->type == R_SPARC_13
00641 && r->address == addr
00642 && bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
00643 && (*r->sym_ptr_ptr)->value == 0)
00644 ++idx;
00645 }
00646 }
00647
00648 rela_hdr = &elf_section_data (sec)->rel_hdr;
00649
00650 rela_hdr->sh_size = rela_hdr->sh_entsize * count;
00651 rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
00652 if (rela_hdr->contents == NULL)
00653 {
00654 *failedp = TRUE;
00655 return;
00656 }
00657
00658
00659 if (rela_hdr->sh_type != SHT_RELA)
00660 abort ();
00661
00662
00663 outbound_relocas = (Elf64_External_Rela *) rela_hdr->contents;
00664 src_rela = outbound_relocas;
00665
00666 for (idx = 0; idx < sec->reloc_count; idx++)
00667 {
00668 Elf_Internal_Rela dst_rela;
00669 arelent *ptr;
00670 asymbol *sym;
00671 int n;
00672
00673 ptr = sec->orelocation[idx];
00674
00675
00676
00677
00678 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
00679 dst_rela.r_offset = ptr->address;
00680 else
00681 dst_rela.r_offset = ptr->address + sec->vma;
00682
00683 sym = *ptr->sym_ptr_ptr;
00684 if (sym == last_sym)
00685 n = last_sym_idx;
00686 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
00687 n = STN_UNDEF;
00688 else
00689 {
00690 last_sym = sym;
00691 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
00692 if (n < 0)
00693 {
00694 *failedp = TRUE;
00695 return;
00696 }
00697 last_sym_idx = n;
00698 }
00699
00700 if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
00701 && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
00702 && ! _bfd_elf_validate_reloc (abfd, ptr))
00703 {
00704 *failedp = TRUE;
00705 return;
00706 }
00707
00708 if (ptr->howto->type == R_SPARC_LO10
00709 && idx < sec->reloc_count - 1)
00710 {
00711 arelent *r = sec->orelocation[idx + 1];
00712
00713 if (r->howto->type == R_SPARC_13
00714 && r->address == ptr->address
00715 && bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
00716 && (*r->sym_ptr_ptr)->value == 0)
00717 {
00718 idx++;
00719 dst_rela.r_info
00720 = ELF64_R_INFO (n, ELF64_R_TYPE_INFO (r->addend,
00721 R_SPARC_OLO10));
00722 }
00723 else
00724 dst_rela.r_info = ELF64_R_INFO (n, R_SPARC_LO10);
00725 }
00726 else
00727 dst_rela.r_info = ELF64_R_INFO (n, ptr->howto->type);
00728
00729 dst_rela.r_addend = ptr->addend;
00730 bfd_elf64_swap_reloca_out (abfd, &dst_rela, (bfd_byte *) src_rela);
00731 ++src_rela;
00732 }
00733 }
00734
00735
00736
00737 struct sparc64_elf_app_reg
00738 {
00739 unsigned char bind;
00740 unsigned short shndx;
00741 bfd *abfd;
00742 char *name;
00743 };
00744
00745 struct sparc64_elf_link_hash_table
00746 {
00747 struct elf_link_hash_table root;
00748
00749
00750 asection *sgot;
00751 asection *srelgot;
00752
00753 struct sparc64_elf_app_reg app_regs [4];
00754 };
00755
00756
00757
00758 #define sparc64_elf_hash_table(p) \
00759 ((struct sparc64_elf_link_hash_table *) ((p)->hash))
00760
00761
00762
00763 static struct bfd_link_hash_table *
00764 sparc64_elf_bfd_link_hash_table_create (abfd)
00765 bfd *abfd;
00766 {
00767 struct sparc64_elf_link_hash_table *ret;
00768 bfd_size_type amt = sizeof (struct sparc64_elf_link_hash_table);
00769
00770 ret = (struct sparc64_elf_link_hash_table *) bfd_zmalloc (amt);
00771 if (ret == (struct sparc64_elf_link_hash_table *) NULL)
00772 return NULL;
00773
00774 if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
00775 _bfd_elf_link_hash_newfunc))
00776 {
00777 free (ret);
00778 return NULL;
00779 }
00780
00781 return &ret->root.root;
00782 }
00783
00784
00785
00786
00787 static bfd_boolean
00788 create_got_section (dynobj, info)
00789 bfd *dynobj;
00790 struct bfd_link_info *info;
00791 {
00792 struct sparc64_elf_link_hash_table *htab;
00793
00794 if (! _bfd_elf_create_got_section (dynobj, info))
00795 return FALSE;
00796
00797 htab = sparc64_elf_hash_table (info);
00798 htab->sgot = bfd_get_section_by_name (dynobj, ".got");
00799 BFD_ASSERT (htab->sgot != NULL);
00800
00801 htab->srelgot = bfd_make_section (dynobj, ".rela.got");
00802 if (htab->srelgot == NULL
00803 || ! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC
00804 | SEC_LOAD
00805 | SEC_HAS_CONTENTS
00806 | SEC_IN_MEMORY
00807 | SEC_LINKER_CREATED
00808 | SEC_READONLY)
00809 || ! bfd_set_section_alignment (dynobj, htab->srelgot, 3))
00810 return FALSE;
00811 return TRUE;
00812 }
00813
00814
00815
00816
00817
00818 static bfd_boolean
00819 sparc64_elf_create_dynamic_sections (dynobj, info)
00820 bfd *dynobj;
00821 struct bfd_link_info *info;
00822 {
00823 struct sparc64_elf_link_hash_table *htab;
00824
00825 htab = sparc64_elf_hash_table (info);
00826 if (!htab->sgot && !create_got_section (dynobj, info))
00827 return FALSE;
00828
00829 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
00830 return FALSE;
00831
00832 return TRUE;
00833 }
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843 static bfd_reloc_status_type
00844 init_insn_reloc (abfd,
00845 reloc_entry,
00846 symbol,
00847 data,
00848 input_section,
00849 output_bfd,
00850 prelocation,
00851 pinsn)
00852 bfd *abfd;
00853 arelent *reloc_entry;
00854 asymbol *symbol;
00855 PTR data;
00856 asection *input_section;
00857 bfd *output_bfd;
00858 bfd_vma *prelocation;
00859 bfd_vma *pinsn;
00860 {
00861 bfd_vma relocation;
00862 reloc_howto_type *howto = reloc_entry->howto;
00863
00864 if (output_bfd != (bfd *) NULL
00865 && (symbol->flags & BSF_SECTION_SYM) == 0
00866 && (! howto->partial_inplace
00867 || reloc_entry->addend == 0))
00868 {
00869 reloc_entry->address += input_section->output_offset;
00870 return bfd_reloc_ok;
00871 }
00872
00873
00874 if (output_bfd != NULL)
00875 return bfd_reloc_continue;
00876
00877 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
00878 return bfd_reloc_outofrange;
00879
00880 relocation = (symbol->value
00881 + symbol->section->output_section->vma
00882 + symbol->section->output_offset);
00883 relocation += reloc_entry->addend;
00884 if (howto->pc_relative)
00885 {
00886 relocation -= (input_section->output_section->vma
00887 + input_section->output_offset);
00888 relocation -= reloc_entry->address;
00889 }
00890
00891 *prelocation = relocation;
00892 *pinsn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
00893 return bfd_reloc_other;
00894 }
00895
00896
00897
00898 static bfd_reloc_status_type
00899 sparc_elf_notsup_reloc (abfd,
00900 reloc_entry,
00901 symbol,
00902 data,
00903 input_section,
00904 output_bfd,
00905 error_message)
00906 bfd *abfd ATTRIBUTE_UNUSED;
00907 arelent *reloc_entry ATTRIBUTE_UNUSED;
00908 asymbol *symbol ATTRIBUTE_UNUSED;
00909 PTR data ATTRIBUTE_UNUSED;
00910 asection *input_section ATTRIBUTE_UNUSED;
00911 bfd *output_bfd ATTRIBUTE_UNUSED;
00912 char **error_message ATTRIBUTE_UNUSED;
00913 {
00914 return bfd_reloc_notsupported;
00915 }
00916
00917
00918
00919 static bfd_reloc_status_type
00920 sparc_elf_wdisp16_reloc (abfd, reloc_entry, symbol, data, input_section,
00921 output_bfd, error_message)
00922 bfd *abfd;
00923 arelent *reloc_entry;
00924 asymbol *symbol;
00925 PTR data;
00926 asection *input_section;
00927 bfd *output_bfd;
00928 char **error_message ATTRIBUTE_UNUSED;
00929 {
00930 bfd_vma relocation;
00931 bfd_vma insn;
00932 bfd_reloc_status_type status;
00933
00934 status = init_insn_reloc (abfd, reloc_entry, symbol, data,
00935 input_section, output_bfd, &relocation, &insn);
00936 if (status != bfd_reloc_other)
00937 return status;
00938
00939 insn &= ~ (bfd_vma) 0x303fff;
00940 insn |= (((relocation >> 2) & 0xc000) << 6) | ((relocation >> 2) & 0x3fff);
00941 bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
00942
00943 if ((bfd_signed_vma) relocation < - 0x40000
00944 || (bfd_signed_vma) relocation > 0x3ffff)
00945 return bfd_reloc_overflow;
00946 else
00947 return bfd_reloc_ok;
00948 }
00949
00950
00951
00952 static bfd_reloc_status_type
00953 sparc_elf_hix22_reloc (abfd,
00954 reloc_entry,
00955 symbol,
00956 data,
00957 input_section,
00958 output_bfd,
00959 error_message)
00960 bfd *abfd;
00961 arelent *reloc_entry;
00962 asymbol *symbol;
00963 PTR data;
00964 asection *input_section;
00965 bfd *output_bfd;
00966 char **error_message ATTRIBUTE_UNUSED;
00967 {
00968 bfd_vma relocation;
00969 bfd_vma insn;
00970 bfd_reloc_status_type status;
00971
00972 status = init_insn_reloc (abfd, reloc_entry, symbol, data,
00973 input_section, output_bfd, &relocation, &insn);
00974 if (status != bfd_reloc_other)
00975 return status;
00976
00977 relocation ^= MINUS_ONE;
00978 insn = (insn &~ (bfd_vma) 0x3fffff) | ((relocation >> 10) & 0x3fffff);
00979 bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
00980
00981 if ((relocation & ~ (bfd_vma) 0xffffffff) != 0)
00982 return bfd_reloc_overflow;
00983 else
00984 return bfd_reloc_ok;
00985 }
00986
00987
00988
00989 static bfd_reloc_status_type
00990 sparc_elf_lox10_reloc (abfd,
00991 reloc_entry,
00992 symbol,
00993 data,
00994 input_section,
00995 output_bfd,
00996 error_message)
00997 bfd *abfd;
00998 arelent *reloc_entry;
00999 asymbol *symbol;
01000 PTR data;
01001 asection *input_section;
01002 bfd *output_bfd;
01003 char **error_message ATTRIBUTE_UNUSED;
01004 {
01005 bfd_vma relocation;
01006 bfd_vma insn;
01007 bfd_reloc_status_type status;
01008
01009 status = init_insn_reloc (abfd, reloc_entry, symbol, data,
01010 input_section, output_bfd, &relocation, &insn);
01011 if (status != bfd_reloc_other)
01012 return status;
01013
01014 insn = (insn &~ (bfd_vma) 0x1fff) | 0x1c00 | (relocation & 0x3ff);
01015 bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
01016
01017 return bfd_reloc_ok;
01018 }
01019
01020
01021
01022
01023 #define PLT_ENTRY_SIZE 32
01024 #define PLT_HEADER_SIZE (4 * PLT_ENTRY_SIZE)
01025 #define LARGE_PLT_THRESHOLD 32768
01026 #define GOT_RESERVED_ENTRIES 1
01027
01028 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/sparcv9/ld.so.1"
01029
01030
01031
01032 static void
01033 sparc64_elf_build_plt (output_bfd, contents, nentries)
01034 bfd *output_bfd;
01035 unsigned char *contents;
01036 int nentries;
01037 {
01038 const unsigned int nop = 0x01000000;
01039 int i, j;
01040
01041
01042
01043
01044 for (i = 0; i < PLT_HEADER_SIZE/4; ++i)
01045 bfd_put_32 (output_bfd, (bfd_vma) 0, contents+i*4);
01046
01047
01048
01049
01050 for (i = 4; i < LARGE_PLT_THRESHOLD && i < nentries; ++i)
01051 {
01052 unsigned char *entry = contents + i * PLT_ENTRY_SIZE;
01053 unsigned int sethi, ba;
01054
01055
01056 sethi = 0x03000000 | (i * PLT_ENTRY_SIZE);
01057
01058
01059 ba = 0x30680000 | (((contents+PLT_ENTRY_SIZE) - (entry+4)) / 4 & 0x7ffff);
01060
01061 bfd_put_32 (output_bfd, (bfd_vma) sethi, entry);
01062 bfd_put_32 (output_bfd, (bfd_vma) ba, entry + 4);
01063 bfd_put_32 (output_bfd, (bfd_vma) nop, entry + 8);
01064 bfd_put_32 (output_bfd, (bfd_vma) nop, entry + 12);
01065 bfd_put_32 (output_bfd, (bfd_vma) nop, entry + 16);
01066 bfd_put_32 (output_bfd, (bfd_vma) nop, entry + 20);
01067 bfd_put_32 (output_bfd, (bfd_vma) nop, entry + 24);
01068 bfd_put_32 (output_bfd, (bfd_vma) nop, entry + 28);
01069 }
01070
01071
01072
01073
01074
01075 for (; i < nentries; i += 160)
01076 {
01077 int block = (i + 160 <= nentries ? 160 : nentries - i);
01078 for (j = 0; j < block; ++j)
01079 {
01080 unsigned char *entry, *ptr;
01081 unsigned int ldx;
01082
01083 entry = contents + i*PLT_ENTRY_SIZE + j*4*6;
01084 ptr = contents + i*PLT_ENTRY_SIZE + block*4*6 + j*8;
01085
01086
01087 ldx = 0xc25be000 | ((ptr - (entry+4)) & 0x1fff);
01088
01089
01090
01091
01092
01093
01094
01095 bfd_put_32 (output_bfd, (bfd_vma) 0x8a10000f, entry);
01096 bfd_put_32 (output_bfd, (bfd_vma) 0x40000002, entry + 4);
01097 bfd_put_32 (output_bfd, (bfd_vma) nop, entry + 8);
01098 bfd_put_32 (output_bfd, (bfd_vma) ldx, entry + 12);
01099 bfd_put_32 (output_bfd, (bfd_vma) 0x83c3c001, entry + 16);
01100 bfd_put_32 (output_bfd, (bfd_vma) 0x9e100005, entry + 20);
01101
01102 bfd_put_64 (output_bfd, (bfd_vma) (contents - (entry + 4)), ptr);
01103 }
01104 }
01105 }
01106
01107
01108
01109 static bfd_vma
01110 sparc64_elf_plt_entry_offset (index)
01111 bfd_vma index;
01112 {
01113 bfd_vma block, ofs;
01114
01115 if (index < LARGE_PLT_THRESHOLD)
01116 return index * PLT_ENTRY_SIZE;
01117
01118
01119
01120 block = (index - LARGE_PLT_THRESHOLD) / 160;
01121 ofs = (index - LARGE_PLT_THRESHOLD) % 160;
01122
01123 return (LARGE_PLT_THRESHOLD + block * 160) * PLT_ENTRY_SIZE + ofs * 6 * 4;
01124 }
01125
01126 static bfd_vma
01127 sparc64_elf_plt_ptr_offset (index, max)
01128 bfd_vma index;
01129 bfd_vma max;
01130 {
01131 bfd_vma block, ofs, last;
01132
01133 BFD_ASSERT(index >= LARGE_PLT_THRESHOLD);
01134
01135
01136
01137 block = (((index - LARGE_PLT_THRESHOLD) / 160) * 160) + LARGE_PLT_THRESHOLD;
01138 ofs = index - block;
01139 if (block + 160 > max)
01140 last = (max - LARGE_PLT_THRESHOLD) % 160;
01141 else
01142 last = 160;
01143
01144 return (block * PLT_ENTRY_SIZE
01145 + last * 6*4
01146 + ofs * 8);
01147 }
01148
01149
01150
01151
01152
01153 static bfd_boolean
01154 sparc64_elf_check_relocs (abfd, info, sec, relocs)
01155 bfd *abfd;
01156 struct bfd_link_info *info;
01157 asection *sec;
01158 const Elf_Internal_Rela *relocs;
01159 {
01160 bfd *dynobj;
01161 Elf_Internal_Shdr *symtab_hdr;
01162 struct elf_link_hash_entry **sym_hashes;
01163 bfd_vma *local_got_offsets;
01164 const Elf_Internal_Rela *rel;
01165 const Elf_Internal_Rela *rel_end;
01166 asection *sgot;
01167 asection *srelgot;
01168 asection *sreloc;
01169
01170 if (info->relocatable || !(sec->flags & SEC_ALLOC))
01171 return TRUE;
01172
01173 dynobj = elf_hash_table (info)->dynobj;
01174 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
01175 sym_hashes = elf_sym_hashes (abfd);
01176 local_got_offsets = elf_local_got_offsets (abfd);
01177
01178 sgot = NULL;
01179 srelgot = NULL;
01180 sreloc = NULL;
01181
01182 rel_end = relocs + NUM_SHDR_ENTRIES (& elf_section_data (sec)->rel_hdr);
01183 for (rel = relocs; rel < rel_end; rel++)
01184 {
01185 unsigned long r_symndx;
01186 struct elf_link_hash_entry *h;
01187
01188 r_symndx = ELF64_R_SYM (rel->r_info);
01189 if (r_symndx < symtab_hdr->sh_info)
01190 h = NULL;
01191 else
01192 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
01193
01194 switch (ELF64_R_TYPE_ID (rel->r_info))
01195 {
01196 case R_SPARC_GOT10:
01197 case R_SPARC_GOT13:
01198 case R_SPARC_GOT22:
01199
01200
01201 if (dynobj == NULL)
01202 {
01203
01204 elf_hash_table (info)->dynobj = dynobj = abfd;
01205 if (! create_got_section (dynobj, info))
01206 return FALSE;
01207 }
01208
01209 if (sgot == NULL)
01210 {
01211 sgot = sparc64_elf_hash_table (info)->sgot;
01212 BFD_ASSERT (sgot != NULL);
01213 }
01214
01215 if (srelgot == NULL && (h != NULL || info->shared))
01216 {
01217 srelgot = sparc64_elf_hash_table (info)->srelgot;
01218 BFD_ASSERT (srelgot != NULL);
01219 }
01220
01221 if (h != NULL)
01222 {
01223 if (h->got.offset != (bfd_vma) -1)
01224 {
01225
01226 break;
01227 }
01228 h->got.offset = sgot->size;
01229
01230
01231 if (h->dynindx == -1)
01232 {
01233 if (! bfd_elf_link_record_dynamic_symbol (info, h))
01234 return FALSE;
01235 }
01236
01237 srelgot->size += sizeof (Elf64_External_Rela);
01238 }
01239 else
01240 {
01241
01242
01243 if (local_got_offsets == NULL)
01244 {
01245 bfd_size_type size;
01246 register unsigned int i;
01247
01248 size = symtab_hdr->sh_info;
01249 size *= sizeof (bfd_vma);
01250 local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
01251 if (local_got_offsets == NULL)
01252 return FALSE;
01253 elf_local_got_offsets (abfd) = local_got_offsets;
01254 for (i = 0; i < symtab_hdr->sh_info; i++)
01255 local_got_offsets[i] = (bfd_vma) -1;
01256 }
01257 if (local_got_offsets[r_symndx] != (bfd_vma) -1)
01258 {
01259
01260 break;
01261 }
01262 local_got_offsets[r_symndx] = sgot->size;
01263
01264 if (info->shared)
01265 {
01266
01267
01268
01269 srelgot->size += sizeof (Elf64_External_Rela);
01270 }
01271 }
01272
01273 sgot->size += 8;
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289 break;
01290
01291 case R_SPARC_WPLT30:
01292 case R_SPARC_PLT32:
01293 case R_SPARC_HIPLT22:
01294 case R_SPARC_LOPLT10:
01295 case R_SPARC_PCPLT32:
01296 case R_SPARC_PCPLT22:
01297 case R_SPARC_PCPLT10:
01298 case R_SPARC_PLT64:
01299
01300
01301
01302
01303
01304
01305 if (h == NULL)
01306 {
01307
01308
01309 bfd_set_error (bfd_error_bad_value);
01310 return FALSE;
01311 }
01312
01313
01314 if (h->dynindx == -1)
01315 {
01316 if (! bfd_elf_link_record_dynamic_symbol (info, h))
01317 return FALSE;
01318 }
01319
01320 h->needs_plt = 1;
01321 if (ELF64_R_TYPE_ID (rel->r_info) != R_SPARC_PLT32
01322 && ELF64_R_TYPE_ID (rel->r_info) != R_SPARC_PLT64)
01323 break;
01324
01325 case R_SPARC_PC10:
01326 case R_SPARC_PC22:
01327 case R_SPARC_PC_HH22:
01328 case R_SPARC_PC_HM10:
01329 case R_SPARC_PC_LM22:
01330 if (h != NULL
01331 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
01332 break;
01333
01334 case R_SPARC_DISP8:
01335 case R_SPARC_DISP16:
01336 case R_SPARC_DISP32:
01337 case R_SPARC_DISP64:
01338 case R_SPARC_WDISP30:
01339 case R_SPARC_WDISP22:
01340 case R_SPARC_WDISP19:
01341 case R_SPARC_WDISP16:
01342 if (h == NULL)
01343 break;
01344
01345 case R_SPARC_8:
01346 case R_SPARC_16:
01347 case R_SPARC_32:
01348 case R_SPARC_HI22:
01349 case R_SPARC_22:
01350 case R_SPARC_13:
01351 case R_SPARC_LO10:
01352 case R_SPARC_UA32:
01353 case R_SPARC_10:
01354 case R_SPARC_11:
01355 case R_SPARC_64:
01356 case R_SPARC_OLO10:
01357 case R_SPARC_HH22:
01358 case R_SPARC_HM10:
01359 case R_SPARC_LM22:
01360 case R_SPARC_7:
01361 case R_SPARC_5:
01362 case R_SPARC_6:
01363 case R_SPARC_HIX22:
01364 case R_SPARC_LOX10:
01365 case R_SPARC_H44:
01366 case R_SPARC_M44:
01367 case R_SPARC_L44:
01368 case R_SPARC_UA64:
01369 case R_SPARC_UA16:
01370
01371
01372
01373
01374
01375
01376
01377
01378 if (info->shared && (sec->flags & SEC_ALLOC))
01379 {
01380 if (sreloc == NULL)
01381 {
01382 const char *name;
01383
01384 name = (bfd_elf_string_from_elf_section
01385 (abfd,
01386 elf_elfheader (abfd)->e_shstrndx,
01387 elf_section_data (sec)->rel_hdr.sh_name));
01388 if (name == NULL)
01389 return FALSE;
01390
01391 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
01392 && strcmp (bfd_get_section_name (abfd, sec),
01393 name + 5) == 0);
01394
01395 sreloc = bfd_get_section_by_name (dynobj, name);
01396 if (sreloc == NULL)
01397 {
01398 flagword flags;
01399
01400 sreloc = bfd_make_section (dynobj, name);
01401 flags = (SEC_HAS_CONTENTS | SEC_READONLY
01402 | SEC_IN_MEMORY | SEC_LINKER_CREATED);
01403 if ((sec->flags & SEC_ALLOC) != 0)
01404 flags |= SEC_ALLOC | SEC_LOAD;
01405 if (sreloc == NULL
01406 || ! bfd_set_section_flags (dynobj, sreloc, flags)
01407 || ! bfd_set_section_alignment (dynobj, sreloc, 3))
01408 return FALSE;
01409 }
01410 if (sec->flags & SEC_READONLY)
01411 info->flags |= DF_TEXTREL;
01412 }
01413
01414 sreloc->size += sizeof (Elf64_External_Rela);
01415 }
01416 break;
01417
01418 case R_SPARC_REGISTER:
01419
01420 break;
01421
01422 default:
01423 (*_bfd_error_handler) (_("%B: check_relocs: unhandled reloc type %d"),
01424 abfd, ELF64_R_TYPE_ID (rel->r_info));
01425 return FALSE;
01426 }
01427 }
01428
01429 return TRUE;
01430 }
01431
01432
01433
01434
01435 static bfd_boolean
01436 sparc64_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
01437 bfd *abfd;
01438 struct bfd_link_info *info;
01439 Elf_Internal_Sym *sym;
01440 const char **namep;
01441 flagword *flagsp ATTRIBUTE_UNUSED;
01442 asection **secp ATTRIBUTE_UNUSED;
01443 bfd_vma *valp ATTRIBUTE_UNUSED;
01444 {
01445 static const char *const stt_types[] = { "NOTYPE", "OBJECT", "FUNCTION" };
01446
01447 if (ELF_ST_TYPE (sym->st_info) == STT_REGISTER)
01448 {
01449 int reg;
01450 struct sparc64_elf_app_reg *p;
01451
01452 reg = (int)sym->st_value;
01453 switch (reg & ~1)
01454 {
01455 case 2: reg -= 2; break;
01456 case 6: reg -= 4; break;
01457 default:
01458 (*_bfd_error_handler)
01459 (_("%B: Only registers %%g[2367] can be declared using STT_REGISTER"),
01460 abfd);
01461 return FALSE;
01462 }
01463
01464 if (info->hash->creator != abfd->xvec
01465 || (abfd->flags & DYNAMIC) != 0)
01466 {
01467
01468
01469
01470 *namep = NULL;
01471 return TRUE;
01472 }
01473
01474 p = sparc64_elf_hash_table(info)->app_regs + reg;
01475
01476 if (p->name != NULL && strcmp (p->name, *namep))
01477 {
01478 (*_bfd_error_handler)
01479 (_("Register %%g%d used incompatibly: %s in %B, previously %s in %B"),
01480 abfd, p->abfd, (int) sym->st_value,
01481 **namep ? *namep : "#scratch",
01482 *p->name ? p->name : "#scratch");
01483 return FALSE;
01484 }
01485
01486 if (p->name == NULL)
01487 {
01488 if (**namep)
01489 {
01490 struct elf_link_hash_entry *h;
01491
01492 h = (struct elf_link_hash_entry *)
01493 bfd_link_hash_lookup (info->hash, *namep, FALSE, FALSE, FALSE);
01494
01495 if (h != NULL)
01496 {
01497 unsigned char type = h->type;
01498
01499 if (type > STT_FUNC)
01500 type = 0;
01501 (*_bfd_error_handler)
01502 (_("Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"),
01503 abfd, p->abfd, *namep, stt_types[type]);
01504 return FALSE;
01505 }
01506
01507 p->name = bfd_hash_allocate (&info->hash->table,
01508 strlen (*namep) + 1);
01509 if (!p->name)
01510 return FALSE;
01511
01512 strcpy (p->name, *namep);
01513 }
01514 else
01515 p->name = "";
01516 p->bind = ELF_ST_BIND (sym->st_info);
01517 p->abfd = abfd;
01518 p->shndx = sym->st_shndx;
01519 }
01520 else
01521 {
01522 if (p->bind == STB_WEAK
01523 && ELF_ST_BIND (sym->st_info) == STB_GLOBAL)
01524 {
01525 p->bind = STB_GLOBAL;
01526 p->abfd = abfd;
01527 }
01528 }
01529 *namep = NULL;
01530 return TRUE;
01531 }
01532 else if (*namep && **namep
01533 && info->hash->creator == abfd->xvec)
01534 {
01535 int i;
01536 struct sparc64_elf_app_reg *p;
01537
01538 p = sparc64_elf_hash_table(info)->app_regs;
01539 for (i = 0; i < 4; i++, p++)
01540 if (p->name != NULL && ! strcmp (p->name, *namep))
01541 {
01542 unsigned char type = ELF_ST_TYPE (sym->st_info);
01543
01544 if (type > STT_FUNC)
01545 type = 0;
01546 (*_bfd_error_handler)
01547 (_("Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"),
01548 abfd, p->abfd, *namep, stt_types[type]);
01549 return FALSE;
01550 }
01551 }
01552 return TRUE;
01553 }
01554
01555
01556
01557
01558 static bfd_boolean
01559 sparc64_elf_output_arch_syms (output_bfd, info, finfo, func)
01560 bfd *output_bfd ATTRIBUTE_UNUSED;
01561 struct bfd_link_info *info;
01562 PTR finfo;
01563 bfd_boolean (*func)
01564 PARAMS ((PTR, const char *, Elf_Internal_Sym *, asection *,
01565 struct elf_link_hash_entry *));
01566 {
01567 int reg;
01568 struct sparc64_elf_app_reg *app_regs =
01569 sparc64_elf_hash_table(info)->app_regs;
01570 Elf_Internal_Sym sym;
01571
01572
01573
01574
01575
01576 if (elf_hash_table (info)->dynlocal)
01577 {
01578 bfd * dynobj = elf_hash_table (info)->dynobj;
01579 asection *dynsymsec = bfd_get_section_by_name (dynobj, ".dynsym");
01580 struct elf_link_local_dynamic_entry *e;
01581
01582 for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
01583 if (e->input_indx == -1)
01584 break;
01585 if (e)
01586 {
01587 elf_section_data (dynsymsec->output_section)->this_hdr.sh_info
01588 = e->dynindx;
01589 }
01590 }
01591
01592 if (info->strip == strip_all)
01593 return TRUE;
01594
01595 for (reg = 0; reg < 4; reg++)
01596 if (app_regs [reg].name != NULL)
01597 {
01598 if (info->strip == strip_some
01599 && bfd_hash_lookup (info->keep_hash,
01600 app_regs [reg].name,
01601 FALSE, FALSE) == NULL)
01602 continue;
01603
01604 sym.st_value = reg < 2 ? reg + 2 : reg + 4;
01605 sym.st_size = 0;
01606 sym.st_other = 0;
01607 sym.st_info = ELF_ST_INFO (app_regs [reg].bind, STT_REGISTER);
01608 sym.st_shndx = app_regs [reg].shndx;
01609 if (! (*func) (finfo, app_regs [reg].name, &sym,
01610 sym.st_shndx == SHN_ABS
01611 ? bfd_abs_section_ptr : bfd_und_section_ptr,
01612 NULL))
01613 return FALSE;
01614 }
01615
01616 return TRUE;
01617 }
01618
01619 static int
01620 sparc64_elf_get_symbol_type (elf_sym, type)
01621 Elf_Internal_Sym * elf_sym;
01622 int type;
01623 {
01624 if (ELF_ST_TYPE (elf_sym->st_info) == STT_REGISTER)
01625 return STT_REGISTER;
01626 else
01627 return type;
01628 }
01629
01630
01631
01632
01633 static void
01634 sparc64_elf_symbol_processing (abfd, asym)
01635 bfd *abfd ATTRIBUTE_UNUSED;
01636 asymbol *asym;
01637 {
01638 elf_symbol_type *elfsym;
01639
01640 elfsym = (elf_symbol_type *) asym;
01641 if (elfsym->internal_elf_sym.st_info
01642 == ELF_ST_INFO (STB_GLOBAL, STT_REGISTER))
01643 {
01644 asym->flags |= BSF_GLOBAL;
01645 }
01646 }
01647
01648
01649
01650
01651
01652
01653
01654 static bfd_boolean
01655 sparc64_elf_adjust_dynamic_symbol (info, h)
01656 struct bfd_link_info *info;
01657 struct elf_link_hash_entry *h;
01658 {
01659 bfd *dynobj;
01660 asection *s;
01661 unsigned int power_of_two;
01662
01663 dynobj = elf_hash_table (info)->dynobj;
01664
01665
01666 BFD_ASSERT (dynobj != NULL
01667 && (h->needs_plt
01668 || h->u.weakdef != NULL
01669 || (h->def_dynamic
01670 && h->ref_regular
01671 && !h->def_regular)));
01672
01673
01674
01675
01676
01677
01678
01679
01680 if (h->type == STT_FUNC
01681 || h->needs_plt
01682 || (h->type == STT_NOTYPE
01683 && (h->root.type == bfd_link_hash_defined
01684 || h->root.type == bfd_link_hash_defweak)
01685 && (h->root.u.def.section->flags & SEC_CODE) != 0))
01686 {
01687 if (! info->shared
01688 && !h->def_dynamic
01689 && !h->ref_dynamic
01690 && h->root.type != bfd_link_hash_undefweak
01691 && h->root.type != bfd_link_hash_undefined)
01692 {
01693
01694
01695
01696
01697
01698 BFD_ASSERT (h->needs_plt);
01699 return TRUE;
01700 }
01701
01702 s = bfd_get_section_by_name (dynobj, ".plt");
01703 BFD_ASSERT (s != NULL);
01704
01705
01706 if (s->size == 0)
01707 s->size = PLT_HEADER_SIZE;
01708
01709
01710 h->plt.offset = s->size / PLT_ENTRY_SIZE;
01711
01712
01713
01714
01715
01716
01717 if (! info->shared
01718 && !h->def_regular)
01719 {
01720 h->root.u.def.section = s;
01721 h->root.u.def.value = sparc64_elf_plt_entry_offset (h->plt.offset);
01722 }
01723
01724
01725 s->size += PLT_ENTRY_SIZE;
01726
01727
01728
01729 s = bfd_get_section_by_name (dynobj, ".rela.plt");
01730 BFD_ASSERT (s != NULL);
01731
01732 s->size += sizeof (Elf64_External_Rela);
01733
01734
01735
01736 if (s->size >= (bfd_vma)1 << 32)
01737 {
01738 bfd_set_error (bfd_error_bad_value);
01739 return FALSE;
01740 }
01741
01742 return TRUE;
01743 }
01744
01745
01746
01747
01748 if (h->u.weakdef != NULL)
01749 {
01750 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
01751 || h->u.weakdef->root.type == bfd_link_hash_defweak);
01752 h->root.u.def.section = h->u.weakdef->root.u.def.section;
01753 h->root.u.def.value = h->u.weakdef->root.u.def.value;
01754 return TRUE;
01755 }
01756
01757
01758
01759
01760
01761
01762
01763
01764 if (info->shared)
01765 return TRUE;
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777 s = bfd_get_section_by_name (dynobj, ".dynbss");
01778 BFD_ASSERT (s != NULL);
01779
01780
01781
01782
01783
01784 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
01785 {
01786 asection *srel;
01787
01788 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
01789 BFD_ASSERT (srel != NULL);
01790 srel->size += sizeof (Elf64_External_Rela);
01791 h->needs_copy = 1;
01792 }
01793
01794
01795
01796
01797 power_of_two = bfd_log2 (h->size);
01798 if (power_of_two > 4)
01799 power_of_two = 4;
01800
01801
01802 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
01803 if (power_of_two > bfd_get_section_alignment (dynobj, s))
01804 {
01805 if (! bfd_set_section_alignment (dynobj, s, power_of_two))
01806 return FALSE;
01807 }
01808
01809
01810 h->root.u.def.section = s;
01811 h->root.u.def.value = s->size;
01812
01813
01814 s->size += h->size;
01815
01816 return TRUE;
01817 }
01818
01819
01820
01821
01822 static bfd_boolean
01823 sparc64_elf_omit_section_dynsym (bfd *output_bfd,
01824 struct bfd_link_info *info,
01825 asection *p)
01826 {
01827
01828
01829
01830 if (strcmp (p->name, ".got") == 0)
01831 return FALSE;
01832
01833 return _bfd_elf_link_omit_section_dynsym (output_bfd, info, p);
01834 }
01835
01836
01837
01838 static bfd_boolean
01839 sparc64_elf_size_dynamic_sections (output_bfd, info)
01840 bfd *output_bfd;
01841 struct bfd_link_info *info;
01842 {
01843 bfd *dynobj;
01844 asection *s;
01845 bfd_boolean relplt;
01846
01847 dynobj = elf_hash_table (info)->dynobj;
01848 BFD_ASSERT (dynobj != NULL);
01849
01850 if (elf_hash_table (info)->dynamic_sections_created)
01851 {
01852
01853 if (info->executable)
01854 {
01855 s = bfd_get_section_by_name (dynobj, ".interp");
01856 BFD_ASSERT (s != NULL);
01857 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
01858 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
01859 }
01860 }
01861 else
01862 {
01863
01864
01865
01866
01867
01868 s = sparc64_elf_hash_table (info)->srelgot;
01869 if (s != NULL)
01870 s->size = 0;
01871 }
01872
01873
01874
01875
01876 relplt = FALSE;
01877 for (s = dynobj->sections; s != NULL; s = s->next)
01878 {
01879 const char *name;
01880 bfd_boolean strip;
01881
01882 if ((s->flags & SEC_LINKER_CREATED) == 0)
01883 continue;
01884
01885
01886
01887 name = bfd_get_section_name (dynobj, s);
01888
01889 strip = FALSE;
01890
01891 if (strncmp (name, ".rela", 5) == 0)
01892 {
01893 if (s->size == 0)
01894 {
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904 strip = TRUE;
01905 }
01906 else
01907 {
01908 if (strcmp (name, ".rela.plt") == 0)
01909 relplt = TRUE;
01910
01911
01912
01913 s->reloc_count = 0;
01914 }
01915 }
01916 else if (strcmp (name, ".plt") != 0
01917 && strncmp (name, ".got", 4) != 0)
01918 {
01919
01920 continue;
01921 }
01922
01923 if (strip)
01924 {
01925 _bfd_strip_section_from_output (info, s);
01926 continue;
01927 }
01928
01929
01930
01931
01932 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
01933 if (s->contents == NULL && s->size != 0)
01934 return FALSE;
01935 }
01936
01937 if (elf_hash_table (info)->dynamic_sections_created)
01938 {
01939
01940
01941
01942
01943
01944 #define add_dynamic_entry(TAG, VAL) \
01945 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
01946
01947 int reg;
01948 struct sparc64_elf_app_reg * app_regs;
01949 struct elf_strtab_hash *dynstr;
01950 struct elf_link_hash_table *eht = elf_hash_table (info);
01951
01952 if (info->executable)
01953 {
01954 if (!add_dynamic_entry (DT_DEBUG, 0))
01955 return FALSE;
01956 }
01957
01958 if (relplt)
01959 {
01960 if (!add_dynamic_entry (DT_PLTGOT, 0)
01961 || !add_dynamic_entry (DT_PLTRELSZ, 0)
01962 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
01963 || !add_dynamic_entry (DT_JMPREL, 0))
01964 return FALSE;
01965 }
01966
01967 if (!add_dynamic_entry (DT_RELA, 0)
01968 || !add_dynamic_entry (DT_RELASZ, 0)
01969 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
01970 return FALSE;
01971
01972 if (info->flags & DF_TEXTREL)
01973 {
01974 if (!add_dynamic_entry (DT_TEXTREL, 0))
01975 return FALSE;
01976 }
01977
01978
01979
01980 app_regs = sparc64_elf_hash_table (info)->app_regs;
01981 dynstr = eht->dynstr;
01982
01983 for (reg = 0; reg < 4; reg++)
01984 if (app_regs [reg].name != NULL)
01985 {
01986 struct elf_link_local_dynamic_entry *entry, *e;
01987
01988 if (!add_dynamic_entry (DT_SPARC_REGISTER, 0))
01989 return FALSE;
01990
01991 entry = (struct elf_link_local_dynamic_entry *)
01992 bfd_hash_allocate (&info->hash->table, sizeof (*entry));
01993 if (entry == NULL)
01994 return FALSE;
01995
01996
01997
01998
01999 entry->isym.st_value = reg < 2 ? reg + 2 : reg + 4;
02000 entry->isym.st_size = 0;
02001 if (*app_regs [reg].name != '\0')
02002 entry->isym.st_name
02003 = _bfd_elf_strtab_add (dynstr, app_regs[reg].name, FALSE);
02004 else
02005 entry->isym.st_name = 0;
02006 entry->isym.st_other = 0;
02007 entry->isym.st_info = ELF_ST_INFO (app_regs [reg].bind,
02008 STT_REGISTER);
02009 entry->isym.st_shndx = app_regs [reg].shndx;
02010 entry->next = NULL;
02011 entry->input_bfd = output_bfd;
02012 entry->input_indx = -1;
02013
02014 if (eht->dynlocal == NULL)
02015 eht->dynlocal = entry;
02016 else
02017 {
02018 for (e = eht->dynlocal; e->next; e = e->next)
02019 ;
02020 e->next = entry;
02021 }
02022 eht->dynsymcount++;
02023 }
02024 }
02025 #undef add_dynamic_entry
02026
02027 return TRUE;
02028 }
02029
02030 static bfd_boolean
02031 sparc64_elf_new_section_hook (abfd, sec)
02032 bfd *abfd;
02033 asection *sec;
02034 {
02035 struct sparc64_elf_section_data *sdata;
02036 bfd_size_type amt = sizeof (*sdata);
02037
02038 sdata = (struct sparc64_elf_section_data *) bfd_zalloc (abfd, amt);
02039 if (sdata == NULL)
02040 return FALSE;
02041 sec->used_by_bfd = (PTR) sdata;
02042
02043 return _bfd_elf_new_section_hook (abfd, sec);
02044 }
02045
02046 static bfd_boolean
02047 sparc64_elf_relax_section (abfd, section, link_info, again)
02048 bfd *abfd ATTRIBUTE_UNUSED;
02049 asection *section ATTRIBUTE_UNUSED;
02050 struct bfd_link_info *link_info ATTRIBUTE_UNUSED;
02051 bfd_boolean *again;
02052 {
02053 *again = FALSE;
02054 sec_do_relax (section) = 1;
02055 return TRUE;
02056 }
02057
02058
02059
02060 static bfd_boolean
02061 sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
02062 contents, relocs, local_syms, local_sections)
02063 bfd *output_bfd;
02064 struct bfd_link_info *info;
02065 bfd *input_bfd;
02066 asection *input_section;
02067 bfd_byte *contents;
02068 Elf_Internal_Rela *relocs;
02069 Elf_Internal_Sym *local_syms;
02070 asection **local_sections;
02071 {
02072 bfd *dynobj;
02073 Elf_Internal_Shdr *symtab_hdr;
02074 struct elf_link_hash_entry **sym_hashes;
02075 bfd_vma *local_got_offsets;
02076 bfd_vma got_base;
02077 asection *sgot;
02078 asection *splt;
02079 asection *sreloc;
02080 Elf_Internal_Rela *rel;
02081 Elf_Internal_Rela *relend;
02082
02083 if (info->relocatable)
02084 return TRUE;
02085
02086 dynobj = elf_hash_table (info)->dynobj;
02087 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
02088 sym_hashes = elf_sym_hashes (input_bfd);
02089 local_got_offsets = elf_local_got_offsets (input_bfd);
02090
02091 if (elf_hash_table(info)->hgot == NULL)
02092 got_base = 0;
02093 else
02094 got_base = elf_hash_table (info)->hgot->root.u.def.value;
02095
02096 sgot = splt = sreloc = NULL;
02097 if (dynobj != NULL)
02098 splt = bfd_get_section_by_name (dynobj, ".plt");
02099
02100 rel = relocs;
02101 relend = relocs + NUM_SHDR_ENTRIES (& elf_section_data (input_section)->rel_hdr);
02102 for (; rel < relend; rel++)
02103 {
02104 int r_type;
02105 reloc_howto_type *howto;
02106 unsigned long r_symndx;
02107 struct elf_link_hash_entry *h;
02108 Elf_Internal_Sym *sym;
02109 asection *sec;
02110 bfd_vma relocation, off;
02111 bfd_reloc_status_type r;
02112 bfd_boolean is_plt = FALSE;
02113 bfd_boolean unresolved_reloc;
02114
02115 r_type = ELF64_R_TYPE_ID (rel->r_info);
02116 if (r_type < 0 || r_type >= (int) R_SPARC_max_std)
02117 {
02118 bfd_set_error (bfd_error_bad_value);
02119 return FALSE;
02120 }
02121 howto = sparc64_elf_howto_table + r_type;
02122
02123
02124 r_symndx = ELF64_R_SYM (rel->r_info);
02125 h = NULL;
02126 sym = NULL;
02127 sec = NULL;
02128 unresolved_reloc = FALSE;
02129 if (r_symndx < symtab_hdr->sh_info)
02130 {
02131 sym = local_syms + r_symndx;
02132 sec = local_sections[r_symndx];
02133 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
02134 }
02135 else
02136 {
02137 bfd_boolean warned;
02138
02139 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
02140 r_symndx, symtab_hdr, sym_hashes,
02141 h, sec, relocation,
02142 unresolved_reloc, warned);
02143 if (warned)
02144 {
02145
02146
02147
02148 if (input_section->output_section != NULL)
02149 relocation = input_section->output_section->vma;
02150 else
02151 relocation = 0;
02152 }
02153 }
02154
02155 do_dynreloc:
02156
02157
02158 if (info->shared && r_symndx != 0 && (input_section->flags & SEC_ALLOC))
02159 {
02160 switch (r_type)
02161 {
02162 case R_SPARC_PC10:
02163 case R_SPARC_PC22:
02164 case R_SPARC_PC_HH22:
02165 case R_SPARC_PC_HM10:
02166 case R_SPARC_PC_LM22:
02167 if (h != NULL
02168 && !strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_"))
02169 break;
02170
02171 case R_SPARC_DISP8:
02172 case R_SPARC_DISP16:
02173 case R_SPARC_DISP32:
02174 case R_SPARC_DISP64:
02175 case R_SPARC_WDISP30:
02176 case R_SPARC_WDISP22:
02177 case R_SPARC_WDISP19:
02178 case R_SPARC_WDISP16:
02179 if (h == NULL)
02180 break;
02181
02182 case R_SPARC_8:
02183 case R_SPARC_16:
02184 case R_SPARC_32:
02185 case R_SPARC_HI22:
02186 case R_SPARC_22:
02187 case R_SPARC_13:
02188 case R_SPARC_LO10:
02189 case R_SPARC_UA32:
02190 case R_SPARC_10:
02191 case R_SPARC_11:
02192 case R_SPARC_64:
02193 case R_SPARC_OLO10:
02194 case R_SPARC_HH22:
02195 case R_SPARC_HM10:
02196 case R_SPARC_LM22:
02197 case R_SPARC_7:
02198 case R_SPARC_5:
02199 case R_SPARC_6:
02200 case R_SPARC_HIX22:
02201 case R_SPARC_LOX10:
02202 case R_SPARC_H44:
02203 case R_SPARC_M44:
02204 case R_SPARC_L44:
02205 case R_SPARC_UA64:
02206 case R_SPARC_UA16:
02207 {
02208 Elf_Internal_Rela outrel;
02209 bfd_byte *loc;
02210 bfd_boolean skip, relocate;
02211
02212 if (sreloc == NULL)
02213 {
02214 const char *name =
02215 (bfd_elf_string_from_elf_section
02216 (input_bfd,
02217 elf_elfheader (input_bfd)->e_shstrndx,
02218 elf_section_data (input_section)->rel_hdr.sh_name));
02219
02220 if (name == NULL)
02221 return FALSE;
02222
02223 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
02224 && strcmp (bfd_get_section_name(input_bfd,
02225 input_section),
02226 name + 5) == 0);
02227
02228 sreloc = bfd_get_section_by_name (dynobj, name);
02229 BFD_ASSERT (sreloc != NULL);
02230 }
02231
02232 skip = FALSE;
02233 relocate = FALSE;
02234
02235 outrel.r_offset =
02236 _bfd_elf_section_offset (output_bfd, info, input_section,
02237 rel->r_offset);
02238 if (outrel.r_offset == (bfd_vma) -1)
02239 skip = TRUE;
02240 else if (outrel.r_offset == (bfd_vma) -2)
02241 skip = TRUE, relocate = TRUE;
02242
02243 outrel.r_offset += (input_section->output_section->vma
02244 + input_section->output_offset);
02245
02246
02247
02248 switch (r_type)
02249 {
02250 case R_SPARC_16:
02251 if (outrel.r_offset & 1) r_type = R_SPARC_UA16;
02252 break;
02253 case R_SPARC_UA16:
02254 if (!(outrel.r_offset & 1)) r_type = R_SPARC_16;
02255 break;
02256 case R_SPARC_32:
02257 if (outrel.r_offset & 3) r_type = R_SPARC_UA32;
02258 break;
02259 case R_SPARC_UA32:
02260 if (!(outrel.r_offset & 3)) r_type = R_SPARC_32;
02261 break;
02262 case R_SPARC_64:
02263 if (outrel.r_offset & 7) r_type = R_SPARC_UA64;
02264 break;
02265 case R_SPARC_UA64:
02266 if (!(outrel.r_offset & 7)) r_type = R_SPARC_64;
02267 break;
02268 case R_SPARC_DISP8:
02269 case R_SPARC_DISP16:
02270 case R_SPARC_DISP32:
02271 case R_SPARC_DISP64:
02272
02273
02274
02275
02276
02277 if (h->dynindx == -1)
02278 skip = TRUE, relocate = TRUE;
02279 break;
02280 }
02281
02282
02283 if (!skip
02284 && h != NULL
02285 && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
02286 && h->root.type == bfd_link_hash_undefweak)
02287 skip = TRUE, relocate = TRUE;
02288
02289 if (skip)
02290 memset (&outrel, 0, sizeof outrel);
02291
02292
02293 else if (h != NULL && ! is_plt
02294 && ((! info->symbolic && h->dynindx != -1)
02295 || !h->def_regular))
02296 {
02297 BFD_ASSERT (h->dynindx != -1);
02298 outrel.r_info
02299 = ELF64_R_INFO (h->dynindx,
02300 ELF64_R_TYPE_INFO (
02301 ELF64_R_TYPE_DATA (rel->r_info),
02302 r_type));
02303 outrel.r_addend = rel->r_addend;
02304 }
02305 else
02306 {
02307 outrel.r_addend = relocation + rel->r_addend;
02308 if (r_type == R_SPARC_64)
02309 outrel.r_info = ELF64_R_INFO (0, R_SPARC_RELATIVE);
02310 else
02311 {
02312 long indx;
02313
02314 if (is_plt)
02315 sec = splt;
02316
02317 if (bfd_is_abs_section (sec))
02318 indx = 0;
02319 else if (sec == NULL || sec->owner == NULL)
02320 {
02321 bfd_set_error (bfd_error_bad_value);
02322 return FALSE;
02323 }
02324 else
02325 {
02326 asection *osec;
02327
02328 osec = sec->output_section;
02329 indx = elf_section_data (osec)->dynindx;
02330
02331
02332
02333
02334
02335
02336 outrel.r_addend -= osec->vma;
02337
02338
02339
02340 if (indx == 0)
02341 {
02342 BFD_FAIL ();
02343 (*_bfd_error_handler)
02344 (_("%B: probably compiled without -fPIC?"),
02345 input_bfd);
02346 bfd_set_error (bfd_error_bad_value);
02347 return FALSE;
02348 }
02349 }
02350
02351 outrel.r_info
02352 = ELF64_R_INFO (indx,
02353 ELF64_R_TYPE_INFO (
02354 ELF64_R_TYPE_DATA (rel->r_info),
02355 r_type));
02356 }
02357 }
02358
02359 loc = sreloc->contents;
02360 loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
02361 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
02362
02363
02364
02365 if (! relocate)
02366 continue;
02367 }
02368 break;
02369 }
02370 }
02371
02372 switch (r_type)
02373 {
02374 case R_SPARC_GOT10:
02375 case R_SPARC_GOT13:
02376 case R_SPARC_GOT22:
02377
02378
02379 if (sgot == NULL)
02380 {
02381 sgot = sparc64_elf_hash_table (info)->sgot;
02382 BFD_ASSERT (sgot != NULL);
02383 }
02384
02385 if (h != NULL)
02386 {
02387 bfd_boolean dyn;
02388
02389 off = h->got.offset;
02390 BFD_ASSERT (off != (bfd_vma) -1);
02391 dyn = elf_hash_table (info)->dynamic_sections_created;
02392
02393 if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
02394 || (info->shared
02395 && (info->symbolic
02396 || h->dynindx == -1
02397 || h->forced_local)
02398 && h->def_regular))
02399 {
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412 if ((off & 1) != 0)
02413 off &= ~1;
02414 else
02415 {
02416 bfd_put_64 (output_bfd, relocation,
02417 sgot->contents + off);
02418 h->got.offset |= 1;
02419 }
02420 }
02421 else
02422 unresolved_reloc = FALSE;
02423 }
02424 else
02425 {
02426 BFD_ASSERT (local_got_offsets != NULL);
02427 off = local_got_offsets[r_symndx];
02428 BFD_ASSERT (off != (bfd_vma) -1);
02429
02430
02431
02432
02433 if ((off & 1) != 0)
02434 off &= ~1;
02435 else
02436 {
02437 local_got_offsets[r_symndx] |= 1;
02438
02439 if (info->shared)
02440 {
02441 asection *s;
02442 Elf_Internal_Rela outrel;
02443 bfd_byte *loc;
02444
02445
02446
02447
02448
02449
02450 bfd_put_64 (output_bfd, (bfd_vma) 0,
02451 sgot->contents + off);
02452
02453
02454
02455 s = sparc64_elf_hash_table (info)->srelgot;
02456 BFD_ASSERT (s != NULL);
02457
02458 outrel.r_offset = (sgot->output_section->vma
02459 + sgot->output_offset
02460 + off);
02461 outrel.r_info = ELF64_R_INFO (0, R_SPARC_RELATIVE);
02462 outrel.r_addend = relocation;
02463 loc = s->contents;
02464 loc += s->reloc_count++ * sizeof (Elf64_External_Rela);
02465 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
02466 }
02467 else
02468 bfd_put_64 (output_bfd, relocation, sgot->contents + off);
02469 }
02470 }
02471 relocation = sgot->output_offset + off - got_base;
02472 goto do_default;
02473
02474 case R_SPARC_WPLT30:
02475 case R_SPARC_PLT32:
02476 case R_SPARC_HIPLT22:
02477 case R_SPARC_LOPLT10:
02478 case R_SPARC_PCPLT32:
02479 case R_SPARC_PCPLT22:
02480 case R_SPARC_PCPLT10:
02481 case R_SPARC_PLT64:
02482
02483
02484 BFD_ASSERT (h != NULL);
02485
02486 if (h->plt.offset == (bfd_vma) -1 || splt == NULL)
02487 {
02488
02489
02490
02491 goto do_default;
02492 }
02493
02494 relocation = (splt->output_section->vma
02495 + splt->output_offset
02496 + sparc64_elf_plt_entry_offset (h->plt.offset));
02497 unresolved_reloc = FALSE;
02498 if (r_type == R_SPARC_WPLT30)
02499 goto do_wplt30;
02500 if (r_type == R_SPARC_PLT32 || r_type == R_SPARC_PLT64)
02501 {
02502 r_type = r_type == R_SPARC_PLT32 ? R_SPARC_32 : R_SPARC_64;
02503 is_plt = TRUE;
02504 goto do_dynreloc;
02505 }
02506 goto do_default;
02507
02508 case R_SPARC_OLO10:
02509 {
02510 bfd_vma x;
02511
02512 relocation += rel->r_addend;
02513 relocation = (relocation & 0x3ff) + ELF64_R_TYPE_DATA (rel->r_info);
02514
02515 x = bfd_get_32 (input_bfd, contents + rel->r_offset);
02516 x = (x & ~(bfd_vma) 0x1fff) | (relocation & 0x1fff);
02517 bfd_put_32 (input_bfd, x, contents + rel->r_offset);
02518
02519 r = bfd_check_overflow (howto->complain_on_overflow,
02520 howto->bitsize, howto->rightshift,
02521 bfd_arch_bits_per_address (input_bfd),
02522 relocation);
02523 }
02524 break;
02525
02526 case R_SPARC_WDISP16:
02527 {
02528 bfd_vma x;
02529
02530 relocation += rel->r_addend;
02531
02532 relocation -= (input_section->output_section->vma
02533 + input_section->output_offset);
02534 relocation -= rel->r_offset;
02535
02536 x = bfd_get_32 (input_bfd, contents + rel->r_offset);
02537 x &= ~(bfd_vma) 0x303fff;
02538 x |= ((((relocation >> 2) & 0xc000) << 6)
02539 | ((relocation >> 2) & 0x3fff));
02540 bfd_put_32 (input_bfd, x, contents + rel->r_offset);
02541
02542 r = bfd_check_overflow (howto->complain_on_overflow,
02543 howto->bitsize, howto->rightshift,
02544 bfd_arch_bits_per_address (input_bfd),
02545 relocation);
02546 }
02547 break;
02548
02549 case R_SPARC_HIX22:
02550 {
02551 bfd_vma x;
02552
02553 relocation += rel->r_addend;
02554 relocation = relocation ^ MINUS_ONE;
02555
02556 x = bfd_get_32 (input_bfd, contents + rel->r_offset);
02557 x = (x & ~(bfd_vma) 0x3fffff) | ((relocation >> 10) & 0x3fffff);
02558 bfd_put_32 (input_bfd, x, contents + rel->r_offset);
02559
02560 r = bfd_check_overflow (howto->complain_on_overflow,
02561 howto->bitsize, howto->rightshift,
02562 bfd_arch_bits_per_address (input_bfd),
02563 relocation);
02564 }
02565 break;
02566
02567 case R_SPARC_LOX10:
02568 {
02569 bfd_vma x;
02570
02571 relocation += rel->r_addend;
02572 relocation = (relocation & 0x3ff) | 0x1c00;
02573
02574 x = bfd_get_32 (input_bfd, contents + rel->r_offset);
02575 x = (x & ~(bfd_vma) 0x1fff) | relocation;
02576 bfd_put_32 (input_bfd, x, contents + rel->r_offset);
02577
02578 r = bfd_reloc_ok;
02579 }
02580 break;
02581
02582 case R_SPARC_WDISP30:
02583 do_wplt30:
02584 if (sec_do_relax (input_section)
02585 && rel->r_offset + 4 < input_section->size)
02586 {
02587 #define G0 0
02588 #define O7 15
02589 #define XCC (2 << 20)
02590 #define COND(x) (((x)&0xf)<<25)
02591 #define CONDA COND(0x8)
02592 #define INSN_BPA (F2(0,1) | CONDA | BPRED | XCC)
02593 #define INSN_BA (F2(0,2) | CONDA)
02594 #define INSN_OR F3(2, 0x2, 0)
02595 #define INSN_NOP F2(0,4)
02596
02597 bfd_vma x, y;
02598
02599
02600
02601
02602
02603
02604
02605 x = bfd_get_32 (input_bfd, contents + rel->r_offset);
02606 y = bfd_get_32 (input_bfd, contents + rel->r_offset + 4);
02607 if ((x & OP(~0)) == OP(1) && (y & OP(~0)) == OP(2))
02608 {
02609 if (((y & OP3(~0)) == OP3(0x3d)
02610 || ((y & OP3(0x28)) == 0
02611 && (y & RD(~0)) == RD(O7)))
02612 && (y & RS1(~0)) != RS1(O7)
02613 && ((y & F3I(~0))
02614 || (y & RS2(~0)) != RS2(O7)))
02615 {
02616 bfd_vma reloc;
02617
02618 reloc = relocation + rel->r_addend - rel->r_offset;
02619 reloc -= (input_section->output_section->vma
02620 + input_section->output_offset);
02621 if (reloc & 3)
02622 goto do_default;
02623
02624
02625 if ((reloc & ~(bfd_vma)0x7fffff)
02626 && ((reloc | 0x7fffff) != MINUS_ONE))
02627 goto do_default;
02628 reloc >>= 2;
02629
02630
02631 if ((reloc & 0x3c0000) == 0
02632 || (reloc & 0x3c0000) == 0x3c0000)
02633 x = INSN_BPA | (reloc & 0x7ffff);
02634 else
02635 x = INSN_BA | (reloc & 0x3fffff);
02636 bfd_put_32 (input_bfd, x, contents + rel->r_offset);
02637 r = bfd_reloc_ok;
02638 if (rel->r_offset >= 4
02639 && (y & (0xffffffff ^ RS1(~0)))
02640 == (INSN_OR | RD(O7) | RS2(G0)))
02641 {
02642 bfd_vma z;
02643 unsigned int reg;
02644
02645 z = bfd_get_32 (input_bfd,
02646 contents + rel->r_offset - 4);
02647 if ((z & (0xffffffff ^ RD(~0)))
02648 != (INSN_OR | RS1(O7) | RS2(G0)))
02649 break;
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659 reg = (y & RS1(~0)) >> 14;
02660 if (reg != ((z & RD(~0)) >> 25)
02661 || reg == G0 || reg == O7)
02662 break;
02663
02664 bfd_put_32 (input_bfd, (bfd_vma) INSN_NOP,
02665 contents + rel->r_offset + 4);
02666 }
02667 break;
02668 }
02669 }
02670 }
02671
02672
02673 default:
02674 do_default:
02675 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
02676 contents, rel->r_offset,
02677 relocation, rel->r_addend);
02678 break;
02679 }
02680
02681
02682
02683
02684 if (unresolved_reloc
02685 && !((input_section->flags & SEC_DEBUGGING) != 0
02686 && h->def_dynamic))
02687 (*_bfd_error_handler)
02688 (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
02689 input_bfd, input_section,
02690 (long) rel->r_offset,
02691 h->root.root.string);
02692
02693 switch (r)
02694 {
02695 case bfd_reloc_ok:
02696 break;
02697
02698 default:
02699 case bfd_reloc_outofrange:
02700 abort ();
02701
02702 case bfd_reloc_overflow:
02703 {
02704 const char *name;
02705
02706
02707
02708
02709
02710 if ((r_type == R_SPARC_32 || r_type == R_SPARC_DISP32)
02711 && (((input_section->flags & SEC_DEBUGGING) != 0
02712 && strcmp (bfd_section_name (input_bfd, input_section),
02713 ".stab") == 0)
02714 || _bfd_elf_section_offset (output_bfd, info,
02715 input_section,
02716 rel->r_offset) == (bfd_vma)-1))
02717 break;
02718
02719 if (h != NULL)
02720 {
02721 if (h->root.type == bfd_link_hash_undefweak
02722 && howto->pc_relative)
02723 {
02724
02725
02726
02727
02728
02729 break;
02730 }
02731
02732 name = NULL;
02733 }
02734 else
02735 {
02736 name = (bfd_elf_string_from_elf_section
02737 (input_bfd,
02738 symtab_hdr->sh_link,
02739 sym->st_name));
02740 if (name == NULL)
02741 return FALSE;
02742 if (*name == '\0')
02743 name = bfd_section_name (input_bfd, sec);
02744 }
02745 if (! ((*info->callbacks->reloc_overflow)
02746 (info, (h ? &h->root : NULL), name, howto->name,
02747 (bfd_vma) 0, input_bfd, input_section,
02748 rel->r_offset)))
02749 return FALSE;
02750 }
02751 break;
02752 }
02753 }
02754
02755 return TRUE;
02756 }
02757
02758
02759
02760
02761 static bfd_boolean
02762 sparc64_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
02763 bfd *output_bfd;
02764 struct bfd_link_info *info;
02765 struct elf_link_hash_entry *h;
02766 Elf_Internal_Sym *sym;
02767 {
02768 bfd *dynobj;
02769
02770 dynobj = elf_hash_table (info)->dynobj;
02771
02772 if (h->plt.offset != (bfd_vma) -1)
02773 {
02774 asection *splt;
02775 asection *srela;
02776 Elf_Internal_Rela rela;
02777 bfd_byte *loc;
02778
02779
02780
02781 BFD_ASSERT (h->dynindx != -1);
02782
02783 splt = bfd_get_section_by_name (dynobj, ".plt");
02784 srela = bfd_get_section_by_name (dynobj, ".rela.plt");
02785 BFD_ASSERT (splt != NULL && srela != NULL);
02786
02787
02788
02789 if (h->plt.offset < LARGE_PLT_THRESHOLD)
02790 {
02791 rela.r_offset = sparc64_elf_plt_entry_offset (h->plt.offset);
02792 rela.r_addend = 0;
02793 }
02794 else
02795 {
02796 bfd_vma max = splt->size / PLT_ENTRY_SIZE;
02797 rela.r_offset = sparc64_elf_plt_ptr_offset (h->plt.offset, max);
02798 rela.r_addend = -(sparc64_elf_plt_entry_offset (h->plt.offset) + 4)
02799 -(splt->output_section->vma + splt->output_offset);
02800 }
02801 rela.r_offset += (splt->output_section->vma + splt->output_offset);
02802 rela.r_info = ELF64_R_INFO (h->dynindx, R_SPARC_JMP_SLOT);
02803
02804
02805
02806
02807
02808
02809 loc = srela->contents;
02810 loc += (h->plt.offset - 4) * sizeof (Elf64_External_Rela);
02811 bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
02812
02813 if (!h->def_regular)
02814 {
02815
02816
02817 sym->st_shndx = SHN_UNDEF;
02818
02819
02820
02821
02822 if (!h->ref_regular_nonweak)
02823 sym->st_value = 0;
02824 }
02825 }
02826
02827 if (h->got.offset != (bfd_vma) -1)
02828 {
02829 asection *sgot;
02830 asection *srela;
02831 Elf_Internal_Rela rela;
02832 bfd_byte *loc;
02833
02834
02835
02836 sgot = sparc64_elf_hash_table (info)->sgot;
02837 srela = sparc64_elf_hash_table (info)->srelgot;
02838 BFD_ASSERT (sgot != NULL && srela != NULL);
02839
02840 rela.r_offset = (sgot->output_section->vma
02841 + sgot->output_offset
02842 + (h->got.offset &~ (bfd_vma) 1));
02843
02844
02845
02846
02847
02848
02849 if (info->shared
02850 && (info->symbolic || h->dynindx == -1)
02851 && h->def_regular)
02852 {
02853 asection *sec = h->root.u.def.section;
02854 rela.r_info = ELF64_R_INFO (0, R_SPARC_RELATIVE);
02855 rela.r_addend = (h->root.u.def.value
02856 + sec->output_section->vma
02857 + sec->output_offset);
02858 }
02859 else
02860 {
02861 rela.r_info = ELF64_R_INFO (h->dynindx, R_SPARC_GLOB_DAT);
02862 rela.r_addend = 0;
02863 }
02864
02865 bfd_put_64 (output_bfd, (bfd_vma) 0,
02866 sgot->contents + (h->got.offset &~ (bfd_vma) 1));
02867 loc = srela->contents;
02868 loc += srela->reloc_count++ * sizeof (Elf64_External_Rela);
02869 bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
02870 }
02871
02872 if (h->needs_copy)
02873 {
02874 asection *s;
02875 Elf_Internal_Rela rela;
02876 bfd_byte *loc;
02877
02878
02879 BFD_ASSERT (h->dynindx != -1);
02880
02881 s = bfd_get_section_by_name (h->root.u.def.section->owner,
02882 ".rela.bss");
02883 BFD_ASSERT (s != NULL);
02884
02885 rela.r_offset = (h->root.u.def.value
02886 + h->root.u.def.section->output_section->vma
02887 + h->root.u.def.section->output_offset);
02888 rela.r_info = ELF64_R_INFO (h->dynindx, R_SPARC_COPY);
02889 rela.r_addend = 0;
02890 loc = s->contents + s->reloc_count++ * sizeof (Elf64_External_Rela);
02891 bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
02892 }
02893
02894
02895 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
02896 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
02897 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
02898 sym->st_shndx = SHN_ABS;
02899
02900 return TRUE;
02901 }
02902
02903
02904
02905 static bfd_boolean
02906 sparc64_elf_finish_dynamic_sections (output_bfd, info)
02907 bfd *output_bfd;
02908 struct bfd_link_info *info;
02909 {
02910 bfd *dynobj;
02911 int stt_regidx = -1;
02912 asection *sdyn;
02913 asection *sgot;
02914
02915 dynobj = elf_hash_table (info)->dynobj;
02916
02917 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
02918
02919 if (elf_hash_table (info)->dynamic_sections_created)
02920 {
02921 asection *splt;
02922 Elf64_External_Dyn *dyncon, *dynconend;
02923
02924 splt = bfd_get_section_by_name (dynobj, ".plt");
02925 BFD_ASSERT (splt != NULL && sdyn != NULL);
02926
02927 dyncon = (Elf64_External_Dyn *) sdyn->contents;
02928 dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
02929 for (; dyncon < dynconend; dyncon++)
02930 {
02931 Elf_Internal_Dyn dyn;
02932 const char *name;
02933 bfd_boolean size;
02934
02935 bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
02936
02937 switch (dyn.d_tag)
02938 {
02939 case DT_PLTGOT: name = ".plt"; size = FALSE; break;
02940 case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break;
02941 case DT_JMPREL: name = ".rela.plt"; size = FALSE; break;
02942 case DT_SPARC_REGISTER:
02943 if (stt_regidx == -1)
02944 {
02945 stt_regidx =
02946 _bfd_elf_link_lookup_local_dynindx (info, output_bfd, -1);
02947 if (stt_regidx == -1)
02948 return FALSE;
02949 }
02950 dyn.d_un.d_val = stt_regidx++;
02951 bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
02952
02953 default: name = NULL; size = FALSE; break;
02954 }
02955
02956 if (name != NULL)
02957 {
02958 asection *s;
02959
02960 s = bfd_get_section_by_name (output_bfd, name);
02961 if (s == NULL)
02962 dyn.d_un.d_val = 0;
02963 else
02964 {
02965 if (! size)
02966 dyn.d_un.d_ptr = s->vma;
02967 else
02968 dyn.d_un.d_val = s->size;
02969 }
02970 bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
02971 }
02972 }
02973
02974
02975 if (splt->size > 0)
02976 sparc64_elf_build_plt (output_bfd, splt->contents,
02977 (int) (splt->size / PLT_ENTRY_SIZE));
02978
02979 elf_section_data (splt->output_section)->this_hdr.sh_entsize =
02980 PLT_ENTRY_SIZE;
02981 }
02982
02983
02984
02985 sgot = sparc64_elf_hash_table (info)->sgot;
02986 BFD_ASSERT (sgot != NULL);
02987 if (sgot->size > 0)
02988 {
02989 if (sdyn == NULL)
02990 bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents);
02991 else
02992 bfd_put_64 (output_bfd,
02993 sdyn->output_section->vma + sdyn->output_offset,
02994 sgot->contents);
02995 }
02996
02997 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 8;
02998
02999 return TRUE;
03000 }
03001
03002 static enum elf_reloc_type_class
03003 sparc64_elf_reloc_type_class (rela)
03004 const Elf_Internal_Rela *rela;
03005 {
03006 switch ((int) ELF64_R_TYPE (rela->r_info))
03007 {
03008 case R_SPARC_RELATIVE:
03009 return reloc_class_relative;
03010 case R_SPARC_JMP_SLOT:
03011 return reloc_class_plt;
03012 case R_SPARC_COPY:
03013 return reloc_class_copy;
03014 default:
03015 return reloc_class_normal;
03016 }
03017 }
03018
03019
03020
03021
03022
03023
03024 static bfd_boolean
03025 sparc64_elf_merge_private_bfd_data (ibfd, obfd)
03026 bfd *ibfd;
03027 bfd *obfd;
03028 {
03029 bfd_boolean error;
03030 flagword new_flags, old_flags;
03031 int new_mm, old_mm;
03032
03033 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
03034 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
03035 return TRUE;
03036
03037 new_flags = elf_elfheader (ibfd)->e_flags;
03038 old_flags = elf_elfheader (obfd)->e_flags;
03039
03040 if (!elf_flags_init (obfd))
03041 {
03042 elf_flags_init (obfd) = TRUE;
03043 elf_elfheader (obfd)->e_flags = new_flags;
03044 }
03045
03046 else if (new_flags == old_flags)
03047 ;
03048
03049 else
03050 {
03051 error = FALSE;
03052
03053 #define EF_SPARC_ISA_EXTENSIONS \
03054 (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3 | EF_SPARC_HAL_R1)
03055
03056 if ((ibfd->flags & DYNAMIC) != 0)
03057 {
03058
03059
03060
03061 new_flags &= ~(EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS);
03062 new_flags |= (old_flags
03063 & (EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS));
03064 }
03065 else
03066 {
03067
03068 old_flags |= (new_flags & EF_SPARC_ISA_EXTENSIONS);
03069 new_flags |= (old_flags & EF_SPARC_ISA_EXTENSIONS);
03070 if ((old_flags & (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3))
03071 && (old_flags & EF_SPARC_HAL_R1))
03072 {
03073 error = TRUE;
03074 (*_bfd_error_handler)
03075 (_("%B: linking UltraSPARC specific with HAL specific code"),
03076 ibfd);
03077 }
03078
03079 old_mm = (old_flags & EF_SPARCV9_MM);
03080 new_mm = (new_flags & EF_SPARCV9_MM);
03081 old_flags &= ~EF_SPARCV9_MM;
03082 new_flags &= ~EF_SPARCV9_MM;
03083 if (new_mm < old_mm)
03084 old_mm = new_mm;
03085 old_flags |= old_mm;
03086 new_flags |= old_mm;
03087 }
03088
03089
03090 if (new_flags != old_flags)
03091 {
03092 error = TRUE;
03093 (*_bfd_error_handler)
03094 (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
03095 ibfd, (long) new_flags, (long) old_flags);
03096 }
03097
03098 elf_elfheader (obfd)->e_flags = old_flags;
03099
03100 if (error)
03101 {
03102 bfd_set_error (bfd_error_bad_value);
03103 return FALSE;
03104 }
03105 }
03106 return TRUE;
03107 }
03108
03109
03110
03111 static bfd_boolean
03112 sparc64_elf_fake_sections (abfd, hdr, sec)
03113 bfd *abfd ATTRIBUTE_UNUSED;
03114 Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED;
03115 asection *sec;
03116 {
03117 const char *name;
03118
03119 name = bfd_get_section_name (abfd, sec);
03120
03121 if (strcmp (name, ".stab") == 0)
03122 {
03123
03124 elf_section_data (sec)->this_hdr.sh_entsize = 12;
03125 }
03126
03127 return TRUE;
03128 }
03129
03130
03131
03132 static const char *
03133 sparc64_elf_print_symbol_all (abfd, filep, symbol)
03134 bfd *abfd ATTRIBUTE_UNUSED;
03135 PTR filep;
03136 asymbol *symbol;
03137 {
03138 FILE *file = (FILE *) filep;
03139 int reg, type;
03140
03141 if (ELF_ST_TYPE (((elf_symbol_type *) symbol)->internal_elf_sym.st_info)
03142 != STT_REGISTER)
03143 return NULL;
03144
03145 reg = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
03146 type = symbol->flags;
03147 fprintf (file, "REG_%c%c%11s%c%c R", "GOLI" [reg / 8], '0' + (reg & 7), "",
03148 ((type & BSF_LOCAL)
03149 ? (type & BSF_GLOBAL) ? '!' : 'l'
03150 : (type & BSF_GLOBAL) ? 'g' : ' '),
03151 (type & BSF_WEAK) ? 'w' : ' ');
03152 if (symbol->name == NULL || symbol->name [0] == '\0')
03153 return "#scratch";
03154 else
03155 return symbol->name;
03156 }
03157
03158
03159
03160 static bfd_boolean
03161 sparc64_elf_object_p (abfd)
03162 bfd *abfd;
03163 {
03164 unsigned long mach = bfd_mach_sparc_v9;
03165
03166 if (elf_elfheader (abfd)->e_flags & EF_SPARC_SUN_US3)
03167 mach = bfd_mach_sparc_v9b;
03168 else if (elf_elfheader (abfd)->e_flags & EF_SPARC_SUN_US1)
03169 mach = bfd_mach_sparc_v9a;
03170 return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, mach);
03171 }
03172
03173
03174
03175
03176 static bfd_vma
03177 sparc64_elf_plt_sym_val (bfd_vma i, const asection *plt,
03178 const arelent *rel ATTRIBUTE_UNUSED)
03179 {
03180 bfd_vma j;
03181
03182 i += PLT_HEADER_SIZE / PLT_ENTRY_SIZE;
03183 if (i < LARGE_PLT_THRESHOLD)
03184 return plt->vma + i * PLT_ENTRY_SIZE;
03185
03186 j = (i - LARGE_PLT_THRESHOLD) % 160;
03187 i -= j;
03188 return plt->vma + i * PLT_ENTRY_SIZE + j * 4 * 6;
03189 }
03190
03191
03192
03193
03194
03195
03196 const struct elf_size_info sparc64_elf_size_info =
03197 {
03198 sizeof (Elf64_External_Ehdr),
03199 sizeof (Elf64_External_Phdr),
03200 sizeof (Elf64_External_Shdr),
03201 sizeof (Elf64_External_Rel),
03202 sizeof (Elf64_External_Rela),
03203 sizeof (Elf64_External_Sym),
03204 sizeof (Elf64_External_Dyn),
03205 sizeof (Elf_External_Note),
03206 4,
03207
03208
03209
03210
03211 1,
03212 64,
03213 3,
03214 ELFCLASS64,
03215 EV_CURRENT,
03216 bfd_elf64_write_out_phdrs,
03217 bfd_elf64_write_shdrs_and_ehdr,
03218 sparc64_elf_write_relocs,
03219 bfd_elf64_swap_symbol_in,
03220 bfd_elf64_swap_symbol_out,
03221 sparc64_elf_slurp_reloc_table,
03222 bfd_elf64_slurp_symbol_table,
03223 bfd_elf64_swap_dyn_in,
03224 bfd_elf64_swap_dyn_out,
03225 bfd_elf64_swap_reloc_in,
03226 bfd_elf64_swap_reloc_out,
03227 bfd_elf64_swap_reloca_in,
03228 bfd_elf64_swap_reloca_out
03229 };
03230
03231 #define TARGET_BIG_SYM bfd_elf64_sparc_vec
03232 #define TARGET_BIG_NAME "elf64-sparc"
03233 #define ELF_ARCH bfd_arch_sparc
03234 #define ELF_MAXPAGESIZE 0x100000
03235
03236
03237 #define ELF_MACHINE_CODE EM_SPARCV9
03238
03239
03240 #define ELF_MACHINE_ALT1 EM_OLD_SPARCV9
03241
03242 #define bfd_elf64_bfd_link_hash_table_create \
03243 sparc64_elf_bfd_link_hash_table_create
03244
03245 #define elf_info_to_howto \
03246 sparc64_elf_info_to_howto
03247 #define bfd_elf64_get_reloc_upper_bound \
03248 sparc64_elf_get_reloc_upper_bound
03249 #define bfd_elf64_get_dynamic_reloc_upper_bound \
03250 sparc64_elf_get_dynamic_reloc_upper_bound
03251 #define bfd_elf64_canonicalize_reloc \
03252 sparc64_elf_canonicalize_reloc
03253 #define bfd_elf64_canonicalize_dynamic_reloc \
03254 sparc64_elf_canonicalize_dynamic_reloc
03255 #define bfd_elf64_bfd_reloc_type_lookup \
03256 sparc64_elf_reloc_type_lookup
03257 #define bfd_elf64_bfd_relax_section \
03258 sparc64_elf_relax_section
03259 #define bfd_elf64_new_section_hook \
03260 sparc64_elf_new_section_hook
03261
03262 #define elf_backend_create_dynamic_sections \
03263 sparc64_elf_create_dynamic_sections
03264 #define elf_backend_add_symbol_hook \
03265 sparc64_elf_add_symbol_hook
03266 #define elf_backend_get_symbol_type \
03267 sparc64_elf_get_symbol_type
03268 #define elf_backend_symbol_processing \
03269 sparc64_elf_symbol_processing
03270 #define elf_backend_check_relocs \
03271 sparc64_elf_check_relocs
03272 #define elf_backend_adjust_dynamic_symbol \
03273 sparc64_elf_adjust_dynamic_symbol
03274 #define elf_backend_omit_section_dynsym \
03275 sparc64_elf_omit_section_dynsym
03276 #define elf_backend_size_dynamic_sections \
03277 sparc64_elf_size_dynamic_sections
03278 #define elf_backend_relocate_section \
03279 sparc64_elf_relocate_section
03280 #define elf_backend_finish_dynamic_symbol \
03281 sparc64_elf_finish_dynamic_symbol
03282 #define elf_backend_finish_dynamic_sections \
03283 sparc64_elf_finish_dynamic_sections
03284 #define elf_backend_print_symbol_all \
03285 sparc64_elf_print_symbol_all
03286 #define elf_backend_output_arch_syms \
03287 sparc64_elf_output_arch_syms
03288 #define bfd_elf64_bfd_merge_private_bfd_data \
03289 sparc64_elf_merge_private_bfd_data
03290 #define elf_backend_fake_sections \
03291 sparc64_elf_fake_sections
03292 #define elf_backend_plt_sym_val \
03293 sparc64_elf_plt_sym_val
03294
03295 #define elf_backend_size_info \
03296 sparc64_elf_size_info
03297 #define elf_backend_object_p \
03298 sparc64_elf_object_p
03299 #define elf_backend_reloc_type_class \
03300 sparc64_elf_reloc_type_class
03301
03302 #define elf_backend_want_got_plt 0
03303 #define elf_backend_plt_readonly 0
03304 #define elf_backend_want_plt_sym 1
03305 #define elf_backend_rela_normal 1
03306
03307
03308 #define elf_backend_plt_alignment 8
03309
03310 #define elf_backend_got_header_size 8
03311
03312 #include "elf64-target.h"