* objcopy.c (add_redefine_syms_file): Avoid symbol buffer
[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,
4a056f14 3 2003, 2005, 2007, 2009 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;
139 unsigned int r_addend;
140 asection *output_section = sym->section->output_section;
141
142 PUT_WORD (abfd, g->address, natptr->r_address);
143
144 r_length = g->howto->size; /* Size as a power of two */
145 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
146 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
147 r_baserel = 0;
148 r_jmptable = 0;
149 r_relative = 0;
150
151 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
152
153 /* name was clobbered by aout_write_syms to be symbol index */
154
155 /* If this relocation is relative to a symbol then set the
156 r_index to the symbols index, and the r_extern bit.
157
158 Absolute symbols can come in in two ways, either as an offset
159 from the abs section, or as a symbol which has an abs value.
160 check for that here
b34976b6 161 */
252b5132
RH
162
163
164 if (bfd_is_com_section (output_section)
165 || bfd_is_abs_section (output_section)
166 || bfd_is_und_section (output_section))
167 {
168 if (bfd_abs_section_ptr->symbol == sym)
169 {
170 /* Whoops, looked like an abs symbol, but is really an offset
b34976b6 171 from the abs section */
252b5132
RH
172 r_index = 0;
173 r_extern = 0;
174 }
175 else
176 {
177 /* Fill in symbol */
178 r_extern = 1;
179 r_index = (*g->sym_ptr_ptr)->KEEPIT;
180 }
181 }
182 else
183 {
184 /* Just an ordinary section */
185 r_extern = 0;
186 r_index = output_section->target_index;
187 }
188
189 /* now the fun stuff */
190 if (bfd_header_big_endian (abfd))
191 {
192 natptr->r_index[0] = r_index >> 16;
193 natptr->r_index[1] = r_index >> 8;
194 natptr->r_index[2] = r_index;
195 natptr->r_type[0] =
196 (r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
197 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
198 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
199 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
200 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
201 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
202 }
203 else
204 {
205 natptr->r_index[2] = r_index >> 16;
206 natptr->r_index[1] = r_index >> 8;
207 natptr->r_index[0] = r_index;
208 natptr->r_type[0] =
209 (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
210 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
211 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
212 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
213 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
214 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
215 }
216}
217
218
219/* Extended stuff */
220/* Output extended relocation information to a file in target byte order. */
221
222void
223NAME(lynx,swap_ext_reloc_out) (abfd, g, natptr)
224 bfd *abfd;
225 arelent *g;
226 register struct reloc_ext_external *natptr;
227{
228 int r_index;
229 int r_extern;
230 unsigned int r_type;
231 unsigned int r_addend;
232 asymbol *sym = *(g->sym_ptr_ptr);
233 asection *output_section = sym->section->output_section;
234
235 PUT_WORD (abfd, g->address, natptr->r_address);
236
237 r_type = (unsigned int) g->howto->type;
238
239 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
240
241
242 /* If this relocation is relative to a symbol then set the
243 r_index to the symbols index, and the r_extern bit.
244
245 Absolute symbols can come in in two ways, either as an offset
246 from the abs section, or as a symbol which has an abs value.
247 check for that here
248 */
249
250 if (bfd_is_com_section (output_section)
251 || bfd_is_abs_section (output_section)
252 || bfd_is_und_section (output_section))
253 {
254 if (bfd_abs_section_ptr->symbol == sym)
255 {
256 /* Whoops, looked like an abs symbol, but is really an offset
257 from the abs section */
258 r_index = 0;
259 r_extern = 0;
260 }
261 else
262 {
263 r_extern = 1;
264 r_index = (*g->sym_ptr_ptr)->KEEPIT;
265 }
266 }
267 else
268 {
269 /* Just an ordinary section */
270 r_extern = 0;
271 r_index = output_section->target_index;
272 }
273
274
275 /* now the fun stuff */
276 if (bfd_header_big_endian (abfd))
277 {
278 natptr->r_index[0] = r_index >> 16;
279 natptr->r_index[1] = r_index >> 8;
280 natptr->r_index[2] = r_index;
281 natptr->r_type[0] =
282 (r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
283 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
284 }
285 else
286 {
287 natptr->r_index[2] = r_index >> 16;
288 natptr->r_index[1] = r_index >> 8;
289 natptr->r_index[0] = r_index;
290 natptr->r_type[0] =
291 (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
292 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
293 }
294
295 PUT_WORD (abfd, r_addend, natptr->r_addend);
296}
297
298/* BFD deals internally with all things based from the section they're
299 in. so, something in 10 bytes into a text section with a base of
300 50 would have a symbol (.text+10) and know .text vma was 50.
301
302 Aout keeps all it's symbols based from zero, so the symbol would
303 contain 60. This macro subs the base of each section from the value
304 to give the true offset from the section */
305
306
307#define MOVE_ADDRESS(ad) \
308 if (r_extern) { \
309 /* undefined symbol */ \
310 cache_ptr->sym_ptr_ptr = symbols + r_index; \
311 cache_ptr->addend = ad; \
312 } else { \
313 /* defined, section relative. replace symbol with pointer to \
314 symbol which points to section */ \
315 switch (r_index) { \
316 case N_TEXT: \
317 case N_TEXT | N_EXT: \
318 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
319 cache_ptr->addend = ad - su->textsec->vma; \
320 break; \
321 case N_DATA: \
322 case N_DATA | N_EXT: \
323 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
324 cache_ptr->addend = ad - su->datasec->vma; \
325 break; \
326 case N_BSS: \
327 case N_BSS | N_EXT: \
328 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
329 cache_ptr->addend = ad - su->bsssec->vma; \
330 break; \
331 default: \
332 case N_ABS: \
333 case N_ABS | N_EXT: \
334 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
335 cache_ptr->addend = ad; \
336 break; \
337 } \
338 } \
339
340void
341NAME(lynx,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
342 bfd *abfd;
343 struct reloc_ext_external *bytes;
344 arelent *cache_ptr;
345 asymbol **symbols;
5f771d47 346 bfd_size_type symcount ATTRIBUTE_UNUSED;
252b5132
RH
347{
348 int r_index;
349 int r_extern;
350 unsigned int r_type;
351 struct aoutdata *su = &(abfd->tdata.aout_data->a);
352
353 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
354
355 r_index = bytes->r_index[1];
356 r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG));
357 r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG)
358 >> RELOC_EXT_BITS_TYPE_SH_BIG;
359
360 cache_ptr->howto = aout_32_ext_howto_table + r_type;
361 MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
362}
363
364void
365NAME(lynx,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
366 bfd *abfd;
367 struct reloc_std_external *bytes;
368 arelent *cache_ptr;
369 asymbol **symbols;
5f771d47 370 bfd_size_type symcount ATTRIBUTE_UNUSED;
252b5132
RH
371{
372 int r_index;
373 int r_extern;
374 unsigned int r_length;
375 int r_pcrel;
376 int r_baserel, r_jmptable, r_relative;
377 struct aoutdata *su = &(abfd->tdata.aout_data->a);
378
dc810e39 379 cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
252b5132
RH
380
381 r_index = bytes->r_index[1];
382 r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG));
383 r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG));
384 r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG));
385 r_jmptable = (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG));
386 r_relative = (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG));
387 r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG)
388 >> RELOC_STD_BITS_LENGTH_SH_BIG;
389
390 cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel;
391 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
392
393 MOVE_ADDRESS (0);
394}
395
396/* Reloc hackery */
397
b34976b6 398bfd_boolean
252b5132
RH
399NAME(lynx,slurp_reloc_table) (abfd, asect, symbols)
400 bfd *abfd;
401 sec_ptr asect;
402 asymbol **symbols;
403{
dc810e39 404 bfd_size_type count;
252b5132
RH
405 bfd_size_type reloc_size;
406 PTR relocs;
407 arelent *reloc_cache;
408 size_t each_size;
409
410 if (asect->relocation)
b34976b6 411 return TRUE;
252b5132
RH
412
413 if (asect->flags & SEC_CONSTRUCTOR)
b34976b6 414 return TRUE;
252b5132
RH
415
416 if (asect == obj_datasec (abfd))
417 {
418 reloc_size = exec_hdr (abfd)->a_drsize;
419 goto doit;
420 }
421
422 if (asect == obj_textsec (abfd))
423 {
424 reloc_size = exec_hdr (abfd)->a_trsize;
425 goto doit;
426 }
427
428 bfd_set_error (bfd_error_invalid_operation);
b34976b6 429 return FALSE;
252b5132
RH
430
431doit:
432 if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
b34976b6 433 return FALSE;
252b5132
RH
434 each_size = obj_reloc_entry_size (abfd);
435
436 count = reloc_size / each_size;
437
438
9bab7074 439 reloc_cache = (arelent *) bfd_zmalloc (count * sizeof (arelent));
252b5132 440 if (!reloc_cache && count != 0)
b34976b6 441 return FALSE;
252b5132
RH
442
443 relocs = (PTR) bfd_alloc (abfd, reloc_size);
444 if (!relocs && reloc_size != 0)
445 {
446 free (reloc_cache);
b34976b6 447 return FALSE;
252b5132
RH
448 }
449
dc810e39 450 if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
252b5132
RH
451 {
452 bfd_release (abfd, relocs);
453 free (reloc_cache);
b34976b6 454 return FALSE;
252b5132
RH
455 }
456
457 if (each_size == RELOC_EXT_SIZE)
458 {
459 register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
460 unsigned int counter = 0;
461 arelent *cache_ptr = reloc_cache;
462
463 for (; counter < count; counter++, rptr++, cache_ptr++)
464 {
465 NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols,
dc810e39 466 (bfd_size_type) bfd_get_symcount (abfd));
252b5132
RH
467 }
468 }
469 else
470 {
471 register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
472 unsigned int counter = 0;
473 arelent *cache_ptr = reloc_cache;
474
475 for (; counter < count; counter++, rptr++, cache_ptr++)
476 {
477 NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,
dc810e39 478 (bfd_size_type) bfd_get_symcount (abfd));
252b5132
RH
479 }
480
481 }
482
483 bfd_release (abfd, relocs);
484 asect->relocation = reloc_cache;
485 asect->reloc_count = count;
b34976b6 486 return TRUE;
252b5132
RH
487}
488
489
490
491/* Write out a relocation section into an object file. */
492
b34976b6 493bfd_boolean
252b5132
RH
494NAME(lynx,squirt_out_relocs) (abfd, section)
495 bfd *abfd;
496 asection *section;
497{
498 arelent **generic;
499 unsigned char *native, *natptr;
500 size_t each_size;
501
502 unsigned int count = section->reloc_count;
dc810e39 503 bfd_size_type natsize;
252b5132
RH
504
505 if (count == 0)
b34976b6 506 return TRUE;
252b5132
RH
507
508 each_size = obj_reloc_entry_size (abfd);
dc810e39
AM
509 natsize = count;
510 natsize *= each_size;
252b5132
RH
511 native = (unsigned char *) bfd_zalloc (abfd, natsize);
512 if (!native)
b34976b6 513 return FALSE;
252b5132
RH
514
515 generic = section->orelocation;
516
517 if (each_size == RELOC_EXT_SIZE)
518 {
519 for (natptr = native;
520 count != 0;
521 --count, natptr += each_size, ++generic)
522 NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr);
523 }
524 else
525 {
526 for (natptr = native;
527 count != 0;
528 --count, natptr += each_size, ++generic)
529 NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr);
530 }
531
dc810e39 532 if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize)
252b5132
RH
533 {
534 bfd_release (abfd, native);
b34976b6 535 return FALSE;
252b5132
RH
536 }
537 bfd_release (abfd, native);
538
b34976b6 539 return TRUE;
252b5132
RH
540}
541
542/* This is stupid. This function should be a boolean predicate */
543long
544NAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols)
545 bfd *abfd;
546 sec_ptr section;
547 arelent **relptr;
548 asymbol **symbols;
549{
550 arelent *tblptr = section->relocation;
551 unsigned int count;
552
553 if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols)))
554 return -1;
555
556 if (section->flags & SEC_CONSTRUCTOR)
557 {
558 arelent_chain *chain = section->constructor_chain;
559 for (count = 0; count < section->reloc_count; count++)
560 {
561 *relptr++ = &chain->relent;
562 chain = chain->next;
563 }
564 }
565 else
566 {
567 tblptr = section->relocation;
568
569 for (count = 0; count++ < section->reloc_count;)
570 {
571 *relptr++ = tblptr++;
572 }
573 }
574 *relptr = 0;
575
576 return section->reloc_count;
577}
578
579#define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
580
581#include "aout-target.h"
This page took 0.603904 seconds and 4 git commands to generate.