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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 #define BYTES_IN_WORD 4
21 #define N_SHARED_LIB(x) 0
23 #define TEXT_START_ADDR 0
24 #define TARGET_PAGE_SIZE 4096
25 #define SEGMENT_SIZE TARGET_PAGE_SIZE
26 #define DEFAULT_ARCH bfd_arch_i386
28 #define MY(OP) CAT(i386lynx_aout_,OP)
29 #define TARGETNAME "a.out-i386-lynx"
36 #define WRITE_HEADERS(abfd, execp) \
38 bfd_size_type text_size; /* dummy vars */ \
40 if (adata(abfd).magic == undecided_magic) \
41 NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \
43 execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \
44 execp->a_entry = bfd_get_start_address (abfd); \
46 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \
47 obj_reloc_entry_size (abfd)); \
48 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \
49 obj_reloc_entry_size (abfd)); \
50 NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \
52 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false; \
53 if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) \
56 /* Now write out reloc info, followed by syms and strings */ \
58 if (bfd_get_symcount (abfd) != 0) \
60 if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET) \
64 if (! NAME(aout,write_syms)(abfd)) return false; \
66 if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET) \
70 if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd))) \
72 if (bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET) \
76 if (!NAME(lynx,squirt_out_relocs)(abfd, obj_datasec (abfd))) \
83 #include "aout/aout64.h"
87 char *lynx_core_file_failing_command ();
88 int lynx_core_file_failing_signal ();
89 boolean lynx_core_file_matches_executable_p ();
90 const bfd_target *lynx_core_file_p ();
92 #define MY_core_file_failing_command lynx_core_file_failing_command
93 #define MY_core_file_failing_signal lynx_core_file_failing_signal
94 #define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
95 #define MY_core_file_p lynx_core_file_p
97 #endif /* LYNX_CORE */
102 extern reloc_howto_type aout_32_ext_howto_table[];
103 extern reloc_howto_type aout_32_std_howto_table[];
105 /* Standard reloc stuff */
106 /* Output standard relocation information to a file in target byte order. */
109 NAME(lynx,swap_std_reloc_out) (abfd, g, natptr)
112 struct reloc_std_external *natptr;
115 asymbol *sym = *(g->sym_ptr_ptr);
117 unsigned int r_length;
119 int r_baserel, r_jmptable, r_relative;
120 unsigned int r_addend;
121 asection *output_section = sym->section->output_section;
123 PUT_WORD (abfd, g->address, natptr->r_address);
125 r_length = g->howto->size; /* Size as a power of two */
126 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
127 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
132 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
134 /* name was clobbered by aout_write_syms to be symbol index */
136 /* If this relocation is relative to a symbol then set the
137 r_index to the symbols index, and the r_extern bit.
139 Absolute symbols can come in in two ways, either as an offset
140 from the abs section, or as a symbol which has an abs value.
145 if (bfd_is_com_section (output_section)
146 || bfd_is_abs_section (output_section)
147 || bfd_is_und_section (output_section))
149 if (bfd_abs_section_ptr->symbol == sym)
151 /* Whoops, looked like an abs symbol, but is really an offset
152 from the abs section */
160 r_index = stoi ((*(g->sym_ptr_ptr))->KEEPIT);
166 /* Just an ordinary section */
168 r_index = output_section->target_index;
171 /* now the fun stuff */
172 if (abfd->xvec->header_byteorder_big_p != false)
174 natptr->r_index[0] = r_index >> 16;
175 natptr->r_index[1] = r_index >> 8;
176 natptr->r_index[2] = r_index;
178 (r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
179 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
180 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
181 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
182 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
183 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
187 natptr->r_index[2] = r_index >> 16;
188 natptr->r_index[1] = r_index >> 8;
189 natptr->r_index[0] = r_index;
191 (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
192 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
193 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
194 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
195 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
196 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
202 /* Output extended relocation information to a file in target byte order. */
205 NAME(lynx,swap_ext_reloc_out) (abfd, g, natptr)
208 register struct reloc_ext_external *natptr;
213 unsigned int r_addend;
214 asymbol *sym = *(g->sym_ptr_ptr);
215 asection *output_section = sym->section->output_section;
217 PUT_WORD (abfd, g->address, natptr->r_address);
219 r_type = (unsigned int) g->howto->type;
221 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
224 /* If this relocation is relative to a symbol then set the
225 r_index to the symbols index, and the r_extern bit.
227 Absolute symbols can come in in two ways, either as an offset
228 from the abs section, or as a symbol which has an abs value.
232 if (bfd_is_com_section (output_section)
233 || bfd_is_abs_section (output_section)
234 || bfd_is_und_section (output_section))
236 if (bfd_abs_section_ptr->symbol == sym)
238 /* Whoops, looked like an abs symbol, but is really an offset
239 from the abs section */
246 r_index = stoi ((*(g->sym_ptr_ptr))->KEEPIT);
251 /* Just an ordinary section */
253 r_index = output_section->target_index;
257 /* now the fun stuff */
258 if (abfd->xvec->header_byteorder_big_p != false)
260 natptr->r_index[0] = r_index >> 16;
261 natptr->r_index[1] = r_index >> 8;
262 natptr->r_index[2] = r_index;
264 (r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
265 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
269 natptr->r_index[2] = r_index >> 16;
270 natptr->r_index[1] = r_index >> 8;
271 natptr->r_index[0] = r_index;
273 (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
274 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
277 PUT_WORD (abfd, r_addend, natptr->r_addend);
280 /* BFD deals internally with all things based from the section they're
281 in. so, something in 10 bytes into a text section with a base of
282 50 would have a symbol (.text+10) and know .text vma was 50.
284 Aout keeps all it's symbols based from zero, so the symbol would
285 contain 60. This macro subs the base of each section from the value
286 to give the true offset from the section */
289 #define MOVE_ADDRESS(ad) \
291 /* undefined symbol */ \
292 cache_ptr->sym_ptr_ptr = symbols + r_index; \
293 cache_ptr->addend = ad; \
295 /* defined, section relative. replace symbol with pointer to \
296 symbol which points to section */ \
299 case N_TEXT | N_EXT: \
300 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
301 cache_ptr->addend = ad - su->textsec->vma; \
304 case N_DATA | N_EXT: \
305 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
306 cache_ptr->addend = ad - su->datasec->vma; \
309 case N_BSS | N_EXT: \
310 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
311 cache_ptr->addend = ad - su->bsssec->vma; \
315 case N_ABS | N_EXT: \
316 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
317 cache_ptr->addend = ad; \
323 NAME(lynx,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
325 struct reloc_ext_external *bytes;
328 bfd_size_type symcount;
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, symcount)
349 struct reloc_std_external *bytes;
352 bfd_size_type symcount;
356 unsigned int r_length;
358 int r_baserel, r_jmptable, r_relative;
359 struct aoutdata *su = &(abfd->tdata.aout_data->a);
361 cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
363 r_index = bytes->r_index[1];
364 r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG));
365 r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG));
366 r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG));
367 r_jmptable = (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG));
368 r_relative = (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG));
369 r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG)
370 >> RELOC_STD_BITS_LENGTH_SH_BIG;
372 cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel;
373 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
381 NAME(lynx,slurp_reloc_table) (abfd, asect, symbols)
387 bfd_size_type reloc_size;
389 arelent *reloc_cache;
392 if (asect->relocation)
395 if (asect->flags & SEC_CONSTRUCTOR)
398 if (asect == obj_datasec (abfd))
400 reloc_size = exec_hdr (abfd)->a_drsize;
404 if (asect == obj_textsec (abfd))
406 reloc_size = exec_hdr (abfd)->a_trsize;
410 bfd_set_error (bfd_error_invalid_operation);
414 if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
416 each_size = obj_reloc_entry_size (abfd);
418 count = reloc_size / each_size;
421 reloc_cache = (arelent *) malloc (count * sizeof (arelent));
422 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,
452 bfd_get_symcount (abfd));
457 register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
458 unsigned int counter = 0;
459 arelent *cache_ptr = reloc_cache;
461 for (; counter < count; counter++, rptr++, cache_ptr++)
463 NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,
464 bfd_get_symcount (abfd));
469 bfd_release (abfd, relocs);
470 asect->relocation = reloc_cache;
471 asect->reloc_count = count;
477 /* Write out a relocation section into an object file. */
480 NAME(lynx,squirt_out_relocs) (abfd, section)
485 unsigned char *native, *natptr;
488 unsigned int count = section->reloc_count;
494 each_size = obj_reloc_entry_size (abfd);
495 natsize = each_size * count;
496 native = (unsigned char *) bfd_zalloc (abfd, natsize);
500 generic = section->orelocation;
502 if (each_size == RELOC_EXT_SIZE)
504 for (natptr = native;
506 --count, natptr += each_size, ++generic)
507 NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr);
511 for (natptr = native;
513 --count, natptr += each_size, ++generic)
514 NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr);
517 if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize)
519 bfd_release (abfd, native);
522 bfd_release (abfd, native);
527 /* This is stupid. This function should be a boolean predicate */
529 NAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols)
535 arelent *tblptr = section->relocation;
538 if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols)))
541 if (section->flags & SEC_CONSTRUCTOR)
543 arelent_chain *chain = section->constructor_chain;
544 for (count = 0; count < section->reloc_count; count++)
546 *relptr++ = &chain->relent;
552 tblptr = section->relocation;
554 for (count = 0; count++ < section->reloc_count;)
556 *relptr++ = tblptr++;
561 return section->reloc_count;
564 #define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
566 #include "aout-target.h"