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