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 bfd_seek (abfd, (file_ptr) 0, SEEK_SET); \
54 bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd); \
55 /* Now write out reloc info, followed by syms and strings */ \
57 if (bfd_get_symcount (abfd) != 0) \
59 bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET); \
61 if (! NAME(aout,write_syms)(abfd)) return false; \
63 bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET); \
65 if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd))) return false; \
66 bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET); \
68 if (!NAME(lynx,squirt_out_relocs)(abfd, obj_datasec (abfd))) return false; \
74 #include "aout/aout64.h"
78 char *lynx_core_file_failing_command ();
79 int lynx_core_file_failing_signal ();
80 boolean lynx_core_file_matches_executable_p ();
81 bfd_target *lynx_core_file_p ();
83 #define MY_core_file_failing_command lynx_core_file_failing_command
84 #define MY_core_file_failing_signal lynx_core_file_failing_signal
85 #define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
86 #define MY_core_file_p lynx_core_file_p
88 #endif /* HOST_LYNX */
93 extern reloc_howto_type aout_32_ext_howto_table[];
94 extern reloc_howto_type aout_32_std_howto_table[];
96 /* Standard reloc stuff */
97 /* Output standard relocation information to a file in target byte order. */
100 NAME (lynx, swap_std_reloc_out) (abfd, g, natptr)
103 struct reloc_std_external *natptr;
106 asymbol *sym = *(g->sym_ptr_ptr);
108 unsigned int r_length;
110 int r_baserel, r_jmptable, r_relative;
111 unsigned int r_addend;
112 asection *output_section = sym->section->output_section;
114 PUT_WORD (abfd, g->address, natptr->r_address);
116 r_length = g->howto->size; /* Size as a power of two */
117 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
118 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
123 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
125 /* name was clobbered by aout_write_syms to be symbol index */
127 /* If this relocation is relative to a symbol then set the
128 r_index to the symbols index, and the r_extern bit.
130 Absolute symbols can come in in two ways, either as an offset
131 from the abs section, or as a symbol which has an abs value.
136 if (bfd_is_com_section (output_section)
137 || output_section == &bfd_abs_section
138 || output_section == &bfd_und_section)
140 if (bfd_abs_section.symbol == sym)
142 /* Whoops, looked like an abs symbol, but is really an offset
143 from the abs section */
151 r_index = stoi ((*(g->sym_ptr_ptr))->KEEPIT);
157 /* Just an ordinary section */
159 r_index = output_section->target_index;
162 /* now the fun stuff */
163 if (abfd->xvec->header_byteorder_big_p != false)
165 natptr->r_index[0] = r_index >> 16;
166 natptr->r_index[1] = r_index >> 8;
167 natptr->r_index[2] = r_index;
169 (r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
170 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
171 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
172 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
173 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
174 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
178 natptr->r_index[2] = r_index >> 16;
179 natptr->r_index[1] = r_index >> 8;
180 natptr->r_index[0] = r_index;
182 (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
183 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
184 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
185 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
186 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
187 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
193 /* Output extended relocation information to a file in target byte order. */
196 NAME (lynx, swap_ext_reloc_out) (abfd, g, natptr)
199 register 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 || output_section == &bfd_abs_section
225 || output_section == &bfd_und_section)
227 if (bfd_abs_section.symbol == sym)
229 /* Whoops, looked like an abs symbol, but is really an offset
230 from the abs section */
237 r_index = stoi ((*(g->sym_ptr_ptr))->KEEPIT);
242 /* Just an ordinary section */
244 r_index = output_section->target_index;
248 /* now the fun stuff */
249 if (abfd->xvec->header_byteorder_big_p != false)
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) \
282 /* undefined symbol */ \
283 cache_ptr->sym_ptr_ptr = symbols + r_index; \
284 cache_ptr->addend = ad; \
286 /* defined, section relative. replace symbol with pointer to \
287 symbol which points to section */ \
290 case N_TEXT | N_EXT: \
291 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
292 cache_ptr->addend = ad - su->textsec->vma; \
295 case N_DATA | N_EXT: \
296 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
297 cache_ptr->addend = ad - su->datasec->vma; \
300 case N_BSS | N_EXT: \
301 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
302 cache_ptr->addend = ad - su->bsssec->vma; \
306 case N_ABS | N_EXT: \
307 cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; \
308 cache_ptr->addend = ad; \
314 NAME (lynx, swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols)
316 struct reloc_ext_external *bytes;
323 struct aoutdata *su = &(abfd->tdata.aout_data->a);
325 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
327 r_index = bytes->r_index[1];
328 r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG));
329 r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG)
330 >> RELOC_EXT_BITS_TYPE_SH_BIG;
332 cache_ptr->howto = aout_32_ext_howto_table + r_type;
333 MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
337 NAME (lynx, swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols)
339 struct reloc_std_external *bytes;
345 unsigned int r_length;
347 int r_baserel, r_jmptable, r_relative;
348 struct aoutdata *su = &(abfd->tdata.aout_data->a);
350 cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
352 r_index = bytes->r_index[1];
353 r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG));
354 r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG));
355 r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG));
356 r_jmptable = (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG));
357 r_relative = (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG));
358 r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG)
359 >> RELOC_STD_BITS_LENGTH_SH_BIG;
361 cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel;
362 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
370 NAME(lynx,slurp_reloc_table) (abfd, asect, symbols)
376 bfd_size_type reloc_size;
378 arelent *reloc_cache;
381 if (asect->relocation)
384 if (asect->flags & SEC_CONSTRUCTOR)
387 if (asect == obj_datasec (abfd))
389 reloc_size = exec_hdr (abfd)->a_drsize;
393 if (asect == obj_textsec (abfd))
395 reloc_size = exec_hdr (abfd)->a_trsize;
399 bfd_set_error (bfd_error_invalid_operation);
403 if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
405 each_size = obj_reloc_entry_size (abfd);
407 count = reloc_size / each_size;
410 reloc_cache = (arelent *) malloc (count * sizeof (arelent));
411 if (!reloc_cache && count != 0)
414 bfd_set_error (bfd_error_no_memory);
417 memset (reloc_cache, 0, count * sizeof (arelent));
419 relocs = (PTR) bfd_alloc (abfd, reloc_size);
426 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size)
428 bfd_release (abfd, relocs);
433 if (each_size == RELOC_EXT_SIZE)
435 register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
436 unsigned int counter = 0;
437 arelent *cache_ptr = reloc_cache;
439 for (; counter < count; counter++, rptr++, cache_ptr++)
441 NAME (lynx, swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols);
446 register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
447 unsigned int counter = 0;
448 arelent *cache_ptr = reloc_cache;
450 for (; counter < count; counter++, rptr++, cache_ptr++)
452 NAME (lynx, swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols);
457 bfd_release (abfd, relocs);
458 asect->relocation = reloc_cache;
459 asect->reloc_count = count;
465 /* Write out a relocation section into an object file. */
468 NAME (lynx, squirt_out_relocs) (abfd, section)
473 unsigned char *native, *natptr;
476 unsigned int count = section->reloc_count;
482 each_size = obj_reloc_entry_size (abfd);
483 natsize = each_size * count;
484 native = (unsigned char *) bfd_zalloc (abfd, natsize);
487 bfd_set_error (bfd_error_no_memory);
491 generic = section->orelocation;
493 if (each_size == RELOC_EXT_SIZE)
495 for (natptr = native;
497 --count, natptr += each_size, ++generic)
498 NAME (lynx, swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr);
502 for (natptr = native;
504 --count, natptr += each_size, ++generic)
505 NAME (lynx, swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr);
508 if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize)
510 bfd_release (abfd, native);
513 bfd_release (abfd, native);
518 /* This is stupid. This function should be a boolean predicate */
520 NAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols)
526 arelent *tblptr = section->relocation;
529 if (!(tblptr || NAME (lynx, slurp_reloc_table) (abfd, section, symbols)))
532 if (section->flags & SEC_CONSTRUCTOR)
534 arelent_chain *chain = section->constructor_chain;
535 for (count = 0; count < section->reloc_count; count++)
537 *relptr++ = &chain->relent;
543 tblptr = section->relocation;
547 for (count = 0; count++ < section->reloc_count;)
549 *relptr++ = tblptr++;
554 return section->reloc_count;
557 #define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
559 #include "aout-target.h"