coff-alpha.c revision 1.1.1.9 1 1.1 christos /* BFD back-end for ALPHA Extended-Coff files.
2 1.1.1.9 christos Copyright (C) 1993-2024 Free Software Foundation, Inc.
3 1.1 christos Modified from coff-mips.c by Steve Chamberlain <sac (at) cygnus.com> and
4 1.1 christos Ian Lance Taylor <ian (at) cygnus.com>.
5 1.1 christos
6 1.1 christos This file is part of BFD, the Binary File Descriptor library.
7 1.1 christos
8 1.1 christos This program is free software; you can redistribute it and/or modify
9 1.1 christos it under the terms of the GNU General Public License as published by
10 1.1 christos the Free Software Foundation; either version 3 of the License, or
11 1.1 christos (at your option) any later version.
12 1.1 christos
13 1.1 christos This program is distributed in the hope that it will be useful,
14 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
15 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 1.1 christos GNU General Public License for more details.
17 1.1 christos
18 1.1 christos You should have received a copy of the GNU General Public License
19 1.1 christos along with this program; if not, write to the Free Software
20 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 1.1 christos MA 02110-1301, USA. */
22 1.1 christos
23 1.1 christos #include "sysdep.h"
24 1.1 christos #include "bfd.h"
25 1.1 christos #include "bfdlink.h"
26 1.1 christos #include "libbfd.h"
27 1.1 christos #include "coff/internal.h"
28 1.1 christos #include "coff/sym.h"
29 1.1 christos #include "coff/symconst.h"
30 1.1 christos #include "coff/ecoff.h"
31 1.1 christos #include "coff/alpha.h"
32 1.1 christos #include "aout/ar.h"
33 1.1 christos #include "libcoff.h"
34 1.1 christos #include "libecoff.h"
35 1.1 christos
36 1.1 christos /* Prototypes for static functions. */
38 1.1.1.2 christos
39 1.1 christos
40 1.1 christos
41 1.1 christos /* ECOFF has COFF sections, but the debugging information is stored in
43 1.1 christos a completely different format. ECOFF targets use some of the
44 1.1 christos swapping routines from coffswap.h, and some of the generic COFF
45 1.1 christos routines in coffgen.c, but, unlike the real COFF targets, do not
46 1.1 christos use coffcode.h itself.
47 1.1 christos
48 1.1 christos Get the generic COFF swapping routines, except for the reloc,
49 1.1 christos symbol, and lineno ones. Give them ecoff names. Define some
50 1.1 christos accessor macros for the large sizes used for Alpha ECOFF. */
51 1.1 christos
52 1.1 christos #define GET_FILEHDR_SYMPTR H_GET_64
53 1.1 christos #define PUT_FILEHDR_SYMPTR H_PUT_64
54 1.1 christos #define GET_AOUTHDR_TSIZE H_GET_64
55 1.1 christos #define PUT_AOUTHDR_TSIZE H_PUT_64
56 1.1 christos #define GET_AOUTHDR_DSIZE H_GET_64
57 1.1 christos #define PUT_AOUTHDR_DSIZE H_PUT_64
58 1.1 christos #define GET_AOUTHDR_BSIZE H_GET_64
59 1.1 christos #define PUT_AOUTHDR_BSIZE H_PUT_64
60 1.1 christos #define GET_AOUTHDR_ENTRY H_GET_64
61 1.1 christos #define PUT_AOUTHDR_ENTRY H_PUT_64
62 1.1 christos #define GET_AOUTHDR_TEXT_START H_GET_64
63 1.1 christos #define PUT_AOUTHDR_TEXT_START H_PUT_64
64 1.1 christos #define GET_AOUTHDR_DATA_START H_GET_64
65 1.1 christos #define PUT_AOUTHDR_DATA_START H_PUT_64
66 1.1 christos #define GET_SCNHDR_PADDR H_GET_64
67 1.1 christos #define PUT_SCNHDR_PADDR H_PUT_64
68 1.1 christos #define GET_SCNHDR_VADDR H_GET_64
69 1.1 christos #define PUT_SCNHDR_VADDR H_PUT_64
70 1.1 christos #define GET_SCNHDR_SIZE H_GET_64
71 1.1 christos #define PUT_SCNHDR_SIZE H_PUT_64
72 1.1 christos #define GET_SCNHDR_SCNPTR H_GET_64
73 1.1 christos #define PUT_SCNHDR_SCNPTR H_PUT_64
74 1.1 christos #define GET_SCNHDR_RELPTR H_GET_64
75 1.1 christos #define PUT_SCNHDR_RELPTR H_PUT_64
76 1.1 christos #define GET_SCNHDR_LNNOPTR H_GET_64
77 1.1 christos #define PUT_SCNHDR_LNNOPTR H_PUT_64
78 1.1 christos
79 1.1 christos #define ALPHAECOFF
80 1.1 christos
81 1.1 christos #define NO_COFF_RELOCS
82 1.1 christos #define NO_COFF_SYMBOLS
83 1.1 christos #define NO_COFF_LINENOS
84 1.1 christos #define coff_swap_filehdr_in alpha_ecoff_swap_filehdr_in
85 1.1 christos #define coff_swap_filehdr_out alpha_ecoff_swap_filehdr_out
86 1.1 christos #define coff_swap_aouthdr_in alpha_ecoff_swap_aouthdr_in
87 1.1 christos #define coff_swap_aouthdr_out alpha_ecoff_swap_aouthdr_out
88 1.1 christos #define coff_swap_scnhdr_in alpha_ecoff_swap_scnhdr_in
89 1.1 christos #define coff_swap_scnhdr_out alpha_ecoff_swap_scnhdr_out
90 1.1 christos #include "coffswap.h"
91 1.1 christos
92 1.1 christos /* Get the ECOFF swapping routines. */
93 1.1 christos #define ECOFF_64
94 1.1 christos #include "ecoffswap.h"
95 1.1 christos
96 1.1 christos /* How to process the various reloc types. */
98 1.1.1.2 christos
99 1.1.1.2 christos static bfd_reloc_status_type
100 1.1.1.2 christos reloc_nil (bfd *abfd ATTRIBUTE_UNUSED,
101 1.1.1.2 christos arelent *reloc ATTRIBUTE_UNUSED,
102 1.1.1.2 christos asymbol *sym ATTRIBUTE_UNUSED,
103 1.1.1.2 christos void * data ATTRIBUTE_UNUSED,
104 1.1 christos asection *sec ATTRIBUTE_UNUSED,
105 1.1 christos bfd *output_bfd ATTRIBUTE_UNUSED,
106 1.1 christos char **error_message ATTRIBUTE_UNUSED)
107 1.1 christos {
108 1.1 christos return bfd_reloc_ok;
109 1.1 christos }
110 1.1 christos
111 1.1 christos /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
112 1.1 christos from smaller values. Start with zero, widen, *then* decrement. */
113 1.1 christos #define MINUS_ONE (((bfd_vma)0) - 1)
114 1.1 christos
115 1.1 christos static reloc_howto_type alpha_howto_table[] =
116 1.1 christos {
117 1.1 christos /* Reloc type 0 is ignored by itself. However, it appears after a
118 1.1 christos GPDISP reloc to identify the location where the low order 16 bits
119 1.1.1.8 christos of the gp register are loaded. */
120 1.1 christos HOWTO (ALPHA_R_IGNORE, /* type */
121 1.1.1.8 christos 0, /* rightshift */
122 1.1 christos 1, /* size */
123 1.1 christos 8, /* bitsize */
124 1.1 christos true, /* pc_relative */
125 1.1 christos 0, /* bitpos */
126 1.1.1.8 christos complain_overflow_dont, /* complain_on_overflow */
127 1.1 christos reloc_nil, /* special_function */
128 1.1 christos "IGNORE", /* name */
129 1.1.1.8 christos true, /* partial_inplace */
130 1.1 christos 0, /* src_mask */
131 1.1 christos 0, /* dst_mask */
132 1.1 christos true), /* pcrel_offset */
133 1.1 christos
134 1.1.1.8 christos /* A 32 bit reference to a symbol. */
135 1.1 christos HOWTO (ALPHA_R_REFLONG, /* type */
136 1.1.1.8 christos 0, /* rightshift */
137 1.1 christos 4, /* size */
138 1.1 christos 32, /* bitsize */
139 1.1 christos false, /* pc_relative */
140 1.1 christos 0, /* bitpos */
141 1.1.1.8 christos complain_overflow_bitfield, /* complain_on_overflow */
142 1.1 christos 0, /* special_function */
143 1.1 christos "REFLONG", /* name */
144 1.1.1.8 christos true, /* partial_inplace */
145 1.1 christos 0xffffffff, /* src_mask */
146 1.1 christos 0xffffffff, /* dst_mask */
147 1.1 christos false), /* pcrel_offset */
148 1.1 christos
149 1.1.1.8 christos /* A 64 bit reference to a symbol. */
150 1.1 christos HOWTO (ALPHA_R_REFQUAD, /* type */
151 1.1.1.8 christos 0, /* rightshift */
152 1.1 christos 8, /* size */
153 1.1 christos 64, /* bitsize */
154 1.1 christos false, /* pc_relative */
155 1.1 christos 0, /* bitpos */
156 1.1.1.8 christos complain_overflow_bitfield, /* complain_on_overflow */
157 1.1 christos 0, /* special_function */
158 1.1 christos "REFQUAD", /* name */
159 1.1.1.8 christos true, /* partial_inplace */
160 1.1 christos MINUS_ONE, /* src_mask */
161 1.1 christos MINUS_ONE, /* dst_mask */
162 1.1 christos false), /* pcrel_offset */
163 1.1 christos
164 1.1 christos /* A 32 bit GP relative offset. This is just like REFLONG except
165 1.1 christos that when the value is used the value of the gp register will be
166 1.1.1.8 christos added in. */
167 1.1 christos HOWTO (ALPHA_R_GPREL32, /* type */
168 1.1.1.8 christos 0, /* rightshift */
169 1.1 christos 4, /* size */
170 1.1 christos 32, /* bitsize */
171 1.1 christos false, /* pc_relative */
172 1.1 christos 0, /* bitpos */
173 1.1.1.8 christos complain_overflow_bitfield, /* complain_on_overflow */
174 1.1 christos 0, /* special_function */
175 1.1 christos "GPREL32", /* name */
176 1.1.1.8 christos true, /* partial_inplace */
177 1.1 christos 0xffffffff, /* src_mask */
178 1.1 christos 0xffffffff, /* dst_mask */
179 1.1 christos false), /* pcrel_offset */
180 1.1 christos
181 1.1 christos /* Used for an instruction that refers to memory off the GP
182 1.1 christos register. The offset is 16 bits of the 32 bit instruction. This
183 1.1.1.8 christos reloc always seems to be against the .lita section. */
184 1.1 christos HOWTO (ALPHA_R_LITERAL, /* type */
185 1.1.1.8 christos 0, /* rightshift */
186 1.1 christos 4, /* size */
187 1.1 christos 16, /* bitsize */
188 1.1 christos false, /* pc_relative */
189 1.1 christos 0, /* bitpos */
190 1.1.1.8 christos complain_overflow_signed, /* complain_on_overflow */
191 1.1 christos 0, /* special_function */
192 1.1 christos "LITERAL", /* name */
193 1.1.1.8 christos true, /* partial_inplace */
194 1.1 christos 0xffff, /* src_mask */
195 1.1 christos 0xffff, /* dst_mask */
196 1.1 christos false), /* pcrel_offset */
197 1.1 christos
198 1.1 christos /* This reloc only appears immediately following a LITERAL reloc.
199 1.1 christos It identifies a use of the literal. It seems that the linker can
200 1.1 christos use this to eliminate a portion of the .lita section. The symbol
201 1.1 christos index is special: 1 means the literal address is in the base
202 1.1 christos register of a memory format instruction; 2 means the literal
203 1.1 christos address is in the byte offset register of a byte-manipulation
204 1.1 christos instruction; 3 means the literal address is in the target
205 1.1 christos register of a jsr instruction. This does not actually do any
206 1.1.1.8 christos relocation. */
207 1.1 christos HOWTO (ALPHA_R_LITUSE, /* type */
208 1.1.1.8 christos 0, /* rightshift */
209 1.1 christos 4, /* size */
210 1.1 christos 32, /* bitsize */
211 1.1 christos false, /* pc_relative */
212 1.1 christos 0, /* bitpos */
213 1.1.1.8 christos complain_overflow_dont, /* complain_on_overflow */
214 1.1 christos reloc_nil, /* special_function */
215 1.1 christos "LITUSE", /* name */
216 1.1.1.8 christos false, /* partial_inplace */
217 1.1 christos 0, /* src_mask */
218 1.1 christos 0, /* dst_mask */
219 1.1 christos false), /* pcrel_offset */
220 1.1 christos
221 1.1 christos /* Load the gp register. This is always used for a ldah instruction
222 1.1 christos which loads the upper 16 bits of the gp register. The next reloc
223 1.1 christos will be an IGNORE reloc which identifies the location of the lda
224 1.1 christos instruction which loads the lower 16 bits. The symbol index of
225 1.1 christos the GPDISP instruction appears to actually be the number of bytes
226 1.1 christos between the ldah and lda instructions. This gives two different
227 1.1 christos ways to determine where the lda instruction is; I don't know why
228 1.1 christos both are used. The value to use for the relocation is the
229 1.1 christos difference between the GP value and the current location; the
230 1.1 christos load will always be done against a register holding the current
231 1.1.1.8 christos address. */
232 1.1 christos HOWTO (ALPHA_R_GPDISP, /* type */
233 1.1.1.8 christos 16, /* rightshift */
234 1.1 christos 4, /* size */
235 1.1 christos 16, /* bitsize */
236 1.1 christos true, /* pc_relative */
237 1.1 christos 0, /* bitpos */
238 1.1.1.8 christos complain_overflow_dont, /* complain_on_overflow */
239 1.1 christos reloc_nil, /* special_function */
240 1.1 christos "GPDISP", /* name */
241 1.1.1.8 christos true, /* partial_inplace */
242 1.1 christos 0xffff, /* src_mask */
243 1.1 christos 0xffff, /* dst_mask */
244 1.1 christos true), /* pcrel_offset */
245 1.1 christos
246 1.1 christos /* A 21 bit branch. The native assembler generates these for
247 1.1 christos branches within the text segment, and also fills in the PC
248 1.1.1.8 christos relative offset in the instruction. */
249 1.1 christos HOWTO (ALPHA_R_BRADDR, /* type */
250 1.1.1.8 christos 2, /* rightshift */
251 1.1 christos 4, /* size */
252 1.1 christos 21, /* bitsize */
253 1.1 christos true, /* pc_relative */
254 1.1 christos 0, /* bitpos */
255 1.1.1.8 christos complain_overflow_signed, /* complain_on_overflow */
256 1.1 christos 0, /* special_function */
257 1.1 christos "BRADDR", /* name */
258 1.1.1.8 christos true, /* partial_inplace */
259 1.1 christos 0x1fffff, /* src_mask */
260 1.1 christos 0x1fffff, /* dst_mask */
261 1.1 christos false), /* pcrel_offset */
262 1.1 christos
263 1.1.1.8 christos /* A hint for a jump to a register. */
264 1.1 christos HOWTO (ALPHA_R_HINT, /* type */
265 1.1.1.8 christos 2, /* rightshift */
266 1.1 christos 4, /* size */
267 1.1 christos 14, /* bitsize */
268 1.1 christos true, /* pc_relative */
269 1.1 christos 0, /* bitpos */
270 1.1.1.8 christos complain_overflow_dont, /* complain_on_overflow */
271 1.1 christos 0, /* special_function */
272 1.1 christos "HINT", /* name */
273 1.1.1.8 christos true, /* partial_inplace */
274 1.1 christos 0x3fff, /* src_mask */
275 1.1 christos 0x3fff, /* dst_mask */
276 1.1 christos false), /* pcrel_offset */
277 1.1 christos
278 1.1.1.8 christos /* 16 bit PC relative offset. */
279 1.1 christos HOWTO (ALPHA_R_SREL16, /* type */
280 1.1.1.8 christos 0, /* rightshift */
281 1.1 christos 2, /* size */
282 1.1 christos 16, /* bitsize */
283 1.1 christos true, /* pc_relative */
284 1.1 christos 0, /* bitpos */
285 1.1.1.8 christos complain_overflow_signed, /* complain_on_overflow */
286 1.1 christos 0, /* special_function */
287 1.1 christos "SREL16", /* name */
288 1.1.1.8 christos true, /* partial_inplace */
289 1.1 christos 0xffff, /* src_mask */
290 1.1 christos 0xffff, /* dst_mask */
291 1.1 christos false), /* pcrel_offset */
292 1.1 christos
293 1.1.1.8 christos /* 32 bit PC relative offset. */
294 1.1 christos HOWTO (ALPHA_R_SREL32, /* type */
295 1.1.1.8 christos 0, /* rightshift */
296 1.1 christos 4, /* size */
297 1.1 christos 32, /* bitsize */
298 1.1 christos true, /* pc_relative */
299 1.1 christos 0, /* bitpos */
300 1.1.1.8 christos complain_overflow_signed, /* complain_on_overflow */
301 1.1 christos 0, /* special_function */
302 1.1 christos "SREL32", /* name */
303 1.1.1.8 christos true, /* partial_inplace */
304 1.1 christos 0xffffffff, /* src_mask */
305 1.1 christos 0xffffffff, /* dst_mask */
306 1.1 christos false), /* pcrel_offset */
307 1.1 christos
308 1.1.1.8 christos /* A 64 bit PC relative offset. */
309 1.1 christos HOWTO (ALPHA_R_SREL64, /* type */
310 1.1.1.8 christos 0, /* rightshift */
311 1.1 christos 8, /* size */
312 1.1 christos 64, /* bitsize */
313 1.1 christos true, /* pc_relative */
314 1.1 christos 0, /* bitpos */
315 1.1.1.8 christos complain_overflow_signed, /* complain_on_overflow */
316 1.1 christos 0, /* special_function */
317 1.1 christos "SREL64", /* name */
318 1.1.1.8 christos true, /* partial_inplace */
319 1.1 christos MINUS_ONE, /* src_mask */
320 1.1 christos MINUS_ONE, /* dst_mask */
321 1.1 christos false), /* pcrel_offset */
322 1.1 christos
323 1.1.1.8 christos /* Push a value on the reloc evaluation stack. */
324 1.1 christos HOWTO (ALPHA_R_OP_PUSH, /* type */
325 1.1.1.8 christos 0, /* rightshift */
326 1.1 christos 0, /* size */
327 1.1 christos 0, /* bitsize */
328 1.1 christos false, /* pc_relative */
329 1.1 christos 0, /* bitpos */
330 1.1.1.8 christos complain_overflow_dont, /* complain_on_overflow */
331 1.1 christos 0, /* special_function */
332 1.1 christos "OP_PUSH", /* name */
333 1.1.1.8 christos false, /* partial_inplace */
334 1.1 christos 0, /* src_mask */
335 1.1 christos 0, /* dst_mask */
336 1.1 christos false), /* pcrel_offset */
337 1.1 christos
338 1.1 christos /* Store the value from the stack at the given address. Store it in
339 1.1.1.8 christos a bitfield of size r_size starting at bit position r_offset. */
340 1.1 christos HOWTO (ALPHA_R_OP_STORE, /* type */
341 1.1.1.8 christos 0, /* rightshift */
342 1.1 christos 8, /* size */
343 1.1 christos 64, /* bitsize */
344 1.1 christos false, /* pc_relative */
345 1.1 christos 0, /* bitpos */
346 1.1.1.8 christos complain_overflow_dont, /* complain_on_overflow */
347 1.1 christos 0, /* special_function */
348 1.1 christos "OP_STORE", /* name */
349 1.1.1.8 christos false, /* partial_inplace */
350 1.1 christos 0, /* src_mask */
351 1.1 christos MINUS_ONE, /* dst_mask */
352 1.1 christos false), /* pcrel_offset */
353 1.1 christos
354 1.1 christos /* Subtract the reloc address from the value on the top of the
355 1.1.1.8 christos relocation stack. */
356 1.1 christos HOWTO (ALPHA_R_OP_PSUB, /* type */
357 1.1.1.8 christos 0, /* rightshift */
358 1.1 christos 0, /* size */
359 1.1 christos 0, /* bitsize */
360 1.1 christos false, /* pc_relative */
361 1.1 christos 0, /* bitpos */
362 1.1.1.8 christos complain_overflow_dont, /* complain_on_overflow */
363 1.1 christos 0, /* special_function */
364 1.1 christos "OP_PSUB", /* name */
365 1.1.1.8 christos false, /* partial_inplace */
366 1.1 christos 0, /* src_mask */
367 1.1 christos 0, /* dst_mask */
368 1.1 christos false), /* pcrel_offset */
369 1.1 christos
370 1.1 christos /* Shift the value on the top of the relocation stack right by the
371 1.1.1.8 christos given value. */
372 1.1 christos HOWTO (ALPHA_R_OP_PRSHIFT, /* type */
373 1.1.1.8 christos 0, /* rightshift */
374 1.1 christos 0, /* size */
375 1.1 christos 0, /* bitsize */
376 1.1 christos false, /* pc_relative */
377 1.1 christos 0, /* bitpos */
378 1.1.1.8 christos complain_overflow_dont, /* complain_on_overflow */
379 1.1 christos 0, /* special_function */
380 1.1 christos "OP_PRSHIFT", /* name */
381 1.1.1.8 christos false, /* partial_inplace */
382 1.1 christos 0, /* src_mask */
383 1.1 christos 0, /* dst_mask */
384 1.1 christos false), /* pcrel_offset */
385 1.1 christos
386 1.1.1.8 christos /* Adjust the GP value for a new range in the object file. */
387 1.1 christos HOWTO (ALPHA_R_GPVALUE, /* type */
388 1.1.1.8 christos 0, /* rightshift */
389 1.1 christos 0, /* size */
390 1.1 christos 0, /* bitsize */
391 1.1 christos false, /* pc_relative */
392 1.1 christos 0, /* bitpos */
393 1.1.1.8 christos complain_overflow_dont, /* complain_on_overflow */
394 1.1 christos 0, /* special_function */
395 1.1 christos "GPVALUE", /* name */
396 1.1.1.8 christos false, /* partial_inplace */
397 1.1 christos 0, /* src_mask */
398 1.1 christos 0, /* dst_mask */
399 1.1 christos false) /* pcrel_offset */
400 1.1 christos };
401 1.1.1.7 christos
402 1.1.1.2 christos /* Recognize an Alpha ECOFF file. */
404 1.1.1.7 christos
405 1.1 christos static bfd_cleanup
406 1.1 christos alpha_ecoff_object_p (bfd *abfd)
407 1.1 christos {
408 1.1 christos bfd_cleanup ret;
409 1.1 christos
410 1.1 christos ret = coff_object_p (abfd);
411 1.1 christos
412 1.1 christos if (ret != NULL)
413 1.1 christos {
414 1.1 christos asection *sec;
415 1.1 christos
416 1.1 christos /* Alpha ECOFF has a .pdata section. The lnnoptr field of the
417 1.1 christos .pdata section is the number of entries it contains. Each
418 1.1 christos entry takes up 8 bytes. The number of entries is required
419 1.1 christos since the section is aligned to a 16 byte boundary. When we
420 1.1 christos link .pdata sections together, we do not want to include the
421 1.1 christos alignment bytes. We handle this on input by faking the size
422 1.1 christos of the .pdata section to remove the unwanted alignment bytes.
423 1.1 christos On output we will set the lnnoptr field and force the
424 1.1 christos alignment. */
425 1.1 christos sec = bfd_get_section_by_name (abfd, _PDATA);
426 1.1.1.7 christos if (sec != (asection *) NULL)
427 1.1 christos {
428 1.1 christos bfd_size_type size;
429 1.1.1.7 christos
430 1.1 christos size = (bfd_size_type) sec->line_filepos * 8;
431 1.1 christos BFD_ASSERT (size == sec->size
432 1.1 christos || size + 8 == sec->size);
433 1.1 christos if (!bfd_set_section_size (sec, size))
434 1.1 christos return NULL;
435 1.1 christos }
436 1.1 christos }
437 1.1 christos
438 1.1 christos return ret;
439 1.1.1.8 christos }
440 1.1.1.2 christos
441 1.1.1.2 christos /* See whether the magic number matches. */
442 1.1 christos
443 1.1 christos static bool
444 1.1 christos alpha_ecoff_bad_format_hook (bfd *abfd ATTRIBUTE_UNUSED,
445 1.1 christos void * filehdr)
446 1.1.1.8 christos {
447 1.1 christos struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
448 1.1 christos
449 1.1.1.5 christos if (! ALPHA_ECOFF_BADMAG (*internal_f))
450 1.1.1.6 christos return true;
451 1.1.1.6 christos
452 1.1 christos if (ALPHA_ECOFF_COMPRESSEDMAG (*internal_f))
453 1.1 christos _bfd_error_handler
454 1.1.1.8 christos (_("%pB: cannot handle compressed Alpha binaries; "
455 1.1 christos "use compiler flags, or objZ, to generate uncompressed binaries"),
456 1.1 christos abfd);
457 1.1 christos
458 1.1 christos return false;
459 1.1 christos }
460 1.1.1.2 christos
461 1.1.1.2 christos /* This is a hook called by coff_real_object_p to create any backend
462 1.1 christos specific information. */
463 1.1.1.2 christos
464 1.1 christos static void *
465 1.1 christos alpha_ecoff_mkobject_hook (bfd *abfd, void * filehdr, void * aouthdr)
466 1.1 christos {
467 1.1 christos void * ecoff;
468 1.1 christos
469 1.1 christos ecoff = _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr);
470 1.1 christos
471 1.1 christos if (ecoff != NULL)
472 1.1 christos {
473 1.1 christos struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
474 1.1 christos
475 1.1 christos /* Set additional BFD flags according to the object type from the
476 1.1 christos machine specific file header flags. */
477 1.1 christos switch (internal_f->f_flags & F_ALPHA_OBJECT_TYPE_MASK)
478 1.1 christos {
479 1.1 christos case F_ALPHA_SHARABLE:
480 1.1 christos abfd->flags |= DYNAMIC;
481 1.1 christos break;
482 1.1 christos case F_ALPHA_CALL_SHARED:
483 1.1 christos /* Always executable if using shared libraries as the run time
484 1.1 christos loader might resolve undefined references. */
485 1.1 christos abfd->flags |= (DYNAMIC | EXEC_P);
486 1.1 christos break;
487 1.1 christos }
488 1.1 christos }
489 1.1 christos return ecoff;
490 1.1 christos }
491 1.1 christos
492 1.1 christos /* Reloc handling. */
494 1.1.1.2 christos
495 1.1.1.2 christos /* Swap a reloc in. */
496 1.1 christos
497 1.1 christos static void
498 1.1 christos alpha_ecoff_swap_reloc_in (bfd *abfd,
499 1.1 christos void * ext_ptr,
500 1.1 christos struct internal_reloc *intern)
501 1.1 christos {
502 1.1 christos const RELOC *ext = (RELOC *) ext_ptr;
503 1.1 christos
504 1.1 christos intern->r_vaddr = H_GET_64 (abfd, ext->r_vaddr);
505 1.1 christos intern->r_symndx = H_GET_32 (abfd, ext->r_symndx);
506 1.1 christos
507 1.1 christos BFD_ASSERT (bfd_header_little_endian (abfd));
508 1.1 christos
509 1.1 christos intern->r_type = ((ext->r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
510 1.1 christos >> RELOC_BITS0_TYPE_SH_LITTLE);
511 1.1 christos intern->r_extern = (ext->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0;
512 1.1 christos intern->r_offset = ((ext->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE)
513 1.1 christos >> RELOC_BITS1_OFFSET_SH_LITTLE);
514 1.1 christos /* Ignored the reserved bits. */
515 1.1 christos intern->r_size = ((ext->r_bits[3] & RELOC_BITS3_SIZE_LITTLE)
516 1.1 christos >> RELOC_BITS3_SIZE_SH_LITTLE);
517 1.1 christos
518 1.1 christos if (intern->r_type == ALPHA_R_LITUSE
519 1.1 christos || intern->r_type == ALPHA_R_GPDISP)
520 1.1 christos {
521 1.1 christos /* Handle the LITUSE and GPDISP relocs specially. Its symndx
522 1.1 christos value is not actually a symbol index, but is instead a
523 1.1 christos special code. We put the code in the r_size field, and
524 1.1 christos clobber the symndx. */
525 1.1 christos if (intern->r_size != 0)
526 1.1 christos abort ();
527 1.1 christos intern->r_size = intern->r_symndx;
528 1.1 christos intern->r_symndx = RELOC_SECTION_NONE;
529 1.1 christos }
530 1.1 christos else if (intern->r_type == ALPHA_R_IGNORE)
531 1.1 christos {
532 1.1 christos /* The IGNORE reloc generally follows a GPDISP reloc, and is
533 1.1 christos against the .lita section. The section is irrelevant. */
534 1.1 christos if (! intern->r_extern &&
535 1.1 christos intern->r_symndx == RELOC_SECTION_ABS)
536 1.1 christos abort ();
537 1.1 christos if (! intern->r_extern && intern->r_symndx == RELOC_SECTION_LITA)
538 1.1 christos intern->r_symndx = RELOC_SECTION_ABS;
539 1.1 christos }
540 1.1.1.2 christos }
541 1.1.1.2 christos
542 1.1.1.2 christos /* Swap a reloc out. */
543 1.1 christos
544 1.1 christos static void
545 1.1 christos alpha_ecoff_swap_reloc_out (bfd *abfd,
546 1.1 christos const struct internal_reloc *intern,
547 1.1 christos void * dst)
548 1.1 christos {
549 1.1 christos RELOC *ext = (RELOC *) dst;
550 1.1 christos long symndx;
551 1.1 christos unsigned char size;
552 1.1 christos
553 1.1 christos /* Undo the hackery done in swap_reloc_in. */
554 1.1 christos if (intern->r_type == ALPHA_R_LITUSE
555 1.1 christos || intern->r_type == ALPHA_R_GPDISP)
556 1.1 christos {
557 1.1 christos symndx = intern->r_size;
558 1.1 christos size = 0;
559 1.1 christos }
560 1.1 christos else if (intern->r_type == ALPHA_R_IGNORE
561 1.1 christos && ! intern->r_extern
562 1.1 christos && intern->r_symndx == RELOC_SECTION_ABS)
563 1.1 christos {
564 1.1 christos symndx = RELOC_SECTION_LITA;
565 1.1 christos size = intern->r_size;
566 1.1 christos }
567 1.1 christos else
568 1.1 christos {
569 1.1 christos symndx = intern->r_symndx;
570 1.1 christos size = intern->r_size;
571 1.1 christos }
572 1.1 christos
573 1.1 christos /* XXX FIXME: The maximum symndx value used to be 14 but this
574 1.1 christos fails with object files produced by DEC's C++ compiler.
575 1.1 christos Where does the value 14 (or 15) come from anyway ? */
576 1.1 christos BFD_ASSERT (intern->r_extern
577 1.1 christos || (intern->r_symndx >= 0 && intern->r_symndx <= 15));
578 1.1 christos
579 1.1 christos H_PUT_64 (abfd, intern->r_vaddr, ext->r_vaddr);
580 1.1 christos H_PUT_32 (abfd, symndx, ext->r_symndx);
581 1.1 christos
582 1.1 christos BFD_ASSERT (bfd_header_little_endian (abfd));
583 1.1 christos
584 1.1 christos ext->r_bits[0] = ((intern->r_type << RELOC_BITS0_TYPE_SH_LITTLE)
585 1.1 christos & RELOC_BITS0_TYPE_LITTLE);
586 1.1 christos ext->r_bits[1] = ((intern->r_extern ? RELOC_BITS1_EXTERN_LITTLE : 0)
587 1.1 christos | ((intern->r_offset << RELOC_BITS1_OFFSET_SH_LITTLE)
588 1.1 christos & RELOC_BITS1_OFFSET_LITTLE));
589 1.1 christos ext->r_bits[2] = 0;
590 1.1 christos ext->r_bits[3] = ((size << RELOC_BITS3_SIZE_SH_LITTLE)
591 1.1 christos & RELOC_BITS3_SIZE_LITTLE);
592 1.1 christos }
593 1.1 christos
594 1.1.1.2 christos /* Finish canonicalizing a reloc. Part of this is generic to all
595 1.1.1.2 christos ECOFF targets, and that part is in ecoff.c. The rest is done in
596 1.1.1.2 christos this backend routine. It must fill in the howto field. */
597 1.1 christos
598 1.1 christos static void
599 1.1 christos alpha_adjust_reloc_in (bfd *abfd,
600 1.1.1.5 christos const struct internal_reloc *intern,
601 1.1.1.6 christos arelent *rptr)
602 1.1.1.6 christos {
603 1.1 christos if (intern->r_type > ALPHA_R_GPVALUE)
604 1.1 christos {
605 1.1 christos /* xgettext:c-format */
606 1.1 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
607 1.1 christos abfd, intern->r_type);
608 1.1 christos bfd_set_error (bfd_error_bad_value);
609 1.1 christos rptr->addend = 0;
610 1.1 christos rptr->howto = NULL;
611 1.1 christos return;
612 1.1 christos }
613 1.1 christos
614 1.1 christos switch (intern->r_type)
615 1.1 christos {
616 1.1.1.6 christos case ALPHA_R_BRADDR:
617 1.1.1.6 christos case ALPHA_R_SREL16:
618 1.1 christos case ALPHA_R_SREL32:
619 1.1 christos case ALPHA_R_SREL64:
620 1.1 christos /* This relocs appear to be fully resolved when they are against
621 1.1 christos internal symbols. Against external symbols, BRADDR at least
622 1.1 christos appears to be resolved against the next instruction. */
623 1.1 christos if (! intern->r_extern)
624 1.1 christos rptr->addend = 0;
625 1.1 christos else
626 1.1 christos rptr->addend = - (intern->r_vaddr + 4);
627 1.1 christos break;
628 1.1 christos
629 1.1 christos case ALPHA_R_GPREL32:
630 1.1 christos case ALPHA_R_LITERAL:
631 1.1 christos /* Copy the gp value for this object file into the addend, to
632 1.1 christos ensure that we are not confused by the linker. */
633 1.1 christos if (! intern->r_extern)
634 1.1 christos rptr->addend += ecoff_data (abfd)->gp;
635 1.1 christos break;
636 1.1 christos
637 1.1 christos case ALPHA_R_LITUSE:
638 1.1 christos case ALPHA_R_GPDISP:
639 1.1 christos /* The LITUSE and GPDISP relocs do not use a symbol, or an
640 1.1 christos addend, but they do use a special code. Put this code in the
641 1.1 christos addend field. */
642 1.1 christos rptr->addend = intern->r_size;
643 1.1 christos break;
644 1.1 christos
645 1.1 christos case ALPHA_R_OP_STORE:
646 1.1 christos /* The STORE reloc needs the size and offset fields. We store
647 1.1 christos them in the addend. */
648 1.1 christos BFD_ASSERT (intern->r_offset <= 256);
649 1.1 christos rptr->addend = (intern->r_offset << 8) + intern->r_size;
650 1.1 christos break;
651 1.1 christos
652 1.1 christos case ALPHA_R_OP_PUSH:
653 1.1 christos case ALPHA_R_OP_PSUB:
654 1.1 christos case ALPHA_R_OP_PRSHIFT:
655 1.1 christos /* The PUSH, PSUB and PRSHIFT relocs do not actually use an
656 1.1 christos address. I believe that the address supplied is really an
657 1.1 christos addend. */
658 1.1 christos rptr->addend = intern->r_vaddr;
659 1.1 christos break;
660 1.1 christos
661 1.1 christos case ALPHA_R_GPVALUE:
662 1.1 christos /* Set the addend field to the new GP value. */
663 1.1 christos rptr->addend = intern->r_symndx + ecoff_data (abfd)->gp;
664 1.1 christos break;
665 1.1 christos
666 1.1 christos case ALPHA_R_IGNORE:
667 1.1 christos /* If the type is ALPHA_R_IGNORE, make sure this is a reference
668 1.1 christos to the absolute section so that the reloc is ignored. For
669 1.1 christos some reason the address of this reloc type is not adjusted by
670 1.1 christos the section vma. We record the gp value for this object file
671 1.1 christos here, for convenience when doing the GPDISP relocation. */
672 1.1 christos rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
673 1.1 christos rptr->address = intern->r_vaddr;
674 1.1 christos rptr->addend = ecoff_data (abfd)->gp;
675 1.1 christos break;
676 1.1 christos
677 1.1 christos default:
678 1.1 christos break;
679 1.1 christos }
680 1.1 christos
681 1.1 christos rptr->howto = &alpha_howto_table[intern->r_type];
682 1.1 christos }
683 1.1 christos
684 1.1 christos /* When writing out a reloc we need to pull some values back out of
685 1.1.1.2 christos the addend field into the reloc. This is roughly the reverse of
686 1.1.1.2 christos alpha_adjust_reloc_in, except that there are several changes we do
687 1.1.1.2 christos not need to undo. */
688 1.1 christos
689 1.1 christos static void
690 1.1 christos alpha_adjust_reloc_out (bfd *abfd ATTRIBUTE_UNUSED,
691 1.1 christos const arelent *rel,
692 1.1 christos struct internal_reloc *intern)
693 1.1 christos {
694 1.1 christos switch (intern->r_type)
695 1.1 christos {
696 1.1 christos case ALPHA_R_LITUSE:
697 1.1 christos case ALPHA_R_GPDISP:
698 1.1 christos intern->r_size = rel->addend;
699 1.1 christos break;
700 1.1 christos
701 1.1 christos case ALPHA_R_OP_STORE:
702 1.1 christos intern->r_size = rel->addend & 0xff;
703 1.1 christos intern->r_offset = (rel->addend >> 8) & 0xff;
704 1.1 christos break;
705 1.1 christos
706 1.1 christos case ALPHA_R_OP_PUSH:
707 1.1 christos case ALPHA_R_OP_PSUB:
708 1.1 christos case ALPHA_R_OP_PRSHIFT:
709 1.1 christos intern->r_vaddr = rel->addend;
710 1.1 christos break;
711 1.1 christos
712 1.1 christos case ALPHA_R_IGNORE:
713 1.1 christos intern->r_vaddr = rel->address;
714 1.1 christos break;
715 1.1 christos
716 1.1 christos default:
717 1.1 christos break;
718 1.1 christos }
719 1.1 christos }
720 1.1 christos
721 1.1 christos /* The size of the stack for the relocation evaluator. */
722 1.1 christos #define RELOC_STACKSIZE (10)
723 1.1 christos
724 1.1 christos /* Alpha ECOFF relocs have a built in expression evaluator as well as
725 1.1 christos other interdependencies. Rather than use a bunch of special
726 1.1.1.2 christos functions and global variables, we use a single routine to do all
727 1.1.1.2 christos the relocation for a section. I haven't yet worked out how the
728 1.1.1.2 christos assembler is going to handle this. */
729 1.1.1.2 christos
730 1.1.1.8 christos static bfd_byte *
731 1.1.1.2 christos alpha_ecoff_get_relocated_section_contents (bfd *abfd,
732 1.1 christos struct bfd_link_info *link_info,
733 1.1 christos struct bfd_link_order *link_order,
734 1.1 christos bfd_byte *data,
735 1.1.1.8 christos bool relocatable,
736 1.1.1.8 christos asymbol **symbols)
737 1.1 christos {
738 1.1 christos bfd *input_bfd = link_order->u.indirect.section->owner;
739 1.1 christos asection *input_section = link_order->u.indirect.section;
740 1.1.1.8 christos long reloc_size;
741 1.1 christos arelent **reloc_vector;
742 1.1 christos long reloc_count;
743 1.1 christos bfd *output_bfd = relocatable ? abfd : (bfd *) NULL;
744 1.1.1.8 christos bfd_vma gp;
745 1.1 christos bool gp_undefined;
746 1.1.1.8 christos bfd_vma stack[RELOC_STACKSIZE];
747 1.1.1.8 christos int tos = 0;
748 1.1.1.8 christos
749 1.1.1.8 christos reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
750 1.1.1.8 christos if (reloc_size < 0)
751 1.1.1.8 christos return NULL;
752 1.1.1.8 christos
753 1.1.1.8 christos bfd_byte *orig_data = data;
754 1.1.1.8 christos if (!bfd_get_full_section_contents (input_bfd, input_section, &data))
755 1.1.1.8 christos return NULL;
756 1.1.1.8 christos
757 1.1 christos if (data == NULL)
758 1.1.1.8 christos return NULL;
759 1.1.1.8 christos
760 1.1 christos if (reloc_size == 0)
761 1.1 christos return data;
762 1.1 christos
763 1.1 christos reloc_vector = (arelent **) bfd_malloc (reloc_size);
764 1.1 christos if (reloc_vector == NULL)
765 1.1 christos goto error_return;
766 1.1 christos
767 1.1 christos reloc_count = bfd_canonicalize_reloc (input_bfd, input_section,
768 1.1 christos reloc_vector, symbols);
769 1.1 christos if (reloc_count < 0)
770 1.1.1.8 christos goto error_return;
771 1.1 christos if (reloc_count == 0)
772 1.1 christos goto successful_return;
773 1.1 christos
774 1.1 christos /* Get the GP value for the output BFD. */
775 1.1 christos gp_undefined = false;
776 1.1 christos gp = _bfd_get_gp_value (abfd);
777 1.1 christos if (gp == 0)
778 1.1 christos {
779 1.1 christos if (relocatable)
780 1.1 christos {
781 1.1 christos asection *sec;
782 1.1 christos bfd_vma lo;
783 1.1 christos
784 1.1 christos /* Make up a value. */
785 1.1 christos lo = (bfd_vma) -1;
786 1.1 christos for (sec = abfd->sections; sec != NULL; sec = sec->next)
787 1.1 christos {
788 1.1 christos if (sec->vma < lo
789 1.1 christos && (strcmp (sec->name, ".sbss") == 0
790 1.1 christos || strcmp (sec->name, ".sdata") == 0
791 1.1 christos || strcmp (sec->name, ".lit4") == 0
792 1.1 christos || strcmp (sec->name, ".lit8") == 0
793 1.1 christos || strcmp (sec->name, ".lita") == 0))
794 1.1 christos lo = sec->vma;
795 1.1 christos }
796 1.1 christos gp = lo + 0x8000;
797 1.1 christos _bfd_set_gp_value (abfd, gp);
798 1.1.1.8 christos }
799 1.1.1.8 christos else
800 1.1 christos {
801 1.1 christos struct bfd_link_hash_entry *h;
802 1.1.1.8 christos
803 1.1 christos h = bfd_link_hash_lookup (link_info->hash, "_gp", false, false,
804 1.1 christos true);
805 1.1 christos if (h == (struct bfd_link_hash_entry *) NULL
806 1.1 christos || h->type != bfd_link_hash_defined)
807 1.1 christos gp_undefined = true;
808 1.1 christos else
809 1.1 christos {
810 1.1 christos gp = (h->u.def.value
811 1.1 christos + h->u.def.section->output_section->vma
812 1.1 christos + h->u.def.section->output_offset);
813 1.1.1.9 christos _bfd_set_gp_value (abfd, gp);
814 1.1 christos }
815 1.1 christos }
816 1.1 christos }
817 1.1 christos
818 1.1.1.9 christos for (arelent **relp = reloc_vector; *relp != NULL; relp++)
819 1.1 christos {
820 1.1.1.9 christos arelent *rel;
821 1.1.1.9 christos bfd_reloc_status_type r;
822 1.1.1.9 christos char *err;
823 1.1.1.9 christos unsigned int r_type;
824 1.1.1.9 christos
825 1.1.1.9 christos rel = *relp;
826 1.1.1.9 christos if (rel->howto == NULL)
827 1.1.1.9 christos {
828 1.1.1.9 christos r = bfd_reloc_notsupported;
829 1.1.1.9 christos r_type = ALPHA_R_IGNORE;
830 1.1.1.9 christos }
831 1.1.1.9 christos else
832 1.1 christos {
833 1.1 christos r = bfd_reloc_ok;
834 1.1 christos r_type = rel->howto->type;
835 1.1 christos }
836 1.1 christos switch (r_type)
837 1.1 christos {
838 1.1 christos case ALPHA_R_IGNORE:
839 1.1 christos rel->address += input_section->output_offset;
840 1.1 christos break;
841 1.1 christos
842 1.1 christos case ALPHA_R_REFLONG:
843 1.1 christos case ALPHA_R_REFQUAD:
844 1.1 christos case ALPHA_R_BRADDR:
845 1.1 christos case ALPHA_R_HINT:
846 1.1 christos case ALPHA_R_SREL16:
847 1.1 christos case ALPHA_R_SREL32:
848 1.1 christos case ALPHA_R_SREL64:
849 1.1 christos if (relocatable
850 1.1 christos && ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0)
851 1.1 christos {
852 1.1 christos rel->address += input_section->output_offset;
853 1.1 christos break;
854 1.1 christos }
855 1.1 christos r = bfd_perform_relocation (input_bfd, rel, data, input_section,
856 1.1 christos output_bfd, &err);
857 1.1 christos break;
858 1.1 christos
859 1.1 christos case ALPHA_R_GPREL32:
860 1.1 christos /* This relocation is used in a switch table. It is a 32
861 1.1 christos bit offset from the current GP value. We must adjust it
862 1.1 christos by the different between the original GP value and the
863 1.1 christos current GP value. The original GP value is stored in the
864 1.1 christos addend. We adjust the addend and let
865 1.1 christos bfd_perform_relocation finish the job. */
866 1.1 christos rel->addend -= gp;
867 1.1 christos r = bfd_perform_relocation (input_bfd, rel, data, input_section,
868 1.1 christos output_bfd, &err);
869 1.1 christos if (r == bfd_reloc_ok && gp_undefined)
870 1.1 christos {
871 1.1 christos r = bfd_reloc_dangerous;
872 1.1 christos err = (char *) _("GP relative relocation used when GP not defined");
873 1.1 christos }
874 1.1 christos break;
875 1.1 christos
876 1.1 christos case ALPHA_R_LITERAL:
877 1.1 christos /* This is a reference to a literal value, generally
878 1.1 christos (always?) in the .lita section. This is a 16 bit GP
879 1.1 christos relative relocation. Sometimes the subsequent reloc is a
880 1.1 christos LITUSE reloc, which indicates how this reloc is used.
881 1.1 christos This sometimes permits rewriting the two instructions
882 1.1 christos referred to by the LITERAL and the LITUSE into different
883 1.1 christos instructions which do not refer to .lita. This can save
884 1.1 christos a memory reference, and permits removing a value from
885 1.1 christos .lita thus saving GP relative space.
886 1.1 christos
887 1.1 christos We do not these optimizations. To do them we would need
888 1.1.1.9 christos to arrange to link the .lita section first, so that by
889 1.1.1.9 christos the time we got here we would know the final values to
890 1.1.1.9 christos use. This would not be particularly difficult, but it is
891 1.1.1.9 christos not currently implemented. */
892 1.1.1.9 christos
893 1.1.1.9 christos rel->addend -= gp;
894 1.1.1.9 christos r = bfd_perform_relocation (input_bfd, rel, data, input_section,
895 1.1.1.9 christos output_bfd, &err);
896 1.1.1.9 christos if (r == bfd_reloc_ok && gp_undefined)
897 1.1 christos {
898 1.1 christos r = bfd_reloc_dangerous;
899 1.1 christos err = (char *) _("GP relative relocation used"
900 1.1 christos " when GP not defined");
901 1.1 christos }
902 1.1 christos break;
903 1.1 christos
904 1.1 christos case ALPHA_R_LITUSE:
905 1.1 christos /* See ALPHA_R_LITERAL above for the uses of this reloc. It
906 1.1 christos does not cause anything to happen, itself. */
907 1.1 christos rel->address += input_section->output_offset;
908 1.1 christos break;
909 1.1 christos
910 1.1 christos case ALPHA_R_GPDISP:
911 1.1.1.9 christos /* This marks the ldah of an ldah/lda pair which loads the
912 1.1.1.9 christos gp register with the difference of the gp value and the
913 1.1.1.9 christos current location. The second of the pair is r_size bytes
914 1.1.1.9 christos ahead; it used to be marked with an ALPHA_R_IGNORE reloc,
915 1.1.1.9 christos but that no longer happens in OSF/1 3.2. */
916 1.1.1.9 christos if (bfd_reloc_offset_in_range (rel->howto, input_bfd, input_section,
917 1.1.1.9 christos rel->address)
918 1.1.1.9 christos && bfd_reloc_offset_in_range (rel->howto, input_bfd, input_section,
919 1.1.1.9 christos rel->address + rel->addend))
920 1.1.1.9 christos {
921 1.1.1.9 christos /* Get the two instructions. */
922 1.1.1.9 christos bfd_byte *p = data + rel->address;
923 1.1.1.9 christos bfd_vma insn1 = bfd_get_32 (input_bfd, p);
924 1.1.1.9 christos bfd_vma insn2 = bfd_get_32 (input_bfd, p + rel->addend);
925 1.1.1.9 christos
926 1.1.1.9 christos BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */
927 1.1.1.9 christos BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */
928 1.1.1.9 christos
929 1.1.1.9 christos /* Get the existing addend. We must account for the sign
930 1.1.1.9 christos extension done by lda and ldah. */
931 1.1.1.9 christos bfd_vma addend = (((((insn1 & 0xffff) ^ 0x8000) - 0x8000) << 16)
932 1.1.1.9 christos + ((((insn2 & 0xffff) ^ 0x8000) - 0x8000)));
933 1.1.1.9 christos
934 1.1.1.9 christos /* The existing addend includes the different between the
935 1.1.1.9 christos gp of the input BFD and the address in the input BFD.
936 1.1.1.9 christos Subtract this out. */
937 1.1.1.9 christos addend -= ecoff_data (input_bfd)->gp - input_section->vma;
938 1.1.1.9 christos
939 1.1.1.9 christos /* Now add in the final gp value, and subtract out the
940 1.1.1.9 christos final address. */
941 1.1.1.9 christos addend += gp - (input_section->output_section->vma
942 1.1.1.9 christos + input_section->output_offset);
943 1.1 christos
944 1.1.1.9 christos /* Change the instructions, accounting for the sign
945 1.1.1.9 christos extension, and write them out. */
946 1.1.1.9 christos insn1 = (insn1 & ~0xffff) | (((addend + 0x8000) >> 16) & 0xffff);
947 1.1.1.9 christos insn2 = (insn2 & ~0xffff) | (addend & 0xffff);
948 1.1.1.9 christos
949 1.1 christos bfd_put_32 (input_bfd, insn1, p);
950 1.1.1.9 christos bfd_put_32 (input_bfd, insn2, p + rel->addend);
951 1.1 christos }
952 1.1 christos else
953 1.1 christos r = bfd_reloc_outofrange;
954 1.1 christos
955 1.1 christos rel->address += input_section->output_offset;
956 1.1 christos break;
957 1.1 christos
958 1.1 christos case ALPHA_R_OP_PUSH:
959 1.1 christos /* Push a value on the reloc evaluation stack. */
960 1.1 christos {
961 1.1 christos asymbol *symbol;
962 1.1 christos bfd_vma relocation;
963 1.1 christos
964 1.1 christos if (relocatable)
965 1.1 christos {
966 1.1 christos rel->address += input_section->output_offset;
967 1.1 christos break;
968 1.1 christos }
969 1.1 christos
970 1.1 christos /* Figure out the relocation of this symbol. */
971 1.1 christos symbol = *rel->sym_ptr_ptr;
972 1.1 christos
973 1.1 christos if (bfd_is_und_section (symbol->section))
974 1.1 christos r = bfd_reloc_undefined;
975 1.1 christos
976 1.1 christos if (bfd_is_com_section (symbol->section))
977 1.1 christos relocation = 0;
978 1.1 christos else
979 1.1 christos relocation = symbol->value;
980 1.1.1.9 christos relocation += symbol->section->output_section->vma;
981 1.1.1.9 christos relocation += symbol->section->output_offset;
982 1.1.1.9 christos relocation += rel->addend;
983 1.1.1.9 christos
984 1.1 christos if (tos >= RELOC_STACKSIZE)
985 1.1 christos {
986 1.1 christos r = bfd_reloc_notsupported;
987 1.1 christos break;
988 1.1 christos }
989 1.1 christos
990 1.1 christos stack[tos++] = relocation;
991 1.1 christos }
992 1.1 christos break;
993 1.1 christos
994 1.1 christos case ALPHA_R_OP_STORE:
995 1.1 christos /* Store a value from the reloc stack into a bitfield. */
996 1.1 christos {
997 1.1 christos if (relocatable)
998 1.1 christos {
999 1.1.1.9 christos rel->address += input_section->output_offset;
1000 1.1.1.9 christos break;
1001 1.1.1.9 christos }
1002 1.1.1.9 christos
1003 1.1.1.9 christos if (tos == 0)
1004 1.1.1.9 christos {
1005 1.1.1.9 christos r = bfd_reloc_notsupported;
1006 1.1.1.9 christos break;
1007 1.1.1.9 christos }
1008 1.1.1.9 christos
1009 1.1.1.9 christos /* The offset and size in bits for this reloc are encoded
1010 1.1.1.9 christos into the addend field by alpha_adjust_reloc_in. */
1011 1.1.1.9 christos unsigned int offset = (rel->addend >> 8) & 0xff;
1012 1.1.1.9 christos unsigned int size = rel->addend & 0xff;
1013 1.1.1.9 christos unsigned int startbyte = offset >> 3;
1014 1.1.1.9 christos unsigned int endbyte = (offset + size + 7) >> 3;
1015 1.1.1.9 christos unsigned int bytes = endbyte + 1 - startbyte;
1016 1.1.1.9 christos
1017 1.1.1.9 christos if (bytes <= 8
1018 1.1.1.9 christos && rel->address + startbyte + bytes >= rel->address
1019 1.1.1.9 christos && (rel->address + startbyte + bytes
1020 1.1.1.9 christos <= bfd_get_section_limit_octets (input_bfd, input_section)))
1021 1.1.1.9 christos {
1022 1.1.1.9 christos uint64_t val = 0;
1023 1.1.1.9 christos for (int off = bytes - 1; off >= 0; --off)
1024 1.1.1.9 christos val = (val << 8) | data[rel->address + startbyte + off];
1025 1.1 christos
1026 1.1.1.9 christos offset -= startbyte << 3;
1027 1.1.1.9 christos size -= startbyte << 3;
1028 1.1.1.9 christos uint64_t mask = (((uint64_t) 1 << size) - 1) << offset;
1029 1.1.1.9 christos val = (val & ~mask) | ((stack[--tos] << offset) & mask);
1030 1.1.1.9 christos
1031 1.1.1.9 christos for (unsigned int off = 0; off < bytes; ++off)
1032 1.1.1.9 christos {
1033 1.1.1.9 christos data[rel->address + startbyte + off] = val & 0xff;
1034 1.1 christos val >>= 8;
1035 1.1 christos }
1036 1.1 christos }
1037 1.1 christos else
1038 1.1 christos r = bfd_reloc_outofrange;
1039 1.1 christos }
1040 1.1 christos break;
1041 1.1 christos
1042 1.1 christos case ALPHA_R_OP_PSUB:
1043 1.1 christos /* Subtract a value from the top of the stack. */
1044 1.1 christos {
1045 1.1 christos asymbol *symbol;
1046 1.1 christos bfd_vma relocation;
1047 1.1 christos
1048 1.1 christos if (relocatable)
1049 1.1 christos {
1050 1.1 christos rel->address += input_section->output_offset;
1051 1.1 christos break;
1052 1.1 christos }
1053 1.1 christos
1054 1.1 christos /* Figure out the relocation of this symbol. */
1055 1.1 christos symbol = *rel->sym_ptr_ptr;
1056 1.1 christos
1057 1.1 christos if (bfd_is_und_section (symbol->section))
1058 1.1 christos r = bfd_reloc_undefined;
1059 1.1 christos
1060 1.1 christos if (bfd_is_com_section (symbol->section))
1061 1.1 christos relocation = 0;
1062 1.1 christos else
1063 1.1 christos relocation = symbol->value;
1064 1.1.1.9 christos relocation += symbol->section->output_section->vma;
1065 1.1.1.9 christos relocation += symbol->section->output_offset;
1066 1.1.1.9 christos relocation += rel->addend;
1067 1.1.1.9 christos
1068 1.1 christos if (tos == 0)
1069 1.1 christos {
1070 1.1 christos r = bfd_reloc_notsupported;
1071 1.1 christos break;
1072 1.1 christos }
1073 1.1 christos
1074 1.1 christos stack[tos - 1] -= relocation;
1075 1.1 christos }
1076 1.1 christos break;
1077 1.1 christos
1078 1.1 christos case ALPHA_R_OP_PRSHIFT:
1079 1.1 christos /* Shift the value on the top of the stack. */
1080 1.1 christos {
1081 1.1 christos asymbol *symbol;
1082 1.1 christos bfd_vma relocation;
1083 1.1 christos
1084 1.1 christos if (relocatable)
1085 1.1 christos {
1086 1.1 christos rel->address += input_section->output_offset;
1087 1.1 christos break;
1088 1.1 christos }
1089 1.1 christos
1090 1.1 christos /* Figure out the relocation of this symbol. */
1091 1.1 christos symbol = *rel->sym_ptr_ptr;
1092 1.1 christos
1093 1.1 christos if (bfd_is_und_section (symbol->section))
1094 1.1 christos r = bfd_reloc_undefined;
1095 1.1 christos
1096 1.1 christos if (bfd_is_com_section (symbol->section))
1097 1.1 christos relocation = 0;
1098 1.1 christos else
1099 1.1 christos relocation = symbol->value;
1100 1.1.1.9 christos relocation += symbol->section->output_section->vma;
1101 1.1.1.9 christos relocation += symbol->section->output_offset;
1102 1.1.1.9 christos relocation += rel->addend;
1103 1.1.1.9 christos
1104 1.1 christos if (tos == 0)
1105 1.1 christos {
1106 1.1 christos r = bfd_reloc_notsupported;
1107 1.1 christos break;
1108 1.1 christos }
1109 1.1 christos
1110 1.1 christos stack[tos - 1] >>= relocation;
1111 1.1 christos }
1112 1.1.1.8 christos break;
1113 1.1 christos
1114 1.1 christos case ALPHA_R_GPVALUE:
1115 1.1 christos /* I really don't know if this does the right thing. */
1116 1.1.1.9 christos gp = rel->addend;
1117 1.1.1.9 christos gp_undefined = false;
1118 1.1 christos break;
1119 1.1 christos
1120 1.1 christos default:
1121 1.1 christos r = bfd_reloc_notsupported;
1122 1.1 christos break;
1123 1.1 christos }
1124 1.1 christos
1125 1.1 christos if (relocatable)
1126 1.1 christos {
1127 1.1 christos asection *os = input_section->output_section;
1128 1.1 christos
1129 1.1 christos /* A partial link, so keep the relocs. */
1130 1.1 christos os->orelocation[os->reloc_count] = rel;
1131 1.1 christos os->reloc_count++;
1132 1.1 christos }
1133 1.1 christos
1134 1.1.1.4 christos if (r != bfd_reloc_ok)
1135 1.1.1.4 christos {
1136 1.1.1.8 christos switch (r)
1137 1.1 christos {
1138 1.1 christos case bfd_reloc_undefined:
1139 1.1.1.4 christos (*link_info->callbacks->undefined_symbol)
1140 1.1.1.4 christos (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr),
1141 1.1 christos input_bfd, input_section, rel->address, true);
1142 1.1 christos break;
1143 1.1.1.4 christos case bfd_reloc_dangerous:
1144 1.1.1.4 christos (*link_info->callbacks->reloc_dangerous)
1145 1.1.1.4 christos (link_info, err, input_bfd, input_section, rel->address);
1146 1.1.1.4 christos break;
1147 1.1 christos case bfd_reloc_overflow:
1148 1.1 christos (*link_info->callbacks->reloc_overflow)
1149 1.1.1.9 christos (link_info, NULL, bfd_asymbol_name (*rel->sym_ptr_ptr),
1150 1.1.1.9 christos rel->howto->name, rel->addend, input_bfd,
1151 1.1.1.9 christos input_section, rel->address);
1152 1.1.1.9 christos break;
1153 1.1.1.9 christos case bfd_reloc_outofrange:
1154 1.1.1.9 christos (*link_info->callbacks->einfo)
1155 1.1.1.9 christos /* xgettext:c-format */
1156 1.1.1.9 christos (_("%X%P: %pB(%pA): relocation \"%pR\" goes out of range\n"),
1157 1.1.1.9 christos input_bfd, input_section, rel);
1158 1.1.1.9 christos goto error_return;
1159 1.1.1.9 christos case bfd_reloc_notsupported:
1160 1.1 christos (*link_info->callbacks->einfo)
1161 1.1.1.9 christos /* xgettext:c-format */
1162 1.1.1.9 christos (_("%X%P: %pB(%pA): relocation \"%pR\" is not supported\n"),
1163 1.1.1.9 christos input_bfd, input_section, rel);
1164 1.1.1.9 christos goto error_return;
1165 1.1.1.9 christos default:
1166 1.1 christos (*link_info->callbacks->einfo)
1167 1.1 christos /* xgettext:c-format */
1168 1.1 christos (_("%X%P: %pB(%pA): relocation \"%pR\""
1169 1.1 christos " returns an unrecognized value %x\n"),
1170 1.1 christos input_bfd, input_section, rel, r);
1171 1.1 christos break;
1172 1.1.1.9 christos }
1173 1.1 christos }
1174 1.1 christos }
1175 1.1.1.7 christos
1176 1.1 christos if (tos != 0)
1177 1.1 christos goto error_return;
1178 1.1 christos
1179 1.1.1.7 christos successful_return:
1180 1.1.1.8 christos free (reloc_vector);
1181 1.1.1.8 christos return data;
1182 1.1 christos
1183 1.1 christos error_return:
1184 1.1 christos free (reloc_vector);
1185 1.1 christos if (orig_data == NULL)
1186 1.1 christos free (data);
1187 1.1 christos return NULL;
1188 1.1.1.2 christos }
1189 1.1.1.2 christos
1190 1.1 christos /* Get the howto structure for a generic reloc type. */
1191 1.1 christos
1192 1.1 christos static reloc_howto_type *
1193 1.1 christos alpha_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1194 1.1 christos bfd_reloc_code_real_type code)
1195 1.1 christos {
1196 1.1 christos int alpha_type;
1197 1.1 christos
1198 1.1 christos switch (code)
1199 1.1 christos {
1200 1.1 christos case BFD_RELOC_32:
1201 1.1 christos alpha_type = ALPHA_R_REFLONG;
1202 1.1 christos break;
1203 1.1 christos case BFD_RELOC_64:
1204 1.1 christos case BFD_RELOC_CTOR:
1205 1.1 christos alpha_type = ALPHA_R_REFQUAD;
1206 1.1 christos break;
1207 1.1 christos case BFD_RELOC_GPREL32:
1208 1.1 christos alpha_type = ALPHA_R_GPREL32;
1209 1.1 christos break;
1210 1.1 christos case BFD_RELOC_ALPHA_LITERAL:
1211 1.1 christos alpha_type = ALPHA_R_LITERAL;
1212 1.1 christos break;
1213 1.1 christos case BFD_RELOC_ALPHA_LITUSE:
1214 1.1 christos alpha_type = ALPHA_R_LITUSE;
1215 1.1 christos break;
1216 1.1 christos case BFD_RELOC_ALPHA_GPDISP_HI16:
1217 1.1 christos alpha_type = ALPHA_R_GPDISP;
1218 1.1 christos break;
1219 1.1 christos case BFD_RELOC_ALPHA_GPDISP_LO16:
1220 1.1 christos alpha_type = ALPHA_R_IGNORE;
1221 1.1 christos break;
1222 1.1 christos case BFD_RELOC_23_PCREL_S2:
1223 1.1 christos alpha_type = ALPHA_R_BRADDR;
1224 1.1 christos break;
1225 1.1 christos case BFD_RELOC_ALPHA_HINT:
1226 1.1 christos alpha_type = ALPHA_R_HINT;
1227 1.1 christos break;
1228 1.1 christos case BFD_RELOC_16_PCREL:
1229 1.1 christos alpha_type = ALPHA_R_SREL16;
1230 1.1 christos break;
1231 1.1 christos case BFD_RELOC_32_PCREL:
1232 1.1 christos alpha_type = ALPHA_R_SREL32;
1233 1.1 christos break;
1234 1.1 christos case BFD_RELOC_64_PCREL:
1235 1.1 christos alpha_type = ALPHA_R_SREL64;
1236 1.1 christos break;
1237 1.1 christos default:
1238 1.1 christos return (reloc_howto_type *) NULL;
1239 1.1 christos }
1240 1.1 christos
1241 1.1 christos return &alpha_howto_table[alpha_type];
1242 1.1 christos }
1243 1.1 christos
1244 1.1 christos static reloc_howto_type *
1245 1.1 christos alpha_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1246 1.1 christos const char *r_name)
1247 1.1 christos {
1248 1.1 christos unsigned int i;
1249 1.1 christos
1250 1.1 christos for (i = 0;
1251 1.1 christos i < sizeof (alpha_howto_table) / sizeof (alpha_howto_table[0]);
1252 1.1 christos i++)
1253 1.1 christos if (alpha_howto_table[i].name != NULL
1254 1.1 christos && strcasecmp (alpha_howto_table[i].name, r_name) == 0)
1255 1.1 christos return &alpha_howto_table[i];
1256 1.1 christos
1257 1.1 christos return NULL;
1258 1.1 christos }
1259 1.1 christos
1260 1.1.1.2 christos /* A helper routine for alpha_relocate_section which converts an
1262 1.1.1.2 christos external reloc when generating relocatable output. Returns the
1263 1.1.1.2 christos relocation amount. */
1264 1.1.1.2 christos
1265 1.1 christos static bfd_vma
1266 1.1 christos alpha_convert_external_reloc (bfd *output_bfd ATTRIBUTE_UNUSED,
1267 1.1 christos struct bfd_link_info *info,
1268 1.1 christos bfd *input_bfd,
1269 1.1.1.4 christos struct external_reloc *ext_rel,
1270 1.1 christos struct ecoff_link_hash_entry *h)
1271 1.1 christos {
1272 1.1 christos unsigned long r_symndx;
1273 1.1 christos bfd_vma relocation;
1274 1.1 christos
1275 1.1 christos BFD_ASSERT (bfd_link_relocatable (info));
1276 1.1 christos
1277 1.1 christos if (h->root.type == bfd_link_hash_defined
1278 1.1 christos || h->root.type == bfd_link_hash_defweak)
1279 1.1 christos {
1280 1.1 christos asection *hsec;
1281 1.1 christos const char *name;
1282 1.1 christos
1283 1.1 christos /* This symbol is defined in the output. Convert the reloc from
1284 1.1 christos being against the symbol to being against the section. */
1285 1.1.1.7 christos
1286 1.1 christos /* Clear the r_extern bit. */
1287 1.1 christos ext_rel->r_bits[1] &=~ RELOC_BITS1_EXTERN_LITTLE;
1288 1.1 christos
1289 1.1 christos /* Compute a new r_symndx value. */
1290 1.1 christos hsec = h->root.u.def.section;
1291 1.1 christos name = bfd_section_name (hsec->output_section);
1292 1.1 christos
1293 1.1 christos r_symndx = (unsigned long) -1;
1294 1.1 christos switch (name[1])
1295 1.1 christos {
1296 1.1 christos case 'A':
1297 1.1 christos if (strcmp (name, "*ABS*") == 0)
1298 1.1 christos r_symndx = RELOC_SECTION_ABS;
1299 1.1 christos break;
1300 1.1 christos case 'b':
1301 1.1 christos if (strcmp (name, ".bss") == 0)
1302 1.1 christos r_symndx = RELOC_SECTION_BSS;
1303 1.1 christos break;
1304 1.1 christos case 'd':
1305 1.1 christos if (strcmp (name, ".data") == 0)
1306 1.1 christos r_symndx = RELOC_SECTION_DATA;
1307 1.1 christos break;
1308 1.1 christos case 'f':
1309 1.1 christos if (strcmp (name, ".fini") == 0)
1310 1.1 christos r_symndx = RELOC_SECTION_FINI;
1311 1.1 christos break;
1312 1.1 christos case 'i':
1313 1.1 christos if (strcmp (name, ".init") == 0)
1314 1.1 christos r_symndx = RELOC_SECTION_INIT;
1315 1.1 christos break;
1316 1.1 christos case 'l':
1317 1.1 christos if (strcmp (name, ".lita") == 0)
1318 1.1 christos r_symndx = RELOC_SECTION_LITA;
1319 1.1 christos else if (strcmp (name, ".lit8") == 0)
1320 1.1 christos r_symndx = RELOC_SECTION_LIT8;
1321 1.1 christos else if (strcmp (name, ".lit4") == 0)
1322 1.1 christos r_symndx = RELOC_SECTION_LIT4;
1323 1.1 christos break;
1324 1.1 christos case 'p':
1325 1.1 christos if (strcmp (name, ".pdata") == 0)
1326 1.1 christos r_symndx = RELOC_SECTION_PDATA;
1327 1.1 christos break;
1328 1.1 christos case 'r':
1329 1.1 christos if (strcmp (name, ".rdata") == 0)
1330 1.1 christos r_symndx = RELOC_SECTION_RDATA;
1331 1.1 christos else if (strcmp (name, ".rconst") == 0)
1332 1.1 christos r_symndx = RELOC_SECTION_RCONST;
1333 1.1 christos break;
1334 1.1 christos case 's':
1335 1.1 christos if (strcmp (name, ".sdata") == 0)
1336 1.1 christos r_symndx = RELOC_SECTION_SDATA;
1337 1.1 christos else if (strcmp (name, ".sbss") == 0)
1338 1.1 christos r_symndx = RELOC_SECTION_SBSS;
1339 1.1 christos break;
1340 1.1 christos case 't':
1341 1.1 christos if (strcmp (name, ".text") == 0)
1342 1.1 christos r_symndx = RELOC_SECTION_TEXT;
1343 1.1 christos break;
1344 1.1 christos case 'x':
1345 1.1 christos if (strcmp (name, ".xdata") == 0)
1346 1.1 christos r_symndx = RELOC_SECTION_XDATA;
1347 1.1 christos break;
1348 1.1 christos }
1349 1.1 christos
1350 1.1 christos if (r_symndx == (unsigned long) -1)
1351 1.1 christos abort ();
1352 1.1 christos
1353 1.1 christos /* Add the section VMA and the symbol value. */
1354 1.1 christos relocation = (h->root.u.def.value
1355 1.1 christos + hsec->output_section->vma
1356 1.1 christos + hsec->output_offset);
1357 1.1 christos }
1358 1.1 christos else
1359 1.1 christos {
1360 1.1 christos /* Change the symndx value to the right one for
1361 1.1 christos the output BFD. */
1362 1.1 christos r_symndx = h->indx;
1363 1.1 christos if (r_symndx == (unsigned long) -1)
1364 1.1 christos {
1365 1.1 christos /* Caller must give an error. */
1366 1.1 christos r_symndx = 0;
1367 1.1 christos }
1368 1.1 christos relocation = 0;
1369 1.1 christos }
1370 1.1 christos
1371 1.1 christos /* Write out the new r_symndx value. */
1372 1.1 christos H_PUT_32 (input_bfd, r_symndx, ext_rel->r_symndx);
1373 1.1 christos
1374 1.1 christos return relocation;
1375 1.1.1.8 christos }
1376 1.1.1.2 christos
1377 1.1.1.2 christos /* Relocate a section while linking an Alpha ECOFF file. This is
1378 1.1.1.2 christos quite similar to get_relocated_section_contents. Perhaps they
1379 1.1.1.2 christos could be combined somehow. */
1380 1.1.1.2 christos
1381 1.1.1.2 christos static bool
1382 1.1 christos alpha_relocate_section (bfd *output_bfd,
1383 1.1 christos struct bfd_link_info *info,
1384 1.1 christos bfd *input_bfd,
1385 1.1 christos asection *input_section,
1386 1.1.1.8 christos bfd_byte *contents,
1387 1.1 christos void * external_relocs)
1388 1.1 christos {
1389 1.1 christos asection **symndx_to_section, *lita_sec;
1390 1.1 christos struct ecoff_link_hash_entry **sym_hashes;
1391 1.1 christos bfd_vma gp;
1392 1.1.1.9 christos bool gp_undefined;
1393 1.1 christos bfd_vma stack[RELOC_STACKSIZE];
1394 1.1 christos int tos = 0;
1395 1.1 christos struct external_reloc *ext_rel;
1396 1.1 christos struct external_reloc *ext_rel_end;
1397 1.1 christos bfd_size_type amt;
1398 1.1 christos bool ret = true;
1399 1.1 christos
1400 1.1 christos /* We keep a table mapping the symndx found in an internal reloc to
1401 1.1 christos the appropriate section. This is faster than looking up the
1402 1.1 christos section by name each time. */
1403 1.1.1.8 christos symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
1404 1.1 christos if (symndx_to_section == (asection **) NULL)
1405 1.1 christos {
1406 1.1 christos amt = NUM_RELOC_SECTIONS * sizeof (asection *);
1407 1.1 christos symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
1408 1.1 christos if (!symndx_to_section)
1409 1.1 christos return false;
1410 1.1 christos
1411 1.1 christos symndx_to_section[RELOC_SECTION_NONE] = NULL;
1412 1.1 christos symndx_to_section[RELOC_SECTION_TEXT] =
1413 1.1 christos bfd_get_section_by_name (input_bfd, ".text");
1414 1.1 christos symndx_to_section[RELOC_SECTION_RDATA] =
1415 1.1 christos bfd_get_section_by_name (input_bfd, ".rdata");
1416 1.1 christos symndx_to_section[RELOC_SECTION_DATA] =
1417 1.1 christos bfd_get_section_by_name (input_bfd, ".data");
1418 1.1 christos symndx_to_section[RELOC_SECTION_SDATA] =
1419 1.1 christos bfd_get_section_by_name (input_bfd, ".sdata");
1420 1.1 christos symndx_to_section[RELOC_SECTION_SBSS] =
1421 1.1 christos bfd_get_section_by_name (input_bfd, ".sbss");
1422 1.1 christos symndx_to_section[RELOC_SECTION_BSS] =
1423 1.1 christos bfd_get_section_by_name (input_bfd, ".bss");
1424 1.1 christos symndx_to_section[RELOC_SECTION_INIT] =
1425 1.1 christos bfd_get_section_by_name (input_bfd, ".init");
1426 1.1 christos symndx_to_section[RELOC_SECTION_LIT8] =
1427 1.1 christos bfd_get_section_by_name (input_bfd, ".lit8");
1428 1.1 christos symndx_to_section[RELOC_SECTION_LIT4] =
1429 1.1 christos bfd_get_section_by_name (input_bfd, ".lit4");
1430 1.1 christos symndx_to_section[RELOC_SECTION_XDATA] =
1431 1.1 christos bfd_get_section_by_name (input_bfd, ".xdata");
1432 1.1 christos symndx_to_section[RELOC_SECTION_PDATA] =
1433 1.1 christos bfd_get_section_by_name (input_bfd, ".pdata");
1434 1.1 christos symndx_to_section[RELOC_SECTION_FINI] =
1435 1.1 christos bfd_get_section_by_name (input_bfd, ".fini");
1436 1.1 christos symndx_to_section[RELOC_SECTION_LITA] =
1437 1.1 christos bfd_get_section_by_name (input_bfd, ".lita");
1438 1.1 christos symndx_to_section[RELOC_SECTION_ABS] = bfd_abs_section_ptr;
1439 1.1 christos symndx_to_section[RELOC_SECTION_RCONST] =
1440 1.1 christos bfd_get_section_by_name (input_bfd, ".rconst");
1441 1.1 christos
1442 1.1 christos ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
1443 1.1 christos }
1444 1.1 christos
1445 1.1 christos sym_hashes = ecoff_data (input_bfd)->sym_hashes;
1446 1.1 christos
1447 1.1 christos /* On the Alpha, the .lita section must be addressable by the global
1448 1.1 christos pointer. To support large programs, we need to allow multiple
1449 1.1.1.4 christos global pointers. This works as long as each input .lita section
1450 1.1 christos is <64KB big. This implies that when producing relocatable
1451 1.1 christos output, the .lita section is limited to 64KB. . */
1452 1.1 christos
1453 1.1 christos lita_sec = symndx_to_section[RELOC_SECTION_LITA];
1454 1.1 christos gp = _bfd_get_gp_value (output_bfd);
1455 1.1 christos if (! bfd_link_relocatable (info) && lita_sec != NULL)
1456 1.1 christos {
1457 1.1 christos struct ecoff_section_tdata *lita_sec_data;
1458 1.1 christos
1459 1.1 christos /* Make sure we have a section data structure to which we can
1460 1.1 christos hang on to the gp value we pick for the section. */
1461 1.1 christos lita_sec_data = ecoff_section_data (input_bfd, lita_sec);
1462 1.1 christos if (lita_sec_data == NULL)
1463 1.1 christos {
1464 1.1 christos amt = sizeof (struct ecoff_section_tdata);
1465 1.1 christos lita_sec_data = ((struct ecoff_section_tdata *)
1466 1.1 christos bfd_zalloc (input_bfd, amt));
1467 1.1 christos lita_sec->used_by_bfd = lita_sec_data;
1468 1.1 christos }
1469 1.1 christos
1470 1.1 christos if (lita_sec_data->gp != 0)
1471 1.1 christos {
1472 1.1 christos /* If we already assigned a gp to this section, we better
1473 1.1 christos stick with that value. */
1474 1.1 christos gp = lita_sec_data->gp;
1475 1.1 christos }
1476 1.1 christos else
1477 1.1 christos {
1478 1.1 christos bfd_vma lita_vma;
1479 1.1 christos bfd_size_type lita_size;
1480 1.1 christos
1481 1.1 christos lita_vma = lita_sec->output_offset + lita_sec->output_section->vma;
1482 1.1 christos lita_size = lita_sec->size;
1483 1.1 christos
1484 1.1 christos if (gp == 0
1485 1.1 christos || lita_vma < gp - 0x8000
1486 1.1 christos || lita_vma + lita_size >= gp + 0x8000)
1487 1.1 christos {
1488 1.1 christos /* Either gp hasn't been set at all or the current gp
1489 1.1 christos cannot address this .lita section. In both cases we
1490 1.1 christos reset the gp to point into the "middle" of the
1491 1.1 christos current input .lita section. */
1492 1.1.1.8 christos if (gp && !ecoff_data (output_bfd)->issued_multiple_gp_warning)
1493 1.1 christos {
1494 1.1 christos (*info->callbacks->warning) (info,
1495 1.1 christos _("using multiple gp values"),
1496 1.1 christos (char *) NULL, output_bfd,
1497 1.1 christos (asection *) NULL, (bfd_vma) 0);
1498 1.1 christos ecoff_data (output_bfd)->issued_multiple_gp_warning = true;
1499 1.1 christos }
1500 1.1 christos if (lita_vma < gp - 0x8000)
1501 1.1 christos gp = lita_vma + lita_size - 0x8000;
1502 1.1 christos else
1503 1.1 christos gp = lita_vma + 0x8000;
1504 1.1 christos
1505 1.1 christos }
1506 1.1 christos
1507 1.1 christos lita_sec_data->gp = gp;
1508 1.1 christos }
1509 1.1 christos
1510 1.1 christos _bfd_set_gp_value (output_bfd, gp);
1511 1.1 christos }
1512 1.1 christos
1513 1.1 christos gp_undefined = (gp == 0);
1514 1.1 christos
1515 1.1 christos BFD_ASSERT (bfd_header_little_endian (output_bfd));
1516 1.1 christos BFD_ASSERT (bfd_header_little_endian (input_bfd));
1517 1.1 christos
1518 1.1 christos ext_rel = (struct external_reloc *) external_relocs;
1519 1.1 christos ext_rel_end = ext_rel + input_section->reloc_count;
1520 1.1 christos for (; ext_rel < ext_rel_end; ext_rel++)
1521 1.1 christos {
1522 1.1.1.8 christos bfd_vma r_vaddr;
1523 1.1.1.8 christos unsigned long r_symndx;
1524 1.1.1.8 christos int r_type;
1525 1.1 christos int r_extern;
1526 1.1.1.9 christos int r_offset;
1527 1.1 christos int r_size;
1528 1.1 christos bool relocatep;
1529 1.1 christos bool adjust_addrp;
1530 1.1 christos bool gp_usedp;
1531 1.1 christos bfd_vma addend;
1532 1.1 christos bfd_reloc_status_type r;
1533 1.1 christos
1534 1.1 christos r_vaddr = H_GET_64 (input_bfd, ext_rel->r_vaddr);
1535 1.1 christos r_symndx = H_GET_32 (input_bfd, ext_rel->r_symndx);
1536 1.1 christos
1537 1.1 christos r_type = ((ext_rel->r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
1538 1.1 christos >> RELOC_BITS0_TYPE_SH_LITTLE);
1539 1.1 christos r_extern = (ext_rel->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0;
1540 1.1.1.8 christos r_offset = ((ext_rel->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE)
1541 1.1.1.8 christos >> RELOC_BITS1_OFFSET_SH_LITTLE);
1542 1.1.1.8 christos /* Ignored the reserved bits. */
1543 1.1 christos r_size = ((ext_rel->r_bits[3] & RELOC_BITS3_SIZE_LITTLE)
1544 1.1.1.9 christos >> RELOC_BITS3_SIZE_SH_LITTLE);
1545 1.1 christos
1546 1.1 christos relocatep = false;
1547 1.1 christos adjust_addrp = true;
1548 1.1 christos gp_usedp = false;
1549 1.1.1.9 christos addend = 0;
1550 1.1.1.9 christos r = bfd_reloc_ok;
1551 1.1 christos
1552 1.1 christos switch (r_type)
1553 1.1 christos {
1554 1.1 christos default:
1555 1.1 christos r = bfd_reloc_notsupported;
1556 1.1 christos break;
1557 1.1 christos
1558 1.1 christos case ALPHA_R_IGNORE:
1559 1.1.1.4 christos /* This reloc appears after a GPDISP reloc. On earlier
1560 1.1 christos versions of OSF/1, It marked the position of the second
1561 1.1 christos instruction to be altered by the GPDISP reloc, but it is
1562 1.1.1.8 christos not otherwise used for anything. For some reason, the
1563 1.1 christos address of the relocation does not appear to include the
1564 1.1 christos section VMA, unlike the other relocation types. */
1565 1.1 christos if (bfd_link_relocatable (info))
1566 1.1 christos H_PUT_64 (input_bfd, input_section->output_offset + r_vaddr,
1567 1.1 christos ext_rel->r_vaddr);
1568 1.1.1.8 christos adjust_addrp = false;
1569 1.1 christos break;
1570 1.1 christos
1571 1.1 christos case ALPHA_R_REFLONG:
1572 1.1 christos case ALPHA_R_REFQUAD:
1573 1.1 christos case ALPHA_R_HINT:
1574 1.1 christos relocatep = true;
1575 1.1 christos break;
1576 1.1 christos
1577 1.1.1.8 christos case ALPHA_R_BRADDR:
1578 1.1 christos case ALPHA_R_SREL16:
1579 1.1 christos case ALPHA_R_SREL32:
1580 1.1 christos case ALPHA_R_SREL64:
1581 1.1 christos if (r_extern)
1582 1.1 christos addend += - (r_vaddr + 4);
1583 1.1 christos relocatep = true;
1584 1.1 christos break;
1585 1.1.1.8 christos
1586 1.1 christos case ALPHA_R_GPREL32:
1587 1.1.1.8 christos /* This relocation is used in a switch table. It is a 32
1588 1.1 christos bit offset from the current GP value. We must adjust it
1589 1.1 christos by the different between the original GP value and the
1590 1.1 christos current GP value. */
1591 1.1 christos relocatep = true;
1592 1.1 christos addend = ecoff_data (input_bfd)->gp - gp;
1593 1.1 christos gp_usedp = true;
1594 1.1 christos break;
1595 1.1 christos
1596 1.1 christos case ALPHA_R_LITERAL:
1597 1.1 christos /* This is a reference to a literal value, generally
1598 1.1 christos (always?) in the .lita section. This is a 16 bit GP
1599 1.1 christos relative relocation. Sometimes the subsequent reloc is a
1600 1.1 christos LITUSE reloc, which indicates how this reloc is used.
1601 1.1 christos This sometimes permits rewriting the two instructions
1602 1.1 christos referred to by the LITERAL and the LITUSE into different
1603 1.1 christos instructions which do not refer to .lita. This can save
1604 1.1 christos a memory reference, and permits removing a value from
1605 1.1 christos .lita thus saving GP relative space.
1606 1.1 christos
1607 1.1.1.8 christos We do not these optimizations. To do them we would need
1608 1.1 christos to arrange to link the .lita section first, so that by
1609 1.1.1.8 christos the time we got here we would know the final values to
1610 1.1 christos use. This would not be particularly difficult, but it is
1611 1.1 christos not currently implemented. */
1612 1.1 christos
1613 1.1 christos relocatep = true;
1614 1.1 christos addend = ecoff_data (input_bfd)->gp - gp;
1615 1.1 christos gp_usedp = true;
1616 1.1 christos break;
1617 1.1 christos
1618 1.1 christos case ALPHA_R_LITUSE:
1619 1.1 christos /* See ALPHA_R_LITERAL above for the uses of this reloc. It
1620 1.1 christos does not cause anything to happen, itself. */
1621 1.1 christos break;
1622 1.1 christos
1623 1.1.1.9 christos case ALPHA_R_GPDISP:
1624 1.1.1.9 christos /* This marks the ldah of an ldah/lda pair which loads the
1625 1.1.1.9 christos gp register with the difference of the gp value and the
1626 1.1.1.9 christos current location. The second of the pair is r_symndx
1627 1.1.1.9 christos bytes ahead. It used to be marked with an ALPHA_R_IGNORE
1628 1.1.1.9 christos reloc, but OSF/1 3.2 no longer does that. */
1629 1.1.1.9 christos if (r_vaddr >= input_section->vma
1630 1.1.1.9 christos && r_vaddr - input_section->vma < input_section->size
1631 1.1.1.9 christos && input_section->size - (r_vaddr - input_section->vma) > r_symndx
1632 1.1.1.9 christos && (input_section->size - (r_vaddr - input_section->vma)
1633 1.1.1.9 christos - r_symndx >= 4))
1634 1.1.1.9 christos {
1635 1.1.1.9 christos /* Get the two instructions. */
1636 1.1.1.9 christos bfd_byte *p = contents + r_vaddr - input_section->vma;
1637 1.1.1.9 christos bfd_vma insn1 = bfd_get_32 (input_bfd, p);
1638 1.1.1.9 christos bfd_vma insn2 = bfd_get_32 (input_bfd, p + r_symndx);
1639 1.1.1.9 christos
1640 1.1.1.9 christos BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */
1641 1.1.1.9 christos BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */
1642 1.1.1.9 christos
1643 1.1.1.9 christos /* Get the existing addend. We must account for the sign
1644 1.1.1.9 christos extension done by lda and ldah. */
1645 1.1.1.9 christos addend = (((((insn1 & 0xffff) ^ 0x8000) - 0x8000) << 16)
1646 1.1.1.9 christos + (((insn2 & 0xffff) ^ 0x8000) - 0x8000));
1647 1.1.1.9 christos
1648 1.1.1.9 christos /* The existing addend includes the difference between the
1649 1.1.1.9 christos gp of the input BFD and the address in the input BFD.
1650 1.1.1.9 christos We want to change this to the difference between the
1651 1.1.1.9 christos final GP and the final address. */
1652 1.1.1.9 christos addend -= ecoff_data (input_bfd)->gp - input_section->vma;
1653 1.1.1.9 christos addend += gp - (input_section->output_section->vma
1654 1.1 christos + input_section->output_offset);
1655 1.1.1.9 christos
1656 1.1.1.9 christos /* Change the instructions, accounting for the sign
1657 1.1 christos extension, and write them out. */
1658 1.1.1.9 christos insn1 = (insn1 & ~0xffff) | (((addend + 0x8000) >> 16) & 0xffff);
1659 1.1.1.9 christos insn2 = (insn2 & ~0xffff) | (addend & 0xffff);
1660 1.1.1.9 christos
1661 1.1.1.9 christos bfd_put_32 (input_bfd, insn1, p);
1662 1.1 christos bfd_put_32 (input_bfd, insn2, p + r_symndx);
1663 1.1 christos
1664 1.1 christos gp_usedp = true;
1665 1.1 christos }
1666 1.1 christos else
1667 1.1 christos r = bfd_reloc_outofrange;
1668 1.1 christos break;
1669 1.1 christos
1670 1.1 christos case ALPHA_R_OP_PUSH:
1671 1.1 christos case ALPHA_R_OP_PSUB:
1672 1.1 christos case ALPHA_R_OP_PRSHIFT:
1673 1.1 christos /* Manipulate values on the reloc evaluation stack. The
1674 1.1 christos r_vaddr field is not an address in input_section, it is
1675 1.1 christos the current value (including any addend) of the object
1676 1.1.1.9 christos being used. */
1677 1.1.1.9 christos if (! r_extern)
1678 1.1.1.9 christos {
1679 1.1.1.9 christos asection *s;
1680 1.1.1.9 christos
1681 1.1 christos s = symndx_to_section[r_symndx];
1682 1.1 christos if (s == NULL)
1683 1.1 christos {
1684 1.1 christos r = bfd_reloc_notsupported;
1685 1.1 christos break;
1686 1.1 christos }
1687 1.1 christos addend = s->output_section->vma + s->output_offset - s->vma;
1688 1.1.1.9 christos }
1689 1.1.1.9 christos else
1690 1.1.1.9 christos {
1691 1.1.1.9 christos struct ecoff_link_hash_entry *h;
1692 1.1.1.9 christos
1693 1.1 christos h = sym_hashes[r_symndx];
1694 1.1.1.4 christos if (h == NULL)
1695 1.1 christos {
1696 1.1 christos r = bfd_reloc_notsupported;
1697 1.1 christos break;
1698 1.1 christos }
1699 1.1 christos
1700 1.1 christos if (! bfd_link_relocatable (info))
1701 1.1 christos {
1702 1.1 christos if (h->root.type == bfd_link_hash_defined
1703 1.1 christos || h->root.type == bfd_link_hash_defweak)
1704 1.1 christos addend = (h->root.u.def.value
1705 1.1 christos + h->root.u.def.section->output_section->vma
1706 1.1 christos + h->root.u.def.section->output_offset);
1707 1.1.1.4 christos else
1708 1.1.1.4 christos {
1709 1.1.1.8 christos /* Note that we pass the address as 0, since we
1710 1.1 christos do not have a meaningful number for the
1711 1.1 christos location within the section that is being
1712 1.1 christos relocated. */
1713 1.1 christos (*info->callbacks->undefined_symbol)
1714 1.1 christos (info, h->root.root.string, input_bfd,
1715 1.1 christos input_section, (bfd_vma) 0, true);
1716 1.1 christos addend = 0;
1717 1.1 christos }
1718 1.1 christos }
1719 1.1 christos else
1720 1.1 christos {
1721 1.1 christos if (h->root.type != bfd_link_hash_defined
1722 1.1.1.4 christos && h->root.type != bfd_link_hash_defweak
1723 1.1.1.4 christos && h->indx == -1)
1724 1.1.1.4 christos {
1725 1.1 christos /* This symbol is not being written out. Pass
1726 1.1 christos the address as 0, as with undefined_symbol,
1727 1.1 christos above. */
1728 1.1 christos (*info->callbacks->unattached_reloc)
1729 1.1 christos (info, h->root.root.string,
1730 1.1 christos input_bfd, input_section, (bfd_vma) 0);
1731 1.1 christos }
1732 1.1 christos
1733 1.1 christos addend = alpha_convert_external_reloc (output_bfd, info,
1734 1.1 christos input_bfd,
1735 1.1.1.4 christos ext_rel, h);
1736 1.1 christos }
1737 1.1 christos }
1738 1.1 christos
1739 1.1 christos addend += r_vaddr;
1740 1.1 christos
1741 1.1 christos if (bfd_link_relocatable (info))
1742 1.1 christos {
1743 1.1 christos /* Adjust r_vaddr by the addend. */
1744 1.1 christos H_PUT_64 (input_bfd, addend, ext_rel->r_vaddr);
1745 1.1 christos }
1746 1.1.1.9 christos else
1747 1.1.1.9 christos {
1748 1.1.1.9 christos switch (r_type)
1749 1.1.1.9 christos {
1750 1.1 christos case ALPHA_R_OP_PUSH:
1751 1.1 christos if (tos >= RELOC_STACKSIZE)
1752 1.1 christos {
1753 1.1 christos r = bfd_reloc_notsupported;
1754 1.1 christos break;
1755 1.1.1.9 christos }
1756 1.1.1.9 christos stack[tos++] = addend;
1757 1.1.1.9 christos break;
1758 1.1.1.9 christos
1759 1.1 christos case ALPHA_R_OP_PSUB:
1760 1.1 christos if (tos == 0)
1761 1.1 christos {
1762 1.1 christos r = bfd_reloc_notsupported;
1763 1.1 christos break;
1764 1.1.1.9 christos }
1765 1.1.1.9 christos stack[tos - 1] -= addend;
1766 1.1.1.9 christos break;
1767 1.1.1.9 christos
1768 1.1 christos case ALPHA_R_OP_PRSHIFT:
1769 1.1 christos if (tos == 0)
1770 1.1 christos {
1771 1.1 christos r = bfd_reloc_notsupported;
1772 1.1 christos break;
1773 1.1.1.8 christos }
1774 1.1 christos stack[tos - 1] >>= addend;
1775 1.1 christos break;
1776 1.1 christos }
1777 1.1 christos }
1778 1.1 christos
1779 1.1 christos adjust_addrp = false;
1780 1.1.1.4 christos break;
1781 1.1 christos
1782 1.1.1.9 christos case ALPHA_R_OP_STORE:
1783 1.1.1.9 christos /* Store a value from the reloc stack into a bitfield. If
1784 1.1.1.9 christos we are generating relocatable output, all we do is
1785 1.1.1.9 christos adjust the address of the reloc. */
1786 1.1.1.9 christos if (! bfd_link_relocatable (info))
1787 1.1.1.9 christos {
1788 1.1.1.9 christos unsigned int startbyte = r_offset >> 3;
1789 1.1.1.9 christos unsigned int endbyte = (r_offset + r_size + 7) >> 3;
1790 1.1.1.9 christos unsigned int bytes = endbyte + 1 - startbyte;
1791 1.1.1.9 christos
1792 1.1.1.9 christos if (bytes <= 8
1793 1.1.1.9 christos && r_vaddr >= input_section->vma
1794 1.1.1.9 christos && r_vaddr - input_section->vma < input_section->size
1795 1.1.1.9 christos && (input_section->size - (r_vaddr - input_section->vma)
1796 1.1.1.9 christos >= startbyte + bytes))
1797 1.1.1.9 christos {
1798 1.1.1.9 christos bfd_byte *p = contents + (r_vaddr - input_section->vma);
1799 1.1.1.9 christos uint64_t val = 0;
1800 1.1.1.9 christos for (int off = bytes - 1; off >= 0; --off)
1801 1.1 christos val = (val << 8) | p[startbyte + off];
1802 1.1.1.9 christos
1803 1.1.1.9 christos r_offset -= startbyte << 3;
1804 1.1.1.9 christos r_size -= startbyte << 3;
1805 1.1.1.9 christos uint64_t mask = (((uint64_t) 1 << r_size) - 1) << r_offset;
1806 1.1.1.9 christos val = (val & ~mask) | ((stack[--tos] << r_offset) & mask);
1807 1.1.1.9 christos
1808 1.1.1.9 christos for (unsigned int off = 0; off < bytes; ++off)
1809 1.1.1.9 christos {
1810 1.1 christos p[startbyte + off] = val & 0xff;
1811 1.1 christos val >>= 8;
1812 1.1 christos }
1813 1.1 christos }
1814 1.1 christos else
1815 1.1 christos r = bfd_reloc_outofrange;
1816 1.1.1.8 christos }
1817 1.1 christos break;
1818 1.1 christos
1819 1.1 christos case ALPHA_R_GPVALUE:
1820 1.1.1.9 christos /* I really don't know if this does the right thing. */
1821 1.1 christos gp = ecoff_data (input_bfd)->gp + r_symndx;
1822 1.1 christos gp_undefined = false;
1823 1.1 christos break;
1824 1.1 christos }
1825 1.1 christos
1826 1.1 christos if (relocatep && r == bfd_reloc_ok)
1827 1.1 christos {
1828 1.1 christos reloc_howto_type *howto;
1829 1.1 christos struct ecoff_link_hash_entry *h = NULL;
1830 1.1 christos asection *s = NULL;
1831 1.1 christos bfd_vma relocation;
1832 1.1 christos
1833 1.1 christos /* Perform a relocation. */
1834 1.1 christos
1835 1.1 christos howto = &alpha_howto_table[r_type];
1836 1.1 christos
1837 1.1.1.9 christos if (r_extern)
1838 1.1.1.9 christos {
1839 1.1 christos h = sym_hashes[r_symndx];
1840 1.1 christos /* If h is NULL, that means that there is a reloc
1841 1.1 christos against an external symbol which we thought was just
1842 1.1 christos a debugging symbol. This should not happen. */
1843 1.1 christos if (h == NULL)
1844 1.1 christos r = bfd_reloc_notsupported;
1845 1.1 christos }
1846 1.1 christos else
1847 1.1.1.9 christos {
1848 1.1.1.9 christos if (r_symndx >= NUM_RELOC_SECTIONS)
1849 1.1.1.9 christos s = NULL;
1850 1.1 christos else
1851 1.1 christos s = symndx_to_section[r_symndx];
1852 1.1.1.9 christos
1853 1.1.1.9 christos if (s == NULL)
1854 1.1.1.9 christos r = bfd_reloc_notsupported;
1855 1.1 christos
1856 1.1 christos }
1857 1.1 christos
1858 1.1 christos if (r != bfd_reloc_ok)
1859 1.1 christos ;
1860 1.1 christos else if (bfd_link_relocatable (info))
1861 1.1 christos {
1862 1.1 christos /* We are generating relocatable output, and must
1863 1.1 christos convert the existing reloc. */
1864 1.1 christos if (r_extern)
1865 1.1.1.4 christos {
1866 1.1.1.4 christos if (h->root.type != bfd_link_hash_defined
1867 1.1.1.4 christos && h->root.type != bfd_link_hash_defweak
1868 1.1 christos && h->indx == -1)
1869 1.1 christos {
1870 1.1 christos /* This symbol is not being written out. */
1871 1.1 christos (*info->callbacks->unattached_reloc)
1872 1.1 christos (info, h->root.root.string, input_bfd,
1873 1.1 christos input_section, r_vaddr - input_section->vma);
1874 1.1 christos }
1875 1.1 christos
1876 1.1 christos relocation = alpha_convert_external_reloc (output_bfd,
1877 1.1 christos info,
1878 1.1 christos input_bfd,
1879 1.1 christos ext_rel,
1880 1.1 christos h);
1881 1.1 christos }
1882 1.1 christos else
1883 1.1 christos {
1884 1.1 christos /* This is a relocation against a section. Adjust
1885 1.1 christos the value by the amount the section moved. */
1886 1.1 christos relocation = (s->output_section->vma
1887 1.1 christos + s->output_offset
1888 1.1 christos - s->vma);
1889 1.1 christos }
1890 1.1 christos
1891 1.1 christos /* If this is PC relative, the existing object file
1892 1.1 christos appears to already have the reloc worked out. We
1893 1.1 christos must subtract out the old value and add in the new
1894 1.1 christos one. */
1895 1.1 christos if (howto->pc_relative)
1896 1.1 christos relocation -= (input_section->output_section->vma
1897 1.1 christos + input_section->output_offset
1898 1.1 christos - input_section->vma);
1899 1.1 christos
1900 1.1 christos /* Put in any addend. */
1901 1.1 christos relocation += addend;
1902 1.1 christos
1903 1.1 christos /* Adjust the contents. */
1904 1.1 christos r = _bfd_relocate_contents (howto, input_bfd, relocation,
1905 1.1 christos (contents
1906 1.1 christos + r_vaddr
1907 1.1 christos - input_section->vma));
1908 1.1 christos }
1909 1.1 christos else
1910 1.1 christos {
1911 1.1 christos /* We are producing a final executable. */
1912 1.1 christos if (r_extern)
1913 1.1 christos {
1914 1.1 christos /* This is a reloc against a symbol. */
1915 1.1 christos if (h->root.type == bfd_link_hash_defined
1916 1.1 christos || h->root.type == bfd_link_hash_defweak)
1917 1.1 christos {
1918 1.1 christos asection *hsec;
1919 1.1 christos
1920 1.1.1.9 christos hsec = h->root.u.def.section;
1921 1.1 christos relocation = (h->root.u.def.value
1922 1.1 christos + hsec->output_section->vma
1923 1.1 christos + hsec->output_offset);
1924 1.1 christos }
1925 1.1 christos else
1926 1.1 christos r = bfd_reloc_undefined;
1927 1.1 christos }
1928 1.1 christos else
1929 1.1 christos {
1930 1.1 christos /* This is a reloc against a section. */
1931 1.1 christos relocation = (s->output_section->vma
1932 1.1 christos + s->output_offset
1933 1.1 christos - s->vma);
1934 1.1 christos
1935 1.1.1.9 christos /* Adjust a PC relative relocation by removing the
1936 1.1.1.9 christos reference to the original source section. */
1937 1.1.1.9 christos if (howto->pc_relative)
1938 1.1.1.9 christos relocation += input_section->vma;
1939 1.1.1.9 christos }
1940 1.1.1.9 christos
1941 1.1.1.9 christos if (r == bfd_reloc_ok)
1942 1.1.1.9 christos r = _bfd_final_link_relocate (howto,
1943 1.1 christos input_bfd,
1944 1.1 christos input_section,
1945 1.1 christos contents,
1946 1.1.1.4 christos r_vaddr - input_section->vma,
1947 1.1 christos relocation,
1948 1.1 christos addend);
1949 1.1 christos }
1950 1.1 christos }
1951 1.1 christos
1952 1.1 christos if (bfd_link_relocatable (info) && adjust_addrp)
1953 1.1 christos {
1954 1.1 christos /* Change the address of the relocation. */
1955 1.1 christos H_PUT_64 (input_bfd,
1956 1.1 christos (input_section->output_section->vma
1957 1.1 christos + input_section->output_offset
1958 1.1 christos - input_section->vma
1959 1.1.1.9 christos + r_vaddr),
1960 1.1 christos ext_rel->r_vaddr);
1961 1.1 christos }
1962 1.1 christos
1963 1.1.1.8 christos if (gp_usedp && gp_undefined)
1964 1.1 christos {
1965 1.1.1.9 christos r = bfd_reloc_dangerous;
1966 1.1.1.9 christos /* Only give the error once per link. */
1967 1.1.1.9 christos gp = 4;
1968 1.1.1.9 christos _bfd_set_gp_value (output_bfd, gp);
1969 1.1.1.9 christos gp_undefined = false;
1970 1.1.1.9 christos }
1971 1.1.1.9 christos
1972 1.1.1.9 christos if (r != bfd_reloc_ok)
1973 1.1.1.9 christos {
1974 1.1.1.9 christos switch (r)
1975 1.1.1.9 christos {
1976 1.1.1.9 christos case bfd_reloc_overflow:
1977 1.1.1.9 christos {
1978 1.1.1.9 christos const char *name;
1979 1.1.1.9 christos
1980 1.1.1.9 christos if (r_extern)
1981 1.1.1.9 christos name = sym_hashes[r_symndx]->root.root.string;
1982 1.1.1.9 christos else
1983 1.1.1.9 christos name = bfd_section_name (symndx_to_section[r_symndx]);
1984 1.1.1.9 christos (*info->callbacks->reloc_overflow)
1985 1.1.1.9 christos (info, NULL, name, alpha_howto_table[r_type].name,
1986 1.1.1.9 christos (bfd_vma) 0, input_bfd, input_section,
1987 1.1.1.9 christos r_vaddr - input_section->vma);
1988 1.1.1.9 christos }
1989 1.1.1.9 christos break;
1990 1.1.1.9 christos case bfd_reloc_outofrange:
1991 1.1.1.9 christos (*info->callbacks->einfo)
1992 1.1.1.9 christos /* xgettext:c-format */
1993 1.1.1.9 christos (_("%X%P: %pB(%pA): relocation out of range\n"),
1994 1.1.1.9 christos input_bfd, input_section);
1995 1.1.1.9 christos break;
1996 1.1.1.9 christos case bfd_reloc_undefined:
1997 1.1.1.9 christos (*info->callbacks->undefined_symbol)
1998 1.1.1.9 christos (info, sym_hashes[r_symndx]->root.root.string,
1999 1.1.1.9 christos input_bfd, input_section,
2000 1.1.1.9 christos r_vaddr - input_section->vma, true);
2001 1.1.1.9 christos break;
2002 1.1.1.9 christos case bfd_reloc_notsupported:
2003 1.1.1.9 christos (*info->callbacks->einfo)
2004 1.1.1.9 christos /* xgettext:c-format */
2005 1.1.1.9 christos (_("%X%P: %pB(%pA): relocation is not supported\n"),
2006 1.1.1.9 christos input_bfd, input_section);
2007 1.1.1.9 christos break;
2008 1.1.1.9 christos case bfd_reloc_dangerous:
2009 1.1.1.9 christos (*info->callbacks->reloc_dangerous)
2010 1.1.1.9 christos (info, _("GP relative relocation used when GP not defined"),
2011 1.1.1.9 christos input_bfd, input_section, r_vaddr - input_section->vma);
2012 1.1 christos break;
2013 1.1 christos default:
2014 1.1 christos abort ();
2015 1.1.1.9 christos }
2016 1.1 christos ret = false;
2017 1.1.1.9 christos }
2018 1.1 christos }
2019 1.1 christos
2020 1.1 christos if (tos != 0)
2021 1.1 christos ret = false;
2022 1.1 christos
2023 1.1.1.8 christos return ret;
2024 1.1.1.2 christos }
2025 1.1.1.2 christos
2026 1.1.1.2 christos /* Do final adjustments to the filehdr and the aouthdr. This routine
2028 1.1 christos sets the dynamic bits in the file header. */
2029 1.1 christos
2030 1.1 christos static bool
2031 1.1 christos alpha_adjust_headers (bfd *abfd,
2032 1.1.1.8 christos struct internal_filehdr *fhdr,
2033 1.1 christos struct internal_aouthdr *ahdr ATTRIBUTE_UNUSED)
2034 1.1 christos {
2035 1.1 christos if ((abfd->flags & (DYNAMIC | EXEC_P)) == (DYNAMIC | EXEC_P))
2036 1.1 christos fhdr->f_flags |= F_ALPHA_CALL_SHARED;
2037 1.1 christos else if ((abfd->flags & DYNAMIC) != 0)
2038 1.1 christos fhdr->f_flags |= F_ALPHA_SHARABLE;
2039 1.1 christos return true;
2040 1.1 christos }
2041 1.1 christos
2042 1.1 christos /* Archive handling. In OSF/1 (or Digital Unix) v3.2, Digital
2044 1.1 christos introduced archive packing, in which the elements in an archive are
2045 1.1 christos optionally compressed using a simple dictionary scheme. We know
2046 1.1 christos how to read such archives, but we don't write them. */
2047 1.1 christos
2048 1.1 christos #define alpha_ecoff_slurp_armap _bfd_ecoff_slurp_armap
2049 1.1 christos #define alpha_ecoff_slurp_extended_name_table \
2050 1.1 christos _bfd_ecoff_slurp_extended_name_table
2051 1.1 christos #define alpha_ecoff_construct_extended_name_table \
2052 1.1 christos _bfd_ecoff_construct_extended_name_table
2053 1.1 christos #define alpha_ecoff_truncate_arname _bfd_ecoff_truncate_arname
2054 1.1 christos #define alpha_ecoff_write_armap _bfd_ecoff_write_armap
2055 1.1 christos #define alpha_ecoff_write_ar_hdr _bfd_generic_write_ar_hdr
2056 1.1 christos #define alpha_ecoff_generic_stat_arch_elt _bfd_ecoff_generic_stat_arch_elt
2057 1.1 christos #define alpha_ecoff_update_armap_timestamp _bfd_ecoff_update_armap_timestamp
2058 1.1.1.2 christos
2059 1.1.1.2 christos /* A compressed file uses this instead of ARFMAG. */
2060 1.1 christos
2061 1.1 christos #define ARFZMAG "Z\012"
2062 1.1 christos
2063 1.1 christos /* Read an archive header. This is like the standard routine, but it
2064 1.1 christos also accepts ARFZMAG. */
2065 1.1 christos
2066 1.1 christos static void *
2067 1.1 christos alpha_ecoff_read_ar_hdr (bfd *abfd)
2068 1.1 christos {
2069 1.1 christos struct areltdata *ret;
2070 1.1 christos struct ar_hdr *h;
2071 1.1 christos
2072 1.1 christos ret = (struct areltdata *) _bfd_generic_read_ar_hdr_mag (abfd, ARFZMAG);
2073 1.1 christos if (ret == NULL)
2074 1.1.1.6 christos return NULL;
2075 1.1.1.9 christos
2076 1.1.1.9 christos h = (struct ar_hdr *) ret->arch_header;
2077 1.1.1.9 christos if (strncmp (h->ar_fmag, ARFZMAG, 2) == 0)
2078 1.1.1.7 christos {
2079 1.1.1.7 christos bfd_byte ab[8];
2080 1.1.1.7 christos
2081 1.1.1.7 christos /* This is a compressed file. We must set the size correctly.
2082 1.1 christos The size is the eight bytes after the dummy file header. */
2083 1.1 christos if (bfd_seek (abfd, FILHSZ, SEEK_CUR) != 0
2084 1.1 christos || bfd_read (ab, 8, abfd) != 8
2085 1.1 christos || bfd_seek (abfd, -(FILHSZ + 8), SEEK_CUR) != 0)
2086 1.1.1.2 christos {
2087 1.1 christos free (ret);
2088 1.1 christos return NULL;
2089 1.1 christos }
2090 1.1 christos
2091 1.1 christos ret->parsed_size = H_GET_64 (abfd, ab);
2092 1.1 christos }
2093 1.1.1.8 christos
2094 1.1.1.8 christos return ret;
2095 1.1 christos }
2096 1.1 christos
2097 1.1 christos /* Get an archive element at a specified file position. This is where
2098 1.1 christos we uncompress the archive element if necessary. */
2099 1.1 christos
2100 1.1 christos static bfd *
2101 1.1 christos alpha_ecoff_get_elt_at_filepos (bfd *archive, file_ptr filepos,
2102 1.1 christos struct bfd_link_info *info)
2103 1.1.1.7 christos {
2104 1.1 christos bfd *nbfd = NULL;
2105 1.1 christos struct areltdata *tdata;
2106 1.1.1.8 christos struct ar_hdr *hdr;
2107 1.1 christos bfd_byte ab[8];
2108 1.1 christos bfd_size_type size;
2109 1.1 christos bfd_byte *buf, *p;
2110 1.1 christos struct bfd_in_memory *bim;
2111 1.1 christos ufile_ptr filesize;
2112 1.1 christos
2113 1.1 christos buf = NULL;
2114 1.1 christos nbfd = _bfd_get_elt_at_filepos (archive, filepos, info);
2115 1.1 christos if (nbfd == NULL)
2116 1.1 christos goto error_return;
2117 1.1 christos
2118 1.1 christos if ((nbfd->flags & BFD_IN_MEMORY) != 0)
2119 1.1 christos {
2120 1.1 christos /* We have already expanded this BFD. */
2121 1.1 christos return nbfd;
2122 1.1.1.9 christos }
2123 1.1 christos
2124 1.1 christos tdata = (struct areltdata *) nbfd->arelt_data;
2125 1.1 christos hdr = (struct ar_hdr *) tdata->arch_header;
2126 1.1 christos if (strncmp (hdr->ar_fmag, ARFZMAG, 2) != 0)
2127 1.1 christos return nbfd;
2128 1.1 christos
2129 1.1.1.9 christos /* We must uncompress this element. We do this by copying it into a
2130 1.1 christos memory buffer, and making bfd_read and bfd_seek use that buffer.
2131 1.1 christos This can use a lot of memory, but it's simpler than getting a
2132 1.1 christos temporary file, making that work with the file descriptor caching
2133 1.1.1.9 christos code, and making sure that it is deleted at all appropriate
2134 1.1 christos times. It can be changed if it ever becomes important. */
2135 1.1 christos
2136 1.1 christos /* The compressed file starts with a dummy ECOFF file header. */
2137 1.1.1.7 christos if (bfd_seek (nbfd, FILHSZ, SEEK_SET) != 0)
2138 1.1.1.7 christos goto error_return;
2139 1.1.1.7 christos
2140 1.1.1.7 christos /* The next eight bytes are the real file size. */
2141 1.1.1.7 christos if (bfd_read (ab, 8, nbfd) != 8)
2142 1.1.1.7 christos goto error_return;
2143 1.1.1.7 christos size = H_GET_64 (nbfd, ab);
2144 1.1.1.7 christos
2145 1.1 christos /* The decompression algorithm will at most expand by eight times. */
2146 1.1 christos filesize = bfd_get_file_size (archive);
2147 1.1 christos if (filesize != 0 && size / 8 > filesize)
2148 1.1 christos {
2149 1.1 christos bfd_set_error (bfd_error_malformed_archive);
2150 1.1 christos goto error_return;
2151 1.1 christos }
2152 1.1 christos
2153 1.1 christos if (size != 0)
2154 1.1 christos {
2155 1.1 christos bfd_size_type left;
2156 1.1 christos bfd_byte dict[4096];
2157 1.1 christos unsigned int h;
2158 1.1 christos bfd_byte b;
2159 1.1 christos
2160 1.1.1.9 christos buf = (bfd_byte *) bfd_malloc (size);
2161 1.1 christos if (buf == NULL)
2162 1.1 christos goto error_return;
2163 1.1 christos p = buf;
2164 1.1 christos
2165 1.1 christos left = size;
2166 1.1 christos
2167 1.1 christos /* I don't know what the next eight bytes are for. */
2168 1.1 christos if (bfd_read (ab, 8, nbfd) != 8)
2169 1.1 christos goto error_return;
2170 1.1 christos
2171 1.1.1.9 christos /* This is the uncompression algorithm. It's a simple
2172 1.1 christos dictionary based scheme in which each character is predicted
2173 1.1 christos by a hash of the previous three characters. A control byte
2174 1.1 christos indicates whether the character is predicted or whether it
2175 1.1 christos appears in the input stream; each control byte manages the
2176 1.1 christos next eight bytes in the output stream. */
2177 1.1 christos memset (dict, 0, sizeof dict);
2178 1.1 christos h = 0;
2179 1.1 christos while (bfd_read (&b, 1, nbfd) == 1)
2180 1.1 christos {
2181 1.1 christos unsigned int i;
2182 1.1 christos
2183 1.1.1.9 christos for (i = 0; i < 8; i++, b >>= 1)
2184 1.1 christos {
2185 1.1 christos bfd_byte n;
2186 1.1 christos
2187 1.1 christos if ((b & 1) == 0)
2188 1.1 christos n = dict[h];
2189 1.1 christos else
2190 1.1 christos {
2191 1.1 christos if (bfd_read (&n, 1, nbfd) != 1)
2192 1.1 christos goto error_return;
2193 1.1 christos dict[h] = n;
2194 1.1 christos }
2195 1.1 christos
2196 1.1 christos *p++ = n;
2197 1.1 christos
2198 1.1 christos --left;
2199 1.1 christos if (left == 0)
2200 1.1 christos break;
2201 1.1 christos
2202 1.1 christos h <<= 4;
2203 1.1 christos h ^= n;
2204 1.1 christos h &= sizeof dict - 1;
2205 1.1 christos }
2206 1.1 christos
2207 1.1 christos if (left == 0)
2208 1.1 christos break;
2209 1.1 christos }
2210 1.1 christos }
2211 1.1 christos
2212 1.1.1.8 christos /* Now the uncompressed file contents are in buf. */
2213 1.1 christos bim = ((struct bfd_in_memory *)
2214 1.1 christos bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory)));
2215 1.1 christos if (bim == NULL)
2216 1.1.1.2 christos goto error_return;
2217 1.1 christos bim->size = size;
2218 1.1 christos bim->buffer = buf;
2219 1.1.1.9 christos
2220 1.1 christos nbfd->mtime_set = true;
2221 1.1 christos nbfd->mtime = strtol (hdr->ar_date, (char **) NULL, 10);
2222 1.1 christos
2223 1.1 christos nbfd->flags |= BFD_IN_MEMORY;
2224 1.1 christos nbfd->iostream = bim;
2225 1.1.1.7 christos nbfd->iovec = &_bfd_memory_iovec;
2226 1.1 christos nbfd->origin = 0;
2227 1.1 christos nbfd->size = 0;
2228 1.1 christos BFD_ASSERT (! nbfd->cacheable);
2229 1.1 christos
2230 1.1 christos return nbfd;
2231 1.1 christos
2232 1.1 christos error_return:
2233 1.1 christos free (buf);
2234 1.1.1.2 christos if (nbfd != NULL)
2235 1.1 christos bfd_close (nbfd);
2236 1.1.1.4 christos return NULL;
2237 1.1 christos }
2238 1.1 christos
2239 1.1 christos /* Open the next archived file. */
2240 1.1 christos
2241 1.1 christos static bfd *
2242 1.1 christos alpha_ecoff_openr_next_archived_file (bfd *archive, bfd *last_file)
2243 1.1 christos {
2244 1.1 christos ufile_ptr filestart;
2245 1.1 christos
2246 1.1 christos if (last_file == NULL)
2247 1.1.1.6 christos filestart = bfd_ardata (archive)->first_file_filepos;
2248 1.1 christos else
2249 1.1 christos {
2250 1.1 christos struct areltdata *t;
2251 1.1 christos struct ar_hdr *h;
2252 1.1 christos bfd_size_type size;
2253 1.1 christos
2254 1.1 christos /* We can't use arelt_size here, because that uses parsed_size,
2255 1.1 christos which is the uncompressed size. We need the compressed size. */
2256 1.1 christos t = (struct areltdata *) last_file->arelt_data;
2257 1.1.1.4 christos h = (struct ar_hdr *) t->arch_header;
2258 1.1.1.4 christos size = strtol (h->ar_size, (char **) NULL, 10);
2259 1.1.1.4 christos
2260 1.1.1.4 christos /* Pad to an even boundary...
2261 1.1.1.4 christos Note that last_file->origin can be odd in the case of
2262 1.1.1.4 christos BSD-4.4-style element with a long odd size. */
2263 1.1 christos filestart = last_file->proxy_origin + size;
2264 1.1 christos filestart += filestart % 2;
2265 1.1.1.8 christos if (filestart < last_file->proxy_origin)
2266 1.1 christos {
2267 1.1 christos /* Prevent looping. See PR19256. */
2268 1.1 christos bfd_set_error (bfd_error_malformed_archive);
2269 1.1 christos return NULL;
2270 1.1 christos }
2271 1.1 christos }
2272 1.1 christos
2273 1.1 christos return alpha_ecoff_get_elt_at_filepos (archive, filestart, NULL);
2274 1.1 christos }
2275 1.1 christos
2276 1.1.1.8 christos /* Open the archive file given an index into the armap. */
2277 1.1.1.8 christos
2278 1.1 christos static bfd *
2279 1.1.1.6 christos alpha_ecoff_get_elt_at_index (bfd *abfd, symindex sym_index)
2280 1.1.1.6 christos {
2281 1.1.1.6 christos carsym *entry;
2282 1.1.1.6 christos
2283 1.1.1.6 christos entry = bfd_ardata (abfd)->symdefs + sym_index;
2284 1.1.1.6 christos return alpha_ecoff_get_elt_at_filepos (abfd, entry->file_offset,
2285 1.1.1.6 christos NULL);
2286 1.1.1.6 christos }
2287 1.1.1.6 christos
2288 1.1.1.6 christos static void
2289 1.1.1.6 christos alpha_ecoff_swap_coff_aux_in (bfd *abfd ATTRIBUTE_UNUSED,
2290 1.1.1.6 christos void *ext1 ATTRIBUTE_UNUSED,
2291 1.1.1.6 christos int type ATTRIBUTE_UNUSED,
2292 1.1.1.6 christos int in_class ATTRIBUTE_UNUSED,
2293 1.1.1.6 christos int indx ATTRIBUTE_UNUSED,
2294 1.1.1.6 christos int numaux ATTRIBUTE_UNUSED,
2295 1.1.1.6 christos void *in1 ATTRIBUTE_UNUSED)
2296 1.1.1.6 christos {
2297 1.1.1.6 christos }
2298 1.1.1.6 christos
2299 1.1.1.6 christos static void
2300 1.1.1.6 christos alpha_ecoff_swap_coff_sym_in (bfd *abfd ATTRIBUTE_UNUSED,
2301 1.1.1.6 christos void *ext1 ATTRIBUTE_UNUSED,
2302 1.1.1.6 christos void *in1 ATTRIBUTE_UNUSED)
2303 1.1.1.6 christos {
2304 1.1.1.6 christos }
2305 1.1.1.6 christos
2306 1.1.1.6 christos static void
2307 1.1.1.6 christos alpha_ecoff_swap_coff_lineno_in (bfd *abfd ATTRIBUTE_UNUSED,
2308 1.1.1.6 christos void *ext1 ATTRIBUTE_UNUSED,
2309 1.1.1.6 christos void *in1 ATTRIBUTE_UNUSED)
2310 1.1.1.6 christos {
2311 1.1.1.6 christos }
2312 1.1.1.6 christos
2313 1.1.1.6 christos static unsigned int
2314 1.1.1.6 christos alpha_ecoff_swap_coff_aux_out (bfd *abfd ATTRIBUTE_UNUSED,
2315 1.1.1.6 christos void *inp ATTRIBUTE_UNUSED,
2316 1.1.1.6 christos int type ATTRIBUTE_UNUSED,
2317 1.1.1.6 christos int in_class ATTRIBUTE_UNUSED,
2318 1.1.1.6 christos int indx ATTRIBUTE_UNUSED,
2319 1.1.1.6 christos int numaux ATTRIBUTE_UNUSED,
2320 1.1.1.6 christos void *extp ATTRIBUTE_UNUSED)
2321 1.1.1.6 christos {
2322 1.1.1.6 christos return 0;
2323 1.1.1.6 christos }
2324 1.1.1.6 christos
2325 1.1.1.6 christos static unsigned int
2326 1.1.1.6 christos alpha_ecoff_swap_coff_sym_out (bfd *abfd ATTRIBUTE_UNUSED,
2327 1.1.1.6 christos void *inp ATTRIBUTE_UNUSED,
2328 1.1.1.6 christos void *extp ATTRIBUTE_UNUSED)
2329 1.1.1.6 christos {
2330 1.1.1.6 christos return 0;
2331 1.1.1.6 christos }
2332 1.1.1.6 christos
2333 1.1.1.6 christos static unsigned int
2334 1.1.1.6 christos alpha_ecoff_swap_coff_lineno_out (bfd *abfd ATTRIBUTE_UNUSED,
2335 1.1.1.6 christos void *inp ATTRIBUTE_UNUSED,
2336 1.1.1.6 christos void *extp ATTRIBUTE_UNUSED)
2337 1.1.1.6 christos {
2338 1.1.1.6 christos return 0;
2339 1.1.1.6 christos }
2340 1.1 christos
2341 1.1 christos static unsigned int
2342 1.1 christos alpha_ecoff_swap_coff_reloc_out (bfd *abfd ATTRIBUTE_UNUSED,
2343 1.1 christos void *inp ATTRIBUTE_UNUSED,
2344 1.1 christos void *extp ATTRIBUTE_UNUSED)
2345 1.1 christos {
2346 1.1 christos return 0;
2347 1.1 christos }
2348 1.1.1.6 christos
2349 1.1.1.6 christos /* This is the ECOFF backend structure. The backend field of the
2351 1.1.1.6 christos target vector points to this. */
2352 1.1 christos
2353 1.1 christos static const struct ecoff_backend_data alpha_ecoff_backend_data =
2354 1.1.1.8 christos {
2355 1.1.1.8 christos /* COFF backend structure. */
2356 1.1 christos {
2357 1.1 christos alpha_ecoff_swap_coff_aux_in, alpha_ecoff_swap_coff_sym_in,
2358 1.1 christos alpha_ecoff_swap_coff_lineno_in, alpha_ecoff_swap_coff_aux_out,
2359 1.1 christos alpha_ecoff_swap_coff_sym_out, alpha_ecoff_swap_coff_lineno_out,
2360 1.1 christos alpha_ecoff_swap_coff_reloc_out,
2361 1.1 christos alpha_ecoff_swap_filehdr_out, alpha_ecoff_swap_aouthdr_out,
2362 1.1 christos alpha_ecoff_swap_scnhdr_out,
2363 1.1 christos FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, true,
2364 1.1 christos ECOFF_NO_LONG_SECTION_NAMES, 4, false, 2, 32768,
2365 1.1 christos alpha_ecoff_swap_filehdr_in, alpha_ecoff_swap_aouthdr_in,
2366 1.1 christos alpha_ecoff_swap_scnhdr_in, NULL,
2367 1.1 christos alpha_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
2368 1.1 christos alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
2369 1.1 christos _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
2370 1.1 christos NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2371 1.1 christos NULL, NULL, NULL, NULL
2372 1.1 christos },
2373 1.1 christos /* Supported architecture. */
2374 1.1.1.8 christos bfd_arch_alpha,
2375 1.1 christos /* Initial portion of armap string. */
2376 1.1 christos "________64",
2377 1.1 christos /* The page boundary used to align sections in a demand-paged
2378 1.1 christos executable file. E.g., 0x1000. */
2379 1.1 christos 0x2000,
2380 1.1 christos /* TRUE if the .rdata section is part of the text segment, as on the
2381 1.1 christos Alpha. FALSE if .rdata is part of the data segment, as on the
2382 1.1 christos MIPS. */
2383 1.1 christos true,
2384 1.1 christos /* Bitsize of constructor entries. */
2385 1.1 christos 64,
2386 1.1 christos /* Reloc to use for constructor entries. */
2387 1.1 christos &alpha_howto_table[ALPHA_R_REFQUAD],
2388 1.1 christos {
2389 1.1 christos /* Symbol table magic number. */
2390 1.1 christos magicSym2,
2391 1.1 christos /* Alignment of debugging information. E.g., 4. */
2392 1.1 christos 8,
2393 1.1 christos /* Sizes of external symbolic information. */
2394 1.1 christos sizeof (struct hdr_ext),
2395 1.1 christos sizeof (struct dnr_ext),
2396 1.1 christos sizeof (struct pdr_ext),
2397 1.1 christos sizeof (struct sym_ext),
2398 1.1 christos sizeof (struct opt_ext),
2399 1.1 christos sizeof (struct fdr_ext),
2400 1.1 christos sizeof (struct rfd_ext),
2401 1.1 christos sizeof (struct ext_ext),
2402 1.1 christos /* Functions to swap in external symbolic data. */
2403 1.1 christos ecoff_swap_hdr_in,
2404 1.1 christos ecoff_swap_dnr_in,
2405 1.1 christos ecoff_swap_pdr_in,
2406 1.1 christos ecoff_swap_sym_in,
2407 1.1 christos ecoff_swap_opt_in,
2408 1.1 christos ecoff_swap_fdr_in,
2409 1.1 christos ecoff_swap_rfd_in,
2410 1.1 christos ecoff_swap_ext_in,
2411 1.1 christos _bfd_ecoff_swap_tir_in,
2412 1.1 christos _bfd_ecoff_swap_rndx_in,
2413 1.1 christos /* Functions to swap out external symbolic data. */
2414 1.1 christos ecoff_swap_hdr_out,
2415 1.1 christos ecoff_swap_dnr_out,
2416 1.1 christos ecoff_swap_pdr_out,
2417 1.1 christos ecoff_swap_sym_out,
2418 1.1 christos ecoff_swap_opt_out,
2419 1.1 christos ecoff_swap_fdr_out,
2420 1.1 christos ecoff_swap_rfd_out,
2421 1.1 christos ecoff_swap_ext_out,
2422 1.1 christos _bfd_ecoff_swap_tir_out,
2423 1.1 christos _bfd_ecoff_swap_rndx_out,
2424 1.1 christos /* Function to read in symbolic data. */
2425 1.1 christos _bfd_ecoff_slurp_symbolic_info
2426 1.1 christos },
2427 1.1 christos /* External reloc size. */
2428 1.1 christos RELSZ,
2429 1.1 christos /* Reloc swapping functions. */
2430 1.1 christos alpha_ecoff_swap_reloc_in,
2431 1.1 christos alpha_ecoff_swap_reloc_out,
2432 1.1 christos /* Backend reloc tweaking. */
2433 1.1 christos alpha_adjust_reloc_in,
2434 1.1 christos alpha_adjust_reloc_out,
2435 1.1 christos /* Relocate section contents while linking. */
2436 1.1 christos alpha_relocate_section,
2437 1.1 christos /* Do final adjustments to filehdr and aouthdr. */
2438 1.1 christos alpha_adjust_headers,
2439 1.1 christos /* Read an element from an archive at a given file position. */
2440 1.1 christos alpha_ecoff_get_elt_at_filepos
2441 1.1 christos };
2442 1.1 christos
2443 1.1.1.2 christos /* Looking up a reloc type is Alpha specific. */
2444 1.1.1.2 christos #define _bfd_ecoff_bfd_reloc_type_lookup alpha_bfd_reloc_type_lookup
2445 1.1.1.2 christos #define _bfd_ecoff_bfd_reloc_name_lookup \
2446 1.1 christos alpha_bfd_reloc_name_lookup
2447 1.1 christos
2448 1.1 christos /* So is getting relocated section contents. */
2449 1.1 christos #define _bfd_ecoff_bfd_get_relocated_section_contents \
2450 1.1 christos alpha_ecoff_get_relocated_section_contents
2451 1.1.1.7 christos
2452 1.1 christos /* Input section flag lookup is generic. */
2453 1.1 christos #define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
2454 1.1.1.2 christos
2455 1.1 christos /* Relaxing sections is generic. */
2456 1.1.1.6 christos #define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
2457 1.1.1.6 christos #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
2458 1.1.1.4 christos #define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
2459 1.1 christos #define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
2460 1.1.1.6 christos #define _bfd_ecoff_bfd_group_name bfd_generic_group_name
2461 1.1.1.6 christos #define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
2462 1.1.1.6 christos #define _bfd_ecoff_section_already_linked \
2463 1.1.1.3 christos _bfd_coff_section_already_linked
2464 1.1 christos #define _bfd_ecoff_bfd_define_common_symbol bfd_generic_define_common_symbol
2465 1.1 christos #define _bfd_ecoff_bfd_link_hide_symbol _bfd_generic_link_hide_symbol
2466 1.1 christos #define _bfd_ecoff_bfd_define_start_stop bfd_generic_define_start_stop
2467 1.1 christos #define _bfd_ecoff_bfd_link_check_relocs _bfd_generic_link_check_relocs
2468 1.1 christos
2469 1.1 christos /* Installing internal relocations in a section is also generic. */
2470 1.1.1.6 christos #define _bfd_ecoff_set_reloc _bfd_generic_set_reloc
2471 1.1.1.6 christos
2472 1.1.1.6 christos const bfd_target alpha_ecoff_le_vec =
2473 1.1 christos {
2474 1.1.1.7 christos "ecoff-littlealpha", /* name */
2475 1.1.1.7 christos bfd_target_ecoff_flavour,
2476 1.1 christos BFD_ENDIAN_LITTLE, /* data byte order is little */
2477 1.1 christos BFD_ENDIAN_LITTLE, /* header byte order is little */
2478 1.1 christos
2479 1.1.1.2 christos (HAS_RELOC | EXEC_P /* object flags */
2480 1.1.1.8 christos | HAS_LINENO | HAS_DEBUG
2481 1.1 christos | HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
2482 1.1 christos
2483 1.1 christos (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE
2484 1.1 christos | SEC_DATA | SEC_SMALL_DATA),
2485 1.1 christos 0, /* leading underscore */
2486 1.1 christos ' ', /* ar_pad_char */
2487 1.1 christos 15, /* ar_max_namelen */
2488 1.1.1.6 christos 0, /* match priority. */
2489 1.1.1.6 christos TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */
2490 1.1.1.6 christos bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2491 1.1.1.6 christos bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2492 1.1.1.6 christos bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
2493 1.1.1.6 christos bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2494 1.1.1.6 christos bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2495 1.1.1.6 christos bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
2496 1.1.1.6 christos
2497 1.1.1.6 christos { /* bfd_check_format */
2498 1.1.1.6 christos _bfd_dummy_target,
2499 1.1.1.6 christos alpha_ecoff_object_p,
2500 1.1.1.6 christos bfd_generic_archive_p,
2501 1.1.1.6 christos _bfd_dummy_target
2502 1.1.1.6 christos },
2503 1.1.1.6 christos { /* bfd_set_format */
2504 1.1.1.6 christos _bfd_bool_bfd_false_error,
2505 1.1.1.6 christos _bfd_ecoff_mkobject,
2506 1.1.1.6 christos _bfd_generic_mkarchive,
2507 1.1.1.6 christos _bfd_bool_bfd_false_error
2508 1.1.1.6 christos },
2509 1.1.1.6 christos { /* bfd_write_contents */
2510 1.1.1.6 christos _bfd_bool_bfd_false_error,
2511 1.1.1.6 christos _bfd_ecoff_write_object_contents,
2512 1.1.1.6 christos _bfd_write_archive_contents,
2513 1.1.1.6 christos _bfd_bool_bfd_false_error
2514 1.1.1.6 christos },
2515 1.1.1.6 christos
2516 1.1 christos BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
2517 1.1 christos BFD_JUMP_TABLE_COPY (_bfd_ecoff),
2518 1.1 christos BFD_JUMP_TABLE_CORE (_bfd_nocore),
2519 1.1.1.6 christos BFD_JUMP_TABLE_ARCHIVE (alpha_ecoff),
2520 1.1 christos BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
2521 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
2522 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
2523 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
2524 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2525
2526 NULL,
2527
2528 &alpha_ecoff_backend_data
2529 };
2530