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