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