1 |
/* VAX series support for 32-bit ELF |
/* VAX series support for 32-bit ELF |
2 |
Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 |
Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, |
3 |
Free Software Foundation, Inc. |
2004, 2005 Free Software Foundation, Inc. |
4 |
Contributed by Matt Thomas <matt@3am-software.com>. |
Contributed by Matt Thomas <matt@3am-software.com>. |
5 |
|
|
6 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
7 |
|
|
8 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
9 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
10 |
the Free Software Foundation; either version 2 of the License, or |
the Free Software Foundation; either version 2 of the License, or |
11 |
(at your option) any later version. |
(at your option) any later version. |
12 |
|
|
13 |
This program is distributed in the hope that it will be useful, |
This program is distributed in the hope that it will be useful, |
14 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 |
GNU General Public License for more details. |
GNU General Public License for more details. |
17 |
|
|
18 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
19 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
20 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
21 |
|
|
22 |
#include "bfd.h" |
#include "bfd.h" |
23 |
#include "sysdep.h" |
#include "sysdep.h" |
29 |
static reloc_howto_type *reloc_type_lookup |
static reloc_howto_type *reloc_type_lookup |
30 |
PARAMS ((bfd *, bfd_reloc_code_real_type)); |
PARAMS ((bfd *, bfd_reloc_code_real_type)); |
31 |
static void rtype_to_howto |
static void rtype_to_howto |
32 |
PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); |
PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); |
33 |
static struct bfd_hash_entry *elf_vax_link_hash_newfunc |
static struct bfd_hash_entry *elf_vax_link_hash_newfunc |
34 |
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); |
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); |
35 |
static struct bfd_link_hash_table *elf_vax_link_hash_table_create |
static struct bfd_link_hash_table *elf_vax_link_hash_table_create |
36 |
PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
37 |
static boolean elf_vax_check_relocs |
static bfd_boolean elf_vax_check_relocs |
38 |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
39 |
const Elf_Internal_Rela *)); |
const Elf_Internal_Rela *)); |
40 |
static asection *elf_vax_gc_mark_hook |
static asection *elf_vax_gc_mark_hook |
41 |
PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, |
PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, |
42 |
struct elf_link_hash_entry *, Elf_Internal_Sym *)); |
struct elf_link_hash_entry *, Elf_Internal_Sym *)); |
43 |
static boolean elf_vax_gc_sweep_hook |
static bfd_boolean elf_vax_gc_sweep_hook |
44 |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
PARAMS ((bfd *, struct bfd_link_info *, asection *, |
45 |
const Elf_Internal_Rela *)); |
const Elf_Internal_Rela *)); |
46 |
static boolean elf_vax_adjust_dynamic_symbol |
static bfd_boolean elf_vax_adjust_dynamic_symbol |
47 |
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); |
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); |
48 |
static boolean elf_vax_size_dynamic_sections |
static bfd_boolean elf_vax_size_dynamic_sections |
49 |
PARAMS ((bfd *, struct bfd_link_info *)); |
PARAMS ((bfd *, struct bfd_link_info *)); |
50 |
static boolean elf_vax_relocate_section |
static bfd_boolean elf_vax_relocate_section |
51 |
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, |
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, |
52 |
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); |
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); |
53 |
static boolean elf_vax_finish_dynamic_symbol |
static bfd_boolean elf_vax_finish_dynamic_symbol |
54 |
PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, |
PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, |
55 |
Elf_Internal_Sym *)); |
Elf_Internal_Sym *)); |
56 |
static boolean elf_vax_finish_dynamic_sections |
static bfd_boolean elf_vax_finish_dynamic_sections |
57 |
PARAMS ((bfd *, struct bfd_link_info *)); |
PARAMS ((bfd *, struct bfd_link_info *)); |
58 |
|
|
59 |
static boolean elf32_vax_set_private_flags |
static bfd_boolean elf32_vax_set_private_flags |
60 |
PARAMS ((bfd *, flagword)); |
PARAMS ((bfd *, flagword)); |
61 |
static boolean elf32_vax_merge_private_bfd_data |
static bfd_boolean elf32_vax_merge_private_bfd_data |
62 |
PARAMS ((bfd *, bfd *)); |
PARAMS ((bfd *, bfd *)); |
63 |
static boolean elf32_vax_print_private_bfd_data |
static bfd_boolean elf32_vax_print_private_bfd_data |
64 |
PARAMS ((bfd *, PTR)); |
PARAMS ((bfd *, PTR)); |
65 |
|
|
66 |
static reloc_howto_type howto_table[] = { |
static reloc_howto_type howto_table[] = { |
68 |
0, /* rightshift */ |
0, /* rightshift */ |
69 |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
70 |
0, /* bitsize */ |
0, /* bitsize */ |
71 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
72 |
0, /* bitpos */ |
0, /* bitpos */ |
73 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
74 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
75 |
"R_VAX_NONE", /* name */ |
"R_VAX_NONE", /* name */ |
76 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
77 |
0, /* src_mask */ |
0, /* src_mask */ |
78 |
0x00000000, /* dst_mask */ |
0x00000000, /* dst_mask */ |
79 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
80 |
|
|
81 |
HOWTO (R_VAX_32, /* type */ |
HOWTO (R_VAX_32, /* type */ |
82 |
0, /* rightshift */ |
0, /* rightshift */ |
83 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
84 |
32, /* bitsize */ |
32, /* bitsize */ |
85 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
86 |
0, /* bitpos */ |
0, /* bitpos */ |
87 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
88 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
89 |
"R_VAX_32", /* name */ |
"R_VAX_32", /* name */ |
90 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
91 |
0, /* src_mask */ |
0, /* src_mask */ |
92 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
93 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
94 |
|
|
95 |
HOWTO (R_VAX_16, /* type */ |
HOWTO (R_VAX_16, /* type */ |
96 |
0, /* rightshift */ |
0, /* rightshift */ |
97 |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
98 |
16, /* bitsize */ |
16, /* bitsize */ |
99 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
100 |
0, /* bitpos */ |
0, /* bitpos */ |
101 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
102 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
103 |
"R_VAX_16", /* name */ |
"R_VAX_16", /* name */ |
104 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
105 |
0, /* src_mask */ |
0, /* src_mask */ |
106 |
0x0000ffff, /* dst_mask */ |
0x0000ffff, /* dst_mask */ |
107 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
108 |
|
|
109 |
HOWTO (R_VAX_8, /* type */ |
HOWTO (R_VAX_8, /* type */ |
110 |
0, /* rightshift */ |
0, /* rightshift */ |
111 |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
112 |
8, /* bitsize */ |
8, /* bitsize */ |
113 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
114 |
0, /* bitpos */ |
0, /* bitpos */ |
115 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
116 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
117 |
"R_VAX_8", /* name */ |
"R_VAX_8", /* name */ |
118 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
119 |
0, /* src_mask */ |
0, /* src_mask */ |
120 |
0x000000ff, /* dst_mask */ |
0x000000ff, /* dst_mask */ |
121 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
122 |
|
|
123 |
HOWTO (R_VAX_PC32, /* type */ |
HOWTO (R_VAX_PC32, /* type */ |
124 |
0, /* rightshift */ |
0, /* rightshift */ |
125 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
126 |
32, /* bitsize */ |
32, /* bitsize */ |
127 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
128 |
0, /* bitpos */ |
0, /* bitpos */ |
129 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
130 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
131 |
"R_VAX_PC32", /* name */ |
"R_VAX_PC32", /* name */ |
132 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
133 |
0, /* src_mask */ |
0, /* src_mask */ |
134 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
135 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
136 |
|
|
137 |
HOWTO (R_VAX_PC16, /* type */ |
HOWTO (R_VAX_PC16, /* type */ |
138 |
0, /* rightshift */ |
0, /* rightshift */ |
139 |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
140 |
16, /* bitsize */ |
16, /* bitsize */ |
141 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
142 |
0, /* bitpos */ |
0, /* bitpos */ |
143 |
complain_overflow_signed, /* complain_on_overflow */ |
complain_overflow_signed, /* complain_on_overflow */ |
144 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
145 |
"R_VAX_PC16", /* name */ |
"R_VAX_PC16", /* name */ |
146 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
147 |
0, /* src_mask */ |
0, /* src_mask */ |
148 |
0x0000ffff, /* dst_mask */ |
0x0000ffff, /* dst_mask */ |
149 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
150 |
|
|
151 |
HOWTO (R_VAX_PC8, /* type */ |
HOWTO (R_VAX_PC8, /* type */ |
152 |
0, /* rightshift */ |
0, /* rightshift */ |
153 |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
154 |
8, /* bitsize */ |
8, /* bitsize */ |
155 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
156 |
0, /* bitpos */ |
0, /* bitpos */ |
157 |
complain_overflow_signed, /* complain_on_overflow */ |
complain_overflow_signed, /* complain_on_overflow */ |
158 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
159 |
"R_VAX_PC8", /* name */ |
"R_VAX_PC8", /* name */ |
160 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
161 |
0, /* src_mask */ |
0, /* src_mask */ |
162 |
0x000000ff, /* dst_mask */ |
0x000000ff, /* dst_mask */ |
163 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
164 |
|
|
165 |
HOWTO (R_VAX_GOT32, /* type */ |
HOWTO (R_VAX_GOT32, /* type */ |
166 |
0, /* rightshift */ |
0, /* rightshift */ |
167 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
168 |
32, /* bitsize */ |
32, /* bitsize */ |
169 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
170 |
0, /* bitpos */ |
0, /* bitpos */ |
171 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
172 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
173 |
"R_VAX_GOT32", /* name */ |
"R_VAX_GOT32", /* name */ |
174 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
175 |
0, /* src_mask */ |
0, /* src_mask */ |
176 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
177 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
178 |
|
|
179 |
EMPTY_HOWTO (-1), |
EMPTY_HOWTO (-1), |
180 |
EMPTY_HOWTO (-1), |
EMPTY_HOWTO (-1), |
186 |
0, /* rightshift */ |
0, /* rightshift */ |
187 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
188 |
32, /* bitsize */ |
32, /* bitsize */ |
189 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
190 |
0, /* bitpos */ |
0, /* bitpos */ |
191 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
192 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
193 |
"R_VAX_PLT32", /* name */ |
"R_VAX_PLT32", /* name */ |
194 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
195 |
0, /* src_mask */ |
0, /* src_mask */ |
196 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
197 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
198 |
|
|
199 |
EMPTY_HOWTO (-1), |
EMPTY_HOWTO (-1), |
200 |
EMPTY_HOWTO (-1), |
EMPTY_HOWTO (-1), |
206 |
0, /* rightshift */ |
0, /* rightshift */ |
207 |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
208 |
0, /* bitsize */ |
0, /* bitsize */ |
209 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
210 |
0, /* bitpos */ |
0, /* bitpos */ |
211 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
212 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
213 |
"R_VAX_COPY", /* name */ |
"R_VAX_COPY", /* name */ |
214 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
215 |
0, /* src_mask */ |
0, /* src_mask */ |
216 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
217 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
218 |
|
|
219 |
HOWTO (R_VAX_GLOB_DAT, /* type */ |
HOWTO (R_VAX_GLOB_DAT, /* type */ |
220 |
0, /* rightshift */ |
0, /* rightshift */ |
221 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
222 |
32, /* bitsize */ |
32, /* bitsize */ |
223 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
224 |
0, /* bitpos */ |
0, /* bitpos */ |
225 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
226 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
227 |
"R_VAX_GLOB_DAT", /* name */ |
"R_VAX_GLOB_DAT", /* name */ |
228 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
229 |
0, /* src_mask */ |
0, /* src_mask */ |
230 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
231 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
232 |
|
|
233 |
HOWTO (R_VAX_JMP_SLOT, /* type */ |
HOWTO (R_VAX_JMP_SLOT, /* type */ |
234 |
0, /* rightshift */ |
0, /* rightshift */ |
235 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
236 |
32, /* bitsize */ |
32, /* bitsize */ |
237 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
238 |
0, /* bitpos */ |
0, /* bitpos */ |
239 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
240 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
241 |
"R_VAX_JMP_SLOT", /* name */ |
"R_VAX_JMP_SLOT", /* name */ |
242 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
243 |
0, /* src_mask */ |
0, /* src_mask */ |
244 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
245 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
246 |
|
|
247 |
HOWTO (R_VAX_RELATIVE, /* type */ |
HOWTO (R_VAX_RELATIVE, /* type */ |
248 |
0, /* rightshift */ |
0, /* rightshift */ |
249 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
250 |
32, /* bitsize */ |
32, /* bitsize */ |
251 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
252 |
0, /* bitpos */ |
0, /* bitpos */ |
253 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
254 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
255 |
"R_VAX_RELATIVE", /* name */ |
"R_VAX_RELATIVE", /* name */ |
256 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
257 |
0, /* src_mask */ |
0, /* src_mask */ |
258 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
259 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
260 |
|
|
261 |
/* GNU extension to record C++ vtable hierarchy */ |
/* GNU extension to record C++ vtable hierarchy */ |
262 |
HOWTO (R_VAX_GNU_VTINHERIT, /* type */ |
HOWTO (R_VAX_GNU_VTINHERIT, /* type */ |
263 |
0, /* rightshift */ |
0, /* rightshift */ |
264 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
265 |
0, /* bitsize */ |
0, /* bitsize */ |
266 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
267 |
0, /* bitpos */ |
0, /* bitpos */ |
268 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
269 |
NULL, /* special_function */ |
NULL, /* special_function */ |
270 |
"R_VAX_GNU_VTINHERIT", /* name */ |
"R_VAX_GNU_VTINHERIT", /* name */ |
271 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
272 |
0, /* src_mask */ |
0, /* src_mask */ |
273 |
0, /* dst_mask */ |
0, /* dst_mask */ |
274 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
275 |
|
|
276 |
/* GNU extension to record C++ vtable member usage */ |
/* GNU extension to record C++ vtable member usage */ |
277 |
HOWTO (R_VAX_GNU_VTENTRY, /* type */ |
HOWTO (R_VAX_GNU_VTENTRY, /* type */ |
278 |
0, /* rightshift */ |
0, /* rightshift */ |
279 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
280 |
0, /* bitsize */ |
0, /* bitsize */ |
281 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
282 |
0, /* bitpos */ |
0, /* bitpos */ |
283 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
284 |
_bfd_elf_rel_vtable_reloc_fn, /* special_function */ |
_bfd_elf_rel_vtable_reloc_fn, /* special_function */ |
285 |
"R_VAX_GNU_VTENTRY", /* name */ |
"R_VAX_GNU_VTENTRY", /* name */ |
286 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
287 |
0, /* src_mask */ |
0, /* src_mask */ |
288 |
0, /* dst_mask */ |
0, /* dst_mask */ |
289 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
290 |
}; |
}; |
291 |
|
|
292 |
static void |
static void |
341 |
#define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup |
#define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup |
342 |
#define ELF_ARCH bfd_arch_vax |
#define ELF_ARCH bfd_arch_vax |
343 |
/* end code generated by elf.el */ |
/* end code generated by elf.el */ |
|
|
|
|
#define USE_RELA |
|
344 |
|
|
345 |
/* Functions for the VAX ELF linker. */ |
/* Functions for the VAX ELF linker. */ |
346 |
|
|
414 |
|
|
415 |
/* Declare this now that the above structures are defined. */ |
/* Declare this now that the above structures are defined. */ |
416 |
|
|
417 |
static boolean elf_vax_discard_copies |
static bfd_boolean elf_vax_discard_copies |
418 |
PARAMS ((struct elf_vax_link_hash_entry *, PTR)); |
PARAMS ((struct elf_vax_link_hash_entry *, PTR)); |
419 |
|
|
420 |
|
/* Declare this now that the above structures are defined. */ |
421 |
|
|
422 |
|
static bfd_boolean elf_vax_instantiate_got_entries |
423 |
|
PARAMS ((struct elf_link_hash_entry *, PTR)); |
424 |
|
|
425 |
/* Traverse an VAX ELF linker hash table. */ |
/* Traverse an VAX ELF linker hash table. */ |
426 |
|
|
427 |
#define elf_vax_link_hash_traverse(table, func, info) \ |
#define elf_vax_link_hash_traverse(table, func, info) \ |
428 |
(elf_link_hash_traverse \ |
(elf_link_hash_traverse \ |
429 |
(&(table)->root, \ |
(&(table)->root, \ |
430 |
(boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \ |
(bfd_boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \ |
431 |
(info))) |
(info))) |
432 |
|
|
433 |
/* Get the VAX ELF linker hash table from a link_info structure. */ |
/* Get the VAX ELF linker hash table from a link_info structure. */ |
491 |
} |
} |
492 |
|
|
493 |
/* Keep vax-specific flags in the ELF header */ |
/* Keep vax-specific flags in the ELF header */ |
494 |
static boolean |
static bfd_boolean |
495 |
elf32_vax_set_private_flags (abfd, flags) |
elf32_vax_set_private_flags (abfd, flags) |
496 |
bfd *abfd; |
bfd *abfd; |
497 |
flagword flags; |
flagword flags; |
498 |
{ |
{ |
499 |
elf_elfheader (abfd)->e_flags = flags; |
elf_elfheader (abfd)->e_flags = flags; |
500 |
elf_flags_init (abfd) = true; |
elf_flags_init (abfd) = TRUE; |
501 |
return true; |
return TRUE; |
502 |
} |
} |
503 |
|
|
504 |
/* Merge backend specific data from an object file to the output |
/* Merge backend specific data from an object file to the output |
505 |
object file when linking. */ |
object file when linking. */ |
506 |
static boolean |
static bfd_boolean |
507 |
elf32_vax_merge_private_bfd_data (ibfd, obfd) |
elf32_vax_merge_private_bfd_data (ibfd, obfd) |
508 |
bfd *ibfd; |
bfd *ibfd; |
509 |
bfd *obfd; |
bfd *obfd; |
513 |
|
|
514 |
if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour |
if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour |
515 |
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour) |
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour) |
516 |
return true; |
return TRUE; |
517 |
|
|
518 |
in_flags = elf_elfheader (ibfd)->e_flags; |
in_flags = elf_elfheader (ibfd)->e_flags; |
519 |
out_flags = elf_elfheader (obfd)->e_flags; |
out_flags = elf_elfheader (obfd)->e_flags; |
520 |
|
|
521 |
if (!elf_flags_init (obfd)) |
if (!elf_flags_init (obfd)) |
522 |
{ |
{ |
523 |
elf_flags_init (obfd) = true; |
elf_flags_init (obfd) = TRUE; |
524 |
elf_elfheader (obfd)->e_flags = in_flags; |
elf_elfheader (obfd)->e_flags = in_flags; |
525 |
} |
} |
526 |
|
|
527 |
return true; |
return TRUE; |
528 |
} |
} |
529 |
|
|
530 |
/* Display the flags field */ |
/* Display the flags field */ |
531 |
static boolean |
static bfd_boolean |
532 |
elf32_vax_print_private_bfd_data (abfd, ptr) |
elf32_vax_print_private_bfd_data (abfd, ptr) |
533 |
bfd *abfd; |
bfd *abfd; |
534 |
PTR ptr; |
PTR ptr; |
556 |
|
|
557 |
fputc ('\n', file); |
fputc ('\n', file); |
558 |
|
|
559 |
return true; |
return TRUE; |
560 |
} |
} |
561 |
/* Look through the relocs for a section during the first phase, and |
/* Look through the relocs for a section during the first phase, and |
562 |
allocate space in the global offset table or procedure linkage |
allocate space in the global offset table or procedure linkage |
563 |
table. */ |
table. */ |
564 |
|
|
565 |
static boolean |
static bfd_boolean |
566 |
elf_vax_check_relocs (abfd, info, sec, relocs) |
elf_vax_check_relocs (abfd, info, sec, relocs) |
567 |
bfd *abfd; |
bfd *abfd; |
568 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
572 |
bfd *dynobj; |
bfd *dynobj; |
573 |
Elf_Internal_Shdr *symtab_hdr; |
Elf_Internal_Shdr *symtab_hdr; |
574 |
struct elf_link_hash_entry **sym_hashes; |
struct elf_link_hash_entry **sym_hashes; |
|
bfd_signed_vma *local_got_refcounts; |
|
575 |
const Elf_Internal_Rela *rel; |
const Elf_Internal_Rela *rel; |
576 |
const Elf_Internal_Rela *rel_end; |
const Elf_Internal_Rela *rel_end; |
577 |
asection *sgot; |
asection *sgot; |
578 |
asection *srelgot; |
asection *srelgot; |
579 |
asection *sreloc; |
asection *sreloc; |
580 |
|
|
581 |
if (info->relocateable) |
if (info->relocatable) |
582 |
return true; |
return TRUE; |
583 |
|
|
584 |
dynobj = elf_hash_table (info)->dynobj; |
dynobj = elf_hash_table (info)->dynobj; |
585 |
symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
586 |
sym_hashes = elf_sym_hashes (abfd); |
sym_hashes = elf_sym_hashes (abfd); |
|
local_got_refcounts = elf_local_got_refcounts (abfd); |
|
587 |
|
|
588 |
sgot = NULL; |
sgot = NULL; |
589 |
srelgot = NULL; |
srelgot = NULL; |
616 |
/* Create the .got section. */ |
/* Create the .got section. */ |
617 |
elf_hash_table (info)->dynobj = dynobj = abfd; |
elf_hash_table (info)->dynobj = dynobj = abfd; |
618 |
if (!_bfd_elf_create_got_section (dynobj, info)) |
if (!_bfd_elf_create_got_section (dynobj, info)) |
619 |
return false; |
return FALSE; |
620 |
} |
} |
621 |
|
|
622 |
if (sgot == NULL) |
if (sgot == NULL) |
641 |
| SEC_LINKER_CREATED |
| SEC_LINKER_CREATED |
642 |
| SEC_READONLY)) |
| SEC_READONLY)) |
643 |
|| !bfd_set_section_alignment (dynobj, srelgot, 2)) |
|| !bfd_set_section_alignment (dynobj, srelgot, 2)) |
644 |
return false; |
return FALSE; |
645 |
} |
} |
646 |
} |
} |
647 |
|
|
654 |
{ |
{ |
655 |
h->got.refcount = 1; |
h->got.refcount = 1; |
656 |
eh->got_addend = rel->r_addend; |
eh->got_addend = rel->r_addend; |
|
|
|
|
/* Make sure this symbol is output as a dynamic symbol. */ |
|
|
if (h->dynindx == -1) |
|
|
{ |
|
|
if (!bfd_elf32_link_record_dynamic_symbol (info, h)) |
|
|
return false; |
|
|
} |
|
|
|
|
|
/* Allocate space in the .got section. */ |
|
|
sgot->_raw_size += 4; |
|
|
/* Allocate relocation space. */ |
|
|
srelgot->_raw_size += sizeof (Elf32_External_Rela); |
|
657 |
} |
} |
658 |
else |
else |
659 |
{ |
{ |
682 |
if (h == NULL) |
if (h == NULL) |
683 |
continue; |
continue; |
684 |
|
|
685 |
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; |
h->needs_plt = 1; |
686 |
if (h->plt.refcount == -1) |
if (h->plt.refcount == -1) |
687 |
h->plt.refcount = 1; |
h->plt.refcount = 1; |
688 |
else |
else |
706 |
&& (sec->flags & SEC_ALLOC) != 0 |
&& (sec->flags & SEC_ALLOC) != 0 |
707 |
&& h != NULL |
&& h != NULL |
708 |
&& (!info->symbolic |
&& (!info->symbolic |
709 |
|| (h->elf_link_hash_flags |
|| !h->def_regular))) |
|
& ELF_LINK_HASH_DEF_REGULAR) == 0))) |
|
710 |
{ |
{ |
711 |
if (h != NULL) |
if (h != NULL) |
712 |
{ |
{ |
751 |
elf_elfheader (abfd)->e_shstrndx, |
elf_elfheader (abfd)->e_shstrndx, |
752 |
elf_section_data (sec)->rel_hdr.sh_name)); |
elf_section_data (sec)->rel_hdr.sh_name)); |
753 |
if (name == NULL) |
if (name == NULL) |
754 |
return false; |
return FALSE; |
755 |
|
|
756 |
BFD_ASSERT (strncmp (name, ".rela", 5) == 0 |
BFD_ASSERT (strncmp (name, ".rela", 5) == 0 |
757 |
&& strcmp (bfd_get_section_name (abfd, sec), |
&& strcmp (bfd_get_section_name (abfd, sec), |
770 |
| SEC_LINKER_CREATED |
| SEC_LINKER_CREATED |
771 |
| SEC_READONLY)) |
| SEC_READONLY)) |
772 |
|| !bfd_set_section_alignment (dynobj, sreloc, 2)) |
|| !bfd_set_section_alignment (dynobj, sreloc, 2)) |
773 |
return false; |
return FALSE; |
774 |
} |
} |
775 |
if (sec->flags & SEC_READONLY) |
if (sec->flags & SEC_READONLY) |
776 |
info->flags |= DF_TEXTREL; |
info->flags |= DF_TEXTREL; |
777 |
} |
} |
778 |
|
|
779 |
sreloc->_raw_size += sizeof (Elf32_External_Rela); |
sreloc->size += sizeof (Elf32_External_Rela); |
780 |
|
|
781 |
/* If we are linking with -Bsymbolic, we count the number of |
/* If we are linking with -Bsymbolic, we count the number of |
782 |
PC relative relocations we have entered for this symbol, |
PC relative relocations we have entered for this symbol, |
783 |
so that we can discard them again if the symbol is later |
so that we can discard them again if the symbol is later |
784 |
defined by a regular object. Note that this function is |
defined by a regular object. Note that this function is |
785 |
only called if we are using an vaxelf linker hash table, |
only called if we are using a vaxelf linker hash table, |
786 |
which means that h is really a pointer to an |
which means that h is really a pointer to an |
787 |
elf_vax_link_hash_entry. */ |
elf_vax_link_hash_entry. */ |
788 |
if ((ELF32_R_TYPE (rel->r_info) == R_VAX_PC8 |
if ((ELF32_R_TYPE (rel->r_info) == R_VAX_PC8 |
804 |
p = ((struct elf_vax_pcrel_relocs_copied *) |
p = ((struct elf_vax_pcrel_relocs_copied *) |
805 |
bfd_alloc (dynobj, (bfd_size_type) sizeof *p)); |
bfd_alloc (dynobj, (bfd_size_type) sizeof *p)); |
806 |
if (p == NULL) |
if (p == NULL) |
807 |
return false; |
return FALSE; |
808 |
p->next = eh->pcrel_relocs_copied; |
p->next = eh->pcrel_relocs_copied; |
809 |
eh->pcrel_relocs_copied = p; |
eh->pcrel_relocs_copied = p; |
810 |
p->section = sreloc; |
p->section = sreloc; |
820 |
/* This relocation describes the C++ object vtable hierarchy. |
/* This relocation describes the C++ object vtable hierarchy. |
821 |
Reconstruct it for later use during GC. */ |
Reconstruct it for later use during GC. */ |
822 |
case R_VAX_GNU_VTINHERIT: |
case R_VAX_GNU_VTINHERIT: |
823 |
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) |
if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) |
824 |
return false; |
return FALSE; |
825 |
break; |
break; |
826 |
|
|
827 |
/* This relocation describes which C++ vtable entries are actually |
/* This relocation describes which C++ vtable entries are actually |
828 |
used. Record for later use during GC. */ |
used. Record for later use during GC. */ |
829 |
case R_VAX_GNU_VTENTRY: |
case R_VAX_GNU_VTENTRY: |
830 |
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) |
if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) |
831 |
return false; |
return FALSE; |
832 |
break; |
break; |
833 |
|
|
834 |
default: |
default: |
836 |
} |
} |
837 |
} |
} |
838 |
|
|
839 |
return true; |
return TRUE; |
840 |
} |
} |
841 |
|
|
842 |
/* Return the section that should be marked against GC for a given |
/* Return the section that should be marked against GC for a given |
881 |
|
|
882 |
/* Update the got entry reference counts for the section being removed. */ |
/* Update the got entry reference counts for the section being removed. */ |
883 |
|
|
884 |
static boolean |
static bfd_boolean |
885 |
elf_vax_gc_sweep_hook (abfd, info, sec, relocs) |
elf_vax_gc_sweep_hook (abfd, info, sec, relocs) |
886 |
bfd *abfd; |
bfd *abfd; |
887 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
890 |
{ |
{ |
891 |
Elf_Internal_Shdr *symtab_hdr; |
Elf_Internal_Shdr *symtab_hdr; |
892 |
struct elf_link_hash_entry **sym_hashes; |
struct elf_link_hash_entry **sym_hashes; |
|
bfd_signed_vma *local_got_refcounts; |
|
893 |
const Elf_Internal_Rela *rel, *relend; |
const Elf_Internal_Rela *rel, *relend; |
|
unsigned long r_symndx; |
|
|
struct elf_link_hash_entry *h; |
|
894 |
bfd *dynobj; |
bfd *dynobj; |
|
asection *sgot; |
|
|
asection *srelgot; |
|
|
|
|
|
symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
|
|
sym_hashes = elf_sym_hashes (abfd); |
|
|
local_got_refcounts = elf_local_got_refcounts (abfd); |
|
895 |
|
|
896 |
dynobj = elf_hash_table (info)->dynobj; |
dynobj = elf_hash_table (info)->dynobj; |
897 |
if (dynobj == NULL) |
if (dynobj == NULL) |
898 |
return true; |
return TRUE; |
899 |
|
|
900 |
sgot = bfd_get_section_by_name (dynobj, ".got"); |
symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
901 |
srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); |
sym_hashes = elf_sym_hashes (abfd); |
902 |
|
|
903 |
relend = relocs + sec->reloc_count; |
relend = relocs + sec->reloc_count; |
904 |
for (rel = relocs; rel < relend; rel++) |
for (rel = relocs; rel < relend; rel++) |
905 |
{ |
{ |
906 |
|
unsigned long r_symndx; |
907 |
|
struct elf_link_hash_entry *h = NULL; |
908 |
|
|
909 |
|
r_symndx = ELF32_R_SYM (rel->r_info); |
910 |
|
if (r_symndx >= symtab_hdr->sh_info) |
911 |
|
{ |
912 |
|
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
913 |
|
while (h->root.type == bfd_link_hash_indirect |
914 |
|
|| h->root.type == bfd_link_hash_warning) |
915 |
|
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
916 |
|
} |
917 |
|
|
918 |
switch (ELF32_R_TYPE (rel->r_info)) |
switch (ELF32_R_TYPE (rel->r_info)) |
919 |
{ |
{ |
920 |
case R_VAX_GOT32: |
case R_VAX_GOT32: |
921 |
r_symndx = ELF32_R_SYM (rel->r_info); |
if (h != NULL && h->got.refcount > 0) |
922 |
if (r_symndx >= symtab_hdr->sh_info) |
--h->got.refcount; |
|
{ |
|
|
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
|
|
if (h->got.refcount > 0) |
|
|
{ |
|
|
--h->got.refcount; |
|
|
if (h->got.refcount == 0) |
|
|
{ |
|
|
/* We don't need the .got entry any more. */ |
|
|
sgot->_raw_size -= 4; |
|
|
srelgot->_raw_size -= sizeof (Elf32_External_Rela); |
|
|
} |
|
|
} |
|
|
} |
|
|
else if (local_got_refcounts != NULL) |
|
|
{ |
|
|
if (local_got_refcounts[r_symndx] > 0) |
|
|
{ |
|
|
--local_got_refcounts[r_symndx]; |
|
|
if (local_got_refcounts[r_symndx] == 0) |
|
|
{ |
|
|
/* We don't need the .got entry any more. */ |
|
|
sgot->_raw_size -= 4; |
|
|
if (info->shared) |
|
|
srelgot->_raw_size -= sizeof (Elf32_External_Rela); |
|
|
} |
|
|
} |
|
|
} |
|
923 |
break; |
break; |
924 |
|
|
925 |
case R_VAX_PLT32: |
case R_VAX_PLT32: |
929 |
case R_VAX_8: |
case R_VAX_8: |
930 |
case R_VAX_16: |
case R_VAX_16: |
931 |
case R_VAX_32: |
case R_VAX_32: |
932 |
r_symndx = ELF32_R_SYM (rel->r_info); |
if (h != NULL && h->plt.refcount > 0) |
933 |
if (r_symndx >= symtab_hdr->sh_info) |
--h->plt.refcount; |
|
{ |
|
|
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
|
|
if (h->plt.refcount > 0) |
|
|
--h->plt.refcount; |
|
|
} |
|
934 |
break; |
break; |
935 |
|
|
936 |
default: |
default: |
938 |
} |
} |
939 |
} |
} |
940 |
|
|
941 |
return true; |
return TRUE; |
942 |
} |
} |
943 |
|
|
944 |
/* Adjust a symbol defined by a dynamic object and referenced by a |
/* Adjust a symbol defined by a dynamic object and referenced by a |
947 |
change the definition to something the rest of the link can |
change the definition to something the rest of the link can |
948 |
understand. */ |
understand. */ |
949 |
|
|
950 |
static boolean |
static bfd_boolean |
951 |
elf_vax_adjust_dynamic_symbol (info, h) |
elf_vax_adjust_dynamic_symbol (info, h) |
952 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
953 |
struct elf_link_hash_entry *h; |
struct elf_link_hash_entry *h; |
960 |
|
|
961 |
/* Make sure we know what is going on here. */ |
/* Make sure we know what is going on here. */ |
962 |
BFD_ASSERT (dynobj != NULL |
BFD_ASSERT (dynobj != NULL |
963 |
&& ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) |
&& (h->needs_plt |
964 |
|| h->weakdef != NULL |
|| h->u.weakdef != NULL |
965 |
|| ((h->elf_link_hash_flags |
|| (h->def_dynamic |
966 |
& ELF_LINK_HASH_DEF_DYNAMIC) != 0 |
&& h->ref_regular |
967 |
&& (h->elf_link_hash_flags |
&& !h->def_regular))); |
|
& ELF_LINK_HASH_REF_REGULAR) != 0 |
|
|
&& (h->elf_link_hash_flags |
|
|
& ELF_LINK_HASH_DEF_REGULAR) == 0))); |
|
968 |
|
|
969 |
/* If this is a function, put it in the procedure linkage table. We |
/* If this is a function, put it in the procedure linkage table. We |
970 |
will fill in the contents of the procedure linkage table later, |
will fill in the contents of the procedure linkage table later, |
971 |
when we know the address of the .got section. */ |
when we know the address of the .got section. */ |
972 |
if (h->type == STT_FUNC |
if (h->type == STT_FUNC |
973 |
|| (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) |
|| h->needs_plt) |
974 |
{ |
{ |
975 |
if (! info->shared |
if (! info->shared |
976 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 |
&& !h->def_dynamic |
977 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0 |
&& !h->ref_dynamic |
978 |
/* We must always create the plt entry if it was referenced |
/* We must always create the plt entry if it was referenced |
979 |
by a PLTxxO relocation. In this case we already recorded |
by a PLTxxO relocation. In this case we already recorded |
980 |
it as a dynamic symbol. */ |
it as a dynamic symbol. */ |
985 |
object. In such a case, we don't actually need to build |
object. In such a case, we don't actually need to build |
986 |
a procedure linkage table, and we can just do a PCxx |
a procedure linkage table, and we can just do a PCxx |
987 |
reloc instead. */ |
reloc instead. */ |
988 |
BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0); |
BFD_ASSERT (h->needs_plt); |
989 |
h->plt.offset = (bfd_vma) -1; |
h->plt.offset = (bfd_vma) -1; |
990 |
return true; |
return TRUE; |
991 |
} |
} |
992 |
|
|
993 |
/* GC may have rendered this entry unused. */ |
/* GC may have rendered this entry unused. */ |
994 |
if (h->plt.refcount <= 0) |
if (h->plt.refcount <= 0) |
995 |
{ |
{ |
996 |
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; |
h->needs_plt = 0; |
997 |
h->plt.offset = (bfd_vma) -1; |
h->plt.offset = (bfd_vma) -1; |
998 |
return true; |
return TRUE; |
999 |
} |
} |
1000 |
|
|
1001 |
/* Make sure this symbol is output as a dynamic symbol. */ |
/* Make sure this symbol is output as a dynamic symbol. */ |
1002 |
if (h->dynindx == -1) |
if (h->dynindx == -1) |
1003 |
{ |
{ |
1004 |
if (! bfd_elf32_link_record_dynamic_symbol (info, h)) |
if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
1005 |
return false; |
return FALSE; |
1006 |
} |
} |
1007 |
|
|
1008 |
s = bfd_get_section_by_name (dynobj, ".plt"); |
s = bfd_get_section_by_name (dynobj, ".plt"); |
1010 |
|
|
1011 |
/* If this is the first .plt entry, make room for the special |
/* If this is the first .plt entry, make room for the special |
1012 |
first entry. */ |
first entry. */ |
1013 |
if (s->_raw_size == 0) |
if (s->size == 0) |
1014 |
{ |
{ |
1015 |
s->_raw_size += PLT_ENTRY_SIZE; |
s->size += PLT_ENTRY_SIZE; |
1016 |
} |
} |
1017 |
|
|
1018 |
/* 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 |
1021 |
pointers compare as equal between the normal executable and |
pointers compare as equal between the normal executable and |
1022 |
the shared library. */ |
the shared library. */ |
1023 |
if (!info->shared |
if (!info->shared |
1024 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) |
&& !h->def_regular) |
1025 |
{ |
{ |
1026 |
h->root.u.def.section = s; |
h->root.u.def.section = s; |
1027 |
h->root.u.def.value = s->_raw_size; |
h->root.u.def.value = s->size; |
1028 |
} |
} |
1029 |
|
|
1030 |
h->plt.offset = s->_raw_size; |
h->plt.offset = s->size; |
1031 |
|
|
1032 |
/* Make room for this entry. */ |
/* Make room for this entry. */ |
1033 |
s->_raw_size += PLT_ENTRY_SIZE; |
s->size += PLT_ENTRY_SIZE; |
1034 |
|
|
1035 |
/* 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 |
1036 |
will be placed in the .got section by the linker script. */ |
will be placed in the .got section by the linker script. */ |
1037 |
|
|
1038 |
s = bfd_get_section_by_name (dynobj, ".got.plt"); |
s = bfd_get_section_by_name (dynobj, ".got.plt"); |
1039 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
1040 |
s->_raw_size += 4; |
s->size += 4; |
1041 |
|
|
1042 |
/* We also need to make an entry in the .rela.plt section. */ |
/* We also need to make an entry in the .rela.plt section. */ |
1043 |
|
|
1044 |
s = bfd_get_section_by_name (dynobj, ".rela.plt"); |
s = bfd_get_section_by_name (dynobj, ".rela.plt"); |
1045 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
1046 |
s->_raw_size += sizeof (Elf32_External_Rela); |
s->size += sizeof (Elf32_External_Rela); |
1047 |
|
|
1048 |
return true; |
return TRUE; |
1049 |
} |
} |
1050 |
|
|
1051 |
/* Reinitialize the plt offset now that it is not used as a reference |
/* Reinitialize the plt offset now that it is not used as a reference |
1055 |
/* 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 |
1056 |
processor independent code will have arranged for us to see the |
processor independent code will have arranged for us to see the |
1057 |
real definition first, and we can just use the same value. */ |
real definition first, and we can just use the same value. */ |
1058 |
if (h->weakdef != NULL) |
if (h->u.weakdef != NULL) |
1059 |
{ |
{ |
1060 |
BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined |
BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined |
1061 |
|| h->weakdef->root.type == bfd_link_hash_defweak); |
|| h->u.weakdef->root.type == bfd_link_hash_defweak); |
1062 |
h->root.u.def.section = h->weakdef->root.u.def.section; |
h->root.u.def.section = h->u.weakdef->root.u.def.section; |
1063 |
h->root.u.def.value = h->weakdef->root.u.def.value; |
h->root.u.def.value = h->u.weakdef->root.u.def.value; |
1064 |
return true; |
return TRUE; |
1065 |
} |
} |
1066 |
|
|
1067 |
/* 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 |
1072 |
For such cases we need not do anything here; the relocations will |
For such cases we need not do anything here; the relocations will |
1073 |
be handled correctly by relocate_section. */ |
be handled correctly by relocate_section. */ |
1074 |
if (info->shared) |
if (info->shared) |
1075 |
return true; |
return TRUE; |
1076 |
|
|
1077 |
/* We must allocate the symbol in our .dynbss section, which will |
/* We must allocate the symbol in our .dynbss section, which will |
1078 |
become part of the .bss section of the executable. There will be |
become part of the .bss section of the executable. There will be |
1097 |
|
|
1098 |
srel = bfd_get_section_by_name (dynobj, ".rela.bss"); |
srel = bfd_get_section_by_name (dynobj, ".rela.bss"); |
1099 |
BFD_ASSERT (srel != NULL); |
BFD_ASSERT (srel != NULL); |
1100 |
srel->_raw_size += sizeof (Elf32_External_Rela); |
srel->size += sizeof (Elf32_External_Rela); |
1101 |
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY; |
h->needs_copy = 1; |
1102 |
} |
} |
1103 |
|
|
1104 |
/* We need to figure out the alignment required for this symbol. I |
/* We need to figure out the alignment required for this symbol. I |
1108 |
power_of_two = 3; |
power_of_two = 3; |
1109 |
|
|
1110 |
/* Apply the required alignment. */ |
/* Apply the required alignment. */ |
1111 |
s->_raw_size = BFD_ALIGN (s->_raw_size, |
s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two)); |
|
(bfd_size_type) (1 << power_of_two)); |
|
1112 |
if (power_of_two > bfd_get_section_alignment (dynobj, s)) |
if (power_of_two > bfd_get_section_alignment (dynobj, s)) |
1113 |
{ |
{ |
1114 |
if (!bfd_set_section_alignment (dynobj, s, power_of_two)) |
if (!bfd_set_section_alignment (dynobj, s, power_of_two)) |
1115 |
return false; |
return FALSE; |
1116 |
} |
} |
1117 |
|
|
1118 |
/* Define the symbol as being at this point in the section. */ |
/* Define the symbol as being at this point in the section. */ |
1119 |
h->root.u.def.section = s; |
h->root.u.def.section = s; |
1120 |
h->root.u.def.value = s->_raw_size; |
h->root.u.def.value = s->size; |
1121 |
|
|
1122 |
/* Increment the section size to make room for the symbol. */ |
/* Increment the section size to make room for the symbol. */ |
1123 |
s->_raw_size += h->size; |
s->size += h->size; |
1124 |
|
|
1125 |
return true; |
return TRUE; |
1126 |
} |
} |
1127 |
|
|
1128 |
/* Set the sizes of the dynamic sections. */ |
/* Set the sizes of the dynamic sections. */ |
1129 |
|
|
1130 |
static boolean |
static bfd_boolean |
1131 |
elf_vax_size_dynamic_sections (output_bfd, info) |
elf_vax_size_dynamic_sections (output_bfd, info) |
1132 |
bfd *output_bfd; |
bfd *output_bfd; |
1133 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
1134 |
{ |
{ |
1135 |
bfd *dynobj; |
bfd *dynobj; |
1136 |
asection *s; |
asection *s; |
1137 |
boolean plt; |
bfd_boolean plt; |
1138 |
boolean relocs; |
bfd_boolean relocs; |
1139 |
boolean reltext; |
bfd_boolean reltext; |
1140 |
|
|
1141 |
dynobj = elf_hash_table (info)->dynobj; |
dynobj = elf_hash_table (info)->dynobj; |
1142 |
BFD_ASSERT (dynobj != NULL); |
BFD_ASSERT (dynobj != NULL); |
1144 |
if (elf_hash_table (info)->dynamic_sections_created) |
if (elf_hash_table (info)->dynamic_sections_created) |
1145 |
{ |
{ |
1146 |
/* Set the contents of the .interp section to the interpreter. */ |
/* Set the contents of the .interp section to the interpreter. */ |
1147 |
if (!info->shared) |
if (info->executable) |
1148 |
{ |
{ |
1149 |
s = bfd_get_section_by_name (dynobj, ".interp"); |
s = bfd_get_section_by_name (dynobj, ".interp"); |
1150 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
1151 |
s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; |
s->size = sizeof ELF_DYNAMIC_INTERPRETER; |
1152 |
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; |
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; |
1153 |
} |
} |
1154 |
} |
} |
1161 |
file below. */ |
file below. */ |
1162 |
s = bfd_get_section_by_name (dynobj, ".rela.got"); |
s = bfd_get_section_by_name (dynobj, ".rela.got"); |
1163 |
if (s != NULL) |
if (s != NULL) |
1164 |
s->_raw_size = 0; |
s->size = 0; |
1165 |
s = bfd_get_section_by_name (dynobj, ".got.plt"); |
s = bfd_get_section_by_name (dynobj, ".got.plt"); |
1166 |
if (s != NULL) |
if (s != NULL) |
1167 |
s->_raw_size = 0; |
s->size = 0; |
1168 |
s = bfd_get_section_by_name (dynobj, ".got"); |
s = bfd_get_section_by_name (dynobj, ".got"); |
1169 |
if (s != NULL) |
if (s != NULL) |
1170 |
s->_raw_size = 0; |
s->size = 0; |
1171 |
} |
} |
1172 |
|
|
1173 |
/* If this is a -Bsymbolic shared link, then we need to discard all PC |
/* If this is a -Bsymbolic shared link, then we need to discard all PC |
1176 |
fill them in in the relocate_section routine. */ |
fill them in in the relocate_section routine. */ |
1177 |
if (info->shared && info->symbolic) |
if (info->shared && info->symbolic) |
1178 |
elf_vax_link_hash_traverse (elf_vax_hash_table (info), |
elf_vax_link_hash_traverse (elf_vax_hash_table (info), |
1179 |
elf_vax_discard_copies, |
elf_vax_discard_copies, |
1180 |
(PTR) NULL); |
(PTR) NULL); |
1181 |
|
|
1182 |
|
/* If this is a -Bsymbolic shared link or a static link, we need to |
1183 |
|
discard all the got entries we've recorded. Otherwise, we need to |
1184 |
|
instantiate (allocate space for them). */ |
1185 |
|
elf_link_hash_traverse (elf_hash_table (info), |
1186 |
|
elf_vax_instantiate_got_entries, |
1187 |
|
(PTR) info); |
1188 |
|
|
1189 |
/* The check_relocs and adjust_dynamic_symbol entry points have |
/* The check_relocs and adjust_dynamic_symbol entry points have |
1190 |
determined the sizes of the various dynamic sections. Allocate |
determined the sizes of the various dynamic sections. Allocate |
1191 |
memory for them. */ |
memory for them. */ |
1192 |
plt = false; |
plt = FALSE; |
1193 |
relocs = false; |
relocs = FALSE; |
1194 |
reltext = false; |
reltext = FALSE; |
1195 |
for (s = dynobj->sections; s != NULL; s = s->next) |
for (s = dynobj->sections; s != NULL; s = s->next) |
1196 |
{ |
{ |
1197 |
const char *name; |
const char *name; |
1198 |
boolean strip; |
bfd_boolean strip; |
1199 |
|
|
1200 |
if ((s->flags & SEC_LINKER_CREATED) == 0) |
if ((s->flags & SEC_LINKER_CREATED) == 0) |
1201 |
continue; |
continue; |
1204 |
of the dynobj section names depend upon the input files. */ |
of the dynobj section names depend upon the input files. */ |
1205 |
name = bfd_get_section_name (dynobj, s); |
name = bfd_get_section_name (dynobj, s); |
1206 |
|
|
1207 |
strip = false; |
strip = FALSE; |
1208 |
|
|
1209 |
if (strcmp (name, ".plt") == 0) |
if (strcmp (name, ".plt") == 0) |
1210 |
{ |
{ |
1211 |
if (s->_raw_size == 0) |
if (s->size == 0) |
1212 |
{ |
{ |
1213 |
/* Strip this section if we don't need it; see the |
/* Strip this section if we don't need it; see the |
1214 |
comment below. */ |
comment below. */ |
1215 |
strip = true; |
strip = TRUE; |
1216 |
} |
} |
1217 |
else |
else |
1218 |
{ |
{ |
1219 |
/* Remember whether there is a PLT. */ |
/* Remember whether there is a PLT. */ |
1220 |
plt = true; |
plt = TRUE; |
1221 |
} |
} |
1222 |
} |
} |
1223 |
else if (strncmp (name, ".rela", 5) == 0) |
else if (strncmp (name, ".rela", 5) == 0) |
1224 |
{ |
{ |
1225 |
if (s->_raw_size == 0) |
if (s->size == 0) |
1226 |
{ |
{ |
1227 |
/* If we don't need this section, strip it from the |
/* If we don't need this section, strip it from the |
1228 |
output file. This is mostly to handle .rela.bss and |
output file. This is mostly to handle .rela.bss and |
1233 |
adjust_dynamic_symbol is called, and it is that |
adjust_dynamic_symbol is called, and it is that |
1234 |
function which decides whether anything needs to go |
function which decides whether anything needs to go |
1235 |
into these sections. */ |
into these sections. */ |
1236 |
strip = true; |
strip = TRUE; |
1237 |
} |
} |
1238 |
else |
else |
1239 |
{ |
{ |
1245 |
{ |
{ |
1246 |
const char *outname; |
const char *outname; |
1247 |
|
|
1248 |
relocs = true; |
relocs = TRUE; |
1249 |
|
|
1250 |
/* If this relocation section applies to a read only |
/* If this relocation section applies to a read only |
1251 |
section, then we probably need a DT_TEXTREL |
section, then we probably need a DT_TEXTREL |
1257 |
if (target != NULL |
if (target != NULL |
1258 |
&& (target->flags & SEC_READONLY) != 0 |
&& (target->flags & SEC_READONLY) != 0 |
1259 |
&& (target->flags & SEC_ALLOC) != 0) |
&& (target->flags & SEC_ALLOC) != 0) |
1260 |
reltext = true; |
reltext = TRUE; |
1261 |
} |
} |
1262 |
|
|
1263 |
/* We use the reloc_count field as a counter if we need |
/* We use the reloc_count field as a counter if we need |
1278 |
} |
} |
1279 |
|
|
1280 |
/* Allocate memory for the section contents. */ |
/* Allocate memory for the section contents. */ |
1281 |
s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); |
s->contents = (bfd_byte *) bfd_alloc (dynobj, s->size); |
1282 |
if (s->contents == NULL && s->_raw_size != 0) |
if (s->contents == NULL && s->size != 0) |
1283 |
return false; |
return FALSE; |
1284 |
} |
} |
1285 |
|
|
1286 |
if (elf_hash_table (info)->dynamic_sections_created) |
if (elf_hash_table (info)->dynamic_sections_created) |
1291 |
the .dynamic section. The DT_DEBUG entry is filled in by the |
the .dynamic section. The DT_DEBUG entry is filled in by the |
1292 |
dynamic linker and used by the debugger. */ |
dynamic linker and used by the debugger. */ |
1293 |
#define add_dynamic_entry(TAG, VAL) \ |
#define add_dynamic_entry(TAG, VAL) \ |
1294 |
bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL)) |
_bfd_elf_add_dynamic_entry (info, TAG, VAL) |
1295 |
|
|
1296 |
if (!info->shared) |
if (!info->shared) |
1297 |
{ |
{ |
1298 |
if (!add_dynamic_entry (DT_DEBUG, 0)) |
if (!add_dynamic_entry (DT_DEBUG, 0)) |
1299 |
return false; |
return FALSE; |
1300 |
} |
} |
1301 |
|
|
1302 |
if (plt) |
if (plt) |
1305 |
|| !add_dynamic_entry (DT_PLTRELSZ, 0) |
|| !add_dynamic_entry (DT_PLTRELSZ, 0) |
1306 |
|| !add_dynamic_entry (DT_PLTREL, DT_RELA) |
|| !add_dynamic_entry (DT_PLTREL, DT_RELA) |
1307 |
|| !add_dynamic_entry (DT_JMPREL, 0)) |
|| !add_dynamic_entry (DT_JMPREL, 0)) |
1308 |
return false; |
return FALSE; |
1309 |
} |
} |
1310 |
|
|
1311 |
if (relocs) |
if (relocs) |
1313 |
if (!add_dynamic_entry (DT_RELA, 0) |
if (!add_dynamic_entry (DT_RELA, 0) |
1314 |
|| !add_dynamic_entry (DT_RELASZ, 0) |
|| !add_dynamic_entry (DT_RELASZ, 0) |
1315 |
|| !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) |
|| !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) |
1316 |
return false; |
return FALSE; |
1317 |
} |
} |
1318 |
|
|
1319 |
if (reltext || (info->flags & DF_TEXTREL) != 0) |
if (reltext || (info->flags & DF_TEXTREL) != 0) |
1320 |
{ |
{ |
1321 |
if (!add_dynamic_entry (DT_TEXTREL, 0)) |
if (!add_dynamic_entry (DT_TEXTREL, 0)) |
1322 |
return false; |
return FALSE; |
1323 |
} |
} |
1324 |
} |
} |
1325 |
#undef add_dynamic_entry |
#undef add_dynamic_entry |
1326 |
|
|
1327 |
return true; |
return TRUE; |
1328 |
} |
} |
1329 |
|
|
1330 |
/* This function is called via elf_vax_link_hash_traverse if we are |
/* This function is called via elf_vax_link_hash_traverse if we are |
1333 |
in regular objects. We allocated space for them in the check_relocs |
in regular objects. We allocated space for them in the check_relocs |
1334 |
routine, but we won't fill them in in the relocate_section routine. */ |
routine, but we won't fill them in in the relocate_section routine. */ |
1335 |
|
|
1336 |
/*ARGSUSED*/ |
static bfd_boolean |
|
static boolean |
|
1337 |
elf_vax_discard_copies (h, ignore) |
elf_vax_discard_copies (h, ignore) |
1338 |
struct elf_vax_link_hash_entry *h; |
struct elf_vax_link_hash_entry *h; |
1339 |
PTR ignore ATTRIBUTE_UNUSED; |
PTR ignore ATTRIBUTE_UNUSED; |
1344 |
h = (struct elf_vax_link_hash_entry *) h->root.root.u.i.link; |
h = (struct elf_vax_link_hash_entry *) h->root.root.u.i.link; |
1345 |
|
|
1346 |
/* We only discard relocs for symbols defined in a regular object. */ |
/* We only discard relocs for symbols defined in a regular object. */ |
1347 |
if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) |
if (!h->root.def_regular) |
1348 |
return true; |
return TRUE; |
1349 |
|
|
1350 |
for (s = h->pcrel_relocs_copied; s != NULL; s = s->next) |
for (s = h->pcrel_relocs_copied; s != NULL; s = s->next) |
1351 |
s->section->_raw_size -= s->count * sizeof (Elf32_External_Rela); |
s->section->size -= s->count * sizeof (Elf32_External_Rela); |
1352 |
|
|
1353 |
|
return TRUE; |
1354 |
|
} |
1355 |
|
|
1356 |
|
/* This function is called via elf_link_hash_traverse. It looks for entries |
1357 |
|
that have GOT or PLT (.GOT) references. If creating a static object or a |
1358 |
|
shared object with -Bsymbolic, it resets the reference count back to 0 |
1359 |
|
and sets the offset to -1 so normal PC32 relocation will be done. If |
1360 |
|
creating a shared object or executable, space in the .got and .rela.got |
1361 |
|
will be reserved for the symbol. */ |
1362 |
|
|
1363 |
|
static bfd_boolean |
1364 |
|
elf_vax_instantiate_got_entries (h, infoptr) |
1365 |
|
struct elf_link_hash_entry *h; |
1366 |
|
PTR infoptr; |
1367 |
|
{ |
1368 |
|
struct bfd_link_info *info = (struct bfd_link_info *) infoptr; |
1369 |
|
bfd *dynobj; |
1370 |
|
asection *sgot; |
1371 |
|
asection *srelgot; |
1372 |
|
|
1373 |
|
/* We don't care about non-GOT (and non-PLT) entries. */ |
1374 |
|
if (h->got.refcount <= 0 && h->plt.refcount <= 0) |
1375 |
|
return TRUE; |
1376 |
|
|
1377 |
|
dynobj = elf_hash_table (info)->dynobj; |
1378 |
|
if (dynobj == NULL) |
1379 |
|
return TRUE; |
1380 |
|
|
1381 |
|
sgot = bfd_get_section_by_name (dynobj, ".got"); |
1382 |
|
srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); |
1383 |
|
|
1384 |
return true; |
if (!elf_hash_table (info)->dynamic_sections_created |
1385 |
|
|| (info->shared && info->symbolic)) |
1386 |
|
{ |
1387 |
|
h->got.refcount = 0; |
1388 |
|
h->got.offset = (bfd_vma) -1; |
1389 |
|
h->plt.refcount = 0; |
1390 |
|
h->plt.offset = (bfd_vma) -1; |
1391 |
|
} |
1392 |
|
else if (h->got.refcount > 0) |
1393 |
|
{ |
1394 |
|
/* Make sure this symbol is output as a dynamic symbol. */ |
1395 |
|
if (h->dynindx == -1) |
1396 |
|
{ |
1397 |
|
if (!bfd_elf_link_record_dynamic_symbol (info, h)) |
1398 |
|
return FALSE; |
1399 |
|
} |
1400 |
|
|
1401 |
|
/* Allocate space in the .got and .rela.got sections. */ |
1402 |
|
sgot->size += 4; |
1403 |
|
srelgot->size += sizeof (Elf32_External_Rela); |
1404 |
|
} |
1405 |
|
|
1406 |
|
return TRUE; |
1407 |
} |
} |
1408 |
|
|
1409 |
/* Relocate an VAX ELF section. */ |
/* Relocate an VAX ELF section. */ |
1410 |
|
|
1411 |
static boolean |
static bfd_boolean |
1412 |
elf_vax_relocate_section (output_bfd, info, input_bfd, input_section, |
elf_vax_relocate_section (output_bfd, info, input_bfd, input_section, |
1413 |
contents, relocs, local_syms, local_sections) |
contents, relocs, local_syms, local_sections) |
1414 |
bfd *output_bfd; |
bfd *output_bfd; |
1433 |
Elf_Internal_Rela *rel; |
Elf_Internal_Rela *rel; |
1434 |
Elf_Internal_Rela *relend; |
Elf_Internal_Rela *relend; |
1435 |
|
|
1436 |
|
if (info->relocatable) |
1437 |
|
return TRUE; |
1438 |
|
|
1439 |
dynobj = elf_hash_table (info)->dynobj; |
dynobj = elf_hash_table (info)->dynobj; |
1440 |
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; |
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; |
1441 |
sym_hashes = elf_sym_hashes (input_bfd); |
sym_hashes = elf_sym_hashes (input_bfd); |
1463 |
if (r_type < 0 || r_type >= (int) R_VAX_max) |
if (r_type < 0 || r_type >= (int) R_VAX_max) |
1464 |
{ |
{ |
1465 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
1466 |
return false; |
return FALSE; |
1467 |
} |
} |
1468 |
howto = howto_table + r_type; |
howto = howto_table + r_type; |
1469 |
|
|
|
r_symndx = ELF32_R_SYM (rel->r_info); |
|
|
|
|
|
if (info->relocateable) |
|
|
{ |
|
|
/* This is a relocateable link. We don't have to change |
|
|
anything, unless the reloc is against a section symbol, |
|
|
in which case we have to adjust according to where the |
|
|
section symbol winds up in the output section. */ |
|
|
if (r_symndx < symtab_hdr->sh_info) |
|
|
{ |
|
|
sym = local_syms + r_symndx; |
|
|
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) |
|
|
{ |
|
|
sec = local_sections[r_symndx]; |
|
|
rel->r_addend += sec->output_offset + sym->st_value; |
|
|
} |
|
|
} |
|
|
|
|
|
continue; |
|
|
} |
|
|
|
|
1470 |
/* This is a final link. */ |
/* This is a final link. */ |
1471 |
|
r_symndx = ELF32_R_SYM (rel->r_info); |
1472 |
h = NULL; |
h = NULL; |
1473 |
sym = NULL; |
sym = NULL; |
1474 |
sec = NULL; |
sec = NULL; |
1476 |
{ |
{ |
1477 |
sym = local_syms + r_symndx; |
sym = local_syms + r_symndx; |
1478 |
sec = local_sections[r_symndx]; |
sec = local_sections[r_symndx]; |
1479 |
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); |
relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); |
1480 |
} |
} |
1481 |
else |
else |
1482 |
{ |
{ |
1483 |
h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
bfd_boolean unresolved_reloc; |
1484 |
while (h->root.type == bfd_link_hash_indirect |
bfd_boolean warned; |
1485 |
|| h->root.type == bfd_link_hash_warning) |
|
1486 |
h = (struct elf_link_hash_entry *) h->root.u.i.link; |
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, |
1487 |
if (h->root.type == bfd_link_hash_defined |
r_symndx, symtab_hdr, sym_hashes, |
1488 |
|
h, sec, relocation, |
1489 |
|
unresolved_reloc, warned); |
1490 |
|
|
1491 |
|
if ((h->root.type == bfd_link_hash_defined |
1492 |
|| h->root.type == bfd_link_hash_defweak) |
|| h->root.type == bfd_link_hash_defweak) |
1493 |
{ |
&& ((r_type == R_VAX_PLT32 |
|
sec = h->root.u.def.section; |
|
|
if ((r_type == R_VAX_PLT32 |
|
1494 |
&& h->plt.offset != (bfd_vma) -1 |
&& h->plt.offset != (bfd_vma) -1 |
1495 |
&& elf_hash_table (info)->dynamic_sections_created) |
&& elf_hash_table (info)->dynamic_sections_created) |
1496 |
|| (r_type == R_VAX_GOT32 |
|| (r_type == R_VAX_GOT32 |
1499 |
&& elf_hash_table (info)->dynamic_sections_created |
&& elf_hash_table (info)->dynamic_sections_created |
1500 |
&& (! info->shared |
&& (! info->shared |
1501 |
|| (! info->symbolic && h->dynindx != -1) |
|| (! info->symbolic && h->dynindx != -1) |
1502 |
|| (h->elf_link_hash_flags |
|| !h->def_regular)) |
|
& ELF_LINK_HASH_DEF_REGULAR) == 0)) |
|
1503 |
|| (info->shared |
|| (info->shared |
1504 |
&& ((! info->symbolic && h->dynindx != -1) |
&& ((! info->symbolic && h->dynindx != -1) |
1505 |
|| (h->elf_link_hash_flags |
|| !h->def_regular) |
|
& ELF_LINK_HASH_DEF_REGULAR) == 0) |
|
1506 |
&& ((input_section->flags & SEC_ALLOC) != 0 |
&& ((input_section->flags & SEC_ALLOC) != 0 |
1507 |
/* DWARF will emit R_VAX_32 relocations in its |
/* DWARF will emit R_VAX_32 relocations in its |
1508 |
sections against symbols defined externally |
sections against symbols defined externally |
1510 |
with them here. */ |
with them here. */ |
1511 |
|
|
1512 |
|| ((input_section->flags & SEC_DEBUGGING) != 0 |
|| ((input_section->flags & SEC_DEBUGGING) != 0 |
1513 |
&& (h->elf_link_hash_flags |
&& h->def_dynamic)) |
|
& ELF_LINK_HASH_DEF_DYNAMIC) != 0)) |
|
1514 |
&& (r_type == R_VAX_8 |
&& (r_type == R_VAX_8 |
1515 |
|| r_type == R_VAX_16 |
|| r_type == R_VAX_16 |
1516 |
|| r_type == R_VAX_32 |
|| r_type == R_VAX_32 |
1517 |
|| r_type == R_VAX_PC8 |
|| r_type == R_VAX_PC8 |
1518 |
|| r_type == R_VAX_PC16 |
|| r_type == R_VAX_PC16 |
1519 |
|| r_type == R_VAX_PC32))) |
|| r_type == R_VAX_PC32)))) |
1520 |
{ |
/* In these cases, we don't need the relocation |
1521 |
/* In these cases, we don't need the relocation |
value. We check specially because in some |
1522 |
value. We check specially because in some |
obscure cases sec->output_section will be NULL. */ |
|
obscure cases sec->output_section will be NULL. */ |
|
|
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) |
|
1523 |
relocation = 0; |
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; |
|
|
} |
|
1524 |
} |
} |
1525 |
|
|
1526 |
switch (r_type) |
switch (r_type) |
1528 |
case R_VAX_GOT32: |
case R_VAX_GOT32: |
1529 |
/* Relocation is to the address of the entry for this symbol |
/* Relocation is to the address of the entry for this symbol |
1530 |
in the global offset table. */ |
in the global offset table. */ |
1531 |
if (h != NULL |
if (h == NULL || h->got.offset == (bfd_vma) -1) |
|
&& strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) |
|
1532 |
break; |
break; |
1533 |
|
|
1534 |
/* Relocation is the offset of the entry for this symbol in |
/* Relocation is the offset of the entry for this symbol in |
1537 |
{ |
{ |
1538 |
bfd_vma off; |
bfd_vma off; |
1539 |
|
|
|
if (!elf_hash_table (info)->dynamic_sections_created |
|
|
|| (h == NULL) |
|
|
|| (info->shared |
|
|
&& info->symbolic |
|
|
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) |
|
|
{ |
|
|
/* This is actually a static link, or it is a -Bsymbolic link |
|
|
and the symbol is defined locally or there is no symbol. |
|
|
Change the GOT32 entry to a PC32 entry. */ |
|
|
break; |
|
|
} |
|
|
|
|
1540 |
if (sgot == NULL) |
if (sgot == NULL) |
1541 |
{ |
{ |
1542 |
sgot = bfd_get_section_by_name (dynobj, ".got"); |
sgot = bfd_get_section_by_name (dynobj, ".got"); |
1546 |
BFD_ASSERT (h != NULL); |
BFD_ASSERT (h != NULL); |
1547 |
off = h->got.offset; |
off = h->got.offset; |
1548 |
BFD_ASSERT (off != (bfd_vma) -1); |
BFD_ASSERT (off != (bfd_vma) -1); |
1549 |
|
BFD_ASSERT (off < sgot->size); |
1550 |
|
|
1551 |
if (info->shared |
if (info->shared |
1552 |
&& h->dynindx == -1 |
&& h->dynindx == -1 |
1553 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) |
&& h->def_regular) |
1554 |
{ |
{ |
1555 |
/* The symbol was forced to be local |
/* The symbol was forced to be local |
1556 |
because of a version file.. We must initialize |
because of a version file.. We must initialize |
1575 |
} |
} |
1576 |
|
|
1577 |
relocation = sgot->output_offset + off; |
relocation = sgot->output_offset + off; |
1578 |
/* Neither GOT relocation uses the addend. */ |
/* The GOT relocation uses the addend. */ |
1579 |
rel->r_addend = 0; |
rel->r_addend = 0; |
1580 |
|
|
1581 |
if (r_type == R_VAX_GOT32) |
/* Change the reference to be indirect. */ |
1582 |
{ |
contents[rel->r_offset - 1] |= 0x10; |
1583 |
/* Change the reference to be indirect */ |
relocation += sgot->output_section->vma; |
|
contents[rel->r_offset - 1] |= 0x10; |
|
|
relocation += sgot->output_section->vma; |
|
|
} |
|
1584 |
} |
} |
1585 |
break; |
break; |
1586 |
|
|
1657 |
&& r_type != R_VAX_PC16 |
&& r_type != R_VAX_PC16 |
1658 |
&& r_type != R_VAX_PC32) |
&& r_type != R_VAX_PC32) |
1659 |
|| (!info->symbolic |
|| (!info->symbolic |
1660 |
|| (h->elf_link_hash_flags |
|| !h->def_regular))) |
|
& ELF_LINK_HASH_DEF_REGULAR) == 0))) |
|
1661 |
{ |
{ |
1662 |
Elf_Internal_Rela outrel; |
Elf_Internal_Rela outrel; |
1663 |
boolean skip, relocate; |
bfd_byte *loc; |
1664 |
|
bfd_boolean skip, relocate; |
1665 |
|
|
1666 |
/* When generating a shared object, these relocations |
/* When generating a shared object, these relocations |
1667 |
are copied into the output file to be resolved at run |
are copied into the output file to be resolved at run |
1668 |
time. */ |
time. */ |
|
|
|
1669 |
if (sreloc == NULL) |
if (sreloc == NULL) |
1670 |
{ |
{ |
1671 |
const char *name; |
const char *name; |
1675 |
elf_elfheader (input_bfd)->e_shstrndx, |
elf_elfheader (input_bfd)->e_shstrndx, |
1676 |
elf_section_data (input_section)->rel_hdr.sh_name)); |
elf_section_data (input_section)->rel_hdr.sh_name)); |
1677 |
if (name == NULL) |
if (name == NULL) |
1678 |
return false; |
return FALSE; |
1679 |
|
|
1680 |
BFD_ASSERT (strncmp (name, ".rela", 5) == 0 |
BFD_ASSERT (strncmp (name, ".rela", 5) == 0 |
1681 |
&& strcmp (bfd_get_section_name (input_bfd, |
&& strcmp (bfd_get_section_name (input_bfd, |
1686 |
BFD_ASSERT (sreloc != NULL); |
BFD_ASSERT (sreloc != NULL); |
1687 |
} |
} |
1688 |
|
|
1689 |
skip = false; |
skip = FALSE; |
1690 |
relocate = false; |
relocate = FALSE; |
1691 |
|
|
1692 |
outrel.r_offset = |
outrel.r_offset = |
1693 |
_bfd_elf_section_offset (output_bfd, info, input_section, |
_bfd_elf_section_offset (output_bfd, info, input_section, |
1694 |
rel->r_offset); |
rel->r_offset); |
1695 |
if (outrel.r_offset == (bfd_vma) -1) |
if (outrel.r_offset == (bfd_vma) -1) |
1696 |
skip = true; |
skip = TRUE; |
1697 |
if (outrel.r_offset == (bfd_vma) -2) |
if (outrel.r_offset == (bfd_vma) -2) |
1698 |
skip = true, relocate = true; |
skip = TRUE, relocate = TRUE; |
1699 |
outrel.r_offset += (input_section->output_section->vma |
outrel.r_offset += (input_section->output_section->vma |
1700 |
+ input_section->output_offset); |
+ input_section->output_offset); |
1701 |
|
|
1705 |
become local. */ |
become local. */ |
1706 |
else if (h != NULL |
else if (h != NULL |
1707 |
&& ((! info->symbolic && h->dynindx != -1) |
&& ((! info->symbolic && h->dynindx != -1) |
1708 |
|| (h->elf_link_hash_flags |
|| !h->def_regular)) |
|
& ELF_LINK_HASH_DEF_REGULAR) == 0)) |
|
1709 |
{ |
{ |
1710 |
BFD_ASSERT (h->dynindx != -1); |
BFD_ASSERT (h->dynindx != -1); |
1711 |
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); |
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); |
1715 |
{ |
{ |
1716 |
if (r_type == R_VAX_32) |
if (r_type == R_VAX_32) |
1717 |
{ |
{ |
1718 |
relocate = true; |
relocate = TRUE; |
1719 |
outrel.r_info = ELF32_R_INFO (0, R_VAX_RELATIVE); |
outrel.r_info = ELF32_R_INFO (0, R_VAX_RELATIVE); |
1720 |
BFD_ASSERT (bfd_get_signed_32 (input_bfd, |
BFD_ASSERT (bfd_get_signed_32 (input_bfd, |
1721 |
&contents[rel->r_offset]) == 0); |
&contents[rel->r_offset]) == 0); |
1725 |
{ |
{ |
1726 |
long indx; |
long indx; |
1727 |
|
|
1728 |
if (h == NULL) |
if (bfd_is_abs_section (sec)) |
|
sec = local_sections[r_symndx]; |
|
|
else |
|
|
{ |
|
|
BFD_ASSERT (h->root.type == bfd_link_hash_defined |
|
|
|| (h->root.type |
|
|
== bfd_link_hash_defweak)); |
|
|
sec = h->root.u.def.section; |
|
|
} |
|
|
if (sec != NULL && bfd_is_abs_section (sec)) |
|
1729 |
indx = 0; |
indx = 0; |
1730 |
else if (sec == NULL || sec->owner == NULL) |
else if (sec == NULL || sec->owner == NULL) |
1731 |
{ |
{ |
1732 |
bfd_set_error (bfd_error_bad_value); |
bfd_set_error (bfd_error_bad_value); |
1733 |
return false; |
return FALSE; |
1734 |
} |
} |
1735 |
else |
else |
1736 |
{ |
{ |
1768 |
outrel.r_addend, |
outrel.r_addend, |
1769 |
bfd_get_section_name (input_bfd, input_section)); |
bfd_get_section_name (input_bfd, input_section)); |
1770 |
} |
} |
1771 |
bfd_elf32_swap_reloca_out (output_bfd, &outrel, |
loc = sreloc->contents; |
1772 |
(((Elf32_External_Rela *) |
loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela); |
1773 |
sreloc->contents) |
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); |
|
+ sreloc->reloc_count)); |
|
|
++sreloc->reloc_count; |
|
1774 |
|
|
1775 |
/* This reloc will be computed at runtime, so there's no |
/* This reloc will be computed at runtime, so there's no |
1776 |
need to do anything now, except for R_VAX_32 |
need to do anything now, except for R_VAX_32 |
1791 |
break; |
break; |
1792 |
} |
} |
1793 |
|
|
1794 |
/* VAX PCREL relocations are from the end of relocation, not the start */ |
/* VAX PCREL relocations are from the end of relocation, not the start. |
1795 |
|
So subtract the difference from the relocation amount since we can't |
1796 |
|
add it to the offset. */ |
1797 |
if (howto->pc_relative && howto->pcrel_offset) |
if (howto->pc_relative && howto->pcrel_offset) |
1798 |
{ |
relocation -= bfd_get_reloc_size(howto); |
|
relocation -= bfd_get_reloc_size(howto); |
|
|
} |
|
1799 |
|
|
1800 |
r = _bfd_final_link_relocate (howto, input_bfd, input_section, |
r = _bfd_final_link_relocate (howto, input_bfd, input_section, |
1801 |
contents, rel->r_offset, |
contents, rel->r_offset, |
1813 |
const char *name; |
const char *name; |
1814 |
|
|
1815 |
if (h != NULL) |
if (h != NULL) |
1816 |
name = h->root.root.string; |
name = NULL; |
1817 |
else |
else |
1818 |
{ |
{ |
1819 |
name = bfd_elf_string_from_elf_section (input_bfd, |
name = bfd_elf_string_from_elf_section (input_bfd, |
1820 |
symtab_hdr->sh_link, |
symtab_hdr->sh_link, |
1821 |
sym->st_name); |
sym->st_name); |
1822 |
if (name == NULL) |
if (name == NULL) |
1823 |
return false; |
return FALSE; |
1824 |
if (*name == '\0') |
if (*name == '\0') |
1825 |
name = bfd_section_name (input_bfd, sec); |
name = bfd_section_name (input_bfd, sec); |
1826 |
} |
} |
1827 |
if (!(info->callbacks->reloc_overflow |
if (!(info->callbacks->reloc_overflow |
1828 |
(info, name, howto->name, (bfd_vma) 0, |
(info, (h ? &h->root : NULL), name, howto->name, |
1829 |
input_bfd, input_section, rel->r_offset))) |
(bfd_vma) 0, input_bfd, input_section, |
1830 |
return false; |
rel->r_offset))) |
1831 |
|
return FALSE; |
1832 |
} |
} |
1833 |
break; |
break; |
1834 |
} |
} |
1835 |
} |
} |
1836 |
} |
} |
1837 |
|
|
1838 |
return true; |
return TRUE; |
1839 |
} |
} |
1840 |
|
|
1841 |
/* Finish up dynamic symbol handling. We set the contents of various |
/* Finish up dynamic symbol handling. We set the contents of various |
1842 |
dynamic sections here. */ |
dynamic sections here. */ |
1843 |
|
|
1844 |
static boolean |
static bfd_boolean |
1845 |
elf_vax_finish_dynamic_symbol (output_bfd, info, h, sym) |
elf_vax_finish_dynamic_symbol (output_bfd, info, h, sym) |
1846 |
bfd *output_bfd; |
bfd *output_bfd; |
1847 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
1861 |
bfd_vma got_offset; |
bfd_vma got_offset; |
1862 |
bfd_vma addend; |
bfd_vma addend; |
1863 |
Elf_Internal_Rela rela; |
Elf_Internal_Rela rela; |
1864 |
|
bfd_byte *loc; |
1865 |
|
|
1866 |
/* This symbol has an entry in the procedure linkage table. Set |
/* This symbol has an entry in the procedure linkage table. Set |
1867 |
it up. */ |
it up. */ |
|
|
|
1868 |
BFD_ASSERT (h->dynindx != -1); |
BFD_ASSERT (h->dynindx != -1); |
1869 |
|
|
1870 |
splt = bfd_get_section_by_name (dynobj, ".plt"); |
splt = bfd_get_section_by_name (dynobj, ".plt"); |
1911 |
+ got_offset); |
+ got_offset); |
1912 |
rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_JMP_SLOT); |
rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_JMP_SLOT); |
1913 |
rela.r_addend = addend; |
rela.r_addend = addend; |
1914 |
bfd_elf32_swap_reloca_out (output_bfd, &rela, |
loc = srela->contents + plt_index * sizeof (Elf32_External_Rela); |
1915 |
((Elf32_External_Rela *) srela->contents |
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); |
|
+ plt_index)); |
|
1916 |
|
|
1917 |
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) |
if (!h->def_regular) |
1918 |
{ |
{ |
1919 |
/* Mark the symbol as undefined, rather than as defined in |
/* Mark the symbol as undefined, rather than as defined in |
1920 |
the .plt section. Leave the value alone. */ |
the .plt section. Leave the value alone. */ |
1927 |
asection *sgot; |
asection *sgot; |
1928 |
asection *srela; |
asection *srela; |
1929 |
Elf_Internal_Rela rela; |
Elf_Internal_Rela rela; |
1930 |
|
bfd_byte *loc; |
1931 |
|
|
1932 |
/* This symbol has an entry in the global offset table. Set it |
/* This symbol has an entry in the global offset table. Set it |
1933 |
up. */ |
up. */ |
|
|
|
1934 |
sgot = bfd_get_section_by_name (dynobj, ".got"); |
sgot = bfd_get_section_by_name (dynobj, ".got"); |
1935 |
srela = bfd_get_section_by_name (dynobj, ".rela.got"); |
srela = bfd_get_section_by_name (dynobj, ".rela.got"); |
1936 |
BFD_ASSERT (sgot != NULL && srela != NULL); |
BFD_ASSERT (sgot != NULL && srela != NULL); |
1945 |
the relocate_section function. */ |
the relocate_section function. */ |
1946 |
if (info->shared |
if (info->shared |
1947 |
&& h->dynindx == -1 |
&& h->dynindx == -1 |
1948 |
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) |
&& h->def_regular) |
1949 |
{ |
{ |
1950 |
rela.r_info = ELF32_R_INFO (0, R_VAX_RELATIVE); |
rela.r_info = ELF32_R_INFO (0, R_VAX_RELATIVE); |
1951 |
} |
} |
1957 |
(sgot->contents |
(sgot->contents |
1958 |
+ (h->got.offset & ~1))); |
+ (h->got.offset & ~1))); |
1959 |
|
|
1960 |
bfd_elf32_swap_reloca_out (output_bfd, &rela, |
loc = srela->contents; |
1961 |
((Elf32_External_Rela *) srela->contents |
loc += srela->reloc_count++ * sizeof (Elf32_External_Rela); |
1962 |
+ srela->reloc_count)); |
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); |
|
++srela->reloc_count; |
|
1963 |
} |
} |
1964 |
|
|
1965 |
if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) |
if (h->needs_copy) |
1966 |
{ |
{ |
1967 |
asection *s; |
asection *s; |
1968 |
Elf_Internal_Rela rela; |
Elf_Internal_Rela rela; |
1969 |
|
bfd_byte *loc; |
1970 |
|
|
1971 |
/* This symbol needs a copy reloc. Set it up. */ |
/* This symbol needs a copy reloc. Set it up. */ |
|
|
|
1972 |
BFD_ASSERT (h->dynindx != -1 |
BFD_ASSERT (h->dynindx != -1 |
1973 |
&& (h->root.type == bfd_link_hash_defined |
&& (h->root.type == bfd_link_hash_defined |
1974 |
|| h->root.type == bfd_link_hash_defweak)); |
|| h->root.type == bfd_link_hash_defweak)); |
1982 |
+ h->root.u.def.section->output_offset); |
+ h->root.u.def.section->output_offset); |
1983 |
rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_COPY); |
rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_COPY); |
1984 |
rela.r_addend = 0; |
rela.r_addend = 0; |
1985 |
bfd_elf32_swap_reloca_out (output_bfd, &rela, |
loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela); |
1986 |
((Elf32_External_Rela *) s->contents |
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); |
|
+ s->reloc_count)); |
|
|
++s->reloc_count; |
|
1987 |
} |
} |
1988 |
|
|
1989 |
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ |
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ |
1991 |
|| strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) |
|| strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) |
1992 |
sym->st_shndx = SHN_ABS; |
sym->st_shndx = SHN_ABS; |
1993 |
|
|
1994 |
return true; |
return TRUE; |
1995 |
} |
} |
1996 |
|
|
1997 |
/* Finish up the dynamic sections. */ |
/* Finish up the dynamic sections. */ |
1998 |
|
|
1999 |
static boolean |
static bfd_boolean |
2000 |
elf_vax_finish_dynamic_sections (output_bfd, info) |
elf_vax_finish_dynamic_sections (output_bfd, info) |
2001 |
bfd *output_bfd; |
bfd *output_bfd; |
2002 |
struct bfd_link_info *info; |
struct bfd_link_info *info; |
2020 |
BFD_ASSERT (splt != NULL && sdyn != NULL); |
BFD_ASSERT (splt != NULL && sdyn != NULL); |
2021 |
|
|
2022 |
dyncon = (Elf32_External_Dyn *) sdyn->contents; |
dyncon = (Elf32_External_Dyn *) sdyn->contents; |
2023 |
dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); |
dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size); |
2024 |
for (; dyncon < dynconend; dyncon++) |
for (; dyncon < dynconend; dyncon++) |
2025 |
{ |
{ |
2026 |
Elf_Internal_Dyn dyn; |
Elf_Internal_Dyn dyn; |
2049 |
case DT_PLTRELSZ: |
case DT_PLTRELSZ: |
2050 |
s = bfd_get_section_by_name (output_bfd, ".rela.plt"); |
s = bfd_get_section_by_name (output_bfd, ".rela.plt"); |
2051 |
BFD_ASSERT (s != NULL); |
BFD_ASSERT (s != NULL); |
2052 |
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; |
|
2053 |
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); |
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); |
2054 |
break; |
break; |
2055 |
|
|
2063 |
about changing the DT_RELA entry. */ |
about changing the DT_RELA entry. */ |
2064 |
s = bfd_get_section_by_name (output_bfd, ".rela.plt"); |
s = bfd_get_section_by_name (output_bfd, ".rela.plt"); |
2065 |
if (s != NULL) |
if (s != NULL) |
2066 |
{ |
dyn.d_un.d_val -= s->size; |
|
if (s->_cooked_size != 0) |
|
|
dyn.d_un.d_val -= s->_cooked_size; |
|
|
else |
|
|
dyn.d_un.d_val -= s->_raw_size; |
|
|
} |
|
2067 |
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); |
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); |
2068 |
break; |
break; |
2069 |
} |
} |
2070 |
} |
} |
2071 |
|
|
2072 |
/* Fill in the first entry in the procedure linkage table. */ |
/* Fill in the first entry in the procedure linkage table. */ |
2073 |
if (splt->_raw_size > 0) |
if (splt->size > 0) |
2074 |
{ |
{ |
2075 |
memcpy (splt->contents, elf_vax_plt0_entry, PLT_ENTRY_SIZE); |
memcpy (splt->contents, elf_vax_plt0_entry, PLT_ENTRY_SIZE); |
2076 |
bfd_put_32 (output_bfd, |
bfd_put_32 (output_bfd, |
2089 |
} |
} |
2090 |
|
|
2091 |
/* Fill in the first three entries in the global offset table. */ |
/* Fill in the first three entries in the global offset table. */ |
2092 |
if (sgot->_raw_size > 0) |
if (sgot->size > 0) |
2093 |
{ |
{ |
2094 |
if (sdyn == NULL) |
if (sdyn == NULL) |
2095 |
bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); |
bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); |
2103 |
|
|
2104 |
elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; |
elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; |
2105 |
|
|
2106 |
return true; |
return TRUE; |
2107 |
} |
} |
2108 |
|
|
2109 |
#define TARGET_LITTLE_SYM bfd_elf32_vax_vec |
#define TARGET_LITTLE_SYM bfd_elf32_vax_vec |
2115 |
_bfd_elf_create_dynamic_sections |
_bfd_elf_create_dynamic_sections |
2116 |
#define bfd_elf32_bfd_link_hash_table_create \ |
#define bfd_elf32_bfd_link_hash_table_create \ |
2117 |
elf_vax_link_hash_table_create |
elf_vax_link_hash_table_create |
2118 |
#define bfd_elf32_bfd_final_link _bfd_elf32_gc_common_final_link |
#define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link |
2119 |
|
|
2120 |
#define elf_backend_check_relocs elf_vax_check_relocs |
#define elf_backend_check_relocs elf_vax_check_relocs |
2121 |
#define elf_backend_adjust_dynamic_symbol \ |
#define elf_backend_adjust_dynamic_symbol \ |
2141 |
#define elf_backend_plt_readonly 1 |
#define elf_backend_plt_readonly 1 |
2142 |
#define elf_backend_want_plt_sym 0 |
#define elf_backend_want_plt_sym 0 |
2143 |
#define elf_backend_got_header_size 16 |
#define elf_backend_got_header_size 16 |
2144 |
|
#define elf_backend_rela_normal 1 |
2145 |
|
|
2146 |
#include "elf32-target.h" |
#include "elf32-target.h" |