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