1 /* BFD back-end for i386 a.out binaries under LynxOS.
2 Copyright (C) 1990-2023 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 3 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., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
21 #define TEXT_START_ADDR 0
22 #define TARGET_PAGE_SIZE 4096
23 #define SEGMENT_SIZE TARGET_PAGE_SIZE
24 #define DEFAULT_ARCH bfd_arch_i386
26 /* Do not "beautify" the CONCAT* macro args. Traditional C will not
27 remove whitespace added here, and thus will fail to concatenate
29 #define MY(OP) CONCAT2 (i386_aout_lynx_,OP)
30 #define TARGETNAME "a.out-i386-lynx"
37 #define WRITE_HEADERS(abfd, execp) \
39 if (adata(abfd).magic == undecided_magic) \
40 NAME (aout, adjust_sizes_and_vmas) (abfd); \
42 execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \
43 execp->a_entry = bfd_get_start_address (abfd); \
45 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) \
46 * obj_reloc_entry_size (abfd)); \
47 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) \
48 * obj_reloc_entry_size (abfd)); \
49 NAME (aout, swap_exec_header_out) (abfd, execp, &exec_bytes); \
51 if (bfd_seek (abfd, 0, SEEK_SET) != 0 \
52 || bfd_write (&exec_bytes, EXEC_BYTES_SIZE, \
53 abfd) != EXEC_BYTES_SIZE) \
55 /* Now write out reloc info, followed by syms and strings. */ \
57 if (bfd_get_outsymbols (abfd) != NULL \
58 && bfd_get_symcount (abfd) != 0) \
60 if (bfd_seek (abfd, N_SYMOFF (execp), SEEK_SET) != 0) \
63 if (! NAME (aout, write_syms) (abfd)) \
67 if (bfd_seek (abfd, N_TRELOFF (execp), SEEK_SET) != 0) \
69 if (!NAME (lynx, squirt_out_relocs) (abfd, obj_textsec (abfd))) \
72 if (bfd_seek (abfd, N_DRELOFF (execp), SEEK_SET) != 0) \
74 if (!NAME (lynx, squirt_out_relocs) (abfd, obj_datasec (abfd))) \
80 #include "aout/aout64.h"
85 char *lynx_core_file_failing_command ();
86 int lynx_core_file_failing_signal ();
87 bool lynx_core_file_matches_executable_p ();
88 bfd_cleanup
lynx_core_file_p ();
90 #define MY_core_file_failing_command lynx_core_file_failing_command
91 #define MY_core_file_failing_signal lynx_core_file_failing_signal
92 #define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
93 #define MY_core_file_p lynx_core_file_p
95 #endif /* LYNX_CORE */
98 #define KEEPIT udata.i
100 extern reloc_howto_type aout_32_ext_howto_table
[];
101 extern reloc_howto_type aout_32_std_howto_table
[];
103 /* Standard reloc stuff */
104 /* Output standard relocation information to a file in target byte order. */
107 NAME(lynx
,swap_std_reloc_out
) (bfd
*abfd
,
109 struct reloc_std_external
*natptr
)
112 asymbol
*sym
= *(g
->sym_ptr_ptr
);
114 unsigned int r_length
;
116 int r_baserel
, r_jmptable
, r_relative
;
117 asection
*output_section
= sym
->section
->output_section
;
119 PUT_WORD (abfd
, g
->address
, natptr
->r_address
);
121 r_length
= bfd_log2 (bfd_get_reloc_size (g
->howto
));
122 r_pcrel
= (int) g
->howto
->pc_relative
; /* Relative to PC? */
123 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
128 /* name was clobbered by aout_write_syms to be symbol index */
130 /* If this relocation is relative to a symbol then set the
131 r_index to the symbols index, and the r_extern bit.
133 Absolute symbols can come in in two ways, either as an offset
134 from the abs section, or as a symbol which has an abs value.
138 if (bfd_is_com_section (output_section
)
139 || bfd_is_abs_section (output_section
)
140 || bfd_is_und_section (output_section
))
142 if (bfd_abs_section_ptr
->symbol
== sym
)
144 /* Whoops, looked like an abs symbol, but is really an offset
145 from the abs section */
153 r_index
= (*g
->sym_ptr_ptr
)->KEEPIT
;
158 /* Just an ordinary section */
160 r_index
= output_section
->target_index
;
163 /* now the fun stuff */
164 if (bfd_header_big_endian (abfd
))
166 natptr
->r_index
[0] = r_index
>> 16;
167 natptr
->r_index
[1] = r_index
>> 8;
168 natptr
->r_index
[2] = r_index
;
170 (r_extern
? RELOC_STD_BITS_EXTERN_BIG
: 0)
171 | (r_pcrel
? RELOC_STD_BITS_PCREL_BIG
: 0)
172 | (r_baserel
? RELOC_STD_BITS_BASEREL_BIG
: 0)
173 | (r_jmptable
? RELOC_STD_BITS_JMPTABLE_BIG
: 0)
174 | (r_relative
? RELOC_STD_BITS_RELATIVE_BIG
: 0)
175 | (r_length
<< RELOC_STD_BITS_LENGTH_SH_BIG
);
179 natptr
->r_index
[2] = r_index
>> 16;
180 natptr
->r_index
[1] = r_index
>> 8;
181 natptr
->r_index
[0] = r_index
;
183 (r_extern
? RELOC_STD_BITS_EXTERN_LITTLE
: 0)
184 | (r_pcrel
? RELOC_STD_BITS_PCREL_LITTLE
: 0)
185 | (r_baserel
? RELOC_STD_BITS_BASEREL_LITTLE
: 0)
186 | (r_jmptable
? RELOC_STD_BITS_JMPTABLE_LITTLE
: 0)
187 | (r_relative
? RELOC_STD_BITS_RELATIVE_LITTLE
: 0)
188 | (r_length
<< RELOC_STD_BITS_LENGTH_SH_LITTLE
);
194 /* Output extended relocation information to a file in target byte order. */
197 NAME(lynx
,swap_ext_reloc_out
) (bfd
*abfd
,
199 struct reloc_ext_external
*natptr
)
204 unsigned int r_addend
;
205 asymbol
*sym
= *(g
->sym_ptr_ptr
);
206 asection
*output_section
= sym
->section
->output_section
;
208 PUT_WORD (abfd
, g
->address
, natptr
->r_address
);
210 r_type
= (unsigned int) g
->howto
->type
;
212 r_addend
= g
->addend
+ (*(g
->sym_ptr_ptr
))->section
->output_section
->vma
;
215 /* If this relocation is relative to a symbol then set the
216 r_index to the symbols index, and the r_extern bit.
218 Absolute symbols can come in in two ways, either as an offset
219 from the abs section, or as a symbol which has an abs value.
223 if (bfd_is_com_section (output_section
)
224 || bfd_is_abs_section (output_section
)
225 || bfd_is_und_section (output_section
))
227 if (bfd_abs_section_ptr
->symbol
== sym
)
229 /* Whoops, looked like an abs symbol, but is really an offset
230 from the abs section */
237 r_index
= (*g
->sym_ptr_ptr
)->KEEPIT
;
242 /* Just an ordinary section */
244 r_index
= output_section
->target_index
;
248 /* now the fun stuff */
249 if (bfd_header_big_endian (abfd
))
251 natptr
->r_index
[0] = r_index
>> 16;
252 natptr
->r_index
[1] = r_index
>> 8;
253 natptr
->r_index
[2] = r_index
;
255 (r_extern
? RELOC_EXT_BITS_EXTERN_BIG
: 0)
256 | (r_type
<< RELOC_EXT_BITS_TYPE_SH_BIG
);
260 natptr
->r_index
[2] = r_index
>> 16;
261 natptr
->r_index
[1] = r_index
>> 8;
262 natptr
->r_index
[0] = r_index
;
264 (r_extern
? RELOC_EXT_BITS_EXTERN_LITTLE
: 0)
265 | (r_type
<< RELOC_EXT_BITS_TYPE_SH_LITTLE
);
268 PUT_WORD (abfd
, r_addend
, natptr
->r_addend
);
271 /* BFD deals internally with all things based from the section they're
272 in. so, something in 10 bytes into a text section with a base of
273 50 would have a symbol (.text+10) and know .text vma was 50.
275 Aout keeps all it's symbols based from zero, so the symbol would
276 contain 60. This macro subs the base of each section from the value
277 to give the true offset from the section */
280 #define MOVE_ADDRESS(ad) \
283 /* undefined symbol */ \
284 if (symbols != NULL && r_index < bfd_get_symcount (abfd)) \
285 cache_ptr->sym_ptr_ptr = symbols + r_index; \
287 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
288 cache_ptr->addend = ad; \
292 /* defined, section relative. replace symbol with pointer to \
293 symbol which points to section */ \
297 case N_TEXT | N_EXT: \
298 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
299 cache_ptr->addend = ad - su->textsec->vma; \
302 case N_DATA | N_EXT: \
303 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
304 cache_ptr->addend = ad - su->datasec->vma; \
307 case N_BSS | N_EXT: \
308 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
309 cache_ptr->addend = ad - su->bsssec->vma; \
313 case N_ABS | N_EXT: \
314 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
315 cache_ptr->addend = ad; \
321 NAME(lynx
,swap_ext_reloc_in
) (bfd
*abfd
,
322 struct reloc_ext_external
*bytes
,
325 bfd_size_type symcount ATTRIBUTE_UNUSED
)
327 unsigned int r_index
;
330 struct aoutdata
*su
= &(abfd
->tdata
.aout_data
->a
);
332 cache_ptr
->address
= (GET_SWORD (abfd
, bytes
->r_address
));
334 r_index
= bytes
->r_index
[1];
335 r_extern
= (0 != (bytes
->r_index
[0] & RELOC_EXT_BITS_EXTERN_BIG
));
336 r_type
= (bytes
->r_index
[0] & RELOC_EXT_BITS_TYPE_BIG
)
337 >> RELOC_EXT_BITS_TYPE_SH_BIG
;
339 cache_ptr
->howto
= aout_32_ext_howto_table
+ r_type
;
340 MOVE_ADDRESS (GET_SWORD (abfd
, bytes
->r_addend
));
344 NAME(lynx
,swap_std_reloc_in
) (bfd
*abfd
,
345 struct reloc_std_external
*bytes
,
348 bfd_size_type symcount ATTRIBUTE_UNUSED
)
350 unsigned int r_index
;
352 unsigned int r_length
;
354 struct aoutdata
*su
= &(abfd
->tdata
.aout_data
->a
);
356 cache_ptr
->address
= H_GET_32 (abfd
, bytes
->r_address
);
358 r_index
= bytes
->r_index
[1];
359 r_extern
= (0 != (bytes
->r_index
[0] & RELOC_STD_BITS_EXTERN_BIG
));
360 r_pcrel
= (0 != (bytes
->r_index
[0] & RELOC_STD_BITS_PCREL_BIG
));
361 r_length
= (bytes
->r_index
[0] & RELOC_STD_BITS_LENGTH_BIG
)
362 >> RELOC_STD_BITS_LENGTH_SH_BIG
;
364 cache_ptr
->howto
= aout_32_std_howto_table
+ r_length
+ 4 * r_pcrel
;
365 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
373 NAME(lynx
,slurp_reloc_table
) (bfd
*abfd
,
378 bfd_size_type reloc_size
;
380 arelent
*reloc_cache
;
383 if (asect
->relocation
)
386 if (asect
->flags
& SEC_CONSTRUCTOR
)
389 if (asect
== obj_datasec (abfd
))
391 reloc_size
= exec_hdr (abfd
)->a_drsize
;
395 if (asect
== obj_textsec (abfd
))
397 reloc_size
= exec_hdr (abfd
)->a_trsize
;
401 bfd_set_error (bfd_error_invalid_operation
);
405 if (bfd_seek (abfd
, asect
->rel_filepos
, SEEK_SET
) != 0)
407 each_size
= obj_reloc_entry_size (abfd
);
409 count
= reloc_size
/ each_size
;
412 reloc_cache
= (arelent
*) bfd_zmalloc (count
* sizeof (arelent
));
413 if (!reloc_cache
&& count
!= 0)
416 relocs
= _bfd_alloc_and_read (abfd
, reloc_size
, reloc_size
);
417 if (!relocs
&& reloc_size
!= 0)
423 if (each_size
== RELOC_EXT_SIZE
)
425 struct reloc_ext_external
*rptr
= (struct reloc_ext_external
*) relocs
;
426 unsigned int counter
= 0;
427 arelent
*cache_ptr
= reloc_cache
;
429 for (; counter
< count
; counter
++, rptr
++, cache_ptr
++)
431 NAME(lynx
,swap_ext_reloc_in
) (abfd
, rptr
, cache_ptr
, symbols
,
432 (bfd_size_type
) bfd_get_symcount (abfd
));
437 struct reloc_std_external
*rptr
= (struct reloc_std_external
*) relocs
;
438 unsigned int counter
= 0;
439 arelent
*cache_ptr
= reloc_cache
;
441 for (; counter
< count
; counter
++, rptr
++, cache_ptr
++)
443 NAME(lynx
,swap_std_reloc_in
) (abfd
, rptr
, cache_ptr
, symbols
,
444 (bfd_size_type
) bfd_get_symcount (abfd
));
449 bfd_release (abfd
, relocs
);
450 asect
->relocation
= reloc_cache
;
451 asect
->reloc_count
= count
;
457 /* Write out a relocation section into an object file. */
460 NAME(lynx
,squirt_out_relocs
) (bfd
*abfd
, asection
*section
)
463 unsigned char *native
, *natptr
;
465 unsigned int count
= section
->reloc_count
;
466 bfd_size_type natsize
;
471 each_size
= obj_reloc_entry_size (abfd
);
473 natsize
*= each_size
;
474 native
= (unsigned char *) bfd_zalloc (abfd
, natsize
);
478 generic
= section
->orelocation
;
480 if (each_size
== RELOC_EXT_SIZE
)
482 for (natptr
= native
;
484 --count
, natptr
+= each_size
, ++generic
)
485 NAME(lynx
,swap_ext_reloc_out
) (abfd
, *generic
, (struct reloc_ext_external
*) natptr
);
489 for (natptr
= native
;
491 --count
, natptr
+= each_size
, ++generic
)
492 NAME(lynx
,swap_std_reloc_out
) (abfd
, *generic
, (struct reloc_std_external
*) natptr
);
495 if (bfd_write (native
, natsize
, abfd
) != natsize
)
497 bfd_release (abfd
, native
);
500 bfd_release (abfd
, native
);
505 /* This is stupid. This function should be a boolean predicate */
507 NAME(lynx
,canonicalize_reloc
) (bfd
*abfd
,
512 arelent
*tblptr
= section
->relocation
;
515 if (!(tblptr
|| NAME(lynx
,slurp_reloc_table
) (abfd
, section
, symbols
)))
518 if (section
->flags
& SEC_CONSTRUCTOR
)
520 arelent_chain
*chain
= section
->constructor_chain
;
521 for (count
= 0; count
< section
->reloc_count
; count
++)
523 *relptr
++ = &chain
->relent
;
529 tblptr
= section
->relocation
;
531 for (count
= 0; count
++ < section
->reloc_count
;)
533 *relptr
++ = tblptr
++;
538 return section
->reloc_count
;
541 #define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
543 #include "aout-target.h"