daily update
[deliverable/binutils-gdb.git] / bfd / i386lynx.c
CommitLineData
252b5132 1/* BFD back-end for i386 a.out binaries under LynxOS.
9553c638
AM
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2001, 2002,
3 2003 Free Software Foundation, Inc.
252b5132
RH
4
5This file is part of BFD, the Binary File Descriptor library.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
3e110533 19Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
252b5132 20
252b5132
RH
21#define N_SHARED_LIB(x) 0
22
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
27
e43d48cc
AM
28/* Do not "beautify" the CONCAT* macro args. Traditional C will not
29 remove whitespace added here, and thus will fail to concatenate
30 the tokens. */
31#define MY(OP) CONCAT2 (i386lynx_aout_,OP)
252b5132
RH
32#define TARGETNAME "a.out-i386-lynx"
33
34#include "bfd.h"
35#include "sysdep.h"
36#include "libbfd.h"
37
38#ifndef WRITE_HEADERS
39#define WRITE_HEADERS(abfd, execp) \
40 { \
41 bfd_size_type text_size; /* dummy vars */ \
42 file_ptr text_end; \
43 if (adata(abfd).magic == undecided_magic) \
44 NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \
45 \
46 execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \
47 execp->a_entry = bfd_get_start_address (abfd); \
48 \
49 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \
50 obj_reloc_entry_size (abfd)); \
51 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \
52 obj_reloc_entry_size (abfd)); \
53 NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \
54 \
dc810e39
AM
55 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 \
56 || bfd_bwrite ((PTR) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, \
57 abfd) != EXEC_BYTES_SIZE) \
b34976b6 58 return FALSE; \
252b5132
RH
59 /* Now write out reloc info, followed by syms and strings */ \
60 \
61 if (bfd_get_symcount (abfd) != 0) \
62 { \
dc810e39 63 if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) \
252b5132 64 != 0) \
b34976b6 65 return FALSE; \
252b5132 66 \
b34976b6 67 if (! NAME(aout,write_syms) (abfd)) return FALSE; \
252b5132 68 \
dc810e39 69 if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) \
252b5132 70 != 0) \
b34976b6 71 return FALSE; \
252b5132
RH
72 \
73 if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd))) \
b34976b6 74 return FALSE; \
dc810e39 75 if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) \
252b5132
RH
76 != 0) \
77 return 0; \
78 \
dc810e39 79 if (!NAME(lynx,squirt_out_relocs) (abfd, obj_datasec (abfd))) \
b34976b6 80 return FALSE; \
252b5132
RH
81 } \
82 }
83#endif
84
85#include "libaout.h"
86#include "aout/aout64.h"
87
b34976b6
AM
88void NAME (lynx,swap_std_reloc_out)
89 PARAMS ((bfd *, arelent *, struct reloc_std_external *));
90void NAME (lynx,swap_ext_reloc_out)
91 PARAMS ((bfd *, arelent *, struct reloc_ext_external *));
92void NAME (lynx,swap_ext_reloc_in)
93 PARAMS ((bfd *, struct reloc_ext_external *, arelent *, asymbol **,
94 bfd_size_type));
95void NAME (lynx,swap_std_reloc_in)
96 PARAMS ((bfd *, struct reloc_std_external *, arelent *, asymbol **,
97 bfd_size_type));
98bfd_boolean NAME (lynx,slurp_reloc_table)
99 PARAMS ((bfd *, sec_ptr, asymbol **));
100bfd_boolean NAME (lynx,squirt_out_relocs)
101 PARAMS ((bfd *, asection *));
102long NAME (lynx,canonicalize_reloc)
103 PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
e4b17274 104
252b5132
RH
105#ifdef LYNX_CORE
106
107char *lynx_core_file_failing_command ();
108int lynx_core_file_failing_signal ();
b34976b6 109bfd_boolean lynx_core_file_matches_executable_p ();
252b5132
RH
110const bfd_target *lynx_core_file_p ();
111
112#define MY_core_file_failing_command lynx_core_file_failing_command
113#define MY_core_file_failing_signal lynx_core_file_failing_signal
114#define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
115#define MY_core_file_p lynx_core_file_p
116
117#endif /* LYNX_CORE */
118\f
119
120#define KEEPIT udata.i
121
122extern reloc_howto_type aout_32_ext_howto_table[];
123extern reloc_howto_type aout_32_std_howto_table[];
124
125/* Standard reloc stuff */
126/* Output standard relocation information to a file in target byte order. */
127
128void
129NAME(lynx,swap_std_reloc_out) (abfd, g, natptr)
130 bfd *abfd;
131 arelent *g;
132 struct reloc_std_external *natptr;
133{
134 int r_index;
135 asymbol *sym = *(g->sym_ptr_ptr);
136 int r_extern;
137 unsigned int r_length;
138 int r_pcrel;
139 int r_baserel, r_jmptable, r_relative;
140 unsigned int r_addend;
141 asection *output_section = sym->section->output_section;
142
143 PUT_WORD (abfd, g->address, natptr->r_address);
144
145 r_length = g->howto->size; /* Size as a power of two */
146 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
147 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
148 r_baserel = 0;
149 r_jmptable = 0;
150 r_relative = 0;
151
152 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
153
154 /* name was clobbered by aout_write_syms to be symbol index */
155
156 /* If this relocation is relative to a symbol then set the
157 r_index to the symbols index, and the r_extern bit.
158
159 Absolute symbols can come in in two ways, either as an offset
160 from the abs section, or as a symbol which has an abs value.
161 check for that here
b34976b6 162 */
252b5132
RH
163
164
165 if (bfd_is_com_section (output_section)
166 || bfd_is_abs_section (output_section)
167 || bfd_is_und_section (output_section))
168 {
169 if (bfd_abs_section_ptr->symbol == sym)
170 {
171 /* Whoops, looked like an abs symbol, but is really an offset
b34976b6 172 from the abs section */
252b5132
RH
173 r_index = 0;
174 r_extern = 0;
175 }
176 else
177 {
178 /* Fill in symbol */
179 r_extern = 1;
180 r_index = (*g->sym_ptr_ptr)->KEEPIT;
181 }
182 }
183 else
184 {
185 /* Just an ordinary section */
186 r_extern = 0;
187 r_index = output_section->target_index;
188 }
189
190 /* now the fun stuff */
191 if (bfd_header_big_endian (abfd))
192 {
193 natptr->r_index[0] = r_index >> 16;
194 natptr->r_index[1] = r_index >> 8;
195 natptr->r_index[2] = r_index;
196 natptr->r_type[0] =
197 (r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
198 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
199 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
200 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
201 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
202 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
203 }
204 else
205 {
206 natptr->r_index[2] = r_index >> 16;
207 natptr->r_index[1] = r_index >> 8;
208 natptr->r_index[0] = r_index;
209 natptr->r_type[0] =
210 (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
211 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
212 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
213 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
214 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
215 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
216 }
217}
218
219
220/* Extended stuff */
221/* Output extended relocation information to a file in target byte order. */
222
223void
224NAME(lynx,swap_ext_reloc_out) (abfd, g, natptr)
225 bfd *abfd;
226 arelent *g;
227 register struct reloc_ext_external *natptr;
228{
229 int r_index;
230 int r_extern;
231 unsigned int r_type;
232 unsigned int r_addend;
233 asymbol *sym = *(g->sym_ptr_ptr);
234 asection *output_section = sym->section->output_section;
235
236 PUT_WORD (abfd, g->address, natptr->r_address);
237
238 r_type = (unsigned int) g->howto->type;
239
240 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
241
242
243 /* If this relocation is relative to a symbol then set the
244 r_index to the symbols index, and the r_extern bit.
245
246 Absolute symbols can come in in two ways, either as an offset
247 from the abs section, or as a symbol which has an abs value.
248 check for that here
249 */
250
251 if (bfd_is_com_section (output_section)
252 || bfd_is_abs_section (output_section)
253 || bfd_is_und_section (output_section))
254 {
255 if (bfd_abs_section_ptr->symbol == sym)
256 {
257 /* Whoops, looked like an abs symbol, but is really an offset
258 from the abs section */
259 r_index = 0;
260 r_extern = 0;
261 }
262 else
263 {
264 r_extern = 1;
265 r_index = (*g->sym_ptr_ptr)->KEEPIT;
266 }
267 }
268 else
269 {
270 /* Just an ordinary section */
271 r_extern = 0;
272 r_index = output_section->target_index;
273 }
274
275
276 /* now the fun stuff */
277 if (bfd_header_big_endian (abfd))
278 {
279 natptr->r_index[0] = r_index >> 16;
280 natptr->r_index[1] = r_index >> 8;
281 natptr->r_index[2] = r_index;
282 natptr->r_type[0] =
283 (r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
284 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
285 }
286 else
287 {
288 natptr->r_index[2] = r_index >> 16;
289 natptr->r_index[1] = r_index >> 8;
290 natptr->r_index[0] = r_index;
291 natptr->r_type[0] =
292 (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
293 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
294 }
295
296 PUT_WORD (abfd, r_addend, natptr->r_addend);
297}
298
299/* BFD deals internally with all things based from the section they're
300 in. so, something in 10 bytes into a text section with a base of
301 50 would have a symbol (.text+10) and know .text vma was 50.
302
303 Aout keeps all it's symbols based from zero, so the symbol would
304 contain 60. This macro subs the base of each section from the value
305 to give the true offset from the section */
306
307
308#define MOVE_ADDRESS(ad) \
309 if (r_extern) { \
310 /* undefined symbol */ \
311 cache_ptr->sym_ptr_ptr = symbols + r_index; \
312 cache_ptr->addend = ad; \
313 } else { \
314 /* defined, section relative. replace symbol with pointer to \
315 symbol which points to section */ \
316 switch (r_index) { \
317 case N_TEXT: \
318 case N_TEXT | N_EXT: \
319 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
320 cache_ptr->addend = ad - su->textsec->vma; \
321 break; \
322 case N_DATA: \
323 case N_DATA | N_EXT: \
324 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
325 cache_ptr->addend = ad - su->datasec->vma; \
326 break; \
327 case N_BSS: \
328 case N_BSS | N_EXT: \
329 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
330 cache_ptr->addend = ad - su->bsssec->vma; \
331 break; \
332 default: \
333 case N_ABS: \
334 case N_ABS | N_EXT: \
335 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
336 cache_ptr->addend = ad; \
337 break; \
338 } \
339 } \
340
341void
342NAME(lynx,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
343 bfd *abfd;
344 struct reloc_ext_external *bytes;
345 arelent *cache_ptr;
346 asymbol **symbols;
5f771d47 347 bfd_size_type symcount ATTRIBUTE_UNUSED;
252b5132
RH
348{
349 int r_index;
350 int r_extern;
351 unsigned int r_type;
352 struct aoutdata *su = &(abfd->tdata.aout_data->a);
353
354 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
355
356 r_index = bytes->r_index[1];
357 r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG));
358 r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG)
359 >> RELOC_EXT_BITS_TYPE_SH_BIG;
360
361 cache_ptr->howto = aout_32_ext_howto_table + r_type;
362 MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
363}
364
365void
366NAME(lynx,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
367 bfd *abfd;
368 struct reloc_std_external *bytes;
369 arelent *cache_ptr;
370 asymbol **symbols;
5f771d47 371 bfd_size_type symcount ATTRIBUTE_UNUSED;
252b5132
RH
372{
373 int r_index;
374 int r_extern;
375 unsigned int r_length;
376 int r_pcrel;
377 int r_baserel, r_jmptable, r_relative;
378 struct aoutdata *su = &(abfd->tdata.aout_data->a);
379
dc810e39 380 cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
252b5132
RH
381
382 r_index = bytes->r_index[1];
383 r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG));
384 r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG));
385 r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG));
386 r_jmptable = (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG));
387 r_relative = (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG));
388 r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG)
389 >> RELOC_STD_BITS_LENGTH_SH_BIG;
390
391 cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel;
392 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
393
394 MOVE_ADDRESS (0);
395}
396
397/* Reloc hackery */
398
b34976b6 399bfd_boolean
252b5132
RH
400NAME(lynx,slurp_reloc_table) (abfd, asect, symbols)
401 bfd *abfd;
402 sec_ptr asect;
403 asymbol **symbols;
404{
dc810e39 405 bfd_size_type count;
252b5132
RH
406 bfd_size_type reloc_size;
407 PTR relocs;
408 arelent *reloc_cache;
409 size_t each_size;
410
411 if (asect->relocation)
b34976b6 412 return TRUE;
252b5132
RH
413
414 if (asect->flags & SEC_CONSTRUCTOR)
b34976b6 415 return TRUE;
252b5132
RH
416
417 if (asect == obj_datasec (abfd))
418 {
419 reloc_size = exec_hdr (abfd)->a_drsize;
420 goto doit;
421 }
422
423 if (asect == obj_textsec (abfd))
424 {
425 reloc_size = exec_hdr (abfd)->a_trsize;
426 goto doit;
427 }
428
429 bfd_set_error (bfd_error_invalid_operation);
b34976b6 430 return FALSE;
252b5132
RH
431
432doit:
433 if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
b34976b6 434 return FALSE;
252b5132
RH
435 each_size = obj_reloc_entry_size (abfd);
436
437 count = reloc_size / each_size;
438
439
9bab7074 440 reloc_cache = (arelent *) bfd_zmalloc (count * sizeof (arelent));
252b5132 441 if (!reloc_cache && count != 0)
b34976b6 442 return FALSE;
252b5132
RH
443
444 relocs = (PTR) bfd_alloc (abfd, reloc_size);
445 if (!relocs && reloc_size != 0)
446 {
447 free (reloc_cache);
b34976b6 448 return FALSE;
252b5132
RH
449 }
450
dc810e39 451 if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
252b5132
RH
452 {
453 bfd_release (abfd, relocs);
454 free (reloc_cache);
b34976b6 455 return FALSE;
252b5132
RH
456 }
457
458 if (each_size == RELOC_EXT_SIZE)
459 {
460 register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
461 unsigned int counter = 0;
462 arelent *cache_ptr = reloc_cache;
463
464 for (; counter < count; counter++, rptr++, cache_ptr++)
465 {
466 NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols,
dc810e39 467 (bfd_size_type) bfd_get_symcount (abfd));
252b5132
RH
468 }
469 }
470 else
471 {
472 register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
473 unsigned int counter = 0;
474 arelent *cache_ptr = reloc_cache;
475
476 for (; counter < count; counter++, rptr++, cache_ptr++)
477 {
478 NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,
dc810e39 479 (bfd_size_type) bfd_get_symcount (abfd));
252b5132
RH
480 }
481
482 }
483
484 bfd_release (abfd, relocs);
485 asect->relocation = reloc_cache;
486 asect->reloc_count = count;
b34976b6 487 return TRUE;
252b5132
RH
488}
489
490
491
492/* Write out a relocation section into an object file. */
493
b34976b6 494bfd_boolean
252b5132
RH
495NAME(lynx,squirt_out_relocs) (abfd, section)
496 bfd *abfd;
497 asection *section;
498{
499 arelent **generic;
500 unsigned char *native, *natptr;
501 size_t each_size;
502
503 unsigned int count = section->reloc_count;
dc810e39 504 bfd_size_type natsize;
252b5132
RH
505
506 if (count == 0)
b34976b6 507 return TRUE;
252b5132
RH
508
509 each_size = obj_reloc_entry_size (abfd);
dc810e39
AM
510 natsize = count;
511 natsize *= each_size;
252b5132
RH
512 native = (unsigned char *) bfd_zalloc (abfd, natsize);
513 if (!native)
b34976b6 514 return FALSE;
252b5132
RH
515
516 generic = section->orelocation;
517
518 if (each_size == RELOC_EXT_SIZE)
519 {
520 for (natptr = native;
521 count != 0;
522 --count, natptr += each_size, ++generic)
523 NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr);
524 }
525 else
526 {
527 for (natptr = native;
528 count != 0;
529 --count, natptr += each_size, ++generic)
530 NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr);
531 }
532
dc810e39 533 if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize)
252b5132
RH
534 {
535 bfd_release (abfd, native);
b34976b6 536 return FALSE;
252b5132
RH
537 }
538 bfd_release (abfd, native);
539
b34976b6 540 return TRUE;
252b5132
RH
541}
542
543/* This is stupid. This function should be a boolean predicate */
544long
545NAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols)
546 bfd *abfd;
547 sec_ptr section;
548 arelent **relptr;
549 asymbol **symbols;
550{
551 arelent *tblptr = section->relocation;
552 unsigned int count;
553
554 if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols)))
555 return -1;
556
557 if (section->flags & SEC_CONSTRUCTOR)
558 {
559 arelent_chain *chain = section->constructor_chain;
560 for (count = 0; count < section->reloc_count; count++)
561 {
562 *relptr++ = &chain->relent;
563 chain = chain->next;
564 }
565 }
566 else
567 {
568 tblptr = section->relocation;
569
570 for (count = 0; count++ < section->reloc_count;)
571 {
572 *relptr++ = tblptr++;
573 }
574 }
575 *relptr = 0;
576
577 return section->reloc_count;
578}
579
580#define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
581
582#include "aout-target.h"
This page took 0.352393 seconds and 4 git commands to generate.