* coff-h8300.c (COFF_LONG_FILENAMES): Define.
[deliverable/binutils-gdb.git] / bfd / coff-i386.c
CommitLineData
6a469027 1/* BFD back-end for Intel 386 COFF files.
89665c85 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
6a469027 3 Written by Cygnus Support.
517496c5 4
6a469027 5This file is part of BFD, the Binary File Descriptor library.
517496c5 6
6a469027 7This program is free software; you can redistribute it and/or modify
517496c5 8it under the terms of the GNU General Public License as published by
6a469027
JG
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
517496c5 11
6a469027 12This program is distributed in the hope that it will be useful,
517496c5
SC
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
6a469027
JG
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
517496c5 20
517496c5 21#include "bfd.h"
3b4f1a5d 22#include "sysdep.h"
517496c5
SC
23#include "libbfd.h"
24#include "obstack.h"
89665c85 25
294eaca4 26#include "coff/i386.h"
89665c85 27
294eaca4 28#include "coff/internal.h"
89665c85
SC
29
30#ifdef COFF_WITH_PE
31#include "coff/pe.h"
32#endif
33
517496c5
SC
34#include "libcoff.h"
35
82b1edf7
KR
36static bfd_reloc_status_type coff_i386_reloc
37 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
89665c85 38static reloc_howto_type *coff_i386_rtype_to_howto
82b1edf7
KR
39 PARAMS ((bfd *, asection *, struct internal_reloc *,
40 struct coff_link_hash_entry *, struct internal_syment *,
89665c85 41
82b1edf7
KR
42 bfd_vma *));
43
44#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
82b1edf7
KR
45/* The page size is a guess based on ELF. */
46#define COFF_PAGE_SIZE 0x1000
48ee0757
SS
47
48/* For some reason when using i386 COFF the value stored in the .text
49 section for a reference to a common symbol is the value itself plus
50 any desired offset. Ian Taylor, Cygnus Support. */
51
52/* If we are producing relocateable output, we need to do some
53 adjustments to the object file that are not done by the
54 bfd_perform_relocation function. This function is called by every
55 reloc type to make any required adjustments. */
56
57static bfd_reloc_status_type
6812b607
ILT
58coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
59 error_message)
48ee0757
SS
60 bfd *abfd;
61 arelent *reloc_entry;
62 asymbol *symbol;
63 PTR data;
64 asection *input_section;
65 bfd *output_bfd;
6812b607 66 char **error_message;
48ee0757
SS
67{
68 symvalue diff;
69
70 if (output_bfd == (bfd *) NULL)
71 return bfd_reloc_continue;
72
73 if (bfd_is_com_section (symbol->section))
74 {
75 /* We are relocating a common symbol. The current value in the
76 object file is ORIG + OFFSET, where ORIG is the value of the
77 common symbol as seen by the object file when it was compiled
78 (this may be zero if the symbol was undefined) and OFFSET is
79 the offset into the common symbol (normally zero, but may be
80 non-zero when referring to a field in a common structure).
81 ORIG is the negative of reloc_entry->addend, which is set by
82 the CALC_ADDEND macro below. We want to replace the value in
83 the object file with NEW + OFFSET, where NEW is the value of
84 the common symbol which we are going to put in the final
85 object file. NEW is symbol->value. */
86 diff = symbol->value + reloc_entry->addend;
87 }
88 else
89 {
90 /* For some reason bfd_perform_relocation always effectively
91 ignores the addend for a COFF target when producing
92 relocateable output. This seems to be always wrong for 386
93 COFF, so we handle the addend here instead. */
94 diff = reloc_entry->addend;
95 }
96
97#define DOIT(x) \
98 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
99
100 if (diff != 0)
101 {
82b1edf7 102 reloc_howto_type *howto = reloc_entry->howto;
48ee0757
SS
103 unsigned char *addr = (unsigned char *) data + reloc_entry->address;
104
105 switch (howto->size)
106 {
107 case 0:
108 {
109 char x = bfd_get_8 (abfd, addr);
110 DOIT (x);
111 bfd_put_8 (abfd, x, addr);
112 }
113 break;
114
115 case 1:
116 {
117 short x = bfd_get_16 (abfd, addr);
118 DOIT (x);
119 bfd_put_16 (abfd, x, addr);
120 }
121 break;
122
123 case 2:
124 {
125 long x = bfd_get_32 (abfd, addr);
126 DOIT (x);
127 bfd_put_32 (abfd, x, addr);
128 }
129 break;
130
131 default:
132 abort ();
133 }
134 }
135
136 /* Now let bfd_perform_relocation finish everything up. */
137 return bfd_reloc_continue;
138}
517496c5 139
89665c85
SC
140
141
142#ifndef PCRELOFFSET
143#define PCRELOFFSET false
144#endif
145
517496c5
SC
146static reloc_howto_type howto_table[] =
147{
48ee0757
SS
148 {0},
149 {1},
150 {2},
151 {3},
152 {4},
153 {5},
154 HOWTO (R_DIR32, /* type */
89665c85
SC
155 0, /* rightshift */
156 2, /* size (0 = byte, 1 = short, 2 = long) */
157 32, /* bitsize */
158 false, /* pc_relative */
159 0, /* bitpos */
160 complain_overflow_bitfield, /* complain_on_overflow */
161 coff_i386_reloc, /* special_function */
162 "dir32", /* name */
163 true, /* partial_inplace */
164 0xffffffff, /* src_mask */
165 0xffffffff, /* dst_mask */
166 true), /* pcrel_offset */
167 /* {7}, */
168 HOWTO (7, /* type */
48ee0757
SS
169 0, /* rightshift */
170 2, /* size (0 = byte, 1 = short, 2 = long) */
171 32, /* bitsize */
172 false, /* pc_relative */
173 0, /* bitpos */
174 complain_overflow_bitfield, /* complain_on_overflow */
175 coff_i386_reloc, /* special_function */
176 "dir32", /* name */
177 true, /* partial_inplace */
178 0xffffffff, /* src_mask */
179 0xffffffff, /* dst_mask */
180 false), /* pcrel_offset */
48ee0757
SS
181 {010},
182 {011},
183 {012},
184 {013},
185 {014},
186 {015},
187 {016},
188 HOWTO (R_RELBYTE, /* type */
189 0, /* rightshift */
190 0, /* size (0 = byte, 1 = short, 2 = long) */
191 8, /* bitsize */
192 false, /* pc_relative */
193 0, /* bitpos */
194 complain_overflow_bitfield, /* complain_on_overflow */
195 coff_i386_reloc, /* special_function */
196 "8", /* name */
197 true, /* partial_inplace */
198 0x000000ff, /* src_mask */
199 0x000000ff, /* dst_mask */
89665c85 200 PCRELOFFSET), /* pcrel_offset */
48ee0757
SS
201 HOWTO (R_RELWORD, /* type */
202 0, /* rightshift */
203 1, /* size (0 = byte, 1 = short, 2 = long) */
204 16, /* bitsize */
205 false, /* pc_relative */
206 0, /* bitpos */
207 complain_overflow_bitfield, /* complain_on_overflow */
208 coff_i386_reloc, /* special_function */
209 "16", /* name */
210 true, /* partial_inplace */
211 0x0000ffff, /* src_mask */
212 0x0000ffff, /* dst_mask */
89665c85 213 PCRELOFFSET), /* pcrel_offset */
48ee0757
SS
214 HOWTO (R_RELLONG, /* type */
215 0, /* rightshift */
216 2, /* size (0 = byte, 1 = short, 2 = long) */
217 32, /* bitsize */
218 false, /* pc_relative */
219 0, /* bitpos */
220 complain_overflow_bitfield, /* complain_on_overflow */
221 coff_i386_reloc, /* special_function */
222 "32", /* name */
223 true, /* partial_inplace */
224 0xffffffff, /* src_mask */
225 0xffffffff, /* dst_mask */
89665c85 226 PCRELOFFSET), /* pcrel_offset */
48ee0757
SS
227 HOWTO (R_PCRBYTE, /* type */
228 0, /* rightshift */
229 0, /* size (0 = byte, 1 = short, 2 = long) */
230 8, /* bitsize */
231 true, /* pc_relative */
232 0, /* bitpos */
233 complain_overflow_signed, /* complain_on_overflow */
234 coff_i386_reloc, /* special_function */
235 "DISP8", /* name */
236 true, /* partial_inplace */
237 0x000000ff, /* src_mask */
238 0x000000ff, /* dst_mask */
89665c85 239 PCRELOFFSET), /* pcrel_offset */
48ee0757
SS
240 HOWTO (R_PCRWORD, /* type */
241 0, /* rightshift */
242 1, /* size (0 = byte, 1 = short, 2 = long) */
243 16, /* bitsize */
244 true, /* pc_relative */
245 0, /* bitpos */
246 complain_overflow_signed, /* complain_on_overflow */
247 coff_i386_reloc, /* special_function */
248 "DISP16", /* name */
249 true, /* partial_inplace */
250 0x0000ffff, /* src_mask */
251 0x0000ffff, /* dst_mask */
89665c85 252 PCRELOFFSET), /* pcrel_offset */
48ee0757
SS
253 HOWTO (R_PCRLONG, /* type */
254 0, /* rightshift */
255 2, /* size (0 = byte, 1 = short, 2 = long) */
256 32, /* bitsize */
257 true, /* pc_relative */
258 0, /* bitpos */
259 complain_overflow_signed, /* complain_on_overflow */
260 coff_i386_reloc, /* special_function */
261 "DISP32", /* name */
262 true, /* partial_inplace */
263 0xffffffff, /* src_mask */
264 0xffffffff, /* dst_mask */
89665c85 265 PCRELOFFSET) /* pcrel_offset */
517496c5
SC
266};
267
517496c5
SC
268/* Turn a howto into a reloc nunmber */
269
6812b607 270#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
517496c5 271#define BADMAG(x) I386BADMAG(x)
3b4f1a5d
SC
272#define I386 1 /* Customize coffcode.h */
273
c9301d7b 274#define RTYPE2HOWTO(cache_ptr, dst) \
82b1edf7 275 (cache_ptr)->howto = howto_table + (dst)->r_type;
3b4f1a5d 276
48ee0757
SS
277/* On SCO Unix 3.2.2 the native assembler generates two .data
278 sections. We handle that by renaming the second one to .data2. It
279 does no harm to do this for any 386 COFF target. */
280#define TWO_DATA_SECS
281
282/* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
283 library. On some other COFF targets STYP_BSS is normally
284 STYP_NOLOAD. */
285#define BSS_NOLOAD_IS_SHARED_LIBRARY
517496c5 286
48ee0757
SS
287/* Compute the addend of a reloc. If the reloc is to a common symbol,
288 the object file contains the value of the common symbol. By the
289 time this is called, the linker may be using a different symbol
290 from a different object file with a different value. Therefore, we
291 hack wildly to locate the original symbol from this file so that we
292 can make the correct adjustment. This macro sets coffsym to the
293 symbol from the original file, and uses it to set the addend value
294 correctly. If this is not a common symbol, the usual addend
295 calculation is done, except that an additional tweak is needed for
296 PC relative relocs.
297 FIXME: This macro refers to symbols and asect; these are from the
298 calling function, not the macro arguments. */
299
300#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
301 { \
302 coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
303 if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
304 coffsym = (obj_symbols (abfd) \
305 + (cache_ptr->sym_ptr_ptr - symbols)); \
306 else if (ptr) \
307 coffsym = coff_symbol_from (abfd, ptr); \
308 if (coffsym != (coff_symbol_type *) NULL \
309 && coffsym->native->u.syment.n_scnum == 0) \
310 cache_ptr->addend = - coffsym->native->u.syment.n_value; \
311 else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
312 && ptr->section != (asection *) NULL) \
313 cache_ptr->addend = - (ptr->section->vma + ptr->value); \
314 else \
315 cache_ptr->addend = 0; \
316 if (ptr && howto_table[reloc.r_type].pc_relative) \
317 cache_ptr->addend += asect->vma; \
318 }
319
82b1edf7
KR
320/* We use the special COFF backend linker. */
321#define coff_relocate_section _bfd_coff_generic_relocate_section
322
89665c85 323static reloc_howto_type *
82b1edf7
KR
324coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
325 bfd *abfd;
326 asection *sec;
327 struct internal_reloc *rel;
328 struct coff_link_hash_entry *h;
329 struct internal_syment *sym;
330 bfd_vma *addendp;
331{
89665c85
SC
332
333 reloc_howto_type *howto;
82b1edf7
KR
334
335 howto = howto_table + rel->r_type;
336
89665c85
SC
337#ifdef COFF_WITH_PE
338 *addendp = 0;
339#endif
340
82b1edf7
KR
341 if (howto->pc_relative)
342 *addendp += sec->vma;
343
344 if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
345 {
346 /* This is a common symbol. The section contents include the
347 size (sym->n_value) as an addend. The relocate_section
348 function will be adding in the final value of the symbol. We
349 need to subtract out the current size in order to get the
350 correct result. */
89665c85 351
82b1edf7 352 BFD_ASSERT (h != NULL);
89665c85
SC
353
354
355#ifndef COFF_WITH_PE
356 /* I think we *do* want to bypass this. If we don't, I have seen some data
357 parameters get the wrong relcation address. If I link two versions
358 with and without this section bypassed and then do a binary comparison,
359 the addresses which are different can be looked up in the map. The
360 case in which this section has been bypassed has addresses which correspond
361 to values I can find in the map */
82b1edf7 362 *addendp -= sym->n_value;
89665c85 363#endif
82b1edf7
KR
364 }
365
366 /* If the output symbol is common (in which case this must be a
367 relocateable link), we need to add in the final size of the
368 common symbol. */
89665c85 369 if (h != NULL && h->root.type == bfd_link_hash_common)
82b1edf7
KR
370 *addendp += h->root.u.c.size;
371
89665c85
SC
372
373#ifdef COFF_WITH_PE
374 if (howto->pc_relative)
375 *addendp -= 4;
376#endif
377
82b1edf7
KR
378 return howto;
379}
380
381#define coff_rtype_to_howto coff_i386_rtype_to_howto
382
48ee0757 383#include "coffcode.h"
517496c5 384
82b1edf7 385static const bfd_target *
cbd8493e
KR
386i3coff_object_p(a)
387 bfd *a;
388{
389 return coff_object_p(a);
390}
517496c5 391
82b1edf7 392const bfd_target
48ee0757
SS
393#ifdef TARGET_SYM
394 TARGET_SYM =
395#else
396 i386coff_vec =
397#endif
517496c5 398{
48ee0757
SS
399#ifdef TARGET_NAME
400 TARGET_NAME,
401#else
3b4f1a5d 402 "coff-i386", /* name */
48ee0757 403#endif
6a469027
JG
404 bfd_target_coff_flavour,
405 false, /* data byte order is little */
406 false, /* header byte order is little */
517496c5
SC
407
408 (HAS_RELOC | EXEC_P | /* object flags */
409 HAS_LINENO | HAS_DEBUG |
82b1edf7 410 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
517496c5
SC
411
412 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
82b1edf7
KR
413#ifdef TARGET_UNDERSCORE
414 TARGET_UNDERSCORE, /* leading underscore */
415#else
294eaca4 416 0, /* leading underscore */
82b1edf7 417#endif
517496c5
SC
418 '/', /* ar_pad_char */
419 15, /* ar_max_namelen */
420
6a469027 421 2, /* minimum alignment power */
48ee0757
SS
422 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
423 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
424 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
425 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
426 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
427 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
517496c5 428
6a469027
JG
429/* Note that we allow an object file to be treated as a core file as well. */
430 {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */
431 bfd_generic_archive_p, i3coff_object_p},
432 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
433 bfd_false},
434 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
435 _bfd_write_archive_contents, bfd_false},
517496c5 436
6812b607
ILT
437 BFD_JUMP_TABLE_GENERIC (coff),
438 BFD_JUMP_TABLE_COPY (coff),
439 BFD_JUMP_TABLE_CORE (_bfd_nocore),
440 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
441 BFD_JUMP_TABLE_SYMBOLS (coff),
442 BFD_JUMP_TABLE_RELOCS (coff),
443 BFD_JUMP_TABLE_WRITE (coff),
444 BFD_JUMP_TABLE_LINK (coff),
82b1edf7 445 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
6812b607 446
48ee0757
SS
447 COFF_SWAP_TABLE,
448};
This page took 0.149992 seconds and 4 git commands to generate.