1 /* BFD back-end for i386 a.out binaries under LynxOS.
2 Copyright (C) 1990-2024 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 if (!NAME (aout, swap_exec_header_out) (abfd, execp, &exec_bytes)) \
52 if (bfd_seek (abfd, 0, SEEK_SET) != 0 \
53 || bfd_write (&exec_bytes, EXEC_BYTES_SIZE, \
54 abfd) != EXEC_BYTES_SIZE) \
56 /* Now write out reloc info, followed by syms and strings. */ \
58 if (bfd_get_outsymbols (abfd) != NULL \
59 && bfd_get_symcount (abfd) != 0) \
61 if (bfd_seek (abfd, N_SYMOFF (execp), SEEK_SET) != 0) \
64 if (! NAME (aout, write_syms) (abfd)) \
68 if (bfd_seek (abfd, N_TRELOFF (execp), SEEK_SET) != 0) \
70 if (!NAME (lynx, squirt_out_relocs) (abfd, obj_textsec (abfd))) \
73 if (bfd_seek (abfd, N_DRELOFF (execp), SEEK_SET) != 0) \
75 if (!NAME (lynx, squirt_out_relocs) (abfd, obj_datasec (abfd))) \
81 #include "aout/aout64.h"
86 char *lynx_core_file_failing_command ();
87 int lynx_core_file_failing_signal ();
88 bool lynx_core_file_matches_executable_p ();
89 bfd_cleanup
lynx_core_file_p ();
91 #define MY_core_file_failing_command lynx_core_file_failing_command
92 #define MY_core_file_failing_signal lynx_core_file_failing_signal
93 #define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
94 #define MY_core_file_p lynx_core_file_p
96 #endif /* LYNX_CORE */
99 #define KEEPIT udata.i
101 extern reloc_howto_type aout_32_ext_howto_table
[];
102 extern reloc_howto_type aout_32_std_howto_table
[];
104 /* Standard reloc stuff */
105 /* Output standard relocation information to a file in target byte order. */
108 NAME(lynx
,swap_std_reloc_out
) (bfd
*abfd
,
110 struct reloc_std_external
*natptr
)
113 asymbol
*sym
= *(g
->sym_ptr_ptr
);
115 unsigned int r_length
;
117 int r_baserel
, r_jmptable
, r_relative
;
118 asection
*output_section
= sym
->section
->output_section
;
120 PUT_WORD (abfd
, g
->address
, natptr
->r_address
);
122 r_length
= bfd_log2 (bfd_get_reloc_size (g
->howto
));
123 r_pcrel
= (int) g
->howto
->pc_relative
; /* Relative to PC? */
124 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
129 /* name was clobbered by aout_write_syms to be symbol index */
131 /* If this relocation is relative to a symbol then set the
132 r_index to the symbols index, and the r_extern bit.
134 Absolute symbols can come in in two ways, either as an offset
135 from the abs section, or as a symbol which has an abs value.
139 if (bfd_is_com_section (output_section
)
140 || bfd_is_abs_section (output_section
)
141 || bfd_is_und_section (output_section
))
143 if (bfd_abs_section_ptr
->symbol
== sym
)
145 /* Whoops, looked like an abs symbol, but is really an offset
146 from the abs section */
154 r_index
= (*g
->sym_ptr_ptr
)->KEEPIT
;
159 /* Just an ordinary section */
161 r_index
= output_section
->target_index
;
164 /* now the fun stuff */
165 if (bfd_header_big_endian (abfd
))
167 natptr
->r_index
[0] = r_index
>> 16;
168 natptr
->r_index
[1] = r_index
>> 8;
169 natptr
->r_index
[2] = r_index
;
171 (r_extern
? RELOC_STD_BITS_EXTERN_BIG
: 0)
172 | (r_pcrel
? RELOC_STD_BITS_PCREL_BIG
: 0)
173 | (r_baserel
? RELOC_STD_BITS_BASEREL_BIG
: 0)
174 | (r_jmptable
? RELOC_STD_BITS_JMPTABLE_BIG
: 0)
175 | (r_relative
? RELOC_STD_BITS_RELATIVE_BIG
: 0)
176 | (r_length
<< RELOC_STD_BITS_LENGTH_SH_BIG
);
180 natptr
->r_index
[2] = r_index
>> 16;
181 natptr
->r_index
[1] = r_index
>> 8;
182 natptr
->r_index
[0] = r_index
;
184 (r_extern
? RELOC_STD_BITS_EXTERN_LITTLE
: 0)
185 | (r_pcrel
? RELOC_STD_BITS_PCREL_LITTLE
: 0)
186 | (r_baserel
? RELOC_STD_BITS_BASEREL_LITTLE
: 0)
187 | (r_jmptable
? RELOC_STD_BITS_JMPTABLE_LITTLE
: 0)
188 | (r_relative
? RELOC_STD_BITS_RELATIVE_LITTLE
: 0)
189 | (r_length
<< RELOC_STD_BITS_LENGTH_SH_LITTLE
);
195 /* Output extended relocation information to a file in target byte order. */
198 NAME(lynx
,swap_ext_reloc_out
) (bfd
*abfd
,
200 struct reloc_ext_external
*natptr
)
205 unsigned int r_addend
;
206 asymbol
*sym
= *(g
->sym_ptr_ptr
);
207 asection
*output_section
= sym
->section
->output_section
;
209 PUT_WORD (abfd
, g
->address
, natptr
->r_address
);
211 r_type
= (unsigned int) g
->howto
->type
;
213 r_addend
= g
->addend
+ (*(g
->sym_ptr_ptr
))->section
->output_section
->vma
;
216 /* If this relocation is relative to a symbol then set the
217 r_index to the symbols index, and the r_extern bit.
219 Absolute symbols can come in in two ways, either as an offset
220 from the abs section, or as a symbol which has an abs value.
224 if (bfd_is_com_section (output_section
)
225 || bfd_is_abs_section (output_section
)
226 || bfd_is_und_section (output_section
))
228 if (bfd_abs_section_ptr
->symbol
== sym
)
230 /* Whoops, looked like an abs symbol, but is really an offset
231 from the abs section */
238 r_index
= (*g
->sym_ptr_ptr
)->KEEPIT
;
243 /* Just an ordinary section */
245 r_index
= output_section
->target_index
;
249 /* now the fun stuff */
250 if (bfd_header_big_endian (abfd
))
252 natptr
->r_index
[0] = r_index
>> 16;
253 natptr
->r_index
[1] = r_index
>> 8;
254 natptr
->r_index
[2] = r_index
;
256 (r_extern
? RELOC_EXT_BITS_EXTERN_BIG
: 0)
257 | (r_type
<< RELOC_EXT_BITS_TYPE_SH_BIG
);
261 natptr
->r_index
[2] = r_index
>> 16;
262 natptr
->r_index
[1] = r_index
>> 8;
263 natptr
->r_index
[0] = r_index
;
265 (r_extern
? RELOC_EXT_BITS_EXTERN_LITTLE
: 0)
266 | (r_type
<< RELOC_EXT_BITS_TYPE_SH_LITTLE
);
269 PUT_WORD (abfd
, r_addend
, natptr
->r_addend
);
272 /* BFD deals internally with all things based from the section they're
273 in. so, something in 10 bytes into a text section with a base of
274 50 would have a symbol (.text+10) and know .text vma was 50.
276 Aout keeps all it's symbols based from zero, so the symbol would
277 contain 60. This macro subs the base of each section from the value
278 to give the true offset from the section */
281 #define MOVE_ADDRESS(ad) \
284 /* undefined symbol */ \
285 if (symbols != NULL && r_index < bfd_get_symcount (abfd)) \
286 cache_ptr->sym_ptr_ptr = symbols + r_index; \
288 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
289 cache_ptr->addend = ad; \
293 /* defined, section relative. replace symbol with pointer to \
294 symbol which points to section */ \
298 case N_TEXT | N_EXT: \
299 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
300 cache_ptr->addend = ad - su->textsec->vma; \
303 case N_DATA | N_EXT: \
304 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
305 cache_ptr->addend = ad - su->datasec->vma; \
308 case N_BSS | N_EXT: \
309 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
310 cache_ptr->addend = ad - su->bsssec->vma; \
314 case N_ABS | N_EXT: \
315 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
316 cache_ptr->addend = ad; \
322 NAME(lynx
,swap_ext_reloc_in
) (bfd
*abfd
,
323 struct reloc_ext_external
*bytes
,
326 bfd_size_type symcount ATTRIBUTE_UNUSED
)
328 unsigned int r_index
;
331 struct aoutdata
*su
= &(abfd
->tdata
.aout_data
->a
);
333 cache_ptr
->address
= (GET_SWORD (abfd
, bytes
->r_address
));
335 r_index
= bytes
->r_index
[1];
336 r_extern
= (0 != (bytes
->r_index
[0] & RELOC_EXT_BITS_EXTERN_BIG
));
337 r_type
= (bytes
->r_index
[0] & RELOC_EXT_BITS_TYPE_BIG
)
338 >> RELOC_EXT_BITS_TYPE_SH_BIG
;
340 cache_ptr
->howto
= aout_32_ext_howto_table
+ r_type
;
341 MOVE_ADDRESS (GET_SWORD (abfd
, bytes
->r_addend
));
345 NAME(lynx
,swap_std_reloc_in
) (bfd
*abfd
,
346 struct reloc_std_external
*bytes
,
349 bfd_size_type symcount ATTRIBUTE_UNUSED
)
351 unsigned int r_index
;
353 unsigned int r_length
;
355 struct aoutdata
*su
= &(abfd
->tdata
.aout_data
->a
);
357 cache_ptr
->address
= H_GET_32 (abfd
, bytes
->r_address
);
359 r_index
= bytes
->r_index
[1];
360 r_extern
= (0 != (bytes
->r_index
[0] & RELOC_STD_BITS_EXTERN_BIG
));
361 r_pcrel
= (0 != (bytes
->r_index
[0] & RELOC_STD_BITS_PCREL_BIG
));
362 r_length
= (bytes
->r_index
[0] & RELOC_STD_BITS_LENGTH_BIG
)
363 >> RELOC_STD_BITS_LENGTH_SH_BIG
;
365 cache_ptr
->howto
= aout_32_std_howto_table
+ r_length
+ 4 * r_pcrel
;
366 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
374 NAME(lynx
,slurp_reloc_table
) (bfd
*abfd
,
379 bfd_size_type reloc_size
;
381 arelent
*reloc_cache
;
384 if (asect
->relocation
)
387 if (asect
->flags
& SEC_CONSTRUCTOR
)
390 if (asect
== obj_datasec (abfd
))
392 reloc_size
= exec_hdr (abfd
)->a_drsize
;
396 if (asect
== obj_textsec (abfd
))
398 reloc_size
= exec_hdr (abfd
)->a_trsize
;
402 bfd_set_error (bfd_error_invalid_operation
);
406 if (bfd_seek (abfd
, asect
->rel_filepos
, SEEK_SET
) != 0)
408 each_size
= obj_reloc_entry_size (abfd
);
410 count
= reloc_size
/ each_size
;
413 reloc_cache
= (arelent
*) bfd_zmalloc (count
* sizeof (arelent
));
414 if (!reloc_cache
&& count
!= 0)
417 relocs
= _bfd_alloc_and_read (abfd
, reloc_size
, reloc_size
);
418 if (!relocs
&& reloc_size
!= 0)
424 if (each_size
== RELOC_EXT_SIZE
)
426 struct reloc_ext_external
*rptr
= (struct reloc_ext_external
*) relocs
;
427 unsigned int counter
= 0;
428 arelent
*cache_ptr
= reloc_cache
;
430 for (; counter
< count
; counter
++, rptr
++, cache_ptr
++)
432 NAME(lynx
,swap_ext_reloc_in
) (abfd
, rptr
, cache_ptr
, symbols
,
433 (bfd_size_type
) bfd_get_symcount (abfd
));
438 struct reloc_std_external
*rptr
= (struct reloc_std_external
*) relocs
;
439 unsigned int counter
= 0;
440 arelent
*cache_ptr
= reloc_cache
;
442 for (; counter
< count
; counter
++, rptr
++, cache_ptr
++)
444 NAME(lynx
,swap_std_reloc_in
) (abfd
, rptr
, cache_ptr
, symbols
,
445 (bfd_size_type
) bfd_get_symcount (abfd
));
450 bfd_release (abfd
, relocs
);
451 asect
->relocation
= reloc_cache
;
452 asect
->reloc_count
= count
;
458 /* Write out a relocation section into an object file. */
461 NAME(lynx
,squirt_out_relocs
) (bfd
*abfd
, asection
*section
)
464 unsigned char *native
, *natptr
;
466 unsigned int count
= section
->reloc_count
;
467 bfd_size_type natsize
;
472 each_size
= obj_reloc_entry_size (abfd
);
474 natsize
*= each_size
;
475 native
= (unsigned char *) bfd_zalloc (abfd
, natsize
);
479 generic
= section
->orelocation
;
481 if (each_size
== RELOC_EXT_SIZE
)
483 for (natptr
= native
;
485 --count
, natptr
+= each_size
, ++generic
)
486 NAME(lynx
,swap_ext_reloc_out
) (abfd
, *generic
, (struct reloc_ext_external
*) natptr
);
490 for (natptr
= native
;
492 --count
, natptr
+= each_size
, ++generic
)
493 NAME(lynx
,swap_std_reloc_out
) (abfd
, *generic
, (struct reloc_std_external
*) natptr
);
496 if (bfd_write (native
, natsize
, abfd
) != natsize
)
498 bfd_release (abfd
, native
);
501 bfd_release (abfd
, native
);
506 /* This is stupid. This function should be a boolean predicate */
508 NAME(lynx
,canonicalize_reloc
) (bfd
*abfd
,
513 arelent
*tblptr
= section
->relocation
;
516 if (!(tblptr
|| NAME(lynx
,slurp_reloc_table
) (abfd
, section
, symbols
)))
519 if (section
->flags
& SEC_CONSTRUCTOR
)
521 arelent_chain
*chain
= section
->constructor_chain
;
522 for (count
= 0; count
< section
->reloc_count
; count
++)
524 *relptr
++ = &chain
->relent
;
530 tblptr
= section
->relocation
;
532 for (count
= 0; count
++ < section
->reloc_count
;)
534 *relptr
++ = tblptr
++;
539 return section
->reloc_count
;
542 #define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
544 #include "aout-target.h"