* elfread.c (elf_symtab_read): Change storage_needed,
[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
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#define BYTES_IN_WORD 4
21#define ARCH 32
22#define N_SHARED_LIB(x) 0
23
24#define TEXT_START_ADDR 0
25#define PAGE_SIZE 4096
26#define SEGMENT_SIZE PAGE_SIZE
27#define DEFAULT_ARCH bfd_arch_i386
28
29#define MY(OP) CAT(i386lynx_aout_,OP)
30#define TARGETNAME "a.out-i386-lynx"
31
32#include "bfd.h"
33#include "sysdep.h"
34#include "libbfd.h"
35
36#ifndef WRITE_HEADERS
37#define WRITE_HEADERS(abfd, execp) \
38 { \
39 bfd_size_type text_size; /* dummy vars */ \
40 file_ptr text_end; \
41 if (adata(abfd).magic == undecided_magic) \
42 NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \
43 \
44 execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \
45 execp->a_entry = bfd_get_start_address (abfd); \
46 \
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); \
52 \
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 */ \
56 \
57 if (bfd_get_symcount (abfd) != 0) \
58 { \
59 bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET); \
60 \
25057836 61 if (! NAME(aout,write_syms)(abfd)) return false; \
48ee0757
SS
62 \
63 bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET); \
64 \
65 if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd))) return false; \
66 bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET); \
67 \
68 if (!NAME(lynx,squirt_out_relocs)(abfd, obj_datasec (abfd))) return false; \
69 } \
25057836 70 }
48ee0757
SS
71#endif
72
73#include "libaout.h"
74#include "aout/aout64.h"
75
76#ifdef HOST_LYNX
77
25057836
JL
78char *lynx_core_file_failing_command ();
79int lynx_core_file_failing_signal ();
80boolean lynx_core_file_matches_executable_p ();
81bfd_target *lynx_core_file_p ();
48ee0757
SS
82
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
87
88#endif /* HOST_LYNX */
48ee0757 89\f
25057836 90
48ee0757
SS
91#define KEEPIT flags
92
93extern reloc_howto_type aout_32_ext_howto_table[];
94extern reloc_howto_type aout_32_std_howto_table[];
95
96/* Standard reloc stuff */
97/* Output standard relocation information to a file in target byte order. */
98
99void
25057836
JL
100NAME (lynx, swap_std_reloc_out) (abfd, g, natptr)
101 bfd *abfd;
102 arelent *g;
103 struct reloc_std_external *natptr;
48ee0757
SS
104{
105 int r_index;
106 asymbol *sym = *(g->sym_ptr_ptr);
107 int r_extern;
108 unsigned int r_length;
109 int r_pcrel;
110 int r_baserel, r_jmptable, r_relative;
111 unsigned int r_addend;
112 asection *output_section = sym->section->output_section;
113
25057836 114 PUT_WORD (abfd, g->address, natptr->r_address);
48ee0757 115
25057836
JL
116 r_length = g->howto->size; /* Size as a power of two */
117 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
48ee0757
SS
118 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
119 r_baserel = 0;
120 r_jmptable = 0;
121 r_relative = 0;
25057836 122
48ee0757 123 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
25057836 124
48ee0757
SS
125 /* name was clobbered by aout_write_syms to be symbol index */
126
25057836 127 /* If this relocation is relative to a symbol then set the
48ee0757
SS
128 r_index to the symbols index, and the r_extern bit.
129
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.
132 check for that here
133 */
25057836 134
48ee0757
SS
135
136 if (bfd_is_com_section (output_section)
137 || output_section == &bfd_abs_section
25057836 138 || output_section == &bfd_und_section)
48ee0757
SS
139 {
140 if (bfd_abs_section.symbol == sym)
25057836
JL
141 {
142 /* Whoops, looked like an abs symbol, but is really an offset
48ee0757 143 from the abs section */
25057836
JL
144 r_index = 0;
145 r_extern = 0;
146 }
147 else
148 {
149 /* Fill in symbol */
150 r_extern = 1;
151 r_index = stoi ((*(g->sym_ptr_ptr))->KEEPIT);
152
153 }
48ee0757 154 }
25057836 155 else
48ee0757
SS
156 {
157 /* Just an ordinary section */
158 r_extern = 0;
25057836 159 r_index = output_section->target_index;
48ee0757
SS
160 }
161
162 /* now the fun stuff */
25057836
JL
163 if (abfd->xvec->header_byteorder_big_p != false)
164 {
48ee0757
SS
165 natptr->r_index[0] = r_index >> 16;
166 natptr->r_index[1] = r_index >> 8;
167 natptr->r_index[2] = r_index;
168 natptr->r_type[0] =
25057836
JL
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);
175 }
176 else
177 {
178 natptr->r_index[2] = r_index >> 16;
179 natptr->r_index[1] = r_index >> 8;
180 natptr->r_index[0] = r_index;
181 natptr->r_type[0] =
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);
188 }
48ee0757
SS
189}
190
191
192/* Extended stuff */
193/* Output extended relocation information to a file in target byte order. */
194
195void
25057836
JL
196NAME (lynx, swap_ext_reloc_out) (abfd, g, natptr)
197 bfd *abfd;
198 arelent *g;
199 register struct reloc_ext_external *natptr;
48ee0757
SS
200{
201 int r_index;
202 int r_extern;
203 unsigned int r_type;
204 unsigned int r_addend;
25057836 205 asymbol *sym = *(g->sym_ptr_ptr);
48ee0757 206 asection *output_section = sym->section->output_section;
25057836 207
48ee0757 208 PUT_WORD (abfd, g->address, natptr->r_address);
25057836 209
48ee0757 210 r_type = (unsigned int) g->howto->type;
25057836 211
48ee0757
SS
212 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
213
214
25057836 215 /* If this relocation is relative to a symbol then set the
48ee0757
SS
216 r_index to the symbols index, and the r_extern bit.
217
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.
220 check for that here
221 */
25057836 222
48ee0757
SS
223 if (bfd_is_com_section (output_section)
224 || output_section == &bfd_abs_section
225 || output_section == &bfd_und_section)
48ee0757 226 {
25057836
JL
227 if (bfd_abs_section.symbol == sym)
228 {
229 /* Whoops, looked like an abs symbol, but is really an offset
48ee0757 230 from the abs section */
25057836
JL
231 r_index = 0;
232 r_extern = 0;
233 }
234 else
235 {
236 r_extern = 1;
237 r_index = stoi ((*(g->sym_ptr_ptr))->KEEPIT);
238 }
239 }
240 else
48ee0757 241 {
25057836
JL
242 /* Just an ordinary section */
243 r_extern = 0;
244 r_index = output_section->target_index;
48ee0757 245 }
25057836
JL
246
247
48ee0757 248 /* now the fun stuff */
25057836
JL
249 if (abfd->xvec->header_byteorder_big_p != false)
250 {
251 natptr->r_index[0] = r_index >> 16;
252 natptr->r_index[1] = r_index >> 8;
253 natptr->r_index[2] = r_index;
254 natptr->r_type[0] =
255 (r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
256 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
257 }
258 else
259 {
260 natptr->r_index[2] = r_index >> 16;
261 natptr->r_index[1] = r_index >> 8;
262 natptr->r_index[0] = r_index;
263 natptr->r_type[0] =
264 (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
265 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
266 }
48ee0757
SS
267
268 PUT_WORD (abfd, r_addend, natptr->r_addend);
269}
270
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
25057836 273 50 would have a symbol (.text+10) and know .text vma was 50.
48ee0757
SS
274
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 */
278
279
280#define MOVE_ADDRESS(ad) \
281 if (r_extern) { \
282 /* undefined symbol */ \
283 cache_ptr->sym_ptr_ptr = symbols + r_index; \
284 cache_ptr->addend = ad; \
285 } else { \
286 /* defined, section relative. replace symbol with pointer to \
287 symbol which points to section */ \
288 switch (r_index) { \
289 case N_TEXT: \
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; \
293 break; \
294 case N_DATA: \
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; \
298 break; \
299 case N_BSS: \
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; \
303 break; \
304 default: \
305 case N_ABS: \
306 case N_ABS | N_EXT: \
307 cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; \
308 cache_ptr->addend = ad; \
309 break; \
310 } \
311 } \
312
313void
25057836
JL
314NAME (lynx, swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols)
315 bfd *abfd;
316 struct reloc_ext_external *bytes;
317 arelent *cache_ptr;
318 asymbol **symbols;
48ee0757
SS
319{
320 int r_index;
321 int r_extern;
322 unsigned int r_type;
323 struct aoutdata *su = &(abfd->tdata.aout_data->a);
324
325 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
326
25057836
JL
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;
331
332 cache_ptr->howto = aout_32_ext_howto_table + r_type;
333 MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
48ee0757
SS
334}
335
336void
25057836
JL
337NAME (lynx, swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols)
338 bfd *abfd;
339 struct reloc_std_external *bytes;
340 arelent *cache_ptr;
341 asymbol **symbols;
48ee0757 342{
48ee0757
SS
343 int r_index;
344 int r_extern;
345 unsigned int r_length;
346 int r_pcrel;
347 int r_baserel, r_jmptable, r_relative;
25057836 348 struct aoutdata *su = &(abfd->tdata.aout_data->a);
48ee0757
SS
349
350 cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
351
25057836
JL
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));
48ee0757 355 r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG));
25057836
JL
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)
48ee0757
SS
359 >> RELOC_STD_BITS_LENGTH_SH_BIG;
360
25057836 361 cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel;
48ee0757
SS
362 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
363
25057836 364 MOVE_ADDRESS (0);
48ee0757
SS
365}
366
367/* Reloc hackery */
368
369boolean
25057836
JL
370NAME (lynx, slurp_reloc_table) (abfd, asect, symbols)
371 bfd *abfd;
372 sec_ptr asect;
373 asymbol **symbols;
48ee0757
SS
374{
375 unsigned int count;
376 bfd_size_type reloc_size;
377 PTR relocs;
378 arelent *reloc_cache;
379 size_t each_size;
380
25057836
JL
381 if (asect->relocation)
382 return true;
48ee0757 383
25057836
JL
384 if (asect->flags & SEC_CONSTRUCTOR)
385 return true;
48ee0757 386
25057836
JL
387 if (asect == obj_datasec (abfd))
388 {
389 reloc_size = exec_hdr (abfd)->a_drsize;
390 goto doit;
391 }
48ee0757 392
25057836
JL
393 if (asect == obj_textsec (abfd))
394 {
395 reloc_size = exec_hdr (abfd)->a_trsize;
396 goto doit;
397 }
48ee0757 398
25057836 399 bfd_set_error (bfd_error_invalid_operation);
48ee0757
SS
400 return false;
401
25057836 402doit:
48ee0757
SS
403 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
404 each_size = obj_reloc_entry_size (abfd);
405
406 count = reloc_size / each_size;
407
408
25057836
JL
409 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t) (count * sizeof
410 (arelent)));
411 if (!reloc_cache)
412 {
413 nomem:
414 bfd_set_error (bfd_error_no_memory);
415 return false;
416 }
48ee0757
SS
417
418 relocs = (PTR) bfd_alloc (abfd, reloc_size);
25057836
JL
419 if (!relocs)
420 {
421 bfd_release (abfd, reloc_cache);
422 goto nomem;
48ee0757 423 }
48ee0757 424
25057836
JL
425 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size)
426 {
427 bfd_release (abfd, relocs);
428 bfd_release (abfd, reloc_cache);
429 return false;
430 }
431
432 if (each_size == RELOC_EXT_SIZE)
433 {
434 register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
435 unsigned int counter = 0;
436 arelent *cache_ptr = reloc_cache;
437
438 for (; counter < count; counter++, rptr++, cache_ptr++)
439 {
440 NAME (lynx, swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols);
441 }
48ee0757 442 }
25057836
JL
443 else
444 {
445 register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
446 unsigned int counter = 0;
447 arelent *cache_ptr = reloc_cache;
448
449 for (; counter < count; counter++, rptr++, cache_ptr++)
450 {
451 NAME (lynx, swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols);
452 }
48ee0757 453
25057836 454 }
48ee0757 455
25057836 456 bfd_release (abfd, relocs);
48ee0757
SS
457 asect->relocation = reloc_cache;
458 asect->reloc_count = count;
459 return true;
460}
461
462
463
464/* Write out a relocation section into an object file. */
465
466boolean
25057836
JL
467NAME (lynx, squirt_out_relocs) (abfd, section)
468 bfd *abfd;
469 asection *section;
48ee0757
SS
470{
471 arelent **generic;
472 unsigned char *native, *natptr;
473 size_t each_size;
474
475 unsigned int count = section->reloc_count;
476 size_t natsize;
477
25057836
JL
478 if (count == 0)
479 return true;
48ee0757
SS
480
481 each_size = obj_reloc_entry_size (abfd);
482 natsize = each_size * count;
483 native = (unsigned char *) bfd_zalloc (abfd, natsize);
25057836
JL
484 if (!native)
485 {
486 bfd_set_error (bfd_error_no_memory);
487 return false;
488 }
48ee0757
SS
489
490 generic = section->orelocation;
491
25057836 492 if (each_size == RELOC_EXT_SIZE)
48ee0757
SS
493 {
494 for (natptr = native;
495 count != 0;
496 --count, natptr += each_size, ++generic)
25057836 497 NAME (lynx, swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr);
48ee0757 498 }
25057836 499 else
48ee0757
SS
500 {
501 for (natptr = native;
502 count != 0;
503 --count, natptr += each_size, ++generic)
25057836 504 NAME (lynx, swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr);
48ee0757
SS
505 }
506
25057836
JL
507 if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize)
508 {
509 bfd_release (abfd, native);
510 return false;
511 }
48ee0757
SS
512 bfd_release (abfd, native);
513
514 return true;
515}
516
517/* This is stupid. This function should be a boolean predicate */
518unsigned int
25057836
JL
519NAME (lynx, canonicalize_reloc) (abfd, section, relptr, symbols)
520 bfd *abfd;
521 sec_ptr section;
522 arelent **relptr;
523 asymbol **symbols;
48ee0757
SS
524{
525 arelent *tblptr = section->relocation;
526 unsigned int count;
527
25057836 528 if (!(tblptr || NAME (lynx, slurp_reloc_table) (abfd, section, symbols)))
48ee0757
SS
529 return 0;
530
25057836
JL
531 if (section->flags & SEC_CONSTRUCTOR)
532 {
533 arelent_chain *chain = section->constructor_chain;
534 for (count = 0; count < section->reloc_count; count++)
535 {
536 *relptr++ = &chain->relent;
537 chain = chain->next;
538 }
539 }
540 else
541 {
542 tblptr = section->relocation;
543 if (!tblptr)
544 return 0;
545
546 for (count = 0; count++ < section->reloc_count;)
547 {
548 *relptr++ = tblptr++;
549 }
48ee0757 550 }
48ee0757
SS
551 *relptr = 0;
552
553 return section->reloc_count;
554}
555
556#define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
557
558#include "aout-target.h"
This page took 0.066914 seconds and 4 git commands to generate.