* som.c (hppa_som_gen_reloc_type): Choose a reasonable field
[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 \
4002f18a
ILT
53 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false; \
54 if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) \
55 != EXEC_BYTES_SIZE) \
56 return false; \
48ee0757
SS
57 /* Now write out reloc info, followed by syms and strings */ \
58 \
59 if (bfd_get_symcount (abfd) != 0) \
60 { \
4002f18a
ILT
61 if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET) \
62 != 0) \
63 return false; \
48ee0757 64 \
25057836 65 if (! NAME(aout,write_syms)(abfd)) return false; \
48ee0757 66 \
4002f18a
ILT
67 if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET) \
68 != 0) \
69 return false; \
48ee0757 70 \
4002f18a
ILT
71 if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd))) \
72 return false; \
73 if (bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET) \
74 != 0) \
75 return 0; \
48ee0757 76 \
4002f18a
ILT
77 if (!NAME(lynx,squirt_out_relocs)(abfd, obj_datasec (abfd))) \
78 return false; \
48ee0757 79 } \
25057836 80 }
48ee0757
SS
81#endif
82
83#include "libaout.h"
84#include "aout/aout64.h"
85
86#ifdef HOST_LYNX
87
25057836
JL
88char *lynx_core_file_failing_command ();
89int lynx_core_file_failing_signal ();
90boolean lynx_core_file_matches_executable_p ();
2f3508ad 91const bfd_target *lynx_core_file_p ();
48ee0757
SS
92
93#define MY_core_file_failing_command lynx_core_file_failing_command
94#define MY_core_file_failing_signal lynx_core_file_failing_signal
95#define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
96#define MY_core_file_p lynx_core_file_p
97
98#endif /* HOST_LYNX */
48ee0757 99\f
25057836 100
48ee0757
SS
101#define KEEPIT flags
102
103extern reloc_howto_type aout_32_ext_howto_table[];
104extern reloc_howto_type aout_32_std_howto_table[];
105
106/* Standard reloc stuff */
107/* Output standard relocation information to a file in target byte order. */
108
109void
2f3508ad 110NAME(lynx,swap_std_reloc_out) (abfd, g, natptr)
25057836
JL
111 bfd *abfd;
112 arelent *g;
113 struct reloc_std_external *natptr;
48ee0757
SS
114{
115 int r_index;
116 asymbol *sym = *(g->sym_ptr_ptr);
117 int r_extern;
118 unsigned int r_length;
119 int r_pcrel;
120 int r_baserel, r_jmptable, r_relative;
121 unsigned int r_addend;
122 asection *output_section = sym->section->output_section;
123
25057836 124 PUT_WORD (abfd, g->address, natptr->r_address);
48ee0757 125
25057836
JL
126 r_length = g->howto->size; /* Size as a power of two */
127 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
48ee0757
SS
128 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
129 r_baserel = 0;
130 r_jmptable = 0;
131 r_relative = 0;
25057836 132
48ee0757 133 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
25057836 134
48ee0757
SS
135 /* name was clobbered by aout_write_syms to be symbol index */
136
25057836 137 /* If this relocation is relative to a symbol then set the
48ee0757
SS
138 r_index to the symbols index, and the r_extern bit.
139
140 Absolute symbols can come in in two ways, either as an offset
141 from the abs section, or as a symbol which has an abs value.
142 check for that here
143 */
25057836 144
48ee0757
SS
145
146 if (bfd_is_com_section (output_section)
147 || output_section == &bfd_abs_section
25057836 148 || output_section == &bfd_und_section)
48ee0757
SS
149 {
150 if (bfd_abs_section.symbol == sym)
25057836
JL
151 {
152 /* Whoops, looked like an abs symbol, but is really an offset
48ee0757 153 from the abs section */
25057836
JL
154 r_index = 0;
155 r_extern = 0;
156 }
157 else
158 {
159 /* Fill in symbol */
160 r_extern = 1;
161 r_index = stoi ((*(g->sym_ptr_ptr))->KEEPIT);
162
163 }
48ee0757 164 }
25057836 165 else
48ee0757
SS
166 {
167 /* Just an ordinary section */
168 r_extern = 0;
25057836 169 r_index = output_section->target_index;
48ee0757
SS
170 }
171
172 /* now the fun stuff */
25057836
JL
173 if (abfd->xvec->header_byteorder_big_p != false)
174 {
48ee0757
SS
175 natptr->r_index[0] = r_index >> 16;
176 natptr->r_index[1] = r_index >> 8;
177 natptr->r_index[2] = r_index;
178 natptr->r_type[0] =
25057836
JL
179 (r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
180 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
181 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
182 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
183 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
184 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
185 }
186 else
187 {
188 natptr->r_index[2] = r_index >> 16;
189 natptr->r_index[1] = r_index >> 8;
190 natptr->r_index[0] = r_index;
191 natptr->r_type[0] =
192 (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
193 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
194 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
195 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
196 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
197 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
198 }
48ee0757
SS
199}
200
201
202/* Extended stuff */
203/* Output extended relocation information to a file in target byte order. */
204
205void
2f3508ad 206NAME(lynx,swap_ext_reloc_out) (abfd, g, natptr)
25057836
JL
207 bfd *abfd;
208 arelent *g;
209 register struct reloc_ext_external *natptr;
48ee0757
SS
210{
211 int r_index;
212 int r_extern;
213 unsigned int r_type;
214 unsigned int r_addend;
25057836 215 asymbol *sym = *(g->sym_ptr_ptr);
48ee0757 216 asection *output_section = sym->section->output_section;
25057836 217
48ee0757 218 PUT_WORD (abfd, g->address, natptr->r_address);
25057836 219
48ee0757 220 r_type = (unsigned int) g->howto->type;
25057836 221
48ee0757
SS
222 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
223
224
25057836 225 /* If this relocation is relative to a symbol then set the
48ee0757
SS
226 r_index to the symbols index, and the r_extern bit.
227
228 Absolute symbols can come in in two ways, either as an offset
229 from the abs section, or as a symbol which has an abs value.
230 check for that here
231 */
25057836 232
48ee0757
SS
233 if (bfd_is_com_section (output_section)
234 || output_section == &bfd_abs_section
235 || output_section == &bfd_und_section)
48ee0757 236 {
25057836
JL
237 if (bfd_abs_section.symbol == sym)
238 {
239 /* Whoops, looked like an abs symbol, but is really an offset
48ee0757 240 from the abs section */
25057836
JL
241 r_index = 0;
242 r_extern = 0;
243 }
244 else
245 {
246 r_extern = 1;
247 r_index = stoi ((*(g->sym_ptr_ptr))->KEEPIT);
248 }
249 }
250 else
48ee0757 251 {
25057836
JL
252 /* Just an ordinary section */
253 r_extern = 0;
254 r_index = output_section->target_index;
48ee0757 255 }
25057836
JL
256
257
48ee0757 258 /* now the fun stuff */
25057836
JL
259 if (abfd->xvec->header_byteorder_big_p != false)
260 {
261 natptr->r_index[0] = r_index >> 16;
262 natptr->r_index[1] = r_index >> 8;
263 natptr->r_index[2] = r_index;
264 natptr->r_type[0] =
265 (r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
266 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
267 }
268 else
269 {
270 natptr->r_index[2] = r_index >> 16;
271 natptr->r_index[1] = r_index >> 8;
272 natptr->r_index[0] = r_index;
273 natptr->r_type[0] =
274 (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
275 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
276 }
48ee0757
SS
277
278 PUT_WORD (abfd, r_addend, natptr->r_addend);
279}
280
281/* BFD deals internally with all things based from the section they're
282 in. so, something in 10 bytes into a text section with a base of
25057836 283 50 would have a symbol (.text+10) and know .text vma was 50.
48ee0757
SS
284
285 Aout keeps all it's symbols based from zero, so the symbol would
286 contain 60. This macro subs the base of each section from the value
287 to give the true offset from the section */
288
289
290#define MOVE_ADDRESS(ad) \
291 if (r_extern) { \
292 /* undefined symbol */ \
293 cache_ptr->sym_ptr_ptr = symbols + r_index; \
294 cache_ptr->addend = ad; \
295 } else { \
296 /* defined, section relative. replace symbol with pointer to \
297 symbol which points to section */ \
298 switch (r_index) { \
299 case N_TEXT: \
300 case N_TEXT | N_EXT: \
301 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
302 cache_ptr->addend = ad - su->textsec->vma; \
303 break; \
304 case N_DATA: \
305 case N_DATA | N_EXT: \
306 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
307 cache_ptr->addend = ad - su->datasec->vma; \
308 break; \
309 case N_BSS: \
310 case N_BSS | N_EXT: \
311 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
312 cache_ptr->addend = ad - su->bsssec->vma; \
313 break; \
314 default: \
315 case N_ABS: \
316 case N_ABS | N_EXT: \
317 cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; \
318 cache_ptr->addend = ad; \
319 break; \
320 } \
321 } \
322
323void
2f3508ad 324NAME(lynx,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols)
25057836
JL
325 bfd *abfd;
326 struct reloc_ext_external *bytes;
327 arelent *cache_ptr;
328 asymbol **symbols;
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
2f3508ad 347NAME(lynx,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols)
25057836
JL
348 bfd *abfd;
349 struct reloc_std_external *bytes;
350 arelent *cache_ptr;
351 asymbol **symbols;
48ee0757 352{
48ee0757
SS
353 int r_index;
354 int r_extern;
355 unsigned int r_length;
356 int r_pcrel;
357 int r_baserel, r_jmptable, r_relative;
25057836 358 struct aoutdata *su = &(abfd->tdata.aout_data->a);
48ee0757
SS
359
360 cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
361
25057836
JL
362 r_index = bytes->r_index[1];
363 r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG));
364 r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG));
48ee0757 365 r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG));
25057836
JL
366 r_jmptable = (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG));
367 r_relative = (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG));
368 r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG)
48ee0757
SS
369 >> RELOC_STD_BITS_LENGTH_SH_BIG;
370
25057836 371 cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel;
48ee0757
SS
372 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
373
25057836 374 MOVE_ADDRESS (0);
48ee0757
SS
375}
376
377/* Reloc hackery */
378
379boolean
5c8444f8 380NAME(lynx,slurp_reloc_table) (abfd, asect, symbols)
25057836
JL
381 bfd *abfd;
382 sec_ptr asect;
383 asymbol **symbols;
48ee0757
SS
384{
385 unsigned int count;
386 bfd_size_type reloc_size;
387 PTR relocs;
388 arelent *reloc_cache;
389 size_t each_size;
390
25057836
JL
391 if (asect->relocation)
392 return true;
48ee0757 393
25057836
JL
394 if (asect->flags & SEC_CONSTRUCTOR)
395 return true;
48ee0757 396
25057836
JL
397 if (asect == obj_datasec (abfd))
398 {
399 reloc_size = exec_hdr (abfd)->a_drsize;
400 goto doit;
401 }
48ee0757 402
25057836
JL
403 if (asect == obj_textsec (abfd))
404 {
405 reloc_size = exec_hdr (abfd)->a_trsize;
406 goto doit;
407 }
48ee0757 408
25057836 409 bfd_set_error (bfd_error_invalid_operation);
48ee0757
SS
410 return false;
411
25057836 412doit:
5c8444f8
ILT
413 if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
414 return false;
48ee0757
SS
415 each_size = obj_reloc_entry_size (abfd);
416
417 count = reloc_size / each_size;
418
419
5c8444f8
ILT
420 reloc_cache = (arelent *) malloc (count * sizeof (arelent));
421 if (!reloc_cache && count != 0)
25057836
JL
422 {
423 nomem:
424 bfd_set_error (bfd_error_no_memory);
425 return false;
426 }
5c8444f8 427 memset (reloc_cache, 0, count * sizeof (arelent));
48ee0757
SS
428
429 relocs = (PTR) bfd_alloc (abfd, reloc_size);
b3cee0a9 430 if (!relocs && reloc_size != 0)
25057836 431 {
5c8444f8 432 free (reloc_cache);
25057836 433 goto nomem;
48ee0757 434 }
48ee0757 435
25057836
JL
436 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size)
437 {
438 bfd_release (abfd, relocs);
5c8444f8 439 free (reloc_cache);
25057836
JL
440 return false;
441 }
442
443 if (each_size == RELOC_EXT_SIZE)
444 {
445 register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
446 unsigned int counter = 0;
447 arelent *cache_ptr = reloc_cache;
448
449 for (; counter < count; counter++, rptr++, cache_ptr++)
450 {
2f3508ad 451 NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols);
25057836 452 }
48ee0757 453 }
25057836
JL
454 else
455 {
456 register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
457 unsigned int counter = 0;
458 arelent *cache_ptr = reloc_cache;
459
460 for (; counter < count; counter++, rptr++, cache_ptr++)
461 {
2f3508ad 462 NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols);
25057836 463 }
48ee0757 464
25057836 465 }
48ee0757 466
25057836 467 bfd_release (abfd, relocs);
48ee0757
SS
468 asect->relocation = reloc_cache;
469 asect->reloc_count = count;
470 return true;
471}
472
473
474
475/* Write out a relocation section into an object file. */
476
477boolean
2f3508ad 478NAME(lynx,squirt_out_relocs) (abfd, section)
25057836
JL
479 bfd *abfd;
480 asection *section;
48ee0757
SS
481{
482 arelent **generic;
483 unsigned char *native, *natptr;
484 size_t each_size;
485
486 unsigned int count = section->reloc_count;
487 size_t natsize;
488
25057836
JL
489 if (count == 0)
490 return true;
48ee0757
SS
491
492 each_size = obj_reloc_entry_size (abfd);
493 natsize = each_size * count;
494 native = (unsigned char *) bfd_zalloc (abfd, natsize);
25057836
JL
495 if (!native)
496 {
497 bfd_set_error (bfd_error_no_memory);
498 return false;
499 }
48ee0757
SS
500
501 generic = section->orelocation;
502
25057836 503 if (each_size == RELOC_EXT_SIZE)
48ee0757
SS
504 {
505 for (natptr = native;
506 count != 0;
507 --count, natptr += each_size, ++generic)
2f3508ad 508 NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr);
48ee0757 509 }
25057836 510 else
48ee0757
SS
511 {
512 for (natptr = native;
513 count != 0;
514 --count, natptr += each_size, ++generic)
2f3508ad 515 NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr);
48ee0757
SS
516 }
517
25057836
JL
518 if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize)
519 {
520 bfd_release (abfd, native);
521 return false;
522 }
48ee0757
SS
523 bfd_release (abfd, native);
524
525 return true;
526}
527
528/* This is stupid. This function should be a boolean predicate */
326e32d7
ILT
529long
530NAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols)
25057836
JL
531 bfd *abfd;
532 sec_ptr section;
533 arelent **relptr;
534 asymbol **symbols;
48ee0757
SS
535{
536 arelent *tblptr = section->relocation;
537 unsigned int count;
538
b3cee0a9 539 if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols)))
326e32d7 540 return -1;
48ee0757 541
25057836
JL
542 if (section->flags & SEC_CONSTRUCTOR)
543 {
544 arelent_chain *chain = section->constructor_chain;
545 for (count = 0; count < section->reloc_count; count++)
546 {
547 *relptr++ = &chain->relent;
548 chain = chain->next;
549 }
550 }
551 else
552 {
553 tblptr = section->relocation;
25057836
JL
554
555 for (count = 0; count++ < section->reloc_count;)
556 {
557 *relptr++ = tblptr++;
558 }
48ee0757 559 }
48ee0757
SS
560 *relptr = 0;
561
562 return section->reloc_count;
563}
564
565#define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
566
567#include "aout-target.h"
This page took 0.103703 seconds and 4 git commands to generate.