1 /* BFD back-end for Intel 386 COFF files.
2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3 Written by Cygnus Support.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25 #include "coff/i386.h"
26 #include "coff/internal.h"
29 static bfd_reloc_status_type coff_i386_reloc PARAMS ((bfd *abfd,
33 asection *input_section,
36 /* For some reason when using i386 COFF the value stored in the .text
37 section for a reference to a common symbol is the value itself plus
38 any desired offset. Ian Taylor, Cygnus Support. */
40 /* If we are producing relocateable output, we need to do some
41 adjustments to the object file that are not done by the
42 bfd_perform_relocation function. This function is called by every
43 reloc type to make any required adjustments. */
45 static bfd_reloc_status_type
46 coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd)
51 asection *input_section;
56 if (output_bfd == (bfd *) NULL)
57 return bfd_reloc_continue;
59 if (bfd_is_com_section (symbol->section))
61 /* We are relocating a common symbol. The current value in the
62 object file is ORIG + OFFSET, where ORIG is the value of the
63 common symbol as seen by the object file when it was compiled
64 (this may be zero if the symbol was undefined) and OFFSET is
65 the offset into the common symbol (normally zero, but may be
66 non-zero when referring to a field in a common structure).
67 ORIG is the negative of reloc_entry->addend, which is set by
68 the CALC_ADDEND macro below. We want to replace the value in
69 the object file with NEW + OFFSET, where NEW is the value of
70 the common symbol which we are going to put in the final
71 object file. NEW is symbol->value. */
72 diff = symbol->value + reloc_entry->addend;
76 /* For some reason bfd_perform_relocation always effectively
77 ignores the addend for a COFF target when producing
78 relocateable output. This seems to be always wrong for 386
79 COFF, so we handle the addend here instead. */
80 diff = reloc_entry->addend;
84 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
88 reloc_howto_type *howto = reloc_entry->howto;
89 unsigned char *addr = (unsigned char *) data + reloc_entry->address;
95 char x = bfd_get_8 (abfd, addr);
97 bfd_put_8 (abfd, x, addr);
103 short x = bfd_get_16 (abfd, addr);
105 bfd_put_16 (abfd, x, addr);
111 long x = bfd_get_32 (abfd, addr);
113 bfd_put_32 (abfd, x, addr);
122 /* Now let bfd_perform_relocation finish everything up. */
123 return bfd_reloc_continue;
126 static reloc_howto_type howto_table[] =
134 HOWTO (R_DIR32, /* type */
136 2, /* size (0 = byte, 1 = short, 2 = long) */
138 false, /* pc_relative */
140 complain_overflow_bitfield, /* complain_on_overflow */
141 coff_i386_reloc, /* special_function */
143 true, /* partial_inplace */
144 0xffffffff, /* src_mask */
145 0xffffffff, /* dst_mask */
146 false), /* pcrel_offset */
155 HOWTO (R_RELBYTE, /* type */
157 0, /* size (0 = byte, 1 = short, 2 = long) */
159 false, /* pc_relative */
161 complain_overflow_bitfield, /* complain_on_overflow */
162 coff_i386_reloc, /* special_function */
164 true, /* partial_inplace */
165 0x000000ff, /* src_mask */
166 0x000000ff, /* dst_mask */
167 false), /* pcrel_offset */
168 HOWTO (R_RELWORD, /* type */
170 1, /* size (0 = byte, 1 = short, 2 = long) */
172 false, /* pc_relative */
174 complain_overflow_bitfield, /* complain_on_overflow */
175 coff_i386_reloc, /* special_function */
177 true, /* partial_inplace */
178 0x0000ffff, /* src_mask */
179 0x0000ffff, /* dst_mask */
180 false), /* pcrel_offset */
181 HOWTO (R_RELLONG, /* type */
183 2, /* size (0 = byte, 1 = short, 2 = long) */
185 false, /* pc_relative */
187 complain_overflow_bitfield, /* complain_on_overflow */
188 coff_i386_reloc, /* special_function */
190 true, /* partial_inplace */
191 0xffffffff, /* src_mask */
192 0xffffffff, /* dst_mask */
193 false), /* pcrel_offset */
194 HOWTO (R_PCRBYTE, /* type */
196 0, /* size (0 = byte, 1 = short, 2 = long) */
198 true, /* pc_relative */
200 complain_overflow_signed, /* complain_on_overflow */
201 coff_i386_reloc, /* special_function */
203 true, /* partial_inplace */
204 0x000000ff, /* src_mask */
205 0x000000ff, /* dst_mask */
206 false), /* pcrel_offset */
207 HOWTO (R_PCRWORD, /* type */
209 1, /* size (0 = byte, 1 = short, 2 = long) */
211 true, /* pc_relative */
213 complain_overflow_signed, /* complain_on_overflow */
214 coff_i386_reloc, /* special_function */
216 true, /* partial_inplace */
217 0x0000ffff, /* src_mask */
218 0x0000ffff, /* dst_mask */
219 false), /* pcrel_offset */
220 HOWTO (R_PCRLONG, /* type */
222 2, /* size (0 = byte, 1 = short, 2 = long) */
224 true, /* pc_relative */
226 complain_overflow_signed, /* complain_on_overflow */
227 coff_i386_reloc, /* special_function */
229 true, /* partial_inplace */
230 0xffffffff, /* src_mask */
231 0xffffffff, /* dst_mask */
232 false) /* pcrel_offset */
235 /* Turn a howto into a reloc nunmber */
237 #define SELECT_RELOC(x,howto) { x = howto->type; }
238 #define BADMAG(x) I386BADMAG(x)
239 #define I386 1 /* Customize coffcode.h */
241 #define RTYPE2HOWTO(cache_ptr, dst) \
242 cache_ptr->howto = howto_table + (dst)->r_type;
244 /* On SCO Unix 3.2.2 the native assembler generates two .data
245 sections. We handle that by renaming the second one to .data2. It
246 does no harm to do this for any 386 COFF target. */
247 #define TWO_DATA_SECS
249 /* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
250 library. On some other COFF targets STYP_BSS is normally
252 #define BSS_NOLOAD_IS_SHARED_LIBRARY
254 /* Compute the addend of a reloc. If the reloc is to a common symbol,
255 the object file contains the value of the common symbol. By the
256 time this is called, the linker may be using a different symbol
257 from a different object file with a different value. Therefore, we
258 hack wildly to locate the original symbol from this file so that we
259 can make the correct adjustment. This macro sets coffsym to the
260 symbol from the original file, and uses it to set the addend value
261 correctly. If this is not a common symbol, the usual addend
262 calculation is done, except that an additional tweak is needed for
264 FIXME: This macro refers to symbols and asect; these are from the
265 calling function, not the macro arguments. */
267 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
269 coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
270 if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
271 coffsym = (obj_symbols (abfd) \
272 + (cache_ptr->sym_ptr_ptr - symbols)); \
274 coffsym = coff_symbol_from (abfd, ptr); \
275 if (coffsym != (coff_symbol_type *) NULL \
276 && coffsym->native->u.syment.n_scnum == 0) \
277 cache_ptr->addend = - coffsym->native->u.syment.n_value; \
278 else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
279 && ptr->section != (asection *) NULL) \
280 cache_ptr->addend = - (ptr->section->vma + ptr->value); \
282 cache_ptr->addend = 0; \
283 if (ptr && howto_table[reloc.r_type].pc_relative) \
284 cache_ptr->addend += asect->vma; \
287 /* For aix386, define a variable to track the number of sections discarded
290 #if defined(_AIX) && defined(_I386)
291 #define USE_DISCARDED_SECTIONS_COUNT
292 int discarded_sections_count = 0;
295 #include "coffcode.h"
301 return coff_object_p(a);
314 "coff-i386", /* name */
316 bfd_target_coff_flavour,
317 false, /* data byte order is little */
318 false, /* header byte order is little */
320 (HAS_RELOC | EXEC_P | /* object flags */
321 HAS_LINENO | HAS_DEBUG |
322 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
324 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
325 0, /* leading underscore */
326 '/', /* ar_pad_char */
327 15, /* ar_max_namelen */
329 2, /* minimum alignment power */
330 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
331 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
332 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
333 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
334 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
335 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
337 /* Note that we allow an object file to be treated as a core file as well. */
338 {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */
339 bfd_generic_archive_p, i3coff_object_p},
340 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
342 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
343 _bfd_write_archive_contents, bfd_false},