1 |
/* IBM S/390-specific support for 32-bit ELF |
/* IBM S/390-specific support for 32-bit ELF |
2 |
Copyright 2000, 2001, 2002 Free Software Foundation, Inc. |
Copyright 2000, 2001, 2002, 2003, 2004, 2005 |
3 |
|
Free Software Foundation, Inc. |
4 |
Contributed by Carl B. Pedersen and Martin Schwidefsky. |
Contributed by Carl B. Pedersen and Martin Schwidefsky. |
5 |
|
|
6 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
30 |
PARAMS ((bfd *, bfd_reloc_code_real_type)); |
PARAMS ((bfd *, bfd_reloc_code_real_type)); |
31 |
static void elf_s390_info_to_howto |
static void elf_s390_info_to_howto |
32 |
PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); |
PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); |
33 |
static boolean elf_s390_is_local_label_name |
static bfd_boolean elf_s390_is_local_label_name |
34 |
PARAMS ((bfd *, const char *)); |
PARAMS ((bfd *, const char *)); |
35 |
static struct bfd_hash_entry *link_hash_newfunc |
static struct bfd_hash_entry *link_hash_newfunc |
36 |
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); |
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); |
37 |
static struct bfd_link_hash_table *elf_s390_link_hash_table_create |
static struct bfd_link_hash_table *elf_s390_link_hash_table_create |
38 |
PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
39 |
static boolean create_got_section |
static bfd_boolean create_got_section |
40 |
PARAMS((bfd *, struct bfd_link_info *)); |
PARAMS((bfd *, struct bfd_link_info *)); |
41 |
static boolean elf_s390_create_dynamic_sections |
static bfd_boolean elf_s390_create_dynamic_sections |
42 |
PARAMS((bfd *, struct bfd_link_info *)); |
PARAMS((bfd *, struct bfd_link_info *)); |
43 |
static void elf_s390_copy_indirect_symbol |
static void elf_s390_copy_indirect_symbol |
44 |
PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *)); |
PARAMS ((const struct elf_backend_data *, struct elf_link_hash_entry *, |
45 |
static boolean elf_s390_check_relocs |
struct elf_link_hash_entry *)); |
46 |
|
static bfd_boolean elf_s390_check_relocs |
47 |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
48 |
const Elf_Internal_Rela *)); |
const Elf_Internal_Rela *)); |
49 |
static asection *elf_s390_gc_mark_hook |
static asection *elf_s390_gc_mark_hook |
50 |
PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, |
PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, |
51 |
struct elf_link_hash_entry *, Elf_Internal_Sym *)); |
struct elf_link_hash_entry *, Elf_Internal_Sym *)); |
52 |
static boolean elf_s390_gc_sweep_hook |
static bfd_boolean elf_s390_gc_sweep_hook |
53 |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
54 |
const Elf_Internal_Rela *)); |
const Elf_Internal_Rela *)); |
55 |
static boolean elf_s390_adjust_dynamic_symbol |
struct elf_s390_link_hash_entry; |
56 |
|
static void elf_s390_adjust_gotplt |
57 |
|
PARAMS ((struct elf_s390_link_hash_entry *)); |
58 |
|
static bfd_boolean elf_s390_adjust_dynamic_symbol |
59 |
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); |
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); |
60 |
static boolean allocate_dynrelocs |
static bfd_boolean allocate_dynrelocs |
61 |
PARAMS ((struct elf_link_hash_entry *, PTR)); |
PARAMS ((struct elf_link_hash_entry *, PTR)); |
62 |
static boolean readonly_dynrelocs |
static bfd_boolean readonly_dynrelocs |
63 |
PARAMS ((struct elf_link_hash_entry *, PTR)); |
PARAMS ((struct elf_link_hash_entry *, PTR)); |
64 |
static boolean elf_s390_size_dynamic_sections |
static bfd_boolean elf_s390_size_dynamic_sections |
65 |
PARAMS ((bfd *, struct bfd_link_info *)); |
PARAMS ((bfd *, struct bfd_link_info *)); |
66 |
static boolean elf_s390_relocate_section |
static bfd_boolean elf_s390_relocate_section |
67 |
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, |
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, |
68 |
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); |
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); |
69 |
static boolean elf_s390_finish_dynamic_symbol |
static bfd_boolean elf_s390_finish_dynamic_symbol |
70 |
PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, |
PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, |
71 |
Elf_Internal_Sym *)); |
Elf_Internal_Sym *)); |
72 |
static enum elf_reloc_type_class elf_s390_reloc_type_class |
static enum elf_reloc_type_class elf_s390_reloc_type_class |
73 |
PARAMS ((const Elf_Internal_Rela *)); |
PARAMS ((const Elf_Internal_Rela *)); |
74 |
static boolean elf_s390_finish_dynamic_sections |
static bfd_boolean elf_s390_finish_dynamic_sections |
75 |
PARAMS ((bfd *, struct bfd_link_info *)); |
PARAMS ((bfd *, struct bfd_link_info *)); |
76 |
static boolean elf_s390_object_p PARAMS ((bfd *)); |
static bfd_boolean elf_s390_mkobject |
77 |
static boolean elf_s390_grok_prstatus PARAMS ((bfd *, Elf_Internal_Note *)); |
PARAMS ((bfd *)); |
78 |
|
static bfd_boolean elf_s390_object_p |
79 |
#define USE_RELA 1 /* We want RELA relocations, not REL. */ |
PARAMS ((bfd *)); |
80 |
|
static bfd_boolean elf_s390_grok_prstatus |
81 |
|
PARAMS ((bfd *, Elf_Internal_Note *)); |
82 |
|
static int elf_s390_tls_transition |
83 |
|
PARAMS ((struct bfd_link_info *, int, int)); |
84 |
|
static bfd_reloc_status_type s390_tls_reloc |
85 |
|
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
86 |
|
static bfd_vma dtpoff_base |
87 |
|
PARAMS ((struct bfd_link_info *)); |
88 |
|
static bfd_vma tpoff |
89 |
|
PARAMS ((struct bfd_link_info *, bfd_vma)); |
90 |
|
static void invalid_tls_insn |
91 |
|
PARAMS ((bfd *, asection *, Elf_Internal_Rela *)); |
92 |
|
static bfd_reloc_status_type s390_elf_ldisp_reloc |
93 |
|
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
94 |
|
|
95 |
#include "elf/s390.h" |
#include "elf/s390.h" |
96 |
|
|
102 |
0, /* rightshift */ |
0, /* rightshift */ |
103 |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
104 |
0, /* bitsize */ |
0, /* bitsize */ |
105 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
106 |
0, /* bitpos */ |
0, /* bitpos */ |
107 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
108 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
109 |
"R_390_NONE", /* name */ |
"R_390_NONE", /* name */ |
110 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
111 |
0, /* src_mask */ |
0, /* src_mask */ |
112 |
0, /* dst_mask */ |
0, /* dst_mask */ |
113 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
114 |
|
|
115 |
HOWTO(R_390_8, 0, 0, 8, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_8", false, 0,0x000000ff, false), |
HOWTO(R_390_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, |
116 |
HOWTO(R_390_12, 0, 1, 12, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_390_12", false, 0,0x00000fff, false), |
bfd_elf_generic_reloc, "R_390_8", FALSE, 0,0x000000ff, FALSE), |
117 |
HOWTO(R_390_16, 0, 1, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_16", false, 0,0x0000ffff, false), |
HOWTO(R_390_12, 0, 1, 12, FALSE, 0, complain_overflow_dont, |
118 |
HOWTO(R_390_32, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_32", false, 0,0xffffffff, false), |
bfd_elf_generic_reloc, "R_390_12", FALSE, 0,0x00000fff, FALSE), |
119 |
HOWTO(R_390_PC32, 0, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC32", false, 0,0xffffffff, true), |
HOWTO(R_390_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, |
120 |
HOWTO(R_390_GOT12, 0, 1, 12, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_390_GOT12", false, 0,0x00000fff, false), |
bfd_elf_generic_reloc, "R_390_16", FALSE, 0,0x0000ffff, FALSE), |
121 |
HOWTO(R_390_GOT32, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT32", false, 0,0xffffffff, false), |
HOWTO(R_390_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
122 |
HOWTO(R_390_PLT32, 0, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT32", false, 0,0xffffffff, true), |
bfd_elf_generic_reloc, "R_390_32", FALSE, 0,0xffffffff, FALSE), |
123 |
HOWTO(R_390_COPY, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_COPY", false, 0,0xffffffff, false), |
HOWTO(R_390_PC32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, |
124 |
HOWTO(R_390_GLOB_DAT, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GLOB_DAT",false, 0,0xffffffff, false), |
bfd_elf_generic_reloc, "R_390_PC32", FALSE, 0,0xffffffff, TRUE), |
125 |
HOWTO(R_390_JMP_SLOT, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_JMP_SLOT",false, 0,0xffffffff, false), |
HOWTO(R_390_GOT12, 0, 1, 12, FALSE, 0, complain_overflow_bitfield, |
126 |
HOWTO(R_390_RELATIVE, 0, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_RELATIVE",false, 0,0xffffffff, false), |
bfd_elf_generic_reloc, "R_390_GOT12", FALSE, 0,0x00000fff, FALSE), |
127 |
HOWTO(R_390_GOTOFF, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTOFF", false, 0,0xffffffff, false), |
HOWTO(R_390_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
128 |
HOWTO(R_390_GOTPC, 0, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTPC", false, 0,0xffffffff, true), |
bfd_elf_generic_reloc, "R_390_GOT32", FALSE, 0,0xffffffff, FALSE), |
129 |
HOWTO(R_390_GOT16, 0, 1, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT16", false, 0,0x0000ffff, false), |
HOWTO(R_390_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, |
130 |
HOWTO(R_390_PC16, 0, 1, 16, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC16", false, 0,0x0000ffff, true), |
bfd_elf_generic_reloc, "R_390_PLT32", FALSE, 0,0xffffffff, TRUE), |
131 |
HOWTO(R_390_PC16DBL, 1, 1, 16, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC16DBL", false, 0,0x0000ffff, true), |
HOWTO(R_390_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
132 |
HOWTO(R_390_PLT16DBL, 1, 1, 16, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT16DBL", false, 0,0x0000ffff, true), |
bfd_elf_generic_reloc, "R_390_COPY", FALSE, 0,0xffffffff, FALSE), |
133 |
HOWTO(R_390_PC32DBL, 1, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC32DBL", false, 0,0xffffffff, true), |
HOWTO(R_390_GLOB_DAT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
134 |
HOWTO(R_390_PLT32DBL, 1, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT32DBL", false, 0,0xffffffff, true), |
bfd_elf_generic_reloc, "R_390_GLOB_DAT", FALSE, 0,0xffffffff, FALSE), |
135 |
HOWTO(R_390_GOTPCDBL, 1, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTPCDBL", false, 0,0xffffffff, true), |
HOWTO(R_390_JMP_SLOT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
136 |
HOWTO(R_390_GOTENT, 1, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTENT", false, 0,0xffffffff, true), |
bfd_elf_generic_reloc, "R_390_JMP_SLOT", FALSE, 0,0xffffffff, FALSE), |
137 |
|
HOWTO(R_390_RELATIVE, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, |
138 |
|
bfd_elf_generic_reloc, "R_390_RELATIVE", FALSE, 0,0xffffffff, FALSE), |
139 |
|
HOWTO(R_390_GOTOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
140 |
|
bfd_elf_generic_reloc, "R_390_GOTOFF32", FALSE, 0,0xffffffff, FALSE), |
141 |
|
HOWTO(R_390_GOTPC, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, |
142 |
|
bfd_elf_generic_reloc, "R_390_GOTPC", FALSE, 0,0xffffffff, TRUE), |
143 |
|
HOWTO(R_390_GOT16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, |
144 |
|
bfd_elf_generic_reloc, "R_390_GOT16", FALSE, 0,0x0000ffff, FALSE), |
145 |
|
HOWTO(R_390_PC16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield, |
146 |
|
bfd_elf_generic_reloc, "R_390_PC16", FALSE, 0,0x0000ffff, TRUE), |
147 |
|
HOWTO(R_390_PC16DBL, 1, 1, 16, TRUE, 0, complain_overflow_bitfield, |
148 |
|
bfd_elf_generic_reloc, "R_390_PC16DBL", FALSE, 0,0x0000ffff, TRUE), |
149 |
|
HOWTO(R_390_PLT16DBL, 1, 1, 16, TRUE, 0, complain_overflow_bitfield, |
150 |
|
bfd_elf_generic_reloc, "R_390_PLT16DBL", FALSE, 0,0x0000ffff, TRUE), |
151 |
|
HOWTO(R_390_PC32DBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield, |
152 |
|
bfd_elf_generic_reloc, "R_390_PC32DBL", FALSE, 0,0xffffffff, TRUE), |
153 |
|
HOWTO(R_390_PLT32DBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield, |
154 |
|
bfd_elf_generic_reloc, "R_390_PLT32DBL", FALSE, 0,0xffffffff, TRUE), |
155 |
|
HOWTO(R_390_GOTPCDBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield, |
156 |
|
bfd_elf_generic_reloc, "R_390_GOTPCDBL", FALSE, 0,0xffffffff, TRUE), |
157 |
|
EMPTY_HOWTO (R_390_64), /* Empty entry for R_390_64. */ |
158 |
|
EMPTY_HOWTO (R_390_PC64), /* Empty entry for R_390_PC64. */ |
159 |
|
EMPTY_HOWTO (R_390_GOT64), /* Empty entry for R_390_GOT64. */ |
160 |
|
EMPTY_HOWTO (R_390_PLT64), /* Empty entry for R_390_PLT64. */ |
161 |
|
HOWTO(R_390_GOTENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield, |
162 |
|
bfd_elf_generic_reloc, "R_390_GOTENT", FALSE, 0,0xffffffff, TRUE), |
163 |
|
HOWTO(R_390_GOTOFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, |
164 |
|
bfd_elf_generic_reloc, "R_390_GOTOFF16", FALSE, 0,0x0000ffff, FALSE), |
165 |
|
EMPTY_HOWTO (R_390_GOTOFF64), /* Empty entry for R_390_GOTOFF64. */ |
166 |
|
HOWTO(R_390_GOTPLT12, 0, 1, 12, FALSE, 0, complain_overflow_dont, |
167 |
|
bfd_elf_generic_reloc, "R_390_GOTPLT12", FALSE, 0,0x00000fff, FALSE), |
168 |
|
HOWTO(R_390_GOTPLT16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, |
169 |
|
bfd_elf_generic_reloc, "R_390_GOTPLT16", FALSE, 0,0x0000ffff, FALSE), |
170 |
|
HOWTO(R_390_GOTPLT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
171 |
|
bfd_elf_generic_reloc, "R_390_GOTPLT32", FALSE, 0,0xffffffff, FALSE), |
172 |
|
EMPTY_HOWTO (R_390_GOTPLT64), /* Empty entry for R_390_GOTPLT64. */ |
173 |
|
HOWTO(R_390_GOTPLTENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield, |
174 |
|
bfd_elf_generic_reloc, "R_390_GOTPLTENT",FALSE, 0,0xffffffff, TRUE), |
175 |
|
HOWTO(R_390_PLTOFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, |
176 |
|
bfd_elf_generic_reloc, "R_390_PLTOFF16", FALSE, 0,0x0000ffff, FALSE), |
177 |
|
HOWTO(R_390_PLTOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
178 |
|
bfd_elf_generic_reloc, "R_390_PLTOFF32", FALSE, 0,0xffffffff, FALSE), |
179 |
|
EMPTY_HOWTO (R_390_PLTOFF64), /* Empty entry for R_390_PLTOFF64. */ |
180 |
|
HOWTO(R_390_TLS_LOAD, 0, 0, 0, FALSE, 0, complain_overflow_dont, |
181 |
|
s390_tls_reloc, "R_390_TLS_LOAD", FALSE, 0, 0, FALSE), |
182 |
|
HOWTO(R_390_TLS_GDCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont, |
183 |
|
s390_tls_reloc, "R_390_TLS_GDCALL", FALSE, 0, 0, FALSE), |
184 |
|
HOWTO(R_390_TLS_LDCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont, |
185 |
|
s390_tls_reloc, "R_390_TLS_LDCALL", FALSE, 0, 0, FALSE), |
186 |
|
HOWTO(R_390_TLS_GD32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
187 |
|
bfd_elf_generic_reloc, "R_390_TLS_GD32", FALSE, 0, 0xffffffff, FALSE), |
188 |
|
EMPTY_HOWTO (R_390_TLS_GD64), /* Empty entry for R_390_TLS_GD64. */ |
189 |
|
HOWTO(R_390_TLS_GOTIE12, 0, 1, 12, FALSE, 0, complain_overflow_dont, |
190 |
|
bfd_elf_generic_reloc, "R_390_TLS_GOTIE12", FALSE, 0, 0x00000fff, FALSE), |
191 |
|
HOWTO(R_390_TLS_GOTIE32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
192 |
|
bfd_elf_generic_reloc, "R_390_TLS_GOTIE32", FALSE, 0, 0xffffffff, FALSE), |
193 |
|
EMPTY_HOWTO (R_390_TLS_GOTIE64), /* Empty entry for R_390_TLS_GOTIE64. */ |
194 |
|
HOWTO(R_390_TLS_LDM32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
195 |
|
bfd_elf_generic_reloc, "R_390_TLS_LDM32", FALSE, 0, 0xffffffff, FALSE), |
196 |
|
EMPTY_HOWTO (R_390_TLS_LDM64), /* Empty entry for R_390_TLS_LDM64. */ |
197 |
|
HOWTO(R_390_TLS_IE32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
198 |
|
bfd_elf_generic_reloc, "R_390_TLS_IE32", FALSE, 0, 0xffffffff, FALSE), |
199 |
|
EMPTY_HOWTO (R_390_TLS_IE64), /* Empty entry for R_390_TLS_IE64. */ |
200 |
|
HOWTO(R_390_TLS_IEENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield, |
201 |
|
bfd_elf_generic_reloc, "R_390_TLS_IEENT", FALSE, 0, 0xffffffff, TRUE), |
202 |
|
HOWTO(R_390_TLS_LE32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
203 |
|
bfd_elf_generic_reloc, "R_390_TLS_LE32", FALSE, 0, 0xffffffff, FALSE), |
204 |
|
EMPTY_HOWTO (R_390_TLS_LE64), /* Empty entry for R_390_TLS_LE64. */ |
205 |
|
HOWTO(R_390_TLS_LDO32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
206 |
|
bfd_elf_generic_reloc, "R_390_TLS_LDO32", FALSE, 0, 0xffffffff, FALSE), |
207 |
|
EMPTY_HOWTO (R_390_TLS_LDO64), /* Empty entry for R_390_TLS_LDO64. */ |
208 |
|
HOWTO(R_390_TLS_DTPMOD, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
209 |
|
bfd_elf_generic_reloc, "R_390_TLS_DTPMOD", FALSE, 0, 0xffffffff, FALSE), |
210 |
|
HOWTO(R_390_TLS_DTPOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
211 |
|
bfd_elf_generic_reloc, "R_390_TLS_DTPOFF", FALSE, 0, 0xffffffff, FALSE), |
212 |
|
HOWTO(R_390_TLS_TPOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, |
213 |
|
bfd_elf_generic_reloc, "R_390_TLS_TPOFF", FALSE, 0, 0xffffffff, FALSE), |
214 |
|
HOWTO(R_390_20, 0, 2, 20, FALSE, 8, complain_overflow_dont, |
215 |
|
s390_elf_ldisp_reloc, "R_390_20", FALSE, 0,0x0fffff00, FALSE), |
216 |
|
HOWTO(R_390_GOT20, 0, 2, 20, FALSE, 8, complain_overflow_dont, |
217 |
|
s390_elf_ldisp_reloc, "R_390_GOT20", FALSE, 0,0x0fffff00, FALSE), |
218 |
|
HOWTO(R_390_GOTPLT20, 0, 2, 20, FALSE, 8, complain_overflow_dont, |
219 |
|
s390_elf_ldisp_reloc, "R_390_GOTPLT20", FALSE, 0,0x0fffff00, FALSE), |
220 |
|
HOWTO(R_390_TLS_GOTIE20, 0, 2, 20, FALSE, 8, complain_overflow_dont, |
221 |
|
s390_elf_ldisp_reloc, "R_390_TLS_GOTIE20", FALSE, 0,0x0fffff00, FALSE), |
222 |
}; |
}; |
223 |
|
|
224 |
/* GNU extension to record C++ vtable hierarchy. */ |
/* GNU extension to record C++ vtable hierarchy. */ |
225 |
static reloc_howto_type elf32_s390_vtinherit_howto = |
static reloc_howto_type elf32_s390_vtinherit_howto = |
226 |
HOWTO (R_390_GNU_VTINHERIT, 0,2,0,false,0,complain_overflow_dont, NULL, "R_390_GNU_VTINHERIT", false,0, 0, false); |
HOWTO (R_390_GNU_VTINHERIT, 0,2,0,FALSE,0,complain_overflow_dont, NULL, "R_390_GNU_VTINHERIT", FALSE,0, 0, FALSE); |
227 |
static reloc_howto_type elf32_s390_vtentry_howto = |
static reloc_howto_type elf32_s390_vtentry_howto = |
228 |
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); |
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); |
229 |
|
|
230 |
static reloc_howto_type * |
static reloc_howto_type * |
231 |
elf_s390_reloc_type_lookup (abfd, code) |
elf_s390_reloc_type_lookup (abfd, code) |
263 |
case BFD_RELOC_390_RELATIVE: |
case BFD_RELOC_390_RELATIVE: |
264 |
return &elf_howto_table[(int) R_390_RELATIVE]; |
return &elf_howto_table[(int) R_390_RELATIVE]; |
265 |
case BFD_RELOC_32_GOTOFF: |
case BFD_RELOC_32_GOTOFF: |
266 |
return &elf_howto_table[(int) R_390_GOTOFF]; |
return &elf_howto_table[(int) R_390_GOTOFF32]; |
267 |
case BFD_RELOC_390_GOTPC: |
case BFD_RELOC_390_GOTPC: |
268 |
return &elf_howto_table[(int) R_390_GOTPC]; |
return &elf_howto_table[(int) R_390_GOTPC]; |
269 |
case BFD_RELOC_390_GOT16: |
case BFD_RELOC_390_GOT16: |
282 |
return &elf_howto_table[(int) R_390_GOTPCDBL]; |
return &elf_howto_table[(int) R_390_GOTPCDBL]; |
283 |
case BFD_RELOC_390_GOTENT: |
case BFD_RELOC_390_GOTENT: |
284 |
return &elf_howto_table[(int) R_390_GOTENT]; |
return &elf_howto_table[(int) R_390_GOTENT]; |
285 |
|
case BFD_RELOC_16_GOTOFF: |
286 |
|
return &elf_howto_table[(int) R_390_GOTOFF16]; |
287 |
|
case BFD_RELOC_390_GOTPLT12: |
288 |
|
return &elf_howto_table[(int) R_390_GOTPLT12]; |
289 |
|
case BFD_RELOC_390_GOTPLT16: |
290 |
|
return &elf_howto_table[(int) R_390_GOTPLT16]; |
291 |
|
case BFD_RELOC_390_GOTPLT32: |
292 |
|
return &elf_howto_table[(int) R_390_GOTPLT32]; |
293 |
|
case BFD_RELOC_390_GOTPLTENT: |
294 |
|
return &elf_howto_table[(int) R_390_GOTPLTENT]; |
295 |
|
case BFD_RELOC_390_PLTOFF16: |
296 |
|
return &elf_howto_table[(int) R_390_PLTOFF16]; |
297 |
|
case BFD_RELOC_390_PLTOFF32: |
298 |
|
return &elf_howto_table[(int) R_390_PLTOFF32]; |
299 |
|
case BFD_RELOC_390_TLS_LOAD: |
300 |
|
return &elf_howto_table[(int) R_390_TLS_LOAD]; |
301 |
|
case BFD_RELOC_390_TLS_GDCALL: |
302 |
|
return &elf_howto_table[(int) R_390_TLS_GDCALL]; |
303 |
|
case BFD_RELOC_390_TLS_LDCALL: |
304 |
|
return &elf_howto_table[(int) R_390_TLS_LDCALL]; |
305 |
|
case BFD_RELOC_390_TLS_GD32: |
306 |
|
return &elf_howto_table[(int) R_390_TLS_GD32]; |
307 |
|
case BFD_RELOC_390_TLS_GOTIE12: |
308 |
|
return &elf_howto_table[(int) R_390_TLS_GOTIE12]; |
309 |
|
case BFD_RELOC_390_TLS_GOTIE32: |
310 |
|
return &elf_howto_table[(int) R_390_TLS_GOTIE32]; |
311 |
|
case BFD_RELOC_390_TLS_LDM32: |
312 |
|
return &elf_howto_table[(int) R_390_TLS_LDM32]; |
313 |
|
case BFD_RELOC_390_TLS_IE32: |
314 |
|
return &elf_howto_table[(int) R_390_TLS_IE32]; |
315 |
|
case BFD_RELOC_390_TLS_IEENT: |
316 |
|
return &elf_howto_table[(int) R_390_TLS_IEENT]; |
317 |
|
case BFD_RELOC_390_TLS_LE32: |
318 |
|
return &elf_howto_table[(int) R_390_TLS_LE32]; |
319 |
|
case BFD_RELOC_390_TLS_LDO32: |
320 |
|
return &elf_howto_table[(int) R_390_TLS_LDO32]; |
321 |
|
case BFD_RELOC_390_TLS_DTPMOD: |
322 |
|
return &elf_howto_table[(int) R_390_TLS_DTPMOD]; |
323 |
|
case BFD_RELOC_390_TLS_DTPOFF: |
324 |
|
return &elf_howto_table[(int) R_390_TLS_DTPOFF]; |
325 |
|
case BFD_RELOC_390_TLS_TPOFF: |
326 |
|
return &elf_howto_table[(int) R_390_TLS_TPOFF]; |
327 |
|
case BFD_RELOC_390_20: |
328 |
|
return &elf_howto_table[(int) R_390_20]; |
329 |
|
case BFD_RELOC_390_GOT20: |
330 |
|
return &elf_howto_table[(int) R_390_GOT20]; |
331 |
|
case BFD_RELOC_390_GOTPLT20: |
332 |
|
return &elf_howto_table[(int) R_390_GOTPLT20]; |
333 |
|
case BFD_RELOC_390_TLS_GOTIE20: |
334 |
|
return &elf_howto_table[(int) R_390_TLS_GOTIE20]; |
335 |
case BFD_RELOC_VTABLE_INHERIT: |
case BFD_RELOC_VTABLE_INHERIT: |
336 |
return &elf32_s390_vtinherit_howto; |
return &elf32_s390_vtinherit_howto; |
337 |
case BFD_RELOC_VTABLE_ENTRY: |
case BFD_RELOC_VTABLE_ENTRY: |
367 |
} |
} |
368 |
} |
} |
369 |
|
|
370 |
static boolean |
/* A relocation function which doesn't do anything. */ |
371 |
|
static bfd_reloc_status_type |
372 |
|
s390_tls_reloc (abfd, reloc_entry, symbol, data, input_section, |
373 |
|
output_bfd, error_message) |
374 |
|
bfd *abfd ATTRIBUTE_UNUSED; |
375 |
|
arelent *reloc_entry; |
376 |
|
asymbol *symbol ATTRIBUTE_UNUSED; |
377 |
|
PTR data ATTRIBUTE_UNUSED; |
378 |
|
asection *input_section; |
379 |
|
bfd *output_bfd; |
380 |
|
char **error_message ATTRIBUTE_UNUSED; |
381 |
|
{ |
382 |
|
if (output_bfd) |
383 |
|
reloc_entry->address += input_section->output_offset; |
384 |
|
return bfd_reloc_ok; |
385 |
|
} |
386 |
|
|
387 |
|
/* Handle the large displacement relocs. */ |
388 |
|
static bfd_reloc_status_type |
389 |
|
s390_elf_ldisp_reloc (abfd, reloc_entry, symbol, data, input_section, |
390 |
|
output_bfd, error_message) |
391 |
|
bfd *abfd ATTRIBUTE_UNUSED; |
392 |
|
arelent *reloc_entry; |
393 |
|
asymbol *symbol; |
394 |
|
PTR data ATTRIBUTE_UNUSED; |
395 |
|
asection *input_section; |
396 |
|
bfd *output_bfd; |
397 |
|
char **error_message ATTRIBUTE_UNUSED; |
398 |
|
{ |
399 |
|
reloc_howto_type *howto = reloc_entry->howto; |
400 |
|
bfd_vma relocation; |
401 |
|
bfd_vma insn; |
402 |
|
|
403 |
|
if (output_bfd != (bfd *) NULL |
404 |
|
&& (symbol->flags & BSF_SECTION_SYM) == 0 |
405 |
|
&& (! howto->partial_inplace |
406 |
|
|| reloc_entry->addend == 0)) |
407 |
|
{ |
408 |
|
reloc_entry->address += input_section->output_offset; |
409 |
|
return bfd_reloc_ok; |
410 |
|
} |
411 |
|
|
412 |
|
if (output_bfd != NULL) |
413 |
|
return bfd_reloc_continue; |
414 |
|
|
415 |
|
if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) |
416 |
|
return bfd_reloc_outofrange; |
417 |
|
|
418 |
|
relocation = (symbol->value |
419 |
|
+ symbol->section->output_section->vma |
420 |
|
+ symbol->section->output_offset); |
421 |
|
relocation += reloc_entry->addend; |
422 |
|
if (howto->pc_relative) |
423 |
|
{ |
424 |
|
relocation -= (input_section->output_section->vma |
425 |
|
+ input_section->output_offset); |
426 |
|
relocation -= reloc_entry->address; |
427 |
|
} |
428 |
|
|
429 |
|
insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); |
430 |
|
insn |= (relocation & 0xfff) << 16 | (relocation & 0xff000) >> 4; |
431 |
|
bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address); |
432 |
|
|
433 |
|
if ((bfd_signed_vma) relocation < - 0x80000 |
434 |
|
|| (bfd_signed_vma) relocation > 0x7ffff) |
435 |
|
return bfd_reloc_overflow; |
436 |
|
else |
437 |
|
return bfd_reloc_ok; |
438 |
|
} |
439 |
|
|
440 |
|
static bfd_boolean |
441 |
elf_s390_is_local_label_name (abfd, name) |
elf_s390_is_local_label_name (abfd, name) |
442 |
bfd *abfd; |
bfd *abfd; |
443 |
const char *name; |
const char *name; |
444 |
{ |
{ |
445 |
if (name[0] == '.' && (name[1] == 'X' || name[1] == 'L')) |
if (name[0] == '.' && (name[1] == 'X' || name[1] == 'L')) |
446 |
return true; |
return TRUE; |
447 |
|
|
448 |
return _bfd_elf_is_local_label_name (abfd, name); |
return _bfd_elf_is_local_label_name (abfd, name); |
449 |
} |
} |
455 |
|
|
456 |
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" |
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" |
457 |
|
|
458 |
|
/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid |
459 |
|
copying dynamic variables from a shared lib into an app's dynbss |
460 |
|
section, and instead use a dynamic relocation to point into the |
461 |
|
shared lib. */ |
462 |
|
#define ELIMINATE_COPY_RELOCS 1 |
463 |
|
|
464 |
/* The size in bytes of the first entry in the procedure linkage table. */ |
/* The size in bytes of the first entry in the procedure linkage table. */ |
465 |
#define PLT_FIRST_ENTRY_SIZE 32 |
#define PLT_FIRST_ENTRY_SIZE 32 |
466 |
/* The size in bytes of an entry in the procedure linkage table. */ |
/* The size in bytes of an entry in the procedure linkage table. */ |
485 |
Word 1 is a pointer to a structure describing the object |
Word 1 is a pointer to a structure describing the object |
486 |
Word 2 is used to point to the loader entry address. |
Word 2 is used to point to the loader entry address. |
487 |
|
|
488 |
The code for position independand PLT entries looks like this: |
The code for position independent PLT entries looks like this: |
489 |
|
|
490 |
r12 holds addr of the current GOT at entry to the PLT |
r12 holds addr of the current GOT at entry to the PLT |
491 |
|
|
642 |
|
|
643 |
/* Track dynamic relocs copied for this symbol. */ |
/* Track dynamic relocs copied for this symbol. */ |
644 |
struct elf_s390_dyn_relocs *dyn_relocs; |
struct elf_s390_dyn_relocs *dyn_relocs; |
645 |
|
|
646 |
|
/* Number of GOTPLT references for a function. */ |
647 |
|
bfd_signed_vma gotplt_refcount; |
648 |
|
|
649 |
|
#define GOT_UNKNOWN 0 |
650 |
|
#define GOT_NORMAL 1 |
651 |
|
#define GOT_TLS_GD 2 |
652 |
|
#define GOT_TLS_IE 3 |
653 |
|
#define GOT_TLS_IE_NLT 4 |
654 |
|
unsigned char tls_type; |
655 |
|
}; |
656 |
|
|
657 |
|
#define elf_s390_hash_entry(ent) \ |
658 |
|
((struct elf_s390_link_hash_entry *)(ent)) |
659 |
|
|
660 |
|
struct elf_s390_obj_tdata |
661 |
|
{ |
662 |
|
struct elf_obj_tdata root; |
663 |
|
|
664 |
|
/* tls_type for each local got entry. */ |
665 |
|
char *local_got_tls_type; |
666 |
}; |
}; |
667 |
|
|
668 |
|
#define elf_s390_tdata(abfd) \ |
669 |
|
((struct elf_s390_obj_tdata *) (abfd)->tdata.any) |
670 |
|
|
671 |
|
#define elf_s390_local_got_tls_type(abfd) \ |
672 |
|
(elf_s390_tdata (abfd)->local_got_tls_type) |
673 |
|
|
674 |
|
static bfd_boolean |
675 |
|
elf_s390_mkobject (abfd) |
676 |
|
bfd *abfd; |
677 |
|
{ |
678 |
|
bfd_size_type amt = sizeof (struct elf_s390_obj_tdata); |
679 |
|
abfd->tdata.any = bfd_zalloc (abfd, amt); |
680 |
|
if (abfd->tdata.any == NULL) |
681 |
|
return FALSE; |
682 |
|
return TRUE; |
683 |
|
} |
684 |
|
|
685 |
|
static bfd_boolean |
686 |
|
elf_s390_object_p (abfd) |
687 |
|
bfd *abfd; |
688 |
|
{ |
689 |
|
/* Set the right machine number for an s390 elf32 file. */ |
690 |
|
return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_31); |
691 |
|
} |
692 |
|
|
693 |
/* s390 ELF linker hash table. */ |
/* s390 ELF linker hash table. */ |
694 |
|
|
695 |
struct elf_s390_link_hash_table |
struct elf_s390_link_hash_table |
705 |
asection *sdynbss; |
asection *sdynbss; |
706 |
asection *srelbss; |
asection *srelbss; |
707 |
|
|
708 |
|
union { |
709 |
|
bfd_signed_vma refcount; |
710 |
|
bfd_vma offset; |
711 |
|
} tls_ldm_got; |
712 |
|
|
713 |
/* Small local sym to section mapping cache. */ |
/* Small local sym to section mapping cache. */ |
714 |
struct sym_sec_cache sym_sec; |
struct sym_sec_cache sym_sec; |
715 |
}; |
}; |
745 |
|
|
746 |
eh = (struct elf_s390_link_hash_entry *) entry; |
eh = (struct elf_s390_link_hash_entry *) entry; |
747 |
eh->dyn_relocs = NULL; |
eh->dyn_relocs = NULL; |
748 |
|
eh->gotplt_refcount = 0; |
749 |
|
eh->tls_type = GOT_UNKNOWN; |
750 |
} |
} |
751 |
|
|
752 |
return entry; |
return entry; |
778 |
ret->srelplt = NULL; |
ret->srelplt = NULL; |
779 |
ret->sdynbss = NULL; |
ret->sdynbss = NULL; |
780 |
ret->srelbss = NULL; |
ret->srelbss = NULL; |
781 |
|
ret->tls_ldm_got.refcount = 0; |
782 |
ret->sym_sec.abfd = NULL; |
ret->sym_sec.abfd = NULL; |
783 |
|
|
784 |
return &ret->elf.root; |
return &ret->elf.root; |
787 |
/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up |
/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up |
788 |
shortcuts to them in our hash table. */ |
shortcuts to them in our hash table. */ |
789 |
|
|
790 |
static boolean |
static bfd_boolean |
791 |
create_got_section (dynobj, info) |
create_got_section (dynobj, info) |
792 |
bfd *dynobj; |
bfd *dynobj; |
793 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
795 |
struct elf_s390_link_hash_table *htab; |
struct elf_s390_link_hash_table *htab; |
796 |
|
|
797 |
if (! _bfd_elf_create_got_section (dynobj, info)) |
if (! _bfd_elf_create_got_section (dynobj, info)) |
798 |
return false; |
return FALSE; |
799 |
|
|
800 |
htab = elf_s390_hash_table (info); |
htab = elf_s390_hash_table (info); |
801 |
htab->sgot = bfd_get_section_by_name (dynobj, ".got"); |
htab->sgot = bfd_get_section_by_name (dynobj, ".got"); |
810 |
| SEC_IN_MEMORY | SEC_LINKER_CREATED |
| SEC_IN_MEMORY | SEC_LINKER_CREATED |
811 |
| SEC_READONLY)) |
| SEC_READONLY)) |
812 |
|| ! bfd_set_section_alignment (dynobj, htab->srelgot, 2)) |
|| ! bfd_set_section_alignment (dynobj, htab->srelgot, 2)) |
813 |
return false; |
return FALSE; |
814 |
return true; |
return TRUE; |
815 |
} |
} |
816 |
|
|
817 |
/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and |
/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and |
818 |
.rela.bss sections in DYNOBJ, and set up shortcuts to them in our |
.rela.bss sections in DYNOBJ, and set up shortcuts to them in our |
819 |
hash table. */ |
hash table. */ |
820 |
|
|
821 |
static boolean |
static bfd_boolean |
822 |
elf_s390_create_dynamic_sections (dynobj, info) |
elf_s390_create_dynamic_sections (dynobj, info) |
823 |
bfd *dynobj; |
bfd *dynobj; |
824 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
827 |
|
|
828 |
htab = elf_s390_hash_table (info); |
htab = elf_s390_hash_table (info); |
829 |
if (!htab->sgot && !create_got_section (dynobj, info)) |
if (!htab->sgot && !create_got_section (dynobj, info)) |
830 |
return false; |
return FALSE; |
831 |
|
|
832 |
if (!_bfd_elf_create_dynamic_sections (dynobj, info)) |
if (!_bfd_elf_create_dynamic_sections (dynobj, info)) |
833 |
return false; |
return FALSE; |
834 |
|
|
835 |
htab->splt = bfd_get_section_by_name (dynobj, ".plt"); |
htab->splt = bfd_get_section_by_name (dynobj, ".plt"); |
836 |
htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt"); |
htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt"); |
842 |
|| (!info->shared && !htab->srelbss)) |
|| (!info->shared && !htab->srelbss)) |
843 |
abort (); |
abort (); |
844 |
|
|
845 |
return true; |
return TRUE; |
846 |
} |
} |
847 |
|
|
848 |
/* Copy the extra info we tack onto an elf_link_hash_entry. */ |
/* Copy the extra info we tack onto an elf_link_hash_entry. */ |
849 |
|
|
850 |
static void |
static void |
851 |
elf_s390_copy_indirect_symbol (dir, ind) |
elf_s390_copy_indirect_symbol (bed, dir, ind) |
852 |
|
const struct elf_backend_data *bed; |
853 |
struct elf_link_hash_entry *dir, *ind; |
struct elf_link_hash_entry *dir, *ind; |
854 |
{ |
{ |
855 |
struct elf_s390_link_hash_entry *edir, *eind; |
struct elf_s390_link_hash_entry *edir, *eind; |
891 |
eind->dyn_relocs = NULL; |
eind->dyn_relocs = NULL; |
892 |
} |
} |
893 |
|
|
894 |
_bfd_elf_link_hash_copy_indirect (dir, ind); |
if (ind->root.type == bfd_link_hash_indirect |
895 |
|
&& dir->got.refcount <= 0) |
896 |
|
{ |
897 |
|
edir->tls_type = eind->tls_type; |
898 |
|
eind->tls_type = GOT_UNKNOWN; |
899 |
|
} |
900 |
|
|
901 |
|
if (ELIMINATE_COPY_RELOCS |
902 |
|
&& ind->root.type != bfd_link_hash_indirect |
903 |
|
&& dir->dynamic_adjusted) |
904 |
|
{ |
905 |
|
/* If called to transfer flags for a weakdef during processing |
906 |
|
of elf_adjust_dynamic_symbol, don't copy non_got_ref. |
907 |
|
We clear it ourselves for ELIMINATE_COPY_RELOCS. */ |
908 |
|
dir->ref_dynamic |= ind->ref_dynamic; |
909 |
|
dir->ref_regular |= ind->ref_regular; |
910 |
|
dir->ref_regular_nonweak |= ind->ref_regular_nonweak; |
911 |
|
dir->needs_plt |= ind->needs_plt; |
912 |
|
} |
913 |
|
else |
914 |
|
_bfd_elf_link_hash_copy_indirect (bed, dir, ind); |
915 |
|
} |
916 |
|
|
917 |
|
static int |
918 |
|
elf_s390_tls_transition (info, r_type, is_local) |
919 |
|
struct bfd_link_info *info; |
920 |
|
int r_type; |
921 |
|
int is_local; |
922 |
|
{ |
923 |
|
if (info->shared) |
924 |
|
return r_type; |
925 |
|
|
926 |
|
switch (r_type) |
927 |
|
{ |
928 |
|
case R_390_TLS_GD32: |
929 |
|
case R_390_TLS_IE32: |
930 |
|
if (is_local) |
931 |
|
return R_390_TLS_LE32; |
932 |
|
return R_390_TLS_IE32; |
933 |
|
case R_390_TLS_GOTIE32: |
934 |
|
if (is_local) |
935 |
|
return R_390_TLS_LE32; |
936 |
|
return R_390_TLS_GOTIE32; |
937 |
|
case R_390_TLS_LDM32: |
938 |
|
return R_390_TLS_LE32; |
939 |
|
} |
940 |
|
|
941 |
|
return r_type; |
942 |
} |
} |
943 |
|
|
944 |
/* Look through the relocs for a section during the first phase, and |
/* Look through the relocs for a section during the first phase, and |
945 |
allocate space in the global offset table or procedure linkage |
allocate space in the global offset table or procedure linkage |
946 |
table. */ |
table. */ |
947 |
|
|
948 |
static boolean |
static bfd_boolean |
949 |
elf_s390_check_relocs (abfd, info, sec, relocs) |
elf_s390_check_relocs (abfd, info, sec, relocs) |
950 |
bfd *abfd; |
bfd *abfd; |
951 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
958 |
const Elf_Internal_Rela *rel; |
const Elf_Internal_Rela *rel; |
959 |
const Elf_Internal_Rela *rel_end; |
const Elf_Internal_Rela *rel_end; |
960 |
asection *sreloc; |
asection *sreloc; |
961 |
|
bfd_signed_vma *local_got_refcounts; |
962 |
|
int tls_type, old_tls_type; |
963 |
|
|
964 |
if (info->relocateable) |
if (info->relocatable) |
965 |
return true; |
return TRUE; |
966 |
|
|
967 |
htab = elf_s390_hash_table (info); |
htab = elf_s390_hash_table (info); |
968 |
symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
969 |
sym_hashes = elf_sym_hashes (abfd); |
sym_hashes = elf_sym_hashes (abfd); |
970 |
|
local_got_refcounts = elf_local_got_refcounts (abfd); |
971 |
|
|
972 |
sreloc = NULL; |
sreloc = NULL; |
973 |
|
|
974 |
rel_end = relocs + sec->reloc_count; |
rel_end = relocs + sec->reloc_count; |
975 |
for (rel = relocs; rel < rel_end; rel++) |
for (rel = relocs; rel < rel_end; rel++) |
976 |
{ |
{ |
977 |
|
unsigned int r_type; |
978 |
unsigned long r_symndx; |
unsigned long r_symndx; |
979 |
struct elf_link_hash_entry *h; |
struct elf_link_hash_entry *h; |
980 |
|
|
982 |
|
|
983 |
if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) |
if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) |
984 |
{ |
{ |
985 |
(*_bfd_error_handler) (_("%s: bad symbol index: %d"), |
(*_bfd_error_handler) (_("%B: bad symbol index: %d"), |
986 |
bfd_archive_filename (abfd), |
abfd, r_symndx); |
987 |
r_symndx); |
return FALSE; |
|
return false; |
|
988 |
} |
} |
989 |
|
|
990 |
if (r_symndx < symtab_hdr->sh_info) |
if (r_symndx < symtab_hdr->sh_info) |
992 |
else |
else |
993 |
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
994 |
|
|
995 |
switch (ELF32_R_TYPE (rel->r_info)) |
/* Create got section and local_got_refcounts array if they |
996 |
|
are needed. */ |
997 |
|
r_type = elf_s390_tls_transition (info, |
998 |
|
ELF32_R_TYPE (rel->r_info), |
999 |
|
h == NULL); |
1000 |
|
switch (r_type) |
1001 |
{ |
{ |
1002 |
case R_390_GOT12: |
case R_390_GOT12: |
1003 |
case R_390_GOT16: |
case R_390_GOT16: |
1004 |
|
case R_390_GOT20: |
1005 |
case R_390_GOT32: |
case R_390_GOT32: |
1006 |
case R_390_GOTENT: |
case R_390_GOTENT: |
1007 |
/* This symbol requires a global offset table entry. */ |
case R_390_GOTPLT12: |
1008 |
if (h != NULL) |
case R_390_GOTPLT16: |
1009 |
|
case R_390_GOTPLT20: |
1010 |
|
case R_390_GOTPLT32: |
1011 |
|
case R_390_GOTPLTENT: |
1012 |
|
case R_390_TLS_GD32: |
1013 |
|
case R_390_TLS_GOTIE12: |
1014 |
|
case R_390_TLS_GOTIE20: |
1015 |
|
case R_390_TLS_GOTIE32: |
1016 |
|
case R_390_TLS_IEENT: |
1017 |
|
case R_390_TLS_IE32: |
1018 |
|
case R_390_TLS_LDM32: |
1019 |
|
if (h == NULL |
1020 |
|
&& local_got_refcounts == NULL) |
1021 |
{ |
{ |
1022 |
h->got.refcount += 1; |
bfd_size_type size; |
|
} |
|
|
else |
|
|
{ |
|
|
bfd_signed_vma *local_got_refcounts; |
|
1023 |
|
|
1024 |
/* This is a global offset table entry for a local symbol. */ |
size = symtab_hdr->sh_info; |
1025 |
local_got_refcounts = elf_local_got_refcounts (abfd); |
size *= (sizeof (bfd_signed_vma) + sizeof(char)); |
1026 |
|
local_got_refcounts = ((bfd_signed_vma *) |
1027 |
|
bfd_zalloc (abfd, size)); |
1028 |
if (local_got_refcounts == NULL) |
if (local_got_refcounts == NULL) |
1029 |
{ |
return FALSE; |
1030 |
bfd_size_type size; |
elf_local_got_refcounts (abfd) = local_got_refcounts; |
1031 |
|
elf_s390_local_got_tls_type (abfd) |
1032 |
size = symtab_hdr->sh_info; |
= (char *) (local_got_refcounts + symtab_hdr->sh_info); |
|
size *= sizeof (bfd_signed_vma); |
|
|
local_got_refcounts = ((bfd_signed_vma *) |
|
|
bfd_zalloc (abfd, size)); |
|
|
if (local_got_refcounts == NULL) |
|
|
return false; |
|
|
elf_local_got_refcounts (abfd) = local_got_refcounts; |
|
|
} |
|
|
local_got_refcounts[r_symndx] += 1; |
|
1033 |
} |
} |
1034 |
/* Fall through */ |
/* Fall through. */ |
1035 |
|
case R_390_GOTOFF16: |
1036 |
case R_390_GOTOFF: |
case R_390_GOTOFF32: |
1037 |
case R_390_GOTPC: |
case R_390_GOTPC: |
1038 |
case R_390_GOTPCDBL: |
case R_390_GOTPCDBL: |
1039 |
if (htab->sgot == NULL) |
if (htab->sgot == NULL) |
1041 |
if (htab->elf.dynobj == NULL) |
if (htab->elf.dynobj == NULL) |
1042 |
htab->elf.dynobj = abfd; |
htab->elf.dynobj = abfd; |
1043 |
if (!create_got_section (htab->elf.dynobj, info)) |
if (!create_got_section (htab->elf.dynobj, info)) |
1044 |
return false; |
return FALSE; |
1045 |
} |
} |
1046 |
|
} |
1047 |
|
|
1048 |
|
switch (r_type) |
1049 |
|
{ |
1050 |
|
case R_390_GOTOFF16: |
1051 |
|
case R_390_GOTOFF32: |
1052 |
|
case R_390_GOTPC: |
1053 |
|
case R_390_GOTPCDBL: |
1054 |
|
/* Got is created, nothing to be done. */ |
1055 |
break; |
break; |
1056 |
|
|
1057 |
case R_390_PLT16DBL: |
case R_390_PLT16DBL: |
1058 |
case R_390_PLT32DBL: |
case R_390_PLT32DBL: |
1059 |
case R_390_PLT32: |
case R_390_PLT32: |
1060 |
|
case R_390_PLTOFF16: |
1061 |
|
case R_390_PLTOFF32: |
1062 |
/* This symbol requires a procedure linkage table entry. We |
/* This symbol requires a procedure linkage table entry. We |
1063 |
actually build the entry in adjust_dynamic_symbol, |
actually build the entry in adjust_dynamic_symbol, |
1064 |
because this might be a case of linking PIC code which is |
because this might be a case of linking PIC code which is |
1065 |
never referenced by a dynamic object, in which case we |
never referenced by a dynamic object, in which case we |
1066 |
don't need to generate a procedure linkage table entry |
don't need to generate a procedure linkage table entry |
1067 |
after all. */ |
after all. */ |
1068 |
|
|
1069 |
/* If this is a local symbol, we resolve it directly without |
/* If this is a local symbol, we resolve it directly without |
1070 |
creating a procedure linkage table entry. */ |
creating a procedure linkage table entry. */ |
1071 |
if (h == NULL) |
if (h != NULL) |
1072 |
continue; |
{ |
1073 |
|
h->needs_plt = 1; |
1074 |
|
h->plt.refcount += 1; |
1075 |
|
} |
1076 |
|
break; |
1077 |
|
|
1078 |
|
case R_390_GOTPLT12: |
1079 |
|
case R_390_GOTPLT16: |
1080 |
|
case R_390_GOTPLT20: |
1081 |
|
case R_390_GOTPLT32: |
1082 |
|
case R_390_GOTPLTENT: |
1083 |
|
/* This symbol requires either a procedure linkage table entry |
1084 |
|
or an entry in the local got. We actually build the entry |
1085 |
|
in adjust_dynamic_symbol because whether this is really a |
1086 |
|
global reference can change and with it the fact if we have |
1087 |
|
to create a plt entry or a local got entry. To be able to |
1088 |
|
make a once global symbol a local one we have to keep track |
1089 |
|
of the number of gotplt references that exist for this |
1090 |
|
symbol. */ |
1091 |
|
if (h != NULL) |
1092 |
|
{ |
1093 |
|
((struct elf_s390_link_hash_entry *) h)->gotplt_refcount++; |
1094 |
|
h->needs_plt = 1; |
1095 |
|
h->plt.refcount += 1; |
1096 |
|
} |
1097 |
|
else |
1098 |
|
local_got_refcounts[r_symndx] += 1; |
1099 |
|
break; |
1100 |
|
|
1101 |
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; |
case R_390_TLS_LDM32: |
1102 |
h->plt.refcount += 1; |
htab->tls_ldm_got.refcount += 1; |
1103 |
break; |
break; |
1104 |
|
|
1105 |
case R_390_8: |
case R_390_TLS_IE32: |
1106 |
case R_390_16: |
case R_390_TLS_GOTIE12: |
1107 |
|
case R_390_TLS_GOTIE20: |
1108 |
|
case R_390_TLS_GOTIE32: |
1109 |
|
case R_390_TLS_IEENT: |
1110 |
|
if (info->shared) |
1111 |
|
info->flags |= DF_STATIC_TLS; |
1112 |
|
/* Fall through. */ |
1113 |
|
|
1114 |
|
case R_390_GOT12: |
1115 |
|
case R_390_GOT16: |
1116 |
|
case R_390_GOT20: |
1117 |
|
case R_390_GOT32: |
1118 |
|
case R_390_GOTENT: |
1119 |
|
case R_390_TLS_GD32: |
1120 |
|
/* This symbol requires a global offset table entry. */ |
1121 |
|
switch (r_type) |
1122 |
|
{ |
1123 |
|
default: |
1124 |
|
case R_390_GOT12: |
1125 |
|
case R_390_GOT16: |
1126 |
|
case R_390_GOT20: |
1127 |
|
case R_390_GOT32: |
1128 |
|
case R_390_GOTENT: |
1129 |
|
tls_type = GOT_NORMAL; |
1130 |
|
break; |
1131 |
|
case R_390_TLS_GD32: |
1132 |
|
tls_type = GOT_TLS_GD; |
1133 |
|
break; |
1134 |
|
case R_390_TLS_IE32: |
1135 |
|
case R_390_TLS_GOTIE32: |
1136 |
|
tls_type = GOT_TLS_IE; |
1137 |
|
break; |
1138 |
|
case R_390_TLS_GOTIE12: |
1139 |
|
case R_390_TLS_GOTIE20: |
1140 |
|
case R_390_TLS_IEENT: |
1141 |
|
tls_type = GOT_TLS_IE_NLT; |
1142 |
|
break; |
1143 |
|
} |
1144 |
|
|
1145 |
|
if (h != NULL) |
1146 |
|
{ |
1147 |
|
h->got.refcount += 1; |
1148 |
|
old_tls_type = elf_s390_hash_entry(h)->tls_type; |
1149 |
|
} |
1150 |
|
else |
1151 |
|
{ |
1152 |
|
local_got_refcounts[r_symndx] += 1; |
1153 |
|
old_tls_type = elf_s390_local_got_tls_type (abfd) [r_symndx]; |
1154 |
|
} |
1155 |
|
/* If a TLS symbol is accessed using IE at least once, |
1156 |
|
there is no point to use dynamic model for it. */ |
1157 |
|
if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN) |
1158 |
|
{ |
1159 |
|
if (old_tls_type == GOT_NORMAL || tls_type == GOT_NORMAL) |
1160 |
|
{ |
1161 |
|
(*_bfd_error_handler) |
1162 |
|
(_("%B: `%s' accessed both as normal and thread local symbol"), |
1163 |
|
abfd, h->root.root.string); |
1164 |
|
return FALSE; |
1165 |
|
} |
1166 |
|
if (old_tls_type > tls_type) |
1167 |
|
tls_type = old_tls_type; |
1168 |
|
} |
1169 |
|
|
1170 |
|
if (old_tls_type != tls_type) |
1171 |
|
{ |
1172 |
|
if (h != NULL) |
1173 |
|
elf_s390_hash_entry (h)->tls_type = tls_type; |
1174 |
|
else |
1175 |
|
elf_s390_local_got_tls_type (abfd) [r_symndx] = tls_type; |
1176 |
|
} |
1177 |
|
|
1178 |
|
if (r_type != R_390_TLS_IE32) |
1179 |
|
break; |
1180 |
|
/* Fall through. */ |
1181 |
|
|
1182 |
|
case R_390_TLS_LE32: |
1183 |
|
if (!info->shared) |
1184 |
|
break; |
1185 |
|
info->flags |= DF_STATIC_TLS; |
1186 |
|
/* Fall through. */ |
1187 |
|
|
1188 |
|
case R_390_8: |
1189 |
|
case R_390_16: |
1190 |
case R_390_32: |
case R_390_32: |
1191 |
case R_390_PC16: |
case R_390_PC16: |
1192 |
case R_390_PC16DBL: |
case R_390_PC16DBL: |
1193 |
case R_390_PC32DBL: |
case R_390_PC32DBL: |
1194 |
case R_390_PC32: |
case R_390_PC32: |
1195 |
if (h != NULL && !info->shared) |
if (h != NULL && !info->shared) |
1200 |
sections have not yet been mapped to output sections. |
sections have not yet been mapped to output sections. |
1201 |
Tentatively set the flag for now, and correct in |
Tentatively set the flag for now, and correct in |
1202 |
adjust_dynamic_symbol. */ |
adjust_dynamic_symbol. */ |
1203 |
h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF; |
h->non_got_ref = 1; |
1204 |
|
|
1205 |
/* We may need a .plt entry if the function this reloc |
/* We may need a .plt entry if the function this reloc |
1206 |
refers to is in a shared lib. */ |
refers to is in a shared lib. */ |
1237 |
|| (h != NULL |
|| (h != NULL |
1238 |
&& (! info->symbolic |
&& (! info->symbolic |
1239 |
|| h->root.type == bfd_link_hash_defweak |
|| h->root.type == bfd_link_hash_defweak |
1240 |
|| (h->elf_link_hash_flags |
|| !h->def_regular)))) |
1241 |
& ELF_LINK_HASH_DEF_REGULAR) == 0)))) |
|| (ELIMINATE_COPY_RELOCS |
1242 |
|| (!info->shared |
&& !info->shared |
1243 |
&& (sec->flags & SEC_ALLOC) != 0 |
&& (sec->flags & SEC_ALLOC) != 0 |
1244 |
&& h != NULL |
&& h != NULL |
1245 |
&& (h->root.type == bfd_link_hash_defweak |
&& (h->root.type == bfd_link_hash_defweak |
1246 |
|| (h->elf_link_hash_flags |
|| !h->def_regular))) |
|
& ELF_LINK_HASH_DEF_REGULAR) == 0))) |
|
1247 |
{ |
{ |
1248 |
struct elf_s390_dyn_relocs *p; |
struct elf_s390_dyn_relocs *p; |
1249 |
struct elf_s390_dyn_relocs **head; |
struct elf_s390_dyn_relocs **head; |
1261 |
elf_elfheader (abfd)->e_shstrndx, |
elf_elfheader (abfd)->e_shstrndx, |
1262 |
elf_section_data (sec)->rel_hdr.sh_name)); |
elf_section_data (sec)->rel_hdr.sh_name)); |
1263 |
if (name == NULL) |
if (name == NULL) |
1264 |
return false; |
return FALSE; |
1265 |
|
|
1266 |
if (strncmp (name, ".rela", 5) != 0 |
if (strncmp (name, ".rela", 5) != 0 |
1267 |
|| strcmp (bfd_get_section_name (abfd, sec), |
|| strcmp (bfd_get_section_name (abfd, sec), |
1268 |
name + 5) != 0) |
name + 5) != 0) |
1269 |
{ |
{ |
1270 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
1271 |
(_("%s: bad relocation section name `%s\'"), |
(_("%B: bad relocation section name `%s\'"), |
1272 |
bfd_archive_filename (abfd), name); |
abfd, name); |
1273 |
} |
} |
1274 |
|
|
1275 |
if (htab->elf.dynobj == NULL) |
if (htab->elf.dynobj == NULL) |
1289 |
if (sreloc == NULL |
if (sreloc == NULL |
1290 |
|| ! bfd_set_section_flags (dynobj, sreloc, flags) |
|| ! bfd_set_section_flags (dynobj, sreloc, flags) |
1291 |
|| ! bfd_set_section_alignment (dynobj, sreloc, 2)) |
|| ! bfd_set_section_alignment (dynobj, sreloc, 2)) |
1292 |
return false; |
return FALSE; |
1293 |
} |
} |
1294 |
elf_section_data (sec)->sreloc = sreloc; |
elf_section_data (sec)->sreloc = sreloc; |
1295 |
} |
} |
1305 |
/* Track dynamic relocs needed for local syms too. |
/* Track dynamic relocs needed for local syms too. |
1306 |
We really need local syms available to do this |
We really need local syms available to do this |
1307 |
easily. Oh well. */ |
easily. Oh well. */ |
|
|
|
1308 |
asection *s; |
asection *s; |
1309 |
|
|
1310 |
s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, |
s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, |
1311 |
sec, r_symndx); |
sec, r_symndx); |
1312 |
if (s == NULL) |
if (s == NULL) |
1313 |
return false; |
return FALSE; |
1314 |
|
|
1315 |
head = ((struct elf_s390_dyn_relocs **) |
head = ((struct elf_s390_dyn_relocs **) |
1316 |
&elf_section_data (s)->local_dynrel); |
&elf_section_data (s)->local_dynrel); |
1320 |
if (p == NULL || p->sec != sec) |
if (p == NULL || p->sec != sec) |
1321 |
{ |
{ |
1322 |
bfd_size_type amt = sizeof *p; |
bfd_size_type amt = sizeof *p; |
1323 |
|
|
1324 |
p = ((struct elf_s390_dyn_relocs *) |
p = ((struct elf_s390_dyn_relocs *) |
1325 |
bfd_alloc (htab->elf.dynobj, amt)); |
bfd_alloc (htab->elf.dynobj, amt)); |
1326 |
if (p == NULL) |
if (p == NULL) |
1327 |
return false; |
return FALSE; |
1328 |
p->next = *head; |
p->next = *head; |
1329 |
*head = p; |
*head = p; |
1330 |
p->sec = sec; |
p->sec = sec; |
1343 |
|
|
1344 |
/* This relocation describes the C++ object vtable hierarchy. |
/* This relocation describes the C++ object vtable hierarchy. |
1345 |
Reconstruct it for later use during GC. */ |
Reconstruct it for later use during GC. */ |
1346 |
case R_390_GNU_VTINHERIT: |
case R_390_GNU_VTINHERIT: |
1347 |
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) |
if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) |
1348 |
return false; |
return FALSE; |
1349 |
break; |
break; |
1350 |
|
|
1351 |
/* This relocation describes which C++ vtable entries are actually |
/* This relocation describes which C++ vtable entries are actually |
1352 |
used. Record for later use during GC. */ |
used. Record for later use during GC. */ |
1353 |
case R_390_GNU_VTENTRY: |
case R_390_GNU_VTENTRY: |
1354 |
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) |
if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) |
1355 |
return false; |
return FALSE; |
1356 |
break; |
break; |
1357 |
|
|
1358 |
default: |
default: |
1359 |
break; |
break; |
1360 |
} |
} |
1361 |
} |
} |
1362 |
|
|
1363 |
return true; |
return TRUE; |
1364 |
} |
} |
1365 |
|
|
1366 |
/* Return the section that should be marked against GC for a given |
/* Return the section that should be marked against GC for a given |
1405 |
|
|
1406 |
/* Update the got entry reference counts for the section being removed. */ |
/* Update the got entry reference counts for the section being removed. */ |
1407 |
|
|
1408 |
static boolean |
static bfd_boolean |
1409 |
elf_s390_gc_sweep_hook (abfd, info, sec, relocs) |
elf_s390_gc_sweep_hook (abfd, info, sec, relocs) |
1410 |
bfd *abfd; |
bfd *abfd; |
1411 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
1416 |
struct elf_link_hash_entry **sym_hashes; |
struct elf_link_hash_entry **sym_hashes; |
1417 |
bfd_signed_vma *local_got_refcounts; |
bfd_signed_vma *local_got_refcounts; |
1418 |
const Elf_Internal_Rela *rel, *relend; |
const Elf_Internal_Rela *rel, *relend; |
|
unsigned long r_symndx; |
|
|
struct elf_link_hash_entry *h; |
|
1419 |
|
|
1420 |
elf_section_data (sec)->local_dynrel = NULL; |
elf_section_data (sec)->local_dynrel = NULL; |
1421 |
|
|
1425 |
|
|
1426 |
relend = relocs + sec->reloc_count; |
relend = relocs + sec->reloc_count; |
1427 |
for (rel = relocs; rel < relend; rel++) |
for (rel = relocs; rel < relend; rel++) |
1428 |
switch (ELF32_R_TYPE (rel->r_info)) |
{ |
1429 |
{ |
unsigned long r_symndx; |
1430 |
case R_390_GOT12: |
unsigned int r_type; |
1431 |
case R_390_GOT16: |
struct elf_link_hash_entry *h = NULL; |
1432 |
case R_390_GOT32: |
|
1433 |
case R_390_GOTOFF: |
r_symndx = ELF32_R_SYM (rel->r_info); |
1434 |
case R_390_GOTPC: |
if (r_symndx >= symtab_hdr->sh_info) |
1435 |
case R_390_GOTPCDBL: |
{ |
1436 |
case R_390_GOTENT: |
struct elf_s390_link_hash_entry *eh; |
1437 |
r_symndx = ELF32_R_SYM (rel->r_info); |
struct elf_s390_dyn_relocs **pp; |
1438 |
if (r_symndx >= symtab_hdr->sh_info) |
struct elf_s390_dyn_relocs *p; |
1439 |
{ |
|
1440 |
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
1441 |
if (h->got.refcount > 0) |
while (h->root.type == bfd_link_hash_indirect |
1442 |
h->got.refcount -= 1; |
|| h->root.type == bfd_link_hash_warning) |
1443 |
} |
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
1444 |
else if (local_got_refcounts != NULL) |
eh = (struct elf_s390_link_hash_entry *) h; |
1445 |
{ |
|
1446 |
if (local_got_refcounts[r_symndx] > 0) |
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) |
1447 |
local_got_refcounts[r_symndx] -= 1; |
if (p->sec == sec) |
1448 |
} |
{ |
1449 |
break; |
/* Everything must go for SEC. */ |
1450 |
|
*pp = p->next; |
1451 |
|
break; |
1452 |
|
} |
1453 |
|
} |
1454 |
|
|
1455 |
case R_390_8: |
r_type = ELF32_R_TYPE (rel->r_info); |
1456 |
case R_390_12: |
r_type = elf_s390_tls_transition (info, r_type, h != NULL); |
1457 |
case R_390_16: |
switch (r_type) |
1458 |
case R_390_32: |
{ |
1459 |
case R_390_PC16: |
case R_390_TLS_LDM32: |
1460 |
case R_390_PC16DBL: |
if (elf_s390_hash_table (info)->tls_ldm_got.refcount > 0) |
1461 |
case R_390_PC32DBL: |
elf_s390_hash_table (info)->tls_ldm_got.refcount -= 1; |
1462 |
case R_390_PC32: |
break; |
|
r_symndx = ELF32_R_SYM (rel->r_info); |
|
|
if (r_symndx >= symtab_hdr->sh_info) |
|
|
{ |
|
|
struct elf_s390_link_hash_entry *eh; |
|
|
struct elf_s390_dyn_relocs **pp; |
|
|
struct elf_s390_dyn_relocs *p; |
|
|
|
|
|
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
|
1463 |
|
|
1464 |
if (!info->shared && h->plt.refcount > 0) |
case R_390_TLS_GD32: |
1465 |
h->plt.refcount -= 1; |
case R_390_TLS_IE32: |
1466 |
|
case R_390_TLS_GOTIE12: |
1467 |
|
case R_390_TLS_GOTIE20: |
1468 |
|
case R_390_TLS_GOTIE32: |
1469 |
|
case R_390_TLS_IEENT: |
1470 |
|
case R_390_GOT12: |
1471 |
|
case R_390_GOT16: |
1472 |
|
case R_390_GOT20: |
1473 |
|
case R_390_GOT32: |
1474 |
|
case R_390_GOTOFF16: |
1475 |
|
case R_390_GOTOFF32: |
1476 |
|
case R_390_GOTPC: |
1477 |
|
case R_390_GOTPCDBL: |
1478 |
|
case R_390_GOTENT: |
1479 |
|
if (h != NULL) |
1480 |
|
{ |
1481 |
|
if (h->got.refcount > 0) |
1482 |
|
h->got.refcount -= 1; |
1483 |
|
} |
1484 |
|
else if (local_got_refcounts != NULL) |
1485 |
|
{ |
1486 |
|
if (local_got_refcounts[r_symndx] > 0) |
1487 |
|
local_got_refcounts[r_symndx] -= 1; |
1488 |
|
} |
1489 |
|
break; |
1490 |
|
|
1491 |
eh = (struct elf_s390_link_hash_entry *) h; |
case R_390_8: |
1492 |
|
case R_390_12: |
1493 |
|
case R_390_16: |
1494 |
|
case R_390_20: |
1495 |
|
case R_390_32: |
1496 |
|
case R_390_PC16: |
1497 |
|
case R_390_PC16DBL: |
1498 |
|
case R_390_PC32DBL: |
1499 |
|
case R_390_PC32: |
1500 |
|
if (info->shared) |
1501 |
|
break; |
1502 |
|
/* Fall through. */ |
1503 |
|
|
1504 |
|
case R_390_PLT16DBL: |
1505 |
|
case R_390_PLT32DBL: |
1506 |
|
case R_390_PLT32: |
1507 |
|
case R_390_PLTOFF16: |
1508 |
|
case R_390_PLTOFF32: |
1509 |
|
if (h != NULL) |
1510 |
|
{ |
1511 |
|
if (h->plt.refcount > 0) |
1512 |
|
h->plt.refcount -= 1; |
1513 |
|
} |
1514 |
|
break; |
1515 |
|
|
1516 |
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) |
case R_390_GOTPLT12: |
1517 |
if (p->sec == sec) |
case R_390_GOTPLT16: |
1518 |
|
case R_390_GOTPLT20: |
1519 |
|
case R_390_GOTPLT32: |
1520 |
|
case R_390_GOTPLTENT: |
1521 |
|
if (h != NULL) |
1522 |
|
{ |
1523 |
|
if (h->plt.refcount > 0) |
1524 |
{ |
{ |
1525 |
if (ELF32_R_TYPE (rel->r_info) == R_390_PC16 |
((struct elf_s390_link_hash_entry *) h)->gotplt_refcount--; |
1526 |
|| ELF32_R_TYPE (rel->r_info) == R_390_PC16DBL |
h->plt.refcount -= 1; |
|
|| ELF32_R_TYPE (rel->r_info) == R_390_PC32DBL |
|
|
|| ELF32_R_TYPE (rel->r_info) == R_390_PC32) |
|
|
p->pc_count -= 1; |
|
|
p->count -= 1; |
|
|
if (p->count == 0) |
|
|
*pp = p->next; |
|
|
break; |
|
1527 |
} |
} |
1528 |
} |
} |
1529 |
break; |
else if (local_got_refcounts != NULL) |
1530 |
|
{ |
1531 |
|
if (local_got_refcounts[r_symndx] > 0) |
1532 |
|
local_got_refcounts[r_symndx] -= 1; |
1533 |
|
} |
1534 |
|
break; |
1535 |
|
|
1536 |
case R_390_PLT16DBL: |
default: |
1537 |
case R_390_PLT32DBL: |
break; |
1538 |
case R_390_PLT32: |
} |
1539 |
r_symndx = ELF32_R_SYM (rel->r_info); |
} |
|
if (r_symndx >= symtab_hdr->sh_info) |
|
|
{ |
|
|
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
|
|
if (h->plt.refcount > 0) |
|
|
h->plt.refcount -= 1; |
|
|
} |
|
|
break; |
|
1540 |
|
|
1541 |
default: |
return TRUE; |
1542 |
break; |
} |
1543 |
} |
|
1544 |
|
/* Make sure we emit a GOT entry if the symbol was supposed to have a PLT |
1545 |
|
entry but we found we will not create any. Called when we find we will |
1546 |
|
not have any PLT for this symbol, by for example |
1547 |
|
elf_s390_adjust_dynamic_symbol when we're doing a proper dynamic link, |
1548 |
|
or elf_s390_size_dynamic_sections if no dynamic sections will be |
1549 |
|
created (we're only linking static objects). */ |
1550 |
|
|
1551 |
return true; |
static void |
1552 |
|
elf_s390_adjust_gotplt (h) |
1553 |
|
struct elf_s390_link_hash_entry *h; |
1554 |
|
{ |
1555 |
|
if (h->elf.root.type == bfd_link_hash_warning) |
1556 |
|
h = (struct elf_s390_link_hash_entry *) h->elf.root.u.i.link; |
1557 |
|
|
1558 |
|
if (h->gotplt_refcount <= 0) |
1559 |
|
return; |
1560 |
|
|
1561 |
|
/* We simply add the number of gotplt references to the number |
1562 |
|
* of got references for this symbol. */ |
1563 |
|
h->elf.got.refcount += h->gotplt_refcount; |
1564 |
|
h->gotplt_refcount = -1; |
1565 |
} |
} |
1566 |
|
|
1567 |
/* Adjust a symbol defined by a dynamic object and referenced by a |
/* Adjust a symbol defined by a dynamic object and referenced by a |
1570 |
change the definition to something the rest of the link can |
change the definition to something the rest of the link can |
1571 |
understand. */ |
understand. */ |
1572 |
|
|
1573 |
static boolean |
static bfd_boolean |
1574 |
elf_s390_adjust_dynamic_symbol (info, h) |
elf_s390_adjust_dynamic_symbol (info, h) |
1575 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
1576 |
struct elf_link_hash_entry *h; |
struct elf_link_hash_entry *h; |
1577 |
{ |
{ |
1578 |
struct elf_s390_link_hash_table *htab; |
struct elf_s390_link_hash_table *htab; |
|
struct elf_s390_link_hash_entry * eh; |
|
|
struct elf_s390_dyn_relocs *p; |
|
1579 |
asection *s; |
asection *s; |
1580 |
unsigned int power_of_two; |
unsigned int power_of_two; |
1581 |
|
|
1583 |
will fill in the contents of the procedure linkage table later |
will fill in the contents of the procedure linkage table later |
1584 |
(although we could actually do it here). */ |
(although we could actually do it here). */ |
1585 |
if (h->type == STT_FUNC |
if (h->type == STT_FUNC |
1586 |
|| (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) |
|| h->needs_plt) |
1587 |
{ |
{ |
1588 |
if (h->plt.refcount <= 0 |
if (h->plt.refcount <= 0 |
1589 |
|| (! info->shared |
|| (! info->shared |
1590 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 |
&& !h->def_dynamic |
1591 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0 |
&& !h->ref_dynamic |
1592 |
&& h->root.type != bfd_link_hash_undefweak |
&& h->root.type != bfd_link_hash_undefweak |
1593 |
&& h->root.type != bfd_link_hash_undefined)) |
&& h->root.type != bfd_link_hash_undefined)) |
1594 |
{ |
{ |
1595 |
/* This case can occur if we saw a PLT32 reloc in an input |
/* This case can occur if we saw a PLT32 reloc in an input |
1596 |
file, but the symbol was never referred to by a dynamic |
file, but the symbol was never referred to by a dynamic |
1597 |
object, or if all references were garbage collected. In |
object, or if all references were garbage collected. In |
1598 |
such a case, we don't actually need to build a procedure |
such a case, we don't actually need to build a procedure |
1599 |
linkage table, and we can just do a PC32 reloc instead. */ |
linkage table, and we can just do a PC32 reloc instead. */ |
1600 |
h->plt.offset = (bfd_vma) -1; |
h->plt.offset = (bfd_vma) -1; |
1601 |
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; |
h->needs_plt = 0; |
1602 |
|
elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h); |
1603 |
} |
} |
1604 |
|
|
1605 |
return true; |
return TRUE; |
1606 |
} |
} |
1607 |
else |
else |
1608 |
/* It's possible that we incorrectly decided a .plt reloc was |
/* It's possible that we incorrectly decided a .plt reloc was |
1615 |
/* If this is a weak symbol, and there is a real definition, the |
/* If this is a weak symbol, and there is a real definition, the |
1616 |
processor independent code will have arranged for us to see the |
processor independent code will have arranged for us to see the |
1617 |
real definition first, and we can just use the same value. */ |
real definition first, and we can just use the same value. */ |
1618 |
if (h->weakdef != NULL) |
if (h->u.weakdef != NULL) |
1619 |
{ |
{ |
1620 |
BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined |
BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined |
1621 |
|| h->weakdef->root.type == bfd_link_hash_defweak); |
|| h->u.weakdef->root.type == bfd_link_hash_defweak); |
1622 |
h->root.u.def.section = h->weakdef->root.u.def.section; |
h->root.u.def.section = h->u.weakdef->root.u.def.section; |
1623 |
h->root.u.def.value = h->weakdef->root.u.def.value; |
h->root.u.def.value = h->u.weakdef->root.u.def.value; |
1624 |
return true; |
if (ELIMINATE_COPY_RELOCS || info->nocopyreloc) |
1625 |
|
h->non_got_ref = h->u.weakdef->non_got_ref; |
1626 |
|
return TRUE; |
1627 |
} |
} |
1628 |
|
|
1629 |
/* This is a reference to a symbol defined by a dynamic object which |
/* This is a reference to a symbol defined by a dynamic object which |
1634 |
For such cases we need not do anything here; the relocations will |
For such cases we need not do anything here; the relocations will |
1635 |
be handled correctly by relocate_section. */ |
be handled correctly by relocate_section. */ |
1636 |
if (info->shared) |
if (info->shared) |
1637 |
return true; |
return TRUE; |
1638 |
|
|
1639 |
/* If there are no references to this symbol that do not use the |
/* If there are no references to this symbol that do not use the |
1640 |
GOT, we don't need to generate a copy reloc. */ |
GOT, we don't need to generate a copy reloc. */ |
1641 |
if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0) |
if (!h->non_got_ref) |
1642 |
return true; |
return TRUE; |
1643 |
|
|
1644 |
/* If -z nocopyreloc was given, we won't generate them either. */ |
/* If -z nocopyreloc was given, we won't generate them either. */ |
1645 |
if (info->nocopyreloc) |
if (info->nocopyreloc) |
1646 |
{ |
{ |
1647 |
h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF; |
h->non_got_ref = 0; |
1648 |
return true; |
return TRUE; |
1649 |
} |
} |
1650 |
|
|
1651 |
eh = (struct elf_s390_link_hash_entry *) h; |
if (ELIMINATE_COPY_RELOCS) |
|
for (p = eh->dyn_relocs; p != NULL; p = p->next) |
|
1652 |
{ |
{ |
1653 |
s = p->sec->output_section; |
struct elf_s390_link_hash_entry * eh; |
1654 |
if (s != NULL && (s->flags & SEC_READONLY) != 0) |
struct elf_s390_dyn_relocs *p; |
|
break; |
|
|
} |
|
1655 |
|
|
1656 |
/* If we didn't find any dynamic relocs in read-only sections, then |
eh = (struct elf_s390_link_hash_entry *) h; |
1657 |
we'll be keeping the dynamic relocs and avoiding the copy reloc. */ |
for (p = eh->dyn_relocs; p != NULL; p = p->next) |
1658 |
if (p == NULL) |
{ |
1659 |
{ |
s = p->sec->output_section; |
1660 |
h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF; |
if (s != NULL && (s->flags & SEC_READONLY) != 0) |
1661 |
return true; |
break; |
1662 |
|
} |
1663 |
|
|
1664 |
|
/* If we didn't find any dynamic relocs in read-only sections, then |
1665 |
|
we'll be keeping the dynamic relocs and avoiding the copy reloc. */ |
1666 |
|
if (p == NULL) |
1667 |
|
{ |
1668 |
|
h->non_got_ref = 0; |
1669 |
|
return TRUE; |
1670 |
|
} |
1671 |
} |
} |
1672 |
|
|
1673 |
/* We must allocate the symbol in our .dynbss section, which will |
/* We must allocate the symbol in our .dynbss section, which will |
1687 |
runtime process image. */ |
runtime process image. */ |
1688 |
if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) |
if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) |
1689 |
{ |
{ |
1690 |
htab->srelbss->_raw_size += sizeof (Elf32_External_Rela); |
htab->srelbss->size += sizeof (Elf32_External_Rela); |
1691 |
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY; |
h->needs_copy = 1; |
1692 |
} |
} |
1693 |
|
|
1694 |
/* We need to figure out the alignment required for this symbol. I |
/* We need to figure out the alignment required for this symbol. I |
1699 |
|
|
1700 |
/* Apply the required alignment. */ |
/* Apply the required alignment. */ |
1701 |
s = htab->sdynbss; |
s = htab->sdynbss; |
1702 |
s->_raw_size = BFD_ALIGN (s->_raw_size, (bfd_size_type) (1 << power_of_two)); |
s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two)); |
1703 |
if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s)) |
if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s)) |
1704 |
{ |
{ |
1705 |
if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two)) |
if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two)) |
1706 |
return false; |
return FALSE; |
1707 |
} |
} |
1708 |
|
|
1709 |
/* Define the symbol as being at this point in the section. */ |
/* Define the symbol as being at this point in the section. */ |
1710 |
h->root.u.def.section = s; |
h->root.u.def.section = s; |
1711 |
h->root.u.def.value = s->_raw_size; |
h->root.u.def.value = s->size; |
1712 |
|
|
1713 |
/* Increment the section size to make room for the symbol. */ |
/* Increment the section size to make room for the symbol. */ |
1714 |
s->_raw_size += h->size; |
s->size += h->size; |
1715 |
|
|
1716 |
return true; |
return TRUE; |
1717 |
} |
} |
1718 |
|
|
|
/* This is the condition under which elf_s390_finish_dynamic_symbol |
|
|
will be called from elflink.h. If elflink.h doesn't call our |
|
|
finish_dynamic_symbol routine, we'll need to do something about |
|
|
initializing any .plt and .got entries in elf_s390_relocate_section. */ |
|
|
#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \ |
|
|
((DYN) \ |
|
|
&& ((INFO)->shared \ |
|
|
|| ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ |
|
|
&& ((H)->dynindx != -1 \ |
|
|
|| ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) |
|
|
|
|
1719 |
/* Allocate space in .plt, .got and associated reloc sections for |
/* Allocate space in .plt, .got and associated reloc sections for |
1720 |
dynamic relocs. */ |
dynamic relocs. */ |
1721 |
|
|
1722 |
static boolean |
static bfd_boolean |
1723 |
allocate_dynrelocs (h, inf) |
allocate_dynrelocs (h, inf) |
1724 |
struct elf_link_hash_entry *h; |
struct elf_link_hash_entry *h; |
1725 |
PTR inf; |
PTR inf; |
1730 |
struct elf_s390_dyn_relocs *p; |
struct elf_s390_dyn_relocs *p; |
1731 |
|
|
1732 |
if (h->root.type == bfd_link_hash_indirect) |
if (h->root.type == bfd_link_hash_indirect) |
1733 |
return true; |
return TRUE; |
1734 |
|
|
1735 |
if (h->root.type == bfd_link_hash_warning) |
if (h->root.type == bfd_link_hash_warning) |
1736 |
|
/* When warning symbols are created, they **replace** the "real" |
1737 |
|
entry in the hash table, thus we never get to see the real |
1738 |
|
symbol in a hash traversal. So look at it now. */ |
1739 |
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
1740 |
|
|
1741 |
info = (struct bfd_link_info *) inf; |
info = (struct bfd_link_info *) inf; |
1742 |
htab = elf_s390_hash_table (info); |
htab = elf_s390_hash_table (info); |
1743 |
|
|
1744 |
if (htab->elf.dynamic_sections_created |
if (htab->elf.dynamic_sections_created |
1745 |
&& h->plt.refcount > 0) |
&& h->plt.refcount > 0 |
1746 |
|
&& (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT |
1747 |
|
|| h->root.type != bfd_link_hash_undefweak)) |
1748 |
{ |
{ |
1749 |
/* Make sure this symbol is output as a dynamic symbol. |
/* Make sure this symbol is output as a dynamic symbol. |
1750 |
Undefined weak syms won't yet be marked as dynamic. */ |
Undefined weak syms won't yet be marked as dynamic. */ |
1751 |
if (h->dynindx == -1 |
if (h->dynindx == -1 |
1752 |
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) |
&& !h->forced_local) |
1753 |
{ |
{ |
1754 |
if (! bfd_elf32_link_record_dynamic_symbol (info, h)) |
if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
1755 |
return false; |
return FALSE; |
1756 |
} |
} |
1757 |
|
|
1758 |
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h)) |
if (info->shared |
1759 |
|
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h)) |
1760 |
{ |
{ |
1761 |
asection *s = htab->splt; |
asection *s = htab->splt; |
1762 |
|
|
1763 |
/* If this is the first .plt entry, make room for the special |
/* If this is the first .plt entry, make room for the special |
1764 |
first entry. */ |
first entry. */ |
1765 |
if (s->_raw_size == 0) |
if (s->size == 0) |
1766 |
s->_raw_size += PLT_FIRST_ENTRY_SIZE; |
s->size += PLT_FIRST_ENTRY_SIZE; |
1767 |
|
|
1768 |
h->plt.offset = s->_raw_size; |
h->plt.offset = s->size; |
1769 |
|
|
1770 |
/* If this symbol is not defined in a regular file, and we are |
/* If this symbol is not defined in a regular file, and we are |
1771 |
not generating a shared library, then set the symbol to this |
not generating a shared library, then set the symbol to this |
1773 |
pointers compare as equal between the normal executable and |
pointers compare as equal between the normal executable and |
1774 |
the shared library. */ |
the shared library. */ |
1775 |
if (! info->shared |
if (! info->shared |
1776 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) |
&& !h->def_regular) |
1777 |
{ |
{ |
1778 |
h->root.u.def.section = s; |
h->root.u.def.section = s; |
1779 |
h->root.u.def.value = h->plt.offset; |
h->root.u.def.value = h->plt.offset; |
1780 |
} |
} |
1781 |
|
|
1782 |
/* Make room for this entry. */ |
/* Make room for this entry. */ |
1783 |
s->_raw_size += PLT_ENTRY_SIZE; |
s->size += PLT_ENTRY_SIZE; |
1784 |
|
|
1785 |
/* We also need to make an entry in the .got.plt section, which |
/* We also need to make an entry in the .got.plt section, which |
1786 |
will be placed in the .got section by the linker script. */ |
will be placed in the .got section by the linker script. */ |
1787 |
htab->sgotplt->_raw_size += GOT_ENTRY_SIZE; |
htab->sgotplt->size += GOT_ENTRY_SIZE; |
1788 |
|
|
1789 |
/* We also need to make an entry in the .rela.plt section. */ |
/* We also need to make an entry in the .rela.plt section. */ |
1790 |
htab->srelplt->_raw_size += sizeof (Elf32_External_Rela); |
htab->srelplt->size += sizeof (Elf32_External_Rela); |
1791 |
} |
} |
1792 |
else |
else |
1793 |
{ |
{ |
1794 |
h->plt.offset = (bfd_vma) -1; |
h->plt.offset = (bfd_vma) -1; |
1795 |
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; |
h->needs_plt = 0; |
1796 |
|
elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h); |
1797 |
} |
} |
1798 |
} |
} |
1799 |
else |
else |
1800 |
{ |
{ |
1801 |
h->plt.offset = (bfd_vma) -1; |
h->plt.offset = (bfd_vma) -1; |
1802 |
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; |
h->needs_plt = 0; |
1803 |
|
elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h); |
1804 |
} |
} |
1805 |
|
|
1806 |
if (h->got.refcount > 0) |
/* If R_390_TLS_{IE32,GOTIE32,GOTIE12,IEENT} symbol is now local to |
1807 |
{ |
the binary, we can optimize a bit. IE32 and GOTIE32 get converted |
1808 |
|
to R_390_TLS_LE32 requiring no TLS entry. For GOTIE12 and IEENT |
1809 |
|
we can save the dynamic TLS relocation. */ |
1810 |
|
if (h->got.refcount > 0 |
1811 |
|
&& !info->shared |
1812 |
|
&& h->dynindx == -1 |
1813 |
|
&& elf_s390_hash_entry(h)->tls_type >= GOT_TLS_IE) |
1814 |
|
{ |
1815 |
|
if (elf_s390_hash_entry(h)->tls_type == GOT_TLS_IE_NLT) |
1816 |
|
/* For the GOTIE access without a literal pool entry the offset has |
1817 |
|
to be stored somewhere. The immediate value in the instruction |
1818 |
|
is not bit enough so the value is stored in the got. */ |
1819 |
|
{ |
1820 |
|
h->got.offset = htab->sgot->size; |
1821 |
|
htab->sgot->size += GOT_ENTRY_SIZE; |
1822 |
|
} |
1823 |
|
else |
1824 |
|
h->got.offset = (bfd_vma) -1; |
1825 |
|
} |
1826 |
|
else if (h->got.refcount > 0) |
1827 |
|
{ |
1828 |
asection *s; |
asection *s; |
1829 |
boolean dyn; |
bfd_boolean dyn; |
1830 |
|
int tls_type = elf_s390_hash_entry(h)->tls_type; |
1831 |
|
|
1832 |
/* Make sure this symbol is output as a dynamic symbol. |
/* Make sure this symbol is output as a dynamic symbol. |
1833 |
Undefined weak syms won't yet be marked as dynamic. */ |
Undefined weak syms won't yet be marked as dynamic. */ |
1834 |
if (h->dynindx == -1 |
if (h->dynindx == -1 |
1835 |
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) |
&& !h->forced_local) |
1836 |
{ |
{ |
1837 |
if (! bfd_elf32_link_record_dynamic_symbol (info, h)) |
if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
1838 |
return false; |
return FALSE; |
1839 |
} |
} |
1840 |
|
|
1841 |
s = htab->sgot; |
s = htab->sgot; |
1842 |
h->got.offset = s->_raw_size; |
h->got.offset = s->size; |
1843 |
s->_raw_size += GOT_ENTRY_SIZE; |
s->size += GOT_ENTRY_SIZE; |
1844 |
|
/* R_390_TLS_GD32 needs 2 consecutive GOT slots. */ |
1845 |
|
if (tls_type == GOT_TLS_GD) |
1846 |
|
s->size += GOT_ENTRY_SIZE; |
1847 |
dyn = htab->elf.dynamic_sections_created; |
dyn = htab->elf.dynamic_sections_created; |
1848 |
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)) |
/* R_390_TLS_IE32 needs one dynamic relocation, |
1849 |
htab->srelgot->_raw_size += sizeof (Elf32_External_Rela); |
R_390_TLS_GD32 needs one if local symbol and two if global. */ |
1850 |
|
if ((tls_type == GOT_TLS_GD && h->dynindx == -1) |
1851 |
|
|| tls_type >= GOT_TLS_IE) |
1852 |
|
htab->srelgot->size += sizeof (Elf32_External_Rela); |
1853 |
|
else if (tls_type == GOT_TLS_GD) |
1854 |
|
htab->srelgot->size += 2 * sizeof (Elf32_External_Rela); |
1855 |
|
else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT |
1856 |
|
|| h->root.type != bfd_link_hash_undefweak) |
1857 |
|
&& (info->shared |
1858 |
|
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) |
1859 |
|
htab->srelgot->size += sizeof (Elf32_External_Rela); |
1860 |
} |
} |
1861 |
else |
else |
1862 |
h->got.offset = (bfd_vma) -1; |
h->got.offset = (bfd_vma) -1; |
1863 |
|
|
1864 |
eh = (struct elf_s390_link_hash_entry *) h; |
eh = (struct elf_s390_link_hash_entry *) h; |
1865 |
if (eh->dyn_relocs == NULL) |
if (eh->dyn_relocs == NULL) |
1866 |
return true; |
return TRUE; |
1867 |
|
|
1868 |
/* In the shared -Bsymbolic case, discard space allocated for |
/* In the shared -Bsymbolic case, discard space allocated for |
1869 |
dynamic pc-relative relocs against symbols which turn out to be |
dynamic pc-relative relocs against symbols which turn out to be |
1873 |
|
|
1874 |
if (info->shared) |
if (info->shared) |
1875 |
{ |
{ |
1876 |
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 |
if (SYMBOL_REFERENCES_LOCAL (info, h)) |
|
&& ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0 |
|
|
|| info->symbolic)) |
|
1877 |
{ |
{ |
1878 |
struct elf_s390_dyn_relocs **pp; |
struct elf_s390_dyn_relocs **pp; |
1879 |
|
|
1887 |
pp = &p->next; |
pp = &p->next; |
1888 |
} |
} |
1889 |
} |
} |
1890 |
|
|
1891 |
|
/* Also discard relocs on undefined weak syms with non-default |
1892 |
|
visibility. */ |
1893 |
|
if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT |
1894 |
|
&& h->root.type == bfd_link_hash_undefweak) |
1895 |
|
eh->dyn_relocs = NULL; |
1896 |
} |
} |
1897 |
else |
else if (ELIMINATE_COPY_RELOCS) |
1898 |
{ |
{ |
1899 |
/* For the non-shared case, discard space for relocs against |
/* For the non-shared case, discard space for relocs against |
1900 |
symbols which turn out to need copy relocs or are not |
symbols which turn out to need copy relocs or are not |
1901 |
dynamic. */ |
dynamic. */ |
1902 |
|
|
1903 |
if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0 |
if (!h->non_got_ref |
1904 |
&& (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 |
&& ((h->def_dynamic |
1905 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) |
&& !h->def_regular) |
1906 |
|| (htab->elf.dynamic_sections_created |
|| (htab->elf.dynamic_sections_created |
1907 |
&& (h->root.type == bfd_link_hash_undefweak |
&& (h->root.type == bfd_link_hash_undefweak |
1908 |
|| h->root.type == bfd_link_hash_undefined)))) |
|| h->root.type == bfd_link_hash_undefined)))) |
1910 |
/* Make sure this symbol is output as a dynamic symbol. |
/* Make sure this symbol is output as a dynamic symbol. |
1911 |
Undefined weak syms won't yet be marked as dynamic. */ |
Undefined weak syms won't yet be marked as dynamic. */ |
1912 |
if (h->dynindx == -1 |
if (h->dynindx == -1 |
1913 |
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) |
&& !h->forced_local) |
1914 |
{ |
{ |
1915 |
if (! bfd_elf32_link_record_dynamic_symbol (info, h)) |
if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
1916 |
return false; |
return FALSE; |
1917 |
} |
} |
1918 |
|
|
1919 |
/* If that succeeded, we know we'll be keeping all the |
/* If that succeeded, we know we'll be keeping all the |
1931 |
for (p = eh->dyn_relocs; p != NULL; p = p->next) |
for (p = eh->dyn_relocs; p != NULL; p = p->next) |
1932 |
{ |
{ |
1933 |
asection *sreloc = elf_section_data (p->sec)->sreloc; |
asection *sreloc = elf_section_data (p->sec)->sreloc; |
1934 |
sreloc->_raw_size += p->count * sizeof (Elf32_External_Rela); |
|
1935 |
|
sreloc->size += p->count * sizeof (Elf32_External_Rela); |
1936 |
} |
} |
1937 |
|
|
1938 |
return true; |
return TRUE; |
1939 |
} |
} |
1940 |
|
|
1941 |
/* Find any dynamic relocs that apply to read-only sections. */ |
/* Find any dynamic relocs that apply to read-only sections. */ |
1942 |
|
|
1943 |
static boolean |
static bfd_boolean |
1944 |
readonly_dynrelocs (h, inf) |
readonly_dynrelocs (h, inf) |
1945 |
struct elf_link_hash_entry *h; |
struct elf_link_hash_entry *h; |
1946 |
PTR inf; |
PTR inf; |
1963 |
info->flags |= DF_TEXTREL; |
info->flags |= DF_TEXTREL; |
1964 |
|
|
1965 |
/* Not an error, just cut short the traversal. */ |
/* Not an error, just cut short the traversal. */ |
1966 |
return false; |
return FALSE; |
1967 |
} |
} |
1968 |
} |
} |
1969 |
return true; |
return TRUE; |
1970 |
} |
} |
1971 |
|
|
1972 |
/* Set the sizes of the dynamic sections. */ |
/* Set the sizes of the dynamic sections. */ |
1973 |
|
|
1974 |
static boolean |
static bfd_boolean |
1975 |
elf_s390_size_dynamic_sections (output_bfd, info) |
elf_s390_size_dynamic_sections (output_bfd, info) |
1976 |
bfd *output_bfd ATTRIBUTE_UNUSED; |
bfd *output_bfd ATTRIBUTE_UNUSED; |
1977 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
1979 |
struct elf_s390_link_hash_table *htab; |
struct elf_s390_link_hash_table *htab; |
1980 |
bfd *dynobj; |
bfd *dynobj; |
1981 |
asection *s; |
asection *s; |
1982 |
boolean relocs; |
bfd_boolean relocs; |
1983 |
bfd *ibfd; |
bfd *ibfd; |
1984 |
|
|
1985 |
htab = elf_s390_hash_table (info); |
htab = elf_s390_hash_table (info); |
1990 |
if (htab->elf.dynamic_sections_created) |
if (htab->elf.dynamic_sections_created) |
1991 |
{ |
{ |
1992 |
/* Set the contents of the .interp section to the interpreter. */ |
/* Set the contents of the .interp section to the interpreter. */ |
1993 |
if (! info->shared) |
if (info->executable) |
1994 |
{ |
{ |
1995 |
s = bfd_get_section_by_name (dynobj, ".interp"); |
s = bfd_get_section_by_name (dynobj, ".interp"); |
1996 |
if (s == NULL) |
if (s == NULL) |
1997 |
abort (); |
abort (); |
1998 |
s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; |
s->size = sizeof ELF_DYNAMIC_INTERPRETER; |
1999 |
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; |
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; |
2000 |
} |
} |
2001 |
} |
} |
2006 |
{ |
{ |
2007 |
bfd_signed_vma *local_got; |
bfd_signed_vma *local_got; |
2008 |
bfd_signed_vma *end_local_got; |
bfd_signed_vma *end_local_got; |
2009 |
|
char *local_tls_type; |
2010 |
bfd_size_type locsymcount; |
bfd_size_type locsymcount; |
2011 |
Elf_Internal_Shdr *symtab_hdr; |
Elf_Internal_Shdr *symtab_hdr; |
2012 |
asection *srela; |
asection *srela; |
2034 |
else if (p->count != 0) |
else if (p->count != 0) |
2035 |
{ |
{ |
2036 |
srela = elf_section_data (p->sec)->sreloc; |
srela = elf_section_data (p->sec)->sreloc; |
2037 |
srela->_raw_size += p->count * sizeof (Elf32_External_Rela); |
srela->size += p->count * sizeof (Elf32_External_Rela); |
2038 |
if ((p->sec->output_section->flags & SEC_READONLY) != 0) |
if ((p->sec->output_section->flags & SEC_READONLY) != 0) |
2039 |
info->flags |= DF_TEXTREL; |
info->flags |= DF_TEXTREL; |
2040 |
} |
} |
2048 |
symtab_hdr = &elf_tdata (ibfd)->symtab_hdr; |
symtab_hdr = &elf_tdata (ibfd)->symtab_hdr; |
2049 |
locsymcount = symtab_hdr->sh_info; |
locsymcount = symtab_hdr->sh_info; |
2050 |
end_local_got = local_got + locsymcount; |
end_local_got = local_got + locsymcount; |
2051 |
|
local_tls_type = elf_s390_local_got_tls_type (ibfd); |
2052 |
s = htab->sgot; |
s = htab->sgot; |
2053 |
srela = htab->srelgot; |
srela = htab->srelgot; |
2054 |
for (; local_got < end_local_got; ++local_got) |
for (; local_got < end_local_got; ++local_got, ++local_tls_type) |
2055 |
{ |
{ |
2056 |
if (*local_got > 0) |
if (*local_got > 0) |
2057 |
{ |
{ |
2058 |
*local_got = s->_raw_size; |
*local_got = s->size; |
2059 |
s->_raw_size += GOT_ENTRY_SIZE; |
s->size += GOT_ENTRY_SIZE; |
2060 |
|
if (*local_tls_type == GOT_TLS_GD) |
2061 |
|
s->size += GOT_ENTRY_SIZE; |
2062 |
if (info->shared) |
if (info->shared) |
2063 |
srela->_raw_size += sizeof (Elf32_External_Rela); |
srela->size += sizeof (Elf32_External_Rela); |
2064 |
} |
} |
2065 |
else |
else |
2066 |
*local_got = (bfd_vma) -1; |
*local_got = (bfd_vma) -1; |
2067 |
} |
} |
2068 |
} |
} |
2069 |
|
|
2070 |
|
if (htab->tls_ldm_got.refcount > 0) |
2071 |
|
{ |
2072 |
|
/* Allocate 2 got entries and 1 dynamic reloc for R_390_TLS_LDM32 |
2073 |
|
relocs. */ |
2074 |
|
htab->tls_ldm_got.offset = htab->sgot->size; |
2075 |
|
htab->sgot->size += 2 * GOT_ENTRY_SIZE; |
2076 |
|
htab->srelgot->size += sizeof (Elf32_External_Rela); |
2077 |
|
} |
2078 |
|
else |
2079 |
|
htab->tls_ldm_got.offset = -1; |
2080 |
|
|
2081 |
/* Allocate global sym .plt and .got entries, and space for global |
/* Allocate global sym .plt and .got entries, and space for global |
2082 |
sym dynamic relocs. */ |
sym dynamic relocs. */ |
2083 |
elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info); |
elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info); |
2084 |
|
|
2085 |
/* We now have determined the sizes of the various dynamic sections. |
/* We now have determined the sizes of the various dynamic sections. |
2086 |
Allocate memory for them. */ |
Allocate memory for them. */ |
2087 |
relocs = false; |
relocs = FALSE; |
2088 |
for (s = dynobj->sections; s != NULL; s = s->next) |
for (s = dynobj->sections; s != NULL; s = s->next) |
2089 |
{ |
{ |
2090 |
if ((s->flags & SEC_LINKER_CREATED) == 0) |
if ((s->flags & SEC_LINKER_CREATED) == 0) |
2099 |
} |
} |
2100 |
else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0) |
else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0) |
2101 |
{ |
{ |
2102 |
if (s->_raw_size != 0 && s != htab->srelplt) |
if (s->size != 0) |
2103 |
relocs = true; |
relocs = TRUE; |
2104 |
|
|
2105 |
/* We use the reloc_count field as a counter if we need |
/* We use the reloc_count field as a counter if we need |
2106 |
to copy relocs into the output file. */ |
to copy relocs into the output file. */ |
2112 |
continue; |
continue; |
2113 |
} |
} |
2114 |
|
|
2115 |
if (s->_raw_size == 0) |
if (s->size == 0) |
2116 |
{ |
{ |
2117 |
/* If we don't need this section, strip it from the |
/* If we don't need this section, strip it from the |
2118 |
output file. This is to handle .rela.bss and |
output file. This is to handle .rela.bss and |
2133 |
section's contents are written out. This should not happen, |
section's contents are written out. This should not happen, |
2134 |
but this way if it does, we get a R_390_NONE reloc instead |
but this way if it does, we get a R_390_NONE reloc instead |
2135 |
of garbage. */ |
of garbage. */ |
2136 |
s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size); |
s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); |
2137 |
if (s->contents == NULL) |
if (s->contents == NULL) |
2138 |
return false; |
return FALSE; |
2139 |
} |
} |
2140 |
|
|
2141 |
if (htab->elf.dynamic_sections_created) |
if (htab->elf.dynamic_sections_created) |
2146 |
the .dynamic section. The DT_DEBUG entry is filled in by the |
the .dynamic section. The DT_DEBUG entry is filled in by the |
2147 |
dynamic linker and used by the debugger. */ |
dynamic linker and used by the debugger. */ |
2148 |
#define add_dynamic_entry(TAG, VAL) \ |
#define add_dynamic_entry(TAG, VAL) \ |
2149 |
bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL)) |
_bfd_elf_add_dynamic_entry (info, TAG, VAL) |
2150 |
|
|
2151 |
if (! info->shared) |
if (info->executable) |
2152 |
{ |
{ |
2153 |
if (!add_dynamic_entry (DT_DEBUG, 0)) |
if (!add_dynamic_entry (DT_DEBUG, 0)) |
2154 |
return false; |
return FALSE; |
2155 |
} |
} |
2156 |
|
|
2157 |
if (htab->splt->_raw_size != 0) |
if (htab->splt->size != 0) |
2158 |
{ |
{ |
2159 |
if (!add_dynamic_entry (DT_PLTGOT, 0) |
if (!add_dynamic_entry (DT_PLTGOT, 0) |
2160 |
|| !add_dynamic_entry (DT_PLTRELSZ, 0) |
|| !add_dynamic_entry (DT_PLTRELSZ, 0) |
2161 |
|| !add_dynamic_entry (DT_PLTREL, DT_RELA) |
|| !add_dynamic_entry (DT_PLTREL, DT_RELA) |
2162 |
|| !add_dynamic_entry (DT_JMPREL, 0)) |
|| !add_dynamic_entry (DT_JMPREL, 0)) |
2163 |
return false; |
return FALSE; |
2164 |
} |
} |
2165 |
|
|
2166 |
if (relocs) |
if (relocs) |
2167 |
{ |
{ |
2168 |
if (!add_dynamic_entry (DT_RELA, 0) |
if (!add_dynamic_entry (DT_RELA, 0) |
2169 |
|| !add_dynamic_entry (DT_RELASZ, 0) |
|| !add_dynamic_entry (DT_RELASZ, 0) |
2170 |
|| !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) |
|| !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) |
2171 |
return false; |
return FALSE; |
2172 |
|
|
2173 |
/* If any dynamic relocs apply to a read-only section, |
/* If any dynamic relocs apply to a read-only section, |
2174 |
then we need a DT_TEXTREL entry. */ |
then we need a DT_TEXTREL entry. */ |
2179 |
if ((info->flags & DF_TEXTREL) != 0) |
if ((info->flags & DF_TEXTREL) != 0) |
2180 |
{ |
{ |
2181 |
if (!add_dynamic_entry (DT_TEXTREL, 0)) |
if (!add_dynamic_entry (DT_TEXTREL, 0)) |
2182 |
return false; |
return FALSE; |
2183 |
} |
} |
2184 |
} |
} |
2185 |
} |
} |
2186 |
#undef add_dynamic_entry |
#undef add_dynamic_entry |
2187 |
|
|
2188 |
return true; |
return TRUE; |
2189 |
|
} |
2190 |
|
|
2191 |
|
/* Return the base VMA address which should be subtracted from real addresses |
2192 |
|
when resolving @dtpoff relocation. |
2193 |
|
This is PT_TLS segment p_vaddr. */ |
2194 |
|
|
2195 |
|
static bfd_vma |
2196 |
|
dtpoff_base (info) |
2197 |
|
struct bfd_link_info *info; |
2198 |
|
{ |
2199 |
|
/* If tls_sec is NULL, we should have signalled an error already. */ |
2200 |
|
if (elf_hash_table (info)->tls_sec == NULL) |
2201 |
|
return 0; |
2202 |
|
return elf_hash_table (info)->tls_sec->vma; |
2203 |
|
} |
2204 |
|
|
2205 |
|
/* Return the relocation value for @tpoff relocation |
2206 |
|
if STT_TLS virtual address is ADDRESS. */ |
2207 |
|
|
2208 |
|
static bfd_vma |
2209 |
|
tpoff (info, address) |
2210 |
|
struct bfd_link_info *info; |
2211 |
|
bfd_vma address; |
2212 |
|
{ |
2213 |
|
struct elf_link_hash_table *htab = elf_hash_table (info); |
2214 |
|
|
2215 |
|
/* If tls_sec is NULL, we should have signalled an error already. */ |
2216 |
|
if (htab->tls_sec == NULL) |
2217 |
|
return 0; |
2218 |
|
return htab->tls_size + htab->tls_sec->vma - address; |
2219 |
|
} |
2220 |
|
|
2221 |
|
/* Complain if TLS instruction relocation is against an invalid |
2222 |
|
instruction. */ |
2223 |
|
|
2224 |
|
static void |
2225 |
|
invalid_tls_insn (input_bfd, input_section, rel) |
2226 |
|
bfd *input_bfd; |
2227 |
|
asection *input_section; |
2228 |
|
Elf_Internal_Rela *rel; |
2229 |
|
{ |
2230 |
|
reloc_howto_type *howto; |
2231 |
|
|
2232 |
|
howto = elf_howto_table + ELF32_R_TYPE (rel->r_info); |
2233 |
|
(*_bfd_error_handler) |
2234 |
|
(_("%B(%A+0x%lx): invalid instruction for TLS relocation %s"), |
2235 |
|
input_bfd, |
2236 |
|
input_section, |
2237 |
|
(long) rel->r_offset, |
2238 |
|
howto->name); |
2239 |
} |
} |
2240 |
|
|
2241 |
/* Relocate a 390 ELF section. */ |
/* Relocate a 390 ELF section. */ |
2242 |
|
|
2243 |
static boolean |
static bfd_boolean |
2244 |
elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, |
elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, |
2245 |
contents, relocs, local_syms, local_sections) |
contents, relocs, local_syms, local_sections) |
2246 |
bfd *output_bfd; |
bfd *output_bfd; |
2259 |
Elf_Internal_Rela *rel; |
Elf_Internal_Rela *rel; |
2260 |
Elf_Internal_Rela *relend; |
Elf_Internal_Rela *relend; |
2261 |
|
|
2262 |
if (info->relocateable) |
if (info->relocatable) |
2263 |
return true; |
return TRUE; |
2264 |
|
|
2265 |
htab = elf_s390_hash_table (info); |
htab = elf_s390_hash_table (info); |
2266 |
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; |
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; |
2271 |
relend = relocs + input_section->reloc_count; |
relend = relocs + input_section->reloc_count; |
2272 |
for (; rel < relend; rel++) |
for (; rel < relend; rel++) |
2273 |
{ |
{ |
2274 |
int r_type; |
unsigned int r_type; |
2275 |
reloc_howto_type *howto; |
reloc_howto_type *howto; |
2276 |
unsigned long r_symndx; |
unsigned long r_symndx; |
2277 |
struct elf_link_hash_entry *h; |
struct elf_link_hash_entry *h; |
2279 |
asection *sec; |
asection *sec; |
2280 |
bfd_vma off; |
bfd_vma off; |
2281 |
bfd_vma relocation; |
bfd_vma relocation; |
2282 |
boolean unresolved_reloc; |
bfd_boolean unresolved_reloc; |
2283 |
bfd_reloc_status_type r; |
bfd_reloc_status_type r; |
2284 |
|
int tls_type; |
2285 |
|
|
2286 |
r_type = ELF32_R_TYPE (rel->r_info); |
r_type = ELF32_R_TYPE (rel->r_info); |
2287 |
if (r_type == (int) R_390_GNU_VTINHERIT |
if (r_type == (int) R_390_GNU_VTINHERIT |
2288 |
|| r_type == (int) R_390_GNU_VTENTRY) |
|| r_type == (int) R_390_GNU_VTENTRY) |
2289 |
continue; |
continue; |
2290 |
if (r_type < 0 || r_type >= (int) R_390_max) |
if (r_type >= (int) R_390_max) |
2291 |
{ |
{ |
2292 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
2293 |
return false; |
return FALSE; |
2294 |
} |
} |
2295 |
|
|
2296 |
howto = elf_howto_table + r_type; |
howto = elf_howto_table + r_type; |
2297 |
r_symndx = ELF32_R_SYM (rel->r_info); |
r_symndx = ELF32_R_SYM (rel->r_info); |
2298 |
|
|
2299 |
|
/* This is a final link. */ |
2300 |
h = NULL; |
h = NULL; |
2301 |
sym = NULL; |
sym = NULL; |
2302 |
sec = NULL; |
sec = NULL; |
2303 |
unresolved_reloc = false; |
unresolved_reloc = FALSE; |
2304 |
if (r_symndx < symtab_hdr->sh_info) |
if (r_symndx < symtab_hdr->sh_info) |
2305 |
{ |
{ |
2306 |
sym = local_syms + r_symndx; |
sym = local_syms + r_symndx; |
2307 |
sec = local_sections[r_symndx]; |
sec = local_sections[r_symndx]; |
2308 |
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); |
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); |
2309 |
} |
} |
2310 |
else |
else |
2311 |
{ |
{ |
2312 |
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
bfd_boolean warned ATTRIBUTE_UNUSED; |
|
while (h->root.type == bfd_link_hash_indirect |
|
|
|| h->root.type == bfd_link_hash_warning) |
|
|
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
|
2313 |
|
|
2314 |
if (h->root.type == bfd_link_hash_defined |
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, |
2315 |
|| h->root.type == bfd_link_hash_defweak) |
r_symndx, symtab_hdr, sym_hashes, |
2316 |
{ |
h, sec, relocation, |
2317 |
sec = h->root.u.def.section; |
unresolved_reloc, warned); |
|
if (sec->output_section == NULL) |
|
|
{ |
|
|
/* Set a flag that will be cleared later if we find a |
|
|
relocation value for this symbol. output_section |
|
|
is typically NULL for symbols satisfied by a shared |
|
|
library. */ |
|
|
unresolved_reloc = true; |
|
|
relocation = 0; |
|
|
} |
|
|
else |
|
|
relocation = (h->root.u.def.value |
|
|
+ sec->output_section->vma |
|
|
+ sec->output_offset); |
|
|
} |
|
|
else if (h->root.type == bfd_link_hash_undefweak) |
|
|
relocation = 0; |
|
|
else if (info->shared |
|
|
&& (!info->symbolic || info->allow_shlib_undefined) |
|
|
&& !info->no_undefined |
|
|
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) |
|
|
relocation = 0; |
|
|
else |
|
|
{ |
|
|
if (! ((*info->callbacks->undefined_symbol) |
|
|
(info, h->root.root.string, input_bfd, |
|
|
input_section, rel->r_offset, |
|
|
(!info->shared || info->no_undefined |
|
|
|| ELF_ST_VISIBILITY (h->other))))) |
|
|
return false; |
|
|
relocation = 0; |
|
|
} |
|
2318 |
} |
} |
2319 |
|
|
2320 |
switch (r_type) |
switch (r_type) |
2321 |
{ |
{ |
2322 |
case R_390_GOT12: |
case R_390_GOTPLT12: |
2323 |
case R_390_GOT16: |
case R_390_GOTPLT16: |
2324 |
case R_390_GOT32: |
case R_390_GOTPLT20: |
2325 |
|
case R_390_GOTPLT32: |
2326 |
|
case R_390_GOTPLTENT: |
2327 |
|
/* There are three cases for a GOTPLT relocation. 1) The |
2328 |
|
relocation is against the jump slot entry of a plt that |
2329 |
|
will get emitted to the output file. 2) The relocation |
2330 |
|
is against the jump slot of a plt entry that has been |
2331 |
|
removed. elf_s390_adjust_gotplt has created a GOT entry |
2332 |
|
as replacement. 3) The relocation is against a local symbol. |
2333 |
|
Cases 2) and 3) are the same as the GOT relocation code |
2334 |
|
so we just have to test for case 1 and fall through for |
2335 |
|
the other two. */ |
2336 |
|
if (h != NULL && h->plt.offset != (bfd_vma) -1) |
2337 |
|
{ |
2338 |
|
bfd_vma plt_index; |
2339 |
|
|
2340 |
|
/* Calc. index no. |
2341 |
|
Current offset - size first entry / entry size. */ |
2342 |
|
plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / |
2343 |
|
PLT_ENTRY_SIZE; |
2344 |
|
|
2345 |
|
/* Offset in GOT is PLT index plus GOT headers(3) times 4, |
2346 |
|
addr & GOT addr. */ |
2347 |
|
relocation = (plt_index + 3) * GOT_ENTRY_SIZE; |
2348 |
|
unresolved_reloc = FALSE; |
2349 |
|
|
2350 |
|
if (r_type == R_390_GOTPLTENT) |
2351 |
|
relocation += htab->sgot->output_section->vma; |
2352 |
|
break; |
2353 |
|
} |
2354 |
|
/* Fall through. */ |
2355 |
|
|
2356 |
|
case R_390_GOT12: |
2357 |
|
case R_390_GOT16: |
2358 |
|
case R_390_GOT20: |
2359 |
|
case R_390_GOT32: |
2360 |
case R_390_GOTENT: |
case R_390_GOTENT: |
2361 |
/* Relocation is to the entry for this symbol in the global |
/* Relocation is to the entry for this symbol in the global |
2362 |
offset table. */ |
offset table. */ |
2363 |
if (htab->sgot == NULL) |
if (htab->sgot == NULL) |
2364 |
abort (); |
abort (); |
2365 |
|
|
2366 |
if (h != NULL) |
if (h != NULL) |
2367 |
{ |
{ |
2368 |
boolean dyn; |
bfd_boolean dyn; |
2369 |
|
|
2370 |
off = h->got.offset; |
off = h->got.offset; |
2371 |
dyn = htab->elf.dynamic_sections_created; |
dyn = htab->elf.dynamic_sections_created; |
2372 |
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h) |
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) |
2373 |
|| (info->shared |
|| (info->shared |
2374 |
&& (info->symbolic |
&& (info->symbolic |
2375 |
|| h->dynindx == -1 |
|| h->dynindx == -1 |
2376 |
|| (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)) |
|| h->forced_local) |
2377 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) |
&& h->def_regular) |
2378 |
{ |
|| (ELF_ST_VISIBILITY (h->other) |
2379 |
/* This is actually a static link, or it is a |
&& h->root.type == bfd_link_hash_undefweak)) |
2380 |
-Bsymbolic link and the symbol is defined |
{ |
2381 |
locally, or the symbol was forced to be local |
/* This is actually a static link, or it is a |
2382 |
because of a version file. We must initialize |
-Bsymbolic link and the symbol is defined |
2383 |
this entry in the global offset table. Since the |
locally, or the symbol was forced to be local |
2384 |
offset must always be a multiple of 2, we use the |
because of a version file. We must initialize |
2385 |
least significant bit to record whether we have |
this entry in the global offset table. Since the |
2386 |
initialized it already. |
offset must always be a multiple of 2, we use the |
2387 |
|
least significant bit to record whether we have |
2388 |
When doing a dynamic link, we create a .rel.got |
initialized it already. |
2389 |
relocation entry to initialize the value. This |
|
2390 |
is done in the finish_dynamic_symbol routine. */ |
When doing a dynamic link, we create a .rel.got |
2391 |
if ((off & 1) != 0) |
relocation entry to initialize the value. This |
2392 |
off &= ~1; |
is done in the finish_dynamic_symbol routine. */ |
2393 |
else |
if ((off & 1) != 0) |
2394 |
{ |
off &= ~1; |
2395 |
|
else |
2396 |
|
{ |
2397 |
bfd_put_32 (output_bfd, relocation, |
bfd_put_32 (output_bfd, relocation, |
2398 |
htab->sgot->contents + off); |
htab->sgot->contents + off); |
2399 |
h->got.offset |= 1; |
h->got.offset |= 1; |
2400 |
} |
} |
2401 |
} |
} |
2402 |
else |
else |
2403 |
unresolved_reloc = false; |
unresolved_reloc = FALSE; |
2404 |
} |
} |
2405 |
else |
else |
2406 |
{ |
{ |
2407 |
if (local_got_offsets == NULL) |
if (local_got_offsets == NULL) |
2408 |
abort (); |
abort (); |
2409 |
|
|
2410 |
off = local_got_offsets[r_symndx]; |
off = local_got_offsets[r_symndx]; |
2411 |
|
|
2412 |
/* The offset must always be a multiple of 4. We use |
/* The offset must always be a multiple of 4. We use |
2413 |
the least significant bit to record whether we have |
the least significant bit to record whether we have |
2414 |
already generated the necessary reloc. */ |
already generated the necessary reloc. */ |
2415 |
if ((off & 1) != 0) |
if ((off & 1) != 0) |
2416 |
off &= ~1; |
off &= ~1; |
2417 |
else |
else |
2418 |
{ |
{ |
2419 |
bfd_put_32 (output_bfd, relocation, |
bfd_put_32 (output_bfd, relocation, |
2420 |
htab->sgot->contents + off); |
htab->sgot->contents + off); |
2421 |
|
|
2422 |
if (info->shared) |
if (info->shared) |
2423 |
{ |
{ |
2424 |
asection *srelgot; |
asection *srelgot; |
2425 |
Elf_Internal_Rela outrel; |
Elf_Internal_Rela outrel; |
2426 |
Elf32_External_Rela *loc; |
bfd_byte *loc; |
2427 |
|
|
2428 |
srelgot = htab->srelgot; |
srelgot = htab->srelgot; |
2429 |
if (srelgot == NULL) |
if (srelgot == NULL) |
2430 |
abort (); |
abort (); |
2431 |
|
|
2432 |
outrel.r_offset = (htab->sgot->output_section->vma |
outrel.r_offset = (htab->sgot->output_section->vma |
2433 |
+ htab->sgot->output_offset |
+ htab->sgot->output_offset |
2434 |
+ off); |
+ off); |
2435 |
outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE); |
outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE); |
2436 |
outrel.r_addend = relocation; |
outrel.r_addend = relocation; |
2437 |
loc = (Elf32_External_Rela *) srelgot->contents; |
loc = srelgot->contents; |
2438 |
loc += srelgot->reloc_count++; |
loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela); |
2439 |
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
2440 |
} |
} |
2441 |
|
|
2442 |
local_got_offsets[r_symndx] |= 1; |
local_got_offsets[r_symndx] |= 1; |
2443 |
} |
} |
2444 |
} |
} |
2445 |
|
|
2446 |
if (off >= (bfd_vma) -2) |
if (off >= (bfd_vma) -2) |
2447 |
abort (); |
abort (); |
2448 |
|
|
2449 |
relocation = htab->sgot->output_offset + off; |
relocation = htab->sgot->output_offset + off; |
2450 |
|
|
2451 |
/* |
/* For @GOTENT the relocation is against the offset between |
2452 |
* For @GOTENT the relocation is against the offset between |
the instruction and the symbols entry in the GOT and not |
2453 |
* the instruction and the symbols entry in the GOT and not |
between the start of the GOT and the symbols entry. We |
2454 |
* between the start of the GOT and the symbols entry. We |
add the vma of the GOT to get the correct value. */ |
2455 |
* add the vma of the GOT to get the correct value. |
if ( r_type == R_390_GOTENT |
2456 |
*/ |
|| r_type == R_390_GOTPLTENT) |
|
if (r_type == R_390_GOTENT) |
|
2457 |
relocation += htab->sgot->output_section->vma; |
relocation += htab->sgot->output_section->vma; |
2458 |
|
|
2459 |
break; |
break; |
2460 |
|
|
2461 |
case R_390_GOTOFF: |
case R_390_GOTOFF16: |
2462 |
/* Relocation is relative to the start of the global offset |
case R_390_GOTOFF32: |
2463 |
table. */ |
/* Relocation is relative to the start of the global offset |
2464 |
|
table. */ |
2465 |
/* Note that sgot->output_offset is not involved in this |
|
2466 |
calculation. We always want the start of .got. If we |
/* Note that sgot->output_offset is not involved in this |
2467 |
defined _GLOBAL_OFFSET_TABLE in a different way, as is |
calculation. We always want the start of .got. If we |
2468 |
permitted by the ABI, we might have to change this |
defined _GLOBAL_OFFSET_TABLE in a different way, as is |
2469 |
calculation. */ |
permitted by the ABI, we might have to change this |
2470 |
relocation -= htab->sgot->output_section->vma; |
calculation. */ |
2471 |
break; |
relocation -= htab->sgot->output_section->vma; |
2472 |
|
break; |
2473 |
|
|
2474 |
case R_390_GOTPC: |
case R_390_GOTPC: |
2475 |
case R_390_GOTPCDBL: |
case R_390_GOTPCDBL: |
2476 |
/* Use global offset table as symbol value. */ |
/* Use global offset table as symbol value. */ |
2477 |
relocation = htab->sgot->output_section->vma; |
relocation = htab->sgot->output_section->vma; |
2478 |
unresolved_reloc = false; |
unresolved_reloc = FALSE; |
2479 |
break; |
break; |
2480 |
|
|
2481 |
case R_390_PLT16DBL: |
case R_390_PLT16DBL: |
2482 |
case R_390_PLT32DBL: |
case R_390_PLT32DBL: |
2483 |
case R_390_PLT32: |
case R_390_PLT32: |
2484 |
/* Relocation is to the entry for this symbol in the |
/* Relocation is to the entry for this symbol in the |
2485 |
procedure linkage table. */ |
procedure linkage table. */ |
2486 |
|
|
2487 |
/* Resolve a PLT32 reloc against a local symbol directly, |
/* Resolve a PLT32 reloc against a local symbol directly, |
2488 |
without using the procedure linkage table. */ |
without using the procedure linkage table. */ |
2489 |
if (h == NULL) |
if (h == NULL) |
2490 |
break; |
break; |
2491 |
|
|
2492 |
if (h->plt.offset == (bfd_vma) -1 |
if (h->plt.offset == (bfd_vma) -1 |
2493 |
|| htab->splt == NULL) |
|| htab->splt == NULL) |
2494 |
{ |
{ |
2495 |
/* We didn't make a PLT entry for this symbol. This |
/* We didn't make a PLT entry for this symbol. This |
2496 |
happens when statically linking PIC code, or when |
happens when statically linking PIC code, or when |
2497 |
using -Bsymbolic. */ |
using -Bsymbolic. */ |
2498 |
break; |
break; |
2499 |
} |
} |
2500 |
|
|
2501 |
relocation = (htab->splt->output_section->vma |
relocation = (htab->splt->output_section->vma |
2502 |
+ htab->splt->output_offset |
+ htab->splt->output_offset |
2503 |
+ h->plt.offset); |
+ h->plt.offset); |
2504 |
unresolved_reloc = false; |
unresolved_reloc = FALSE; |
2505 |
break; |
break; |
2506 |
|
|
2507 |
case R_390_8: |
case R_390_PLTOFF16: |
2508 |
case R_390_16: |
case R_390_PLTOFF32: |
2509 |
case R_390_32: |
/* Relocation is to the entry for this symbol in the |
2510 |
case R_390_PC16: |
procedure linkage table relative to the start of the GOT. */ |
2511 |
case R_390_PC16DBL: |
|
2512 |
case R_390_PC32DBL: |
/* For local symbols or if we didn't make a PLT entry for |
2513 |
case R_390_PC32: |
this symbol resolve the symbol directly. */ |
2514 |
|
if ( h == NULL |
2515 |
|
|| h->plt.offset == (bfd_vma) -1 |
2516 |
|
|| htab->splt == NULL) |
2517 |
|
{ |
2518 |
|
relocation -= htab->sgot->output_section->vma; |
2519 |
|
break; |
2520 |
|
} |
2521 |
|
|
2522 |
|
relocation = (htab->splt->output_section->vma |
2523 |
|
+ htab->splt->output_offset |
2524 |
|
+ h->plt.offset |
2525 |
|
- htab->sgot->output_section->vma); |
2526 |
|
unresolved_reloc = FALSE; |
2527 |
|
break; |
2528 |
|
|
2529 |
|
case R_390_8: |
2530 |
|
case R_390_16: |
2531 |
|
case R_390_32: |
2532 |
|
case R_390_PC16: |
2533 |
|
case R_390_PC16DBL: |
2534 |
|
case R_390_PC32DBL: |
2535 |
|
case R_390_PC32: |
2536 |
/* r_symndx will be zero only for relocs against symbols |
/* r_symndx will be zero only for relocs against symbols |
2537 |
from removed linkonce sections, or sections discarded by |
from removed linkonce sections, or sections discarded by |
2538 |
a linker script. */ |
a linker script. */ |
2539 |
if (r_symndx == 0 |
if (r_symndx == 0 |
2540 |
|| (input_section->flags & SEC_ALLOC) == 0) |
|| (input_section->flags & SEC_ALLOC) == 0) |
2541 |
break; |
break; |
2542 |
|
|
2543 |
if ((info->shared |
if ((info->shared |
2544 |
|
&& (h == NULL |
2545 |
|
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT |
2546 |
|
|| h->root.type != bfd_link_hash_undefweak) |
2547 |
&& ((r_type != R_390_PC16 |
&& ((r_type != R_390_PC16 |
2548 |
&& r_type != R_390_PC16DBL |
&& r_type != R_390_PC16DBL |
2549 |
&& r_type != R_390_PC32DBL |
&& r_type != R_390_PC32DBL |
2550 |
&& r_type != R_390_PC32) |
&& r_type != R_390_PC32) |
2551 |
|| (h != NULL |
|| (h != NULL |
2552 |
&& h->dynindx != -1 |
&& !SYMBOL_REFERENCES_LOCAL (info, h)))) |
2553 |
&& (! info->symbolic |
|| (ELIMINATE_COPY_RELOCS |
2554 |
|| (h->elf_link_hash_flags |
&& !info->shared |
|
& ELF_LINK_HASH_DEF_REGULAR) == 0)))) |
|
|
|| (!info->shared |
|
2555 |
&& h != NULL |
&& h != NULL |
2556 |
&& h->dynindx != -1 |
&& h->dynindx != -1 |
2557 |
&& (h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0 |
&& !h->non_got_ref |
2558 |
&& (((h->elf_link_hash_flags |
&& ((h->def_dynamic |
2559 |
& ELF_LINK_HASH_DEF_DYNAMIC) != 0 |
&& !h->def_regular) |
|
&& (h->elf_link_hash_flags |
|
|
& ELF_LINK_HASH_DEF_REGULAR) == 0) |
|
2560 |
|| h->root.type == bfd_link_hash_undefweak |
|| h->root.type == bfd_link_hash_undefweak |
2561 |
|| h->root.type == bfd_link_hash_undefined))) |
|| h->root.type == bfd_link_hash_undefined))) |
2562 |
{ |
{ |
2563 |
Elf_Internal_Rela outrel; |
Elf_Internal_Rela outrel; |
2564 |
boolean skip, relocate; |
bfd_boolean skip, relocate; |
2565 |
asection *sreloc; |
asection *sreloc; |
2566 |
Elf32_External_Rela *loc; |
bfd_byte *loc; |
2567 |
|
|
2568 |
/* When generating a shared object, these relocations |
/* When generating a shared object, these relocations |
2569 |
are copied into the output file to be resolved at run |
are copied into the output file to be resolved at run |
2570 |
time. */ |
time. */ |
2571 |
|
|
2572 |
skip = false; |
skip = FALSE; |
2573 |
relocate = false; |
relocate = FALSE; |
2574 |
|
|
2575 |
outrel.r_offset = |
outrel.r_offset = |
2576 |
_bfd_elf_section_offset (output_bfd, info, input_section, |
_bfd_elf_section_offset (output_bfd, info, input_section, |
2577 |
rel->r_offset); |
rel->r_offset); |
2578 |
if (outrel.r_offset == (bfd_vma) -1) |
if (outrel.r_offset == (bfd_vma) -1) |
2579 |
skip = true; |
skip = TRUE; |
2580 |
else if (outrel.r_offset == (bfd_vma) -2) |
else if (outrel.r_offset == (bfd_vma) -2) |
2581 |
skip = true, relocate = true; |
skip = TRUE, relocate = TRUE; |
2582 |
outrel.r_offset += (input_section->output_section->vma |
outrel.r_offset += (input_section->output_section->vma |
2583 |
+ input_section->output_offset); |
+ input_section->output_offset); |
2584 |
|
|
2585 |
if (skip) |
if (skip) |
2586 |
memset (&outrel, 0, sizeof outrel); |
memset (&outrel, 0, sizeof outrel); |
2587 |
else if (h != NULL |
else if (h != NULL |
2588 |
&& h->dynindx != -1 |
&& h->dynindx != -1 |
2589 |
&& (r_type == R_390_PC16 |
&& (r_type == R_390_PC16 |
2590 |
|| r_type == R_390_PC16DBL |
|| r_type == R_390_PC16DBL |
2592 |
|| r_type == R_390_PC32 |
|| r_type == R_390_PC32 |
2593 |
|| !info->shared |
|| !info->shared |
2594 |
|| !info->symbolic |
|| !info->symbolic |
2595 |
|| (h->elf_link_hash_flags |
|| !h->def_regular)) |
2596 |
& ELF_LINK_HASH_DEF_REGULAR) == 0)) |
{ |
2597 |
{ |
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); |
|
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); |
|
2598 |
outrel.r_addend = rel->r_addend; |
outrel.r_addend = rel->r_addend; |
2599 |
} |
} |
2600 |
else |
else |
2601 |
{ |
{ |
2602 |
/* This symbol is local, or marked to become local. */ |
/* This symbol is local, or marked to become local. */ |
|
relocate = true; |
|
|
outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE); |
|
2603 |
outrel.r_addend = relocation + rel->r_addend; |
outrel.r_addend = relocation + rel->r_addend; |
2604 |
} |
if (r_type == R_390_32) |
2605 |
|
{ |
2606 |
|
relocate = TRUE; |
2607 |
|
outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE); |
2608 |
|
} |
2609 |
|
else |
2610 |
|
{ |
2611 |
|
long sindx; |
2612 |
|
|
2613 |
|
if (bfd_is_abs_section (sec)) |
2614 |
|
sindx = 0; |
2615 |
|
else if (sec == NULL || sec->owner == NULL) |
2616 |
|
{ |
2617 |
|
bfd_set_error(bfd_error_bad_value); |
2618 |
|
return FALSE; |
2619 |
|
} |
2620 |
|
else |
2621 |
|
{ |
2622 |
|
asection *osec; |
2623 |
|
|
2624 |
|
osec = sec->output_section; |
2625 |
|
sindx = elf_section_data (osec)->dynindx; |
2626 |
|
BFD_ASSERT (sindx > 0); |
2627 |
|
|
2628 |
|
/* We are turning this relocation into one |
2629 |
|
against a section symbol, so subtract out |
2630 |
|
the output section's address but not the |
2631 |
|
offset of the input section in the output |
2632 |
|
section. */ |
2633 |
|
|
2634 |
|
outrel.r_addend -= osec->vma; |
2635 |
|
} |
2636 |
|
outrel.r_info = ELF32_R_INFO (sindx, r_type); |
2637 |
|
} |
2638 |
|
} |
2639 |
|
|
2640 |
sreloc = elf_section_data (input_section)->sreloc; |
sreloc = elf_section_data (input_section)->sreloc; |
2641 |
if (sreloc == NULL) |
if (sreloc == NULL) |
2642 |
abort (); |
abort (); |
2643 |
|
|
2644 |
loc = (Elf32_External_Rela *) sreloc->contents; |
loc = sreloc->contents; |
2645 |
loc += sreloc->reloc_count++; |
loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela); |
2646 |
|
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
2647 |
|
|
2648 |
|
/* If this reloc is against an external symbol, we do |
2649 |
|
not want to fiddle with the addend. Otherwise, we |
2650 |
|
need to include the symbol value so that it becomes |
2651 |
|
an addend for the dynamic reloc. */ |
2652 |
|
if (! relocate) |
2653 |
|
continue; |
2654 |
|
} |
2655 |
|
break; |
2656 |
|
|
2657 |
|
/* Relocations for tls literal pool entries. */ |
2658 |
|
case R_390_TLS_IE32: |
2659 |
|
if (info->shared) |
2660 |
|
{ |
2661 |
|
Elf_Internal_Rela outrel; |
2662 |
|
asection *sreloc; |
2663 |
|
bfd_byte *loc; |
2664 |
|
|
2665 |
|
outrel.r_offset = rel->r_offset |
2666 |
|
+ input_section->output_section->vma |
2667 |
|
+ input_section->output_offset; |
2668 |
|
outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE); |
2669 |
|
sreloc = elf_section_data (input_section)->sreloc; |
2670 |
|
if (sreloc == NULL) |
2671 |
|
abort (); |
2672 |
|
loc = sreloc->contents; |
2673 |
|
loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela); |
2674 |
|
bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); |
2675 |
|
} |
2676 |
|
/* Fall through. */ |
2677 |
|
|
2678 |
|
case R_390_TLS_GD32: |
2679 |
|
case R_390_TLS_GOTIE32: |
2680 |
|
r_type = elf_s390_tls_transition (info, r_type, h == NULL); |
2681 |
|
tls_type = GOT_UNKNOWN; |
2682 |
|
if (h == NULL && local_got_offsets) |
2683 |
|
tls_type = elf_s390_local_got_tls_type (input_bfd) [r_symndx]; |
2684 |
|
else if (h != NULL) |
2685 |
|
{ |
2686 |
|
tls_type = elf_s390_hash_entry(h)->tls_type; |
2687 |
|
if (!info->shared && h->dynindx == -1 && tls_type >= GOT_TLS_IE) |
2688 |
|
r_type = R_390_TLS_LE32; |
2689 |
|
} |
2690 |
|
if (r_type == R_390_TLS_GD32 && tls_type >= GOT_TLS_IE) |
2691 |
|
r_type = R_390_TLS_IE32; |
2692 |
|
|
2693 |
|
if (r_type == R_390_TLS_LE32) |
2694 |
|
{ |
2695 |
|
/* This relocation gets optimized away by the local exec |
2696 |
|
access optimization. */ |
2697 |
|
BFD_ASSERT (! unresolved_reloc); |
2698 |
|
bfd_put_32 (output_bfd, -tpoff (info, relocation), |
2699 |
|
contents + rel->r_offset); |
2700 |
|
continue; |
2701 |
|
} |
2702 |
|
|
2703 |
|
if (htab->sgot == NULL) |
2704 |
|
abort (); |
2705 |
|
|
2706 |
|
if (h != NULL) |
2707 |
|
off = h->got.offset; |
2708 |
|
else |
2709 |
|
{ |
2710 |
|
if (local_got_offsets == NULL) |
2711 |
|
abort (); |
2712 |
|
|
2713 |
|
off = local_got_offsets[r_symndx]; |
2714 |
|
} |
2715 |
|
|
2716 |
|
emit_tls_relocs: |
2717 |
|
|
2718 |
|
if ((off & 1) != 0) |
2719 |
|
off &= ~1; |
2720 |
|
else |
2721 |
|
{ |
2722 |
|
Elf_Internal_Rela outrel; |
2723 |
|
bfd_byte *loc; |
2724 |
|
int dr_type, indx; |
2725 |
|
|
2726 |
|
if (htab->srelgot == NULL) |
2727 |
|
abort (); |
2728 |
|
|
2729 |
|
outrel.r_offset = (htab->sgot->output_section->vma |
2730 |
|
+ htab->sgot->output_offset + off); |
2731 |
|
|
2732 |
|
indx = h && h->dynindx != -1 ? h->dynindx : 0; |
2733 |
|
if (r_type == R_390_TLS_GD32) |
2734 |
|
dr_type = R_390_TLS_DTPMOD; |
2735 |
|
else |
2736 |
|
dr_type = R_390_TLS_TPOFF; |
2737 |
|
if (dr_type == R_390_TLS_TPOFF && indx == 0) |
2738 |
|
outrel.r_addend = relocation - dtpoff_base (info); |
2739 |
|
else |
2740 |
|
outrel.r_addend = 0; |
2741 |
|
outrel.r_info = ELF32_R_INFO (indx, dr_type); |
2742 |
|
loc = htab->srelgot->contents; |
2743 |
|
loc += htab->srelgot->reloc_count++ |
2744 |
|
* sizeof (Elf32_External_Rela); |
2745 |
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
2746 |
|
|
2747 |
/* If this reloc is against an external symbol, we do |
if (r_type == R_390_TLS_GD32) |
2748 |
not want to fiddle with the addend. Otherwise, we |
{ |
2749 |
need to include the symbol value so that it becomes |
if (indx == 0) |
2750 |
an addend for the dynamic reloc. */ |
{ |
2751 |
if (! relocate) |
BFD_ASSERT (! unresolved_reloc); |
2752 |
continue; |
bfd_put_32 (output_bfd, |
2753 |
} |
relocation - dtpoff_base (info), |
2754 |
|
htab->sgot->contents + off + GOT_ENTRY_SIZE); |
2755 |
|
} |
2756 |
|
else |
2757 |
|
{ |
2758 |
|
outrel.r_info = ELF32_R_INFO (indx, R_390_TLS_DTPOFF); |
2759 |
|
outrel.r_offset += GOT_ENTRY_SIZE; |
2760 |
|
outrel.r_addend = 0; |
2761 |
|
htab->srelgot->reloc_count++; |
2762 |
|
loc += sizeof (Elf32_External_Rela); |
2763 |
|
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
2764 |
|
} |
2765 |
|
} |
2766 |
|
|
2767 |
|
if (h != NULL) |
2768 |
|
h->got.offset |= 1; |
2769 |
|
else |
2770 |
|
local_got_offsets[r_symndx] |= 1; |
2771 |
|
} |
2772 |
|
|
2773 |
|
if (off >= (bfd_vma) -2) |
2774 |
|
abort (); |
2775 |
|
if (r_type == ELF32_R_TYPE (rel->r_info)) |
2776 |
|
{ |
2777 |
|
relocation = htab->sgot->output_offset + off; |
2778 |
|
if (r_type == R_390_TLS_IE32 || r_type == R_390_TLS_IEENT) |
2779 |
|
relocation += htab->sgot->output_section->vma; |
2780 |
|
unresolved_reloc = FALSE; |
2781 |
|
} |
2782 |
|
else |
2783 |
|
{ |
2784 |
|
bfd_put_32 (output_bfd, htab->sgot->output_offset + off, |
2785 |
|
contents + rel->r_offset); |
2786 |
|
continue; |
2787 |
|
} |
2788 |
|
break; |
2789 |
|
|
2790 |
|
case R_390_TLS_GOTIE12: |
2791 |
|
case R_390_TLS_GOTIE20: |
2792 |
|
case R_390_TLS_IEENT: |
2793 |
|
if (h == NULL) |
2794 |
|
{ |
2795 |
|
if (local_got_offsets == NULL) |
2796 |
|
abort(); |
2797 |
|
off = local_got_offsets[r_symndx]; |
2798 |
|
if (info->shared) |
2799 |
|
goto emit_tls_relocs; |
2800 |
|
} |
2801 |
|
else |
2802 |
|
{ |
2803 |
|
off = h->got.offset; |
2804 |
|
tls_type = elf_s390_hash_entry(h)->tls_type; |
2805 |
|
if (info->shared || h->dynindx != -1 || tls_type < GOT_TLS_IE) |
2806 |
|
goto emit_tls_relocs; |
2807 |
|
} |
2808 |
|
|
2809 |
|
if (htab->sgot == NULL) |
2810 |
|
abort (); |
2811 |
|
|
2812 |
|
BFD_ASSERT (! unresolved_reloc); |
2813 |
|
bfd_put_32 (output_bfd, -tpoff (info, relocation), |
2814 |
|
htab->sgot->contents + off); |
2815 |
|
relocation = htab->sgot->output_offset + off; |
2816 |
|
if (r_type == R_390_TLS_IEENT) |
2817 |
|
relocation += htab->sgot->output_section->vma; |
2818 |
|
unresolved_reloc = FALSE; |
2819 |
break; |
break; |
2820 |
|
|
2821 |
|
case R_390_TLS_LDM32: |
2822 |
|
if (! info->shared) |
2823 |
|
/* The literal pool entry this relocation refers to gets ignored |
2824 |
|
by the optimized code of the local exec model. Do nothing |
2825 |
|
and the value will turn out zero. */ |
2826 |
|
continue; |
2827 |
|
|
2828 |
|
if (htab->sgot == NULL) |
2829 |
|
abort (); |
2830 |
|
|
2831 |
|
off = htab->tls_ldm_got.offset; |
2832 |
|
if (off & 1) |
2833 |
|
off &= ~1; |
2834 |
|
else |
2835 |
|
{ |
2836 |
|
Elf_Internal_Rela outrel; |
2837 |
|
bfd_byte *loc; |
2838 |
|
|
2839 |
|
if (htab->srelgot == NULL) |
2840 |
|
abort (); |
2841 |
|
|
2842 |
|
outrel.r_offset = (htab->sgot->output_section->vma |
2843 |
|
+ htab->sgot->output_offset + off); |
2844 |
|
|
2845 |
|
bfd_put_32 (output_bfd, 0, |
2846 |
|
htab->sgot->contents + off + GOT_ENTRY_SIZE); |
2847 |
|
outrel.r_info = ELF32_R_INFO (0, R_390_TLS_DTPMOD); |
2848 |
|
outrel.r_addend = 0; |
2849 |
|
loc = htab->srelgot->contents; |
2850 |
|
loc += htab->srelgot->reloc_count++ |
2851 |
|
* sizeof (Elf32_External_Rela); |
2852 |
|
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
2853 |
|
htab->tls_ldm_got.offset |= 1; |
2854 |
|
} |
2855 |
|
relocation = htab->sgot->output_offset + off; |
2856 |
|
unresolved_reloc = FALSE; |
2857 |
|
break; |
2858 |
|
|
2859 |
|
case R_390_TLS_LE32: |
2860 |
|
if (info->shared) |
2861 |
|
{ |
2862 |
|
/* Linking a shared library with non-fpic code requires |
2863 |
|
a R_390_TLS_TPOFF relocation. */ |
2864 |
|
Elf_Internal_Rela outrel; |
2865 |
|
asection *sreloc; |
2866 |
|
bfd_byte *loc; |
2867 |
|
int indx; |
2868 |
|
|
2869 |
|
outrel.r_offset = rel->r_offset |
2870 |
|
+ input_section->output_section->vma |
2871 |
|
+ input_section->output_offset; |
2872 |
|
if (h != NULL && h->dynindx != -1) |
2873 |
|
indx = h->dynindx; |
2874 |
|
else |
2875 |
|
indx = 0; |
2876 |
|
outrel.r_info = ELF32_R_INFO (indx, R_390_TLS_TPOFF); |
2877 |
|
if (indx == 0) |
2878 |
|
outrel.r_addend = relocation - dtpoff_base (info); |
2879 |
|
else |
2880 |
|
outrel.r_addend = 0; |
2881 |
|
sreloc = elf_section_data (input_section)->sreloc; |
2882 |
|
if (sreloc == NULL) |
2883 |
|
abort (); |
2884 |
|
loc = sreloc->contents; |
2885 |
|
loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela); |
2886 |
|
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
2887 |
|
} |
2888 |
|
else |
2889 |
|
{ |
2890 |
|
BFD_ASSERT (! unresolved_reloc); |
2891 |
|
bfd_put_32 (output_bfd, -tpoff (info, relocation), |
2892 |
|
contents + rel->r_offset); |
2893 |
|
} |
2894 |
|
continue; |
2895 |
|
|
2896 |
|
case R_390_TLS_LDO32: |
2897 |
|
if (info->shared || (input_section->flags & SEC_CODE) == 0) |
2898 |
|
relocation -= dtpoff_base (info); |
2899 |
|
else |
2900 |
|
/* When converting LDO to LE, we must negate. */ |
2901 |
|
relocation = -tpoff (info, relocation); |
2902 |
|
break; |
2903 |
|
|
2904 |
|
/* Relocations for tls instructions. */ |
2905 |
|
case R_390_TLS_LOAD: |
2906 |
|
case R_390_TLS_GDCALL: |
2907 |
|
case R_390_TLS_LDCALL: |
2908 |
|
tls_type = GOT_UNKNOWN; |
2909 |
|
if (h == NULL && local_got_offsets) |
2910 |
|
tls_type = elf_s390_local_got_tls_type (input_bfd) [r_symndx]; |
2911 |
|
else if (h != NULL) |
2912 |
|
tls_type = elf_s390_hash_entry(h)->tls_type; |
2913 |
|
|
2914 |
|
if (tls_type == GOT_TLS_GD) |
2915 |
|
continue; |
2916 |
|
|
2917 |
|
if (r_type == R_390_TLS_LOAD) |
2918 |
|
{ |
2919 |
|
if (!info->shared && (h == NULL || h->dynindx == -1)) |
2920 |
|
{ |
2921 |
|
/* IE->LE transition. Four valid cases: |
2922 |
|
l %rx,0(0,%ry) -> lr %rx,%ry + bcr 0,0 |
2923 |
|
l %rx,0(%ry,0) -> lr %rx,%ry + bcr 0,0 |
2924 |
|
l %rx,0(%ry,%r12) -> lr %rx,%ry + bcr 0,0 |
2925 |
|
l %rx,0(%r12,%ry) -> lr %rx,%ry + bcr 0,0 */ |
2926 |
|
unsigned int insn, ry; |
2927 |
|
|
2928 |
|
insn = bfd_get_32 (input_bfd, contents + rel->r_offset); |
2929 |
|
ry = 0; |
2930 |
|
if ((insn & 0xff00f000) == 0x58000000) |
2931 |
|
/* l %rx,0(%ry,0) -> lr %rx,%ry + bcr 0,0 */ |
2932 |
|
ry = (insn & 0x000f0000); |
2933 |
|
else if ((insn & 0xff0f0000) == 0x58000000) |
2934 |
|
/* l %rx,0(0,%ry) -> lr %rx,%ry + bcr 0,0 */ |
2935 |
|
ry = (insn & 0x0000f000) << 4; |
2936 |
|
else if ((insn & 0xff00f000) == 0x5800c000) |
2937 |
|
/* l %rx,0(%ry,%r12) -> lr %rx,%ry + bcr 0,0 */ |
2938 |
|
ry = (insn & 0x000f0000); |
2939 |
|
else if ((insn & 0xff0f0000) == 0x580c0000) |
2940 |
|
/* l %rx,0(%r12,%ry) -> lr %rx,%ry + bcr 0,0 */ |
2941 |
|
ry = (insn & 0x0000f000) << 4; |
2942 |
|
else |
2943 |
|
invalid_tls_insn (input_bfd, input_section, rel); |
2944 |
|
insn = 0x18000700 | (insn & 0x00f00000) | ry; |
2945 |
|
bfd_put_32 (output_bfd, insn, contents + rel->r_offset); |
2946 |
|
} |
2947 |
|
} |
2948 |
|
else if (r_type == R_390_TLS_GDCALL) |
2949 |
|
{ |
2950 |
|
unsigned int insn; |
2951 |
|
|
2952 |
|
insn = bfd_get_32 (input_bfd, contents + rel->r_offset); |
2953 |
|
if ((insn & 0xff000fff) != 0x4d000000) |
2954 |
|
invalid_tls_insn (input_bfd, input_section, rel); |
2955 |
|
if (!info->shared && (h == NULL || h->dynindx == -1)) |
2956 |
|
/* GD->LE transition. |
2957 |
|
bas %r14,0(%rx,%r13) -> bc 0,0 */ |
2958 |
|
insn = 0x47000000; |
2959 |
|
else |
2960 |
|
/* GD->IE transition. |
2961 |
|
bas %r14,0(%rx,%r13) -> l %r2,0(%r2,%r12) */ |
2962 |
|
insn = 0x5822c000; |
2963 |
|
bfd_put_32 (output_bfd, insn, contents + rel->r_offset); |
2964 |
|
} |
2965 |
|
else if (r_type == R_390_TLS_LDCALL) |
2966 |
|
{ |
2967 |
|
if (!info->shared) |
2968 |
|
{ |
2969 |
|
unsigned int insn; |
2970 |
|
|
2971 |
|
insn = bfd_get_32 (input_bfd, contents + rel->r_offset); |
2972 |
|
if ((insn & 0xff000fff) != 0x4d000000) |
2973 |
|
invalid_tls_insn (input_bfd, input_section, rel); |
2974 |
|
/* LD->LE transition. |
2975 |
|
bas %r14,0(%rx,%r13) -> bc 0,0 */ |
2976 |
|
insn = 0x47000000; |
2977 |
|
bfd_put_32 (output_bfd, insn, contents + rel->r_offset); |
2978 |
|
} |
2979 |
|
} |
2980 |
|
continue; |
2981 |
|
|
2982 |
default: |
default: |
2983 |
break; |
break; |
2984 |
} |
} |
2988 |
not process them. */ |
not process them. */ |
2989 |
if (unresolved_reloc |
if (unresolved_reloc |
2990 |
&& !((input_section->flags & SEC_DEBUGGING) != 0 |
&& !((input_section->flags & SEC_DEBUGGING) != 0 |
2991 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)) |
&& h->def_dynamic)) |
2992 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
2993 |
(_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"), |
(_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"), |
2994 |
bfd_archive_filename (input_bfd), |
input_bfd, |
2995 |
bfd_get_section_name (input_bfd, input_section), |
input_section, |
2996 |
(long) rel->r_offset, |
(long) rel->r_offset, |
2997 |
h->root.root.string); |
h->root.root.string); |
2998 |
|
|
2999 |
r = _bfd_final_link_relocate (howto, input_bfd, input_section, |
if (r_type == R_390_20 |
3000 |
contents, rel->r_offset, |
|| r_type == R_390_GOT20 |
3001 |
relocation, rel->r_addend); |
|| r_type == R_390_GOTPLT20 |
3002 |
|
|| r_type == R_390_TLS_GOTIE20) |
3003 |
|
{ |
3004 |
|
relocation += rel->r_addend; |
3005 |
|
relocation = (relocation&0xfff) << 8 | (relocation&0xff000) >> 12; |
3006 |
|
r = _bfd_final_link_relocate (howto, input_bfd, input_section, |
3007 |
|
contents, rel->r_offset, |
3008 |
|
relocation, 0); |
3009 |
|
} |
3010 |
|
else |
3011 |
|
r = _bfd_final_link_relocate (howto, input_bfd, input_section, |
3012 |
|
contents, rel->r_offset, |
3013 |
|
relocation, rel->r_addend); |
3014 |
|
|
3015 |
if (r != bfd_reloc_ok) |
if (r != bfd_reloc_ok) |
3016 |
{ |
{ |
3024 |
symtab_hdr->sh_link, |
symtab_hdr->sh_link, |
3025 |
sym->st_name); |
sym->st_name); |
3026 |
if (name == NULL) |
if (name == NULL) |
3027 |
return false; |
return FALSE; |
3028 |
if (*name == '\0') |
if (*name == '\0') |
3029 |
name = bfd_section_name (input_bfd, sec); |
name = bfd_section_name (input_bfd, sec); |
3030 |
} |
} |
3033 |
{ |
{ |
3034 |
|
|
3035 |
if (! ((*info->callbacks->reloc_overflow) |
if (! ((*info->callbacks->reloc_overflow) |
3036 |
(info, name, howto->name, (bfd_vma) 0, |
(info, (h ? &h->root : NULL), name, howto->name, |
3037 |
input_bfd, input_section, rel->r_offset))) |
(bfd_vma) 0, input_bfd, input_section, |
3038 |
return false; |
rel->r_offset))) |
3039 |
|
return FALSE; |
3040 |
} |
} |
3041 |
else |
else |
3042 |
{ |
{ |
3043 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
3044 |
(_("%s(%s+0x%lx): reloc against `%s': error %d"), |
(_("%B(%A+0x%lx): reloc against `%s': error %d"), |
3045 |
bfd_archive_filename (input_bfd), |
input_bfd, input_section, |
|
bfd_get_section_name (input_bfd, input_section), |
|
3046 |
(long) rel->r_offset, name, (int) r); |
(long) rel->r_offset, name, (int) r); |
3047 |
return false; |
return FALSE; |
3048 |
} |
} |
3049 |
} |
} |
3050 |
} |
} |
3051 |
|
|
3052 |
return true; |
return TRUE; |
3053 |
} |
} |
3054 |
|
|
3055 |
/* Finish up dynamic symbol handling. We set the contents of various |
/* Finish up dynamic symbol handling. We set the contents of various |
3056 |
dynamic sections here. */ |
dynamic sections here. */ |
3057 |
|
|
3058 |
static boolean |
static bfd_boolean |
3059 |
elf_s390_finish_dynamic_symbol (output_bfd, info, h, sym) |
elf_s390_finish_dynamic_symbol (output_bfd, info, h, sym) |
3060 |
bfd *output_bfd; |
bfd *output_bfd; |
3061 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
3071 |
bfd_vma plt_index; |
bfd_vma plt_index; |
3072 |
bfd_vma got_offset; |
bfd_vma got_offset; |
3073 |
Elf_Internal_Rela rela; |
Elf_Internal_Rela rela; |
3074 |
Elf32_External_Rela *loc; |
bfd_byte *loc; |
3075 |
bfd_vma relative_offset; |
bfd_vma relative_offset; |
3076 |
|
|
3077 |
/* This symbol has an entry in the procedure linkage table. Set |
/* This symbol has an entry in the procedure linkage table. Set |
3078 |
it up. */ |
it up. */ |
|
|
|
3079 |
if (h->dynindx == -1 |
if (h->dynindx == -1 |
3080 |
|| htab->splt == NULL |
|| htab->splt == NULL |
3081 |
|| htab->sgotplt == NULL |
|| htab->sgotplt == NULL |
3083 |
abort (); |
abort (); |
3084 |
|
|
3085 |
/* Calc. index no. |
/* Calc. index no. |
3086 |
Current offset - size first entry / entry size. */ |
Current offset - size first entry / entry size. */ |
3087 |
plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE; |
plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE; |
3088 |
|
|
3089 |
/* Offset in GOT is PLT index plus GOT headers(3) times 4, |
/* Offset in GOT is PLT index plus GOT headers(3) times 4, |
3090 |
addr & GOT addr. */ |
addr & GOT addr. */ |
3091 |
got_offset = (plt_index + 3) * GOT_ENTRY_SIZE; |
got_offset = (plt_index + 3) * GOT_ENTRY_SIZE; |
3092 |
|
|
3093 |
/* S390 uses halfwords for relative branch calc! */ |
/* S390 uses halfwords for relative branch calc! */ |
3094 |
relative_offset = - ((PLT_FIRST_ENTRY_SIZE + |
relative_offset = - ((PLT_FIRST_ENTRY_SIZE + |
3095 |
(PLT_ENTRY_SIZE * plt_index) + 18) / 2); |
(PLT_ENTRY_SIZE * plt_index) + 18) / 2); |
3096 |
/* If offset is > 32768, branch to a previous branch |
/* If offset is > 32768, branch to a previous branch |
3097 |
390 can only handle +-64 K jumps. */ |
390 can only handle +-64 K jumps. */ |
3098 |
if ( -32768 > (int) relative_offset ) |
if ( -32768 > (int) relative_offset ) |
3099 |
relative_offset = |
relative_offset |
3100 |
-(unsigned) (((65536 / PLT_ENTRY_SIZE - 1) * PLT_ENTRY_SIZE) / 2); |
= -(unsigned) (((65536 / PLT_ENTRY_SIZE - 1) * PLT_ENTRY_SIZE) / 2); |
3101 |
|
|
3102 |
/* Fill in the entry in the procedure linkage table. */ |
/* Fill in the entry in the procedure linkage table. */ |
3103 |
if (!info->shared) |
if (!info->shared) |
3104 |
{ |
{ |
3105 |
bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD0, |
bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD0, |
3106 |
htab->splt->contents + h->plt.offset); |
htab->splt->contents + h->plt.offset); |
3107 |
bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD1, |
bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD1, |
3108 |
htab->splt->contents + h->plt.offset + 4); |
htab->splt->contents + h->plt.offset + 4); |
3173 |
} |
} |
3174 |
/* Insert offset into reloc. table here. */ |
/* Insert offset into reloc. table here. */ |
3175 |
bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela), |
bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela), |
3176 |
htab->splt->contents + h->plt.offset + 28); |
htab->splt->contents + h->plt.offset + 28); |
3177 |
|
|
3178 |
/* Fill in the entry in the global offset table. |
/* Fill in the entry in the global offset table. |
3179 |
Points to instruction after GOT offset. */ |
Points to instruction after GOT offset. */ |
3180 |
bfd_put_32 (output_bfd, |
bfd_put_32 (output_bfd, |
3181 |
(htab->splt->output_section->vma |
(htab->splt->output_section->vma |
3182 |
+ htab->splt->output_offset |
+ htab->splt->output_offset |
3190 |
+ got_offset); |
+ got_offset); |
3191 |
rela.r_info = ELF32_R_INFO (h->dynindx, R_390_JMP_SLOT); |
rela.r_info = ELF32_R_INFO (h->dynindx, R_390_JMP_SLOT); |
3192 |
rela.r_addend = 0; |
rela.r_addend = 0; |
3193 |
loc = (Elf32_External_Rela *) htab->srelplt->contents + plt_index; |
loc = htab->srelplt->contents + plt_index * sizeof (Elf32_External_Rela); |
3194 |
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); |
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); |
3195 |
|
|
3196 |
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) |
if (!h->def_regular) |
3197 |
{ |
{ |
3198 |
/* Mark the symbol as undefined, rather than as defined in |
/* Mark the symbol as undefined, rather than as defined in |
3199 |
the .plt section. Leave the value alone. This is a clue |
the .plt section. Leave the value alone. This is a clue |
3204 |
} |
} |
3205 |
} |
} |
3206 |
|
|
3207 |
if (h->got.offset != (bfd_vma) -1) |
if (h->got.offset != (bfd_vma) -1 |
3208 |
|
&& elf_s390_hash_entry(h)->tls_type != GOT_TLS_GD |
3209 |
|
&& elf_s390_hash_entry(h)->tls_type != GOT_TLS_IE |
3210 |
|
&& elf_s390_hash_entry(h)->tls_type != GOT_TLS_IE_NLT) |
3211 |
{ |
{ |
3212 |
Elf_Internal_Rela rela; |
Elf_Internal_Rela rela; |
3213 |
Elf32_External_Rela *loc; |
bfd_byte *loc; |
3214 |
|
|
3215 |
/* This symbol has an entry in the global offset table. Set it |
/* This symbol has an entry in the global offset table. Set it |
3216 |
up. */ |
up. */ |
3217 |
|
|
3218 |
if (htab->sgot == NULL || htab->srelgot == NULL) |
if (htab->sgot == NULL || htab->srelgot == NULL) |
3219 |
abort (); |
abort (); |
3230 |
if (info->shared |
if (info->shared |
3231 |
&& (info->symbolic |
&& (info->symbolic |
3232 |
|| h->dynindx == -1 |
|| h->dynindx == -1 |
3233 |
|| (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)) |
|| h->forced_local) |
3234 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) |
&& h->def_regular) |
3235 |
{ |
{ |
3236 |
BFD_ASSERT((h->got.offset & 1) != 0); |
BFD_ASSERT((h->got.offset & 1) != 0); |
3237 |
rela.r_info = ELF32_R_INFO (0, R_390_RELATIVE); |
rela.r_info = ELF32_R_INFO (0, R_390_RELATIVE); |
3238 |
rela.r_addend = (h->root.u.def.value |
rela.r_addend = (h->root.u.def.value |
3239 |
+ h->root.u.def.section->output_section->vma |
+ h->root.u.def.section->output_section->vma |
3240 |
+ h->root.u.def.section->output_offset); |
+ h->root.u.def.section->output_offset); |
3241 |
} |
} |
3242 |
else |
else |
3243 |
{ |
{ |
3244 |
BFD_ASSERT((h->got.offset & 1) == 0); |
BFD_ASSERT((h->got.offset & 1) == 0); |
3245 |
bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgot->contents + h->got.offset); |
bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgot->contents + h->got.offset); |
3246 |
rela.r_info = ELF32_R_INFO (h->dynindx, R_390_GLOB_DAT); |
rela.r_info = ELF32_R_INFO (h->dynindx, R_390_GLOB_DAT); |
3247 |
rela.r_addend = 0; |
rela.r_addend = 0; |
3248 |
} |
} |
3249 |
|
|
3250 |
loc = (Elf32_External_Rela *) htab->srelgot->contents; |
loc = htab->srelgot->contents; |
3251 |
loc += htab->srelgot->reloc_count++; |
loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rela); |
3252 |
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); |
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); |
3253 |
} |
} |
3254 |
|
|
3255 |
if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) |
if (h->needs_copy) |
3256 |
{ |
{ |
3257 |
Elf_Internal_Rela rela; |
Elf_Internal_Rela rela; |
3258 |
Elf32_External_Rela *loc; |
bfd_byte *loc; |
3259 |
|
|
3260 |
/* This symbols needs a copy reloc. Set it up. */ |
/* This symbols needs a copy reloc. Set it up. */ |
3261 |
|
|
3270 |
+ h->root.u.def.section->output_offset); |
+ h->root.u.def.section->output_offset); |
3271 |
rela.r_info = ELF32_R_INFO (h->dynindx, R_390_COPY); |
rela.r_info = ELF32_R_INFO (h->dynindx, R_390_COPY); |
3272 |
rela.r_addend = 0; |
rela.r_addend = 0; |
3273 |
loc = (Elf32_External_Rela *) htab->srelbss->contents; |
loc = htab->srelbss->contents; |
3274 |
loc += htab->srelbss->reloc_count++; |
loc += htab->srelbss->reloc_count++ * sizeof (Elf32_External_Rela); |
3275 |
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); |
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); |
3276 |
} |
} |
3277 |
|
|
3281 |
|| strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0) |
|| strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0) |
3282 |
sym->st_shndx = SHN_ABS; |
sym->st_shndx = SHN_ABS; |
3283 |
|
|
3284 |
return true; |
return TRUE; |
3285 |
} |
} |
3286 |
|
|
3287 |
/* Used to decide how to sort relocs in an optimal manner for the |
/* Used to decide how to sort relocs in an optimal manner for the |
3306 |
|
|
3307 |
/* Finish up the dynamic sections. */ |
/* Finish up the dynamic sections. */ |
3308 |
|
|
3309 |
static boolean |
static bfd_boolean |
3310 |
elf_s390_finish_dynamic_sections (output_bfd, info) |
elf_s390_finish_dynamic_sections (output_bfd, info) |
3311 |
bfd *output_bfd; |
bfd *output_bfd; |
3312 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
3327 |
abort (); |
abort (); |
3328 |
|
|
3329 |
dyncon = (Elf32_External_Dyn *) sdyn->contents; |
dyncon = (Elf32_External_Dyn *) sdyn->contents; |
3330 |
dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); |
dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size); |
3331 |
for (; dyncon < dynconend; dyncon++) |
for (; dyncon < dynconend; dyncon++) |
3332 |
{ |
{ |
3333 |
Elf_Internal_Dyn dyn; |
Elf_Internal_Dyn dyn; |
3350 |
|
|
3351 |
case DT_PLTRELSZ: |
case DT_PLTRELSZ: |
3352 |
s = htab->srelplt->output_section; |
s = htab->srelplt->output_section; |
3353 |
if (s->_cooked_size != 0) |
dyn.d_un.d_val = s->size; |
|
dyn.d_un.d_val = s->_cooked_size; |
|
|
else |
|
|
dyn.d_un.d_val = s->_raw_size; |
|
3354 |
break; |
break; |
3355 |
} |
} |
3356 |
|
|
3358 |
} |
} |
3359 |
|
|
3360 |
/* Fill in the special first entry in the procedure linkage table. */ |
/* Fill in the special first entry in the procedure linkage table. */ |
3361 |
if (htab->splt && htab->splt->_raw_size > 0) |
if (htab->splt && htab->splt->size > 0) |
3362 |
{ |
{ |
3363 |
memset (htab->splt->contents, 0, PLT_FIRST_ENTRY_SIZE); |
memset (htab->splt->contents, 0, PLT_FIRST_ENTRY_SIZE); |
3364 |
if (info->shared) |
if (info->shared) |
3365 |
{ |
{ |
3366 |
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD0, |
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD0, |
3367 |
htab->splt->contents ); |
htab->splt->contents ); |
3368 |
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD1, |
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD1, |
3369 |
htab->splt->contents +4 ); |
htab->splt->contents +4 ); |
3370 |
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD2, |
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD2, |
3371 |
htab->splt->contents +8 ); |
htab->splt->contents +8 ); |
3372 |
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD3, |
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD3, |
3373 |
htab->splt->contents +12 ); |
htab->splt->contents +12 ); |
3374 |
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD4, |
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD4, |
3375 |
htab->splt->contents +16 ); |
htab->splt->contents +16 ); |
3376 |
} |
} |
3377 |
else |
else |
3378 |
{ |
{ |
3379 |
bfd_put_32 (output_bfd, (bfd_vma)PLT_FIRST_ENTRY_WORD0, |
bfd_put_32 (output_bfd, (bfd_vma)PLT_FIRST_ENTRY_WORD0, |
3380 |
htab->splt->contents ); |
htab->splt->contents ); |
3381 |
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD1, |
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD1, |
3382 |
htab->splt->contents +4 ); |
htab->splt->contents +4 ); |
3383 |
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD2, |
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD2, |
3384 |
htab->splt->contents +8 ); |
htab->splt->contents +8 ); |
3385 |
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD3, |
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD3, |
3386 |
htab->splt->contents +12 ); |
htab->splt->contents +12 ); |
3387 |
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD4, |
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD4, |
3388 |
htab->splt->contents +16 ); |
htab->splt->contents +16 ); |
3389 |
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD5, |
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD5, |
3390 |
htab->splt->contents +20 ); |
htab->splt->contents +20 ); |
3391 |
bfd_put_32 (output_bfd, |
bfd_put_32 (output_bfd, |
3392 |
htab->sgotplt->output_section->vma |
htab->sgotplt->output_section->vma |
3393 |
+ htab->sgotplt->output_offset, |
+ htab->sgotplt->output_offset, |
3394 |
htab->splt->contents + 24); |
htab->splt->contents + 24); |
3395 |
} |
} |
3396 |
elf_section_data (htab->splt->output_section) |
elf_section_data (htab->splt->output_section) |
3397 |
->this_hdr.sh_entsize = 4; |
->this_hdr.sh_entsize = 4; |
3398 |
} |
} |
3402 |
if (htab->sgotplt) |
if (htab->sgotplt) |
3403 |
{ |
{ |
3404 |
/* Fill in the first three entries in the global offset table. */ |
/* Fill in the first three entries in the global offset table. */ |
3405 |
if (htab->sgotplt->_raw_size > 0) |
if (htab->sgotplt->size > 0) |
3406 |
{ |
{ |
3407 |
bfd_put_32 (output_bfd, |
bfd_put_32 (output_bfd, |
3408 |
(sdyn == NULL ? (bfd_vma) 0 |
(sdyn == NULL ? (bfd_vma) 0 |
3417 |
elf_section_data (htab->sgotplt->output_section) |
elf_section_data (htab->sgotplt->output_section) |
3418 |
->this_hdr.sh_entsize = 4; |
->this_hdr.sh_entsize = 4; |
3419 |
} |
} |
3420 |
return true; |
return TRUE; |
|
} |
|
|
|
|
|
static boolean |
|
|
elf_s390_object_p (abfd) |
|
|
bfd *abfd; |
|
|
{ |
|
|
return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_31); |
|
3421 |
} |
} |
3422 |
|
|
3423 |
static boolean |
static bfd_boolean |
3424 |
elf_s390_grok_prstatus (abfd, note) |
elf_s390_grok_prstatus (abfd, note) |
3425 |
bfd * abfd; |
bfd * abfd; |
3426 |
Elf_Internal_Note * note; |
Elf_Internal_Note * note; |
3427 |
{ |
{ |
3428 |
int offset; |
int offset; |
3429 |
unsigned int raw_size; |
unsigned int size; |
3430 |
|
|
3431 |
switch (note->descsz) |
switch (note->descsz) |
3432 |
{ |
{ |
3433 |
default: |
default: |
3434 |
return false; |
return FALSE; |
3435 |
|
|
3436 |
case 224: /* S/390 Linux. */ |
case 224: /* S/390 Linux. */ |
3437 |
/* pr_cursig */ |
/* pr_cursig */ |
3442 |
|
|
3443 |
/* pr_reg */ |
/* pr_reg */ |
3444 |
offset = 72; |
offset = 72; |
3445 |
raw_size = 144; |
size = 144; |
3446 |
break; |
break; |
3447 |
} |
} |
3448 |
|
|
3449 |
/* Make a ".reg/999" section. */ |
/* Make a ".reg/999" section. */ |
3450 |
return _bfd_elfcore_make_pseudosection (abfd, ".reg", |
return _bfd_elfcore_make_pseudosection (abfd, ".reg", |
3451 |
raw_size, note->descpos + offset); |
size, note->descpos + offset); |
3452 |
} |
} |
3453 |
|
|
3454 |
|
/* Return address for Ith PLT stub in section PLT, for relocation REL |
3455 |
|
or (bfd_vma) -1 if it should not be included. */ |
3456 |
|
|
3457 |
|
static bfd_vma |
3458 |
|
elf_s390_plt_sym_val (bfd_vma i, const asection *plt, |
3459 |
|
const arelent *rel ATTRIBUTE_UNUSED) |
3460 |
|
{ |
3461 |
|
return plt->vma + PLT_FIRST_ENTRY_SIZE + i * PLT_ENTRY_SIZE; |
3462 |
|
} |
3463 |
|
|
3464 |
|
|
3465 |
#define TARGET_BIG_SYM bfd_elf32_s390_vec |
#define TARGET_BIG_SYM bfd_elf32_s390_vec |
3466 |
#define TARGET_BIG_NAME "elf32-s390" |
#define TARGET_BIG_NAME "elf32-s390" |
3467 |
#define ELF_ARCH bfd_arch_s390 |
#define ELF_ARCH bfd_arch_s390 |
3475 |
#define elf_backend_plt_readonly 1 |
#define elf_backend_plt_readonly 1 |
3476 |
#define elf_backend_want_plt_sym 0 |
#define elf_backend_want_plt_sym 0 |
3477 |
#define elf_backend_got_header_size 12 |
#define elf_backend_got_header_size 12 |
|
#define elf_backend_plt_header_size PLT_ENTRY_SIZE |
|
3478 |
#define elf_backend_rela_normal 1 |
#define elf_backend_rela_normal 1 |
3479 |
|
|
3480 |
#define elf_info_to_howto elf_s390_info_to_howto |
#define elf_info_to_howto elf_s390_info_to_howto |
3481 |
|
|
3482 |
#define bfd_elf32_bfd_is_local_label_name elf_s390_is_local_label_name |
#define bfd_elf32_bfd_is_local_label_name elf_s390_is_local_label_name |
3483 |
#define bfd_elf32_bfd_link_hash_table_create elf_s390_link_hash_table_create |
#define bfd_elf32_bfd_link_hash_table_create elf_s390_link_hash_table_create |
3484 |
#define bfd_elf32_bfd_reloc_type_lookup elf_s390_reloc_type_lookup |
#define bfd_elf32_bfd_reloc_type_lookup elf_s390_reloc_type_lookup |
3485 |
|
|
3486 |
#define elf_backend_adjust_dynamic_symbol elf_s390_adjust_dynamic_symbol |
#define elf_backend_adjust_dynamic_symbol elf_s390_adjust_dynamic_symbol |
3487 |
#define elf_backend_check_relocs elf_s390_check_relocs |
#define elf_backend_check_relocs elf_s390_check_relocs |
3488 |
#define elf_backend_copy_indirect_symbol elf_s390_copy_indirect_symbol |
#define elf_backend_copy_indirect_symbol elf_s390_copy_indirect_symbol |
3489 |
#define elf_backend_create_dynamic_sections elf_s390_create_dynamic_sections |
#define elf_backend_create_dynamic_sections elf_s390_create_dynamic_sections |
3490 |
#define elf_backend_finish_dynamic_sections elf_s390_finish_dynamic_sections |
#define elf_backend_finish_dynamic_sections elf_s390_finish_dynamic_sections |
3491 |
#define elf_backend_finish_dynamic_symbol elf_s390_finish_dynamic_symbol |
#define elf_backend_finish_dynamic_symbol elf_s390_finish_dynamic_symbol |
3492 |
#define elf_backend_gc_mark_hook elf_s390_gc_mark_hook |
#define elf_backend_gc_mark_hook elf_s390_gc_mark_hook |
3493 |
#define elf_backend_gc_sweep_hook elf_s390_gc_sweep_hook |
#define elf_backend_gc_sweep_hook elf_s390_gc_sweep_hook |
3494 |
#define elf_backend_reloc_type_class elf_s390_reloc_type_class |
#define elf_backend_reloc_type_class elf_s390_reloc_type_class |
3495 |
#define elf_backend_relocate_section elf_s390_relocate_section |
#define elf_backend_relocate_section elf_s390_relocate_section |
3496 |
#define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections |
#define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections |
3497 |
#define elf_backend_reloc_type_class elf_s390_reloc_type_class |
#define elf_backend_reloc_type_class elf_s390_reloc_type_class |
3498 |
#define elf_backend_grok_prstatus elf_s390_grok_prstatus |
#define elf_backend_grok_prstatus elf_s390_grok_prstatus |
3499 |
|
#define elf_backend_plt_sym_val elf_s390_plt_sym_val |
3500 |
|
|
3501 |
#define elf_backend_object_p elf_s390_object_p |
#define bfd_elf32_mkobject elf_s390_mkobject |
3502 |
|
#define elf_backend_object_p elf_s390_object_p |
3503 |
|
|
3504 |
#include "elf32-target.h" |
#include "elf32-target.h" |