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