1 /* BFD back-end for i386 a.out binaries under LynxOS.
2 Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20 #define BYTES_IN_WORD 4
22 #define N_SHARED_LIB(x) 0
24 #define TEXT_START_ADDR 0
25 #define PAGE_SIZE 4096
26 #define SEGMENT_SIZE PAGE_SIZE
27 #define DEFAULT_ARCH bfd_arch_i386
29 #define MY(OP) CAT(i386lynx_aout_,OP)
30 #define TARGETNAME "a.out-i386-lynx"
37 #define WRITE_HEADERS(abfd, execp) \
39 bfd_size_type text_size; /* dummy vars */ \
41 if (adata(abfd).magic == undecided_magic) \
42 NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \
44 execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \
45 execp->a_entry = bfd_get_start_address (abfd); \
47 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \
48 obj_reloc_entry_size (abfd)); \
49 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \
50 obj_reloc_entry_size (abfd)); \
51 NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \
53 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false; \
54 if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) \
57 /* Now write out reloc info, followed by syms and strings */ \
59 if (bfd_get_symcount (abfd) != 0) \
61 if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET) \
65 if (! NAME(aout,write_syms)(abfd)) return false; \
67 if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET) \
71 if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd))) \
73 if (bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET) \
77 if (!NAME(lynx,squirt_out_relocs)(abfd, obj_datasec (abfd))) \
84 #include "aout/aout64.h"
88 char *lynx_core_file_failing_command ();
89 int lynx_core_file_failing_signal ();
90 boolean
lynx_core_file_matches_executable_p ();
91 const bfd_target
*lynx_core_file_p ();
93 #define MY_core_file_failing_command lynx_core_file_failing_command
94 #define MY_core_file_failing_signal lynx_core_file_failing_signal
95 #define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
96 #define MY_core_file_p lynx_core_file_p
98 #endif /* HOST_LYNX */
103 extern reloc_howto_type aout_32_ext_howto_table
[];
104 extern reloc_howto_type aout_32_std_howto_table
[];
106 /* Standard reloc stuff */
107 /* Output standard relocation information to a file in target byte order. */
110 NAME(lynx
,swap_std_reloc_out
) (abfd
, g
, natptr
)
113 struct reloc_std_external
*natptr
;
116 asymbol
*sym
= *(g
->sym_ptr_ptr
);
118 unsigned int r_length
;
120 int r_baserel
, r_jmptable
, r_relative
;
121 unsigned int r_addend
;
122 asection
*output_section
= sym
->section
->output_section
;
124 PUT_WORD (abfd
, g
->address
, natptr
->r_address
);
126 r_length
= g
->howto
->size
; /* Size as a power of two */
127 r_pcrel
= (int) g
->howto
->pc_relative
; /* Relative to PC? */
128 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
133 r_addend
= g
->addend
+ (*(g
->sym_ptr_ptr
))->section
->output_section
->vma
;
135 /* name was clobbered by aout_write_syms to be symbol index */
137 /* If this relocation is relative to a symbol then set the
138 r_index to the symbols index, and the r_extern bit.
140 Absolute symbols can come in in two ways, either as an offset
141 from the abs section, or as a symbol which has an abs value.
146 if (bfd_is_com_section (output_section
)
147 || output_section
== &bfd_abs_section
148 || output_section
== &bfd_und_section
)
150 if (bfd_abs_section
.symbol
== sym
)
152 /* Whoops, looked like an abs symbol, but is really an offset
153 from the abs section */
161 r_index
= stoi ((*(g
->sym_ptr_ptr
))->KEEPIT
);
167 /* Just an ordinary section */
169 r_index
= output_section
->target_index
;
172 /* now the fun stuff */
173 if (abfd
->xvec
->header_byteorder_big_p
!= false)
175 natptr
->r_index
[0] = r_index
>> 16;
176 natptr
->r_index
[1] = r_index
>> 8;
177 natptr
->r_index
[2] = r_index
;
179 (r_extern
? RELOC_STD_BITS_EXTERN_BIG
: 0)
180 | (r_pcrel
? RELOC_STD_BITS_PCREL_BIG
: 0)
181 | (r_baserel
? RELOC_STD_BITS_BASEREL_BIG
: 0)
182 | (r_jmptable
? RELOC_STD_BITS_JMPTABLE_BIG
: 0)
183 | (r_relative
? RELOC_STD_BITS_RELATIVE_BIG
: 0)
184 | (r_length
<< RELOC_STD_BITS_LENGTH_SH_BIG
);
188 natptr
->r_index
[2] = r_index
>> 16;
189 natptr
->r_index
[1] = r_index
>> 8;
190 natptr
->r_index
[0] = r_index
;
192 (r_extern
? RELOC_STD_BITS_EXTERN_LITTLE
: 0)
193 | (r_pcrel
? RELOC_STD_BITS_PCREL_LITTLE
: 0)
194 | (r_baserel
? RELOC_STD_BITS_BASEREL_LITTLE
: 0)
195 | (r_jmptable
? RELOC_STD_BITS_JMPTABLE_LITTLE
: 0)
196 | (r_relative
? RELOC_STD_BITS_RELATIVE_LITTLE
: 0)
197 | (r_length
<< RELOC_STD_BITS_LENGTH_SH_LITTLE
);
203 /* Output extended relocation information to a file in target byte order. */
206 NAME(lynx
,swap_ext_reloc_out
) (abfd
, g
, natptr
)
209 register struct reloc_ext_external
*natptr
;
214 unsigned int r_addend
;
215 asymbol
*sym
= *(g
->sym_ptr_ptr
);
216 asection
*output_section
= sym
->section
->output_section
;
218 PUT_WORD (abfd
, g
->address
, natptr
->r_address
);
220 r_type
= (unsigned int) g
->howto
->type
;
222 r_addend
= g
->addend
+ (*(g
->sym_ptr_ptr
))->section
->output_section
->vma
;
225 /* If this relocation is relative to a symbol then set the
226 r_index to the symbols index, and the r_extern bit.
228 Absolute symbols can come in in two ways, either as an offset
229 from the abs section, or as a symbol which has an abs value.
233 if (bfd_is_com_section (output_section
)
234 || output_section
== &bfd_abs_section
235 || output_section
== &bfd_und_section
)
237 if (bfd_abs_section
.symbol
== sym
)
239 /* Whoops, looked like an abs symbol, but is really an offset
240 from the abs section */
247 r_index
= stoi ((*(g
->sym_ptr_ptr
))->KEEPIT
);
252 /* Just an ordinary section */
254 r_index
= output_section
->target_index
;
258 /* now the fun stuff */
259 if (abfd
->xvec
->header_byteorder_big_p
!= false)
261 natptr
->r_index
[0] = r_index
>> 16;
262 natptr
->r_index
[1] = r_index
>> 8;
263 natptr
->r_index
[2] = r_index
;
265 (r_extern
? RELOC_EXT_BITS_EXTERN_BIG
: 0)
266 | (r_type
<< RELOC_EXT_BITS_TYPE_SH_BIG
);
270 natptr
->r_index
[2] = r_index
>> 16;
271 natptr
->r_index
[1] = r_index
>> 8;
272 natptr
->r_index
[0] = r_index
;
274 (r_extern
? RELOC_EXT_BITS_EXTERN_LITTLE
: 0)
275 | (r_type
<< RELOC_EXT_BITS_TYPE_SH_LITTLE
);
278 PUT_WORD (abfd
, r_addend
, natptr
->r_addend
);
281 /* BFD deals internally with all things based from the section they're
282 in. so, something in 10 bytes into a text section with a base of
283 50 would have a symbol (.text+10) and know .text vma was 50.
285 Aout keeps all it's symbols based from zero, so the symbol would
286 contain 60. This macro subs the base of each section from the value
287 to give the true offset from the section */
290 #define MOVE_ADDRESS(ad) \
292 /* undefined symbol */ \
293 cache_ptr->sym_ptr_ptr = symbols + r_index; \
294 cache_ptr->addend = ad; \
296 /* defined, section relative. replace symbol with pointer to \
297 symbol which points to section */ \
300 case N_TEXT | N_EXT: \
301 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
302 cache_ptr->addend = ad - su->textsec->vma; \
305 case N_DATA | N_EXT: \
306 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
307 cache_ptr->addend = ad - su->datasec->vma; \
310 case N_BSS | N_EXT: \
311 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
312 cache_ptr->addend = ad - su->bsssec->vma; \
316 case N_ABS | N_EXT: \
317 cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; \
318 cache_ptr->addend = ad; \
324 NAME(lynx
,swap_ext_reloc_in
) (abfd
, bytes
, cache_ptr
, symbols
)
326 struct reloc_ext_external
*bytes
;
333 struct aoutdata
*su
= &(abfd
->tdata
.aout_data
->a
);
335 cache_ptr
->address
= (GET_SWORD (abfd
, bytes
->r_address
));
337 r_index
= bytes
->r_index
[1];
338 r_extern
= (0 != (bytes
->r_index
[0] & RELOC_EXT_BITS_EXTERN_BIG
));
339 r_type
= (bytes
->r_index
[0] & RELOC_EXT_BITS_TYPE_BIG
)
340 >> RELOC_EXT_BITS_TYPE_SH_BIG
;
342 cache_ptr
->howto
= aout_32_ext_howto_table
+ r_type
;
343 MOVE_ADDRESS (GET_SWORD (abfd
, bytes
->r_addend
));
347 NAME(lynx
,swap_std_reloc_in
) (abfd
, bytes
, cache_ptr
, symbols
)
349 struct reloc_std_external
*bytes
;
355 unsigned int r_length
;
357 int r_baserel
, r_jmptable
, r_relative
;
358 struct aoutdata
*su
= &(abfd
->tdata
.aout_data
->a
);
360 cache_ptr
->address
= bfd_h_get_32 (abfd
, bytes
->r_address
);
362 r_index
= bytes
->r_index
[1];
363 r_extern
= (0 != (bytes
->r_index
[0] & RELOC_STD_BITS_EXTERN_BIG
));
364 r_pcrel
= (0 != (bytes
->r_index
[0] & RELOC_STD_BITS_PCREL_BIG
));
365 r_baserel
= (0 != (bytes
->r_index
[0] & RELOC_STD_BITS_BASEREL_BIG
));
366 r_jmptable
= (0 != (bytes
->r_index
[0] & RELOC_STD_BITS_JMPTABLE_BIG
));
367 r_relative
= (0 != (bytes
->r_index
[0] & RELOC_STD_BITS_RELATIVE_BIG
));
368 r_length
= (bytes
->r_index
[0] & RELOC_STD_BITS_LENGTH_BIG
)
369 >> RELOC_STD_BITS_LENGTH_SH_BIG
;
371 cache_ptr
->howto
= aout_32_std_howto_table
+ r_length
+ 4 * r_pcrel
;
372 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
380 NAME(lynx
,slurp_reloc_table
) (abfd
, asect
, symbols
)
386 bfd_size_type reloc_size
;
388 arelent
*reloc_cache
;
391 if (asect
->relocation
)
394 if (asect
->flags
& SEC_CONSTRUCTOR
)
397 if (asect
== obj_datasec (abfd
))
399 reloc_size
= exec_hdr (abfd
)->a_drsize
;
403 if (asect
== obj_textsec (abfd
))
405 reloc_size
= exec_hdr (abfd
)->a_trsize
;
409 bfd_set_error (bfd_error_invalid_operation
);
413 if (bfd_seek (abfd
, asect
->rel_filepos
, SEEK_SET
) != 0)
415 each_size
= obj_reloc_entry_size (abfd
);
417 count
= reloc_size
/ each_size
;
420 reloc_cache
= (arelent
*) malloc (count
* sizeof (arelent
));
421 if (!reloc_cache
&& count
!= 0)
424 bfd_set_error (bfd_error_no_memory
);
427 memset (reloc_cache
, 0, count
* sizeof (arelent
));
429 relocs
= (PTR
) bfd_alloc (abfd
, reloc_size
);
430 if (!relocs
&& reloc_size
!= 0)
436 if (bfd_read (relocs
, 1, reloc_size
, abfd
) != reloc_size
)
438 bfd_release (abfd
, relocs
);
443 if (each_size
== RELOC_EXT_SIZE
)
445 register struct reloc_ext_external
*rptr
= (struct reloc_ext_external
*) relocs
;
446 unsigned int counter
= 0;
447 arelent
*cache_ptr
= reloc_cache
;
449 for (; counter
< count
; counter
++, rptr
++, cache_ptr
++)
451 NAME(lynx
,swap_ext_reloc_in
) (abfd
, rptr
, cache_ptr
, symbols
);
456 register struct reloc_std_external
*rptr
= (struct reloc_std_external
*) relocs
;
457 unsigned int counter
= 0;
458 arelent
*cache_ptr
= reloc_cache
;
460 for (; counter
< count
; counter
++, rptr
++, cache_ptr
++)
462 NAME(lynx
,swap_std_reloc_in
) (abfd
, rptr
, cache_ptr
, symbols
);
467 bfd_release (abfd
, relocs
);
468 asect
->relocation
= reloc_cache
;
469 asect
->reloc_count
= count
;
475 /* Write out a relocation section into an object file. */
478 NAME(lynx
,squirt_out_relocs
) (abfd
, section
)
483 unsigned char *native
, *natptr
;
486 unsigned int count
= section
->reloc_count
;
492 each_size
= obj_reloc_entry_size (abfd
);
493 natsize
= each_size
* count
;
494 native
= (unsigned char *) bfd_zalloc (abfd
, natsize
);
497 bfd_set_error (bfd_error_no_memory
);
501 generic
= section
->orelocation
;
503 if (each_size
== RELOC_EXT_SIZE
)
505 for (natptr
= native
;
507 --count
, natptr
+= each_size
, ++generic
)
508 NAME(lynx
,swap_ext_reloc_out
) (abfd
, *generic
, (struct reloc_ext_external
*) natptr
);
512 for (natptr
= native
;
514 --count
, natptr
+= each_size
, ++generic
)
515 NAME(lynx
,swap_std_reloc_out
) (abfd
, *generic
, (struct reloc_std_external
*) natptr
);
518 if (bfd_write ((PTR
) native
, 1, natsize
, abfd
) != natsize
)
520 bfd_release (abfd
, native
);
523 bfd_release (abfd
, native
);
528 /* This is stupid. This function should be a boolean predicate */
530 NAME(lynx
,canonicalize_reloc
) (abfd
, section
, relptr
, symbols
)
536 arelent
*tblptr
= section
->relocation
;
539 if (!(tblptr
|| NAME(lynx
,slurp_reloc_table
) (abfd
, section
, symbols
)))
542 if (section
->flags
& SEC_CONSTRUCTOR
)
544 arelent_chain
*chain
= section
->constructor_chain
;
545 for (count
= 0; count
< section
->reloc_count
; count
++)
547 *relptr
++ = &chain
->relent
;
553 tblptr
= section
->relocation
;
555 for (count
= 0; count
++ < section
->reloc_count
;)
557 *relptr
++ = tblptr
++;
562 return section
->reloc_count
;
565 #define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
567 #include "aout-target.h"