Revert the value change of DT_ENCODING from 2003-01-17. Luckily (and
[deliverable/binutils-gdb.git] / bfd / pdp11.c
CommitLineData
e135f41b 1/* BFD back-end for PDP-11 a.out binaries.
157090f7 2 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007
66eb6687 3 Free Software Foundation, Inc.
e135f41b 4
42ef282f 5 This file is part of BFD, the Binary File Descriptor library.
e135f41b 6
42ef282f
NC
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 2 of the License, or
10 (at your option) any later version.
e135f41b 11
42ef282f
NC
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.
e135f41b 16
42ef282f
NC
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
3e110533 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
e135f41b
NC
20
21/* BFD backend for PDP-11, running 2.11BSD in particular.
22
23 This file was hacked up by looking hard at the existing vaxnetbsd
24 back end and the header files in 2.11BSD.
25
26 TODO
27 * support for V7 file formats
28 * support for overlay object files (see 2.11 a.out(5))
29 * support for old and very old archives
30 (see 2.11 ar(5), historical section)
dc810e39 31
e135f41b
NC
32 Search for TODO to find other areas needing more work. */
33
34#define BYTES_IN_WORD 2
35#define BYTES_IN_LONG 4
36#define ARCH_SIZE 16
37#undef TARGET_IS_BIG_ENDIAN_P
38
39#define TARGET_PAGE_SIZE 1024
40#define SEGMENT__SIZE TARGET_PAGE_SIZE
41
42#define DEFAULT_ARCH bfd_arch_pdp11
43#define DEFAULT_MID M_PDP11
44
e43d48cc
AM
45/* Do not "beautify" the CONCAT* macro args. Traditional C will not
46 remove whitespace added here, and thus will fail to concatenate
47 the tokens. */
48#define MY(OP) CONCAT2 (pdp11_aout_,OP)
49
e135f41b
NC
50/* This needs to start with a.out so GDB knows it is an a.out variant. */
51#define TARGETNAME "a.out-pdp11"
52
53/* This is the normal load address for executables. */
54#define TEXT_START_ADDR 0
55
56/* The header is not included in the text segment. */
57#define N_HEADER_IN_TEXT(x) 0
58
59/* There are no shared libraries. */
60#define N_SHARED_LIB(x) 0
61
62/* There is no flags field. */
63#define N_FLAGS(exec) 0
64
65#define N_SET_FLAGS(exec, flags) do { } while (0)
116c20d2
NC
66#define N_BADMAG(x) (((x).a_info != OMAGIC) \
67 && ((x).a_info != NMAGIC) \
68 && ((x).a_info != A_MAGIC3) \
69 && ((x).a_info != A_MAGIC4) \
70 && ((x).a_info != A_MAGIC5) \
71 && ((x).a_info != A_MAGIC6))
e135f41b
NC
72
73#include "bfd.h"
74
75#define external_exec pdp11_external_exec
76struct pdp11_external_exec
116c20d2
NC
77{
78 bfd_byte e_info[2]; /* Magic number. */
79 bfd_byte e_text[2]; /* Length of text section in bytes. */
80 bfd_byte e_data[2]; /* Length of data section in bytes. */
81 bfd_byte e_bss[2]; /* Length of bss area in bytes. */
82 bfd_byte e_syms[2]; /* Length of symbol table in bytes. */
83 bfd_byte e_entry[2]; /* Start address. */
84 bfd_byte e_unused[2]; /* Not used. */
85 bfd_byte e_flag[2]; /* Relocation info stripped. */
86 bfd_byte e_relocatable; /* Ugly hack. */
87};
e135f41b
NC
88
89#define EXEC_BYTES_SIZE (8 * 2)
90
91#define A_MAGIC1 OMAGIC
92#define OMAGIC 0407 /* ...object file or impure executable. */
93#define A_MAGIC2 NMAGIC
116c20d2
NC
94#define NMAGIC 0410 /* Pure executable. */
95#define ZMAGIC 0413 /* Demand-paged executable. */
96#define A_MAGIC3 0411 /* Separated I&D. */
97#define A_MAGIC4 0405 /* Overlay. */
98#define A_MAGIC5 0430 /* Auto-overlay (nonseparate). */
99#define A_MAGIC6 0431 /* Auto-overlay (separate). */
e135f41b
NC
100#define QMAGIC 0
101#define BMAGIC 0
102
103#define A_FLAG_RELOC_STRIPPED 0x0001
104
105#define external_nlist pdp11_external_nlist
106struct pdp11_external_nlist
116c20d2
NC
107{
108 bfd_byte e_unused[2]; /* Unused. */
109 bfd_byte e_strx[2]; /* Index into string table of name. */
110 bfd_byte e_type[1]; /* Type of symbol. */
111 bfd_byte e_ovly[1]; /* Overlay number. */
112 bfd_byte e_value[2]; /* Value of symbol. */
113};
e135f41b
NC
114
115#define EXTERNAL_NLIST_SIZE 8
116
117#define N_TXTOFF(x) (EXEC_BYTES_SIZE)
118#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
119#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
120#define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_trsize)
121#define N_SYMOFF(x) (N_DRELOFF(x) + (x).a_drsize)
122#define N_STROFF(x) (N_SYMOFF(x) + (x).a_syms)
123
124#define WRITE_HEADERS(abfd, execp) pdp11_aout_write_headers (abfd, execp)
125
126#include "sysdep.h"
127#include "libbfd.h"
128#include "libaout.h"
129
130#define SWAP_MAGIC(ext) bfd_getl16 (ext)
131
132#define MY_entry_is_text_address 1
133
134#define MY_write_object_contents MY(write_object_contents)
116c20d2 135static bfd_boolean MY(write_object_contents) (bfd *);
e135f41b
NC
136#define MY_text_includes_header 1
137
e135f41b
NC
138#define MY_BFD_TARGET
139
140#include "aout-target.h"
141
116c20d2 142/* Start of modified aoutx.h. */
e135f41b
NC
143#define KEEPIT udata.i
144
116c20d2 145#include <string.h> /* For strchr and friends. */
e135f41b
NC
146#include "bfd.h"
147#include "sysdep.h"
3882b010 148#include "safe-ctype.h"
e135f41b
NC
149#include "bfdlink.h"
150
151#include "libaout.h"
e135f41b
NC
152#include "aout/aout64.h"
153#include "aout/stab_gnu.h"
154#include "aout/ar.h"
155
156#undef N_TYPE
157#undef N_UNDF
158#undef N_ABS
159#undef N_TEXT
160#undef N_DATA
161#undef N_BSS
162#undef N_REG
163#undef N_FN
164#undef N_EXT
116c20d2
NC
165#define N_TYPE 0x1f /* Type mask. */
166#define N_UNDF 0x00 /* Undefined. */
167#define N_ABS 0x01 /* Absolute. */
168#define N_TEXT 0x02 /* Text segment. */
169#define N_DATA 0x03 /* Data segment. */
170#define N_BSS 0x04 /* Bss segment. */
171#define N_REG 0x14 /* Register symbol. */
172#define N_FN 0x1f /* File name. */
173#define N_EXT 0x20 /* External flag. */
e135f41b
NC
174
175#define RELOC_SIZE 2
176
116c20d2
NC
177#define RELFLG 0x0001 /* PC-relative flag. */
178#define RTYPE 0x000e /* Type mask. */
179#define RIDXMASK 0xfff0 /* Index mask. */
e135f41b 180
116c20d2
NC
181#define RABS 0x00 /* Absolute. */
182#define RTEXT 0x02 /* Text. */
183#define RDATA 0x04 /* Data. */
184#define RBSS 0x06 /* Bss. */
185#define REXT 0x08 /* External. */
e135f41b
NC
186
187#define RINDEX(x) (((x) & 0xfff0) >> 4)
188
e135f41b
NC
189#ifndef MY_final_link_relocate
190#define MY_final_link_relocate _bfd_final_link_relocate
191#endif
192
193#ifndef MY_relocate_contents
194#define MY_relocate_contents _bfd_relocate_contents
195#endif
196
116c20d2
NC
197/* A hash table used for header files with N_BINCL entries. */
198
199struct aout_link_includes_table
200{
201 struct bfd_hash_table root;
202};
203
204/* A linked list of totals that we have found for a particular header
205 file. */
206
207struct aout_link_includes_totals
208{
209 struct aout_link_includes_totals *next;
210 bfd_vma total;
211};
212
213/* An entry in the header file hash table. */
214
215struct aout_link_includes_entry
216{
217 struct bfd_hash_entry root;
218 /* List of totals we have found for this file. */
219 struct aout_link_includes_totals *totals;
220};
221
222/* During the final link step we need to pass around a bunch of
223 information, so we do it in an instance of this structure. */
224
225struct aout_final_link_info
226{
227 /* General link information. */
228 struct bfd_link_info *info;
229 /* Output bfd. */
230 bfd *output_bfd;
231 /* Reloc file positions. */
232 file_ptr treloff, dreloff;
233 /* File position of symbols. */
234 file_ptr symoff;
235 /* String table. */
236 struct bfd_strtab_hash *strtab;
237 /* Header file hash table. */
238 struct aout_link_includes_table includes;
239 /* A buffer large enough to hold the contents of any section. */
240 bfd_byte *contents;
241 /* A buffer large enough to hold the relocs of any section. */
242 void * relocs;
243 /* A buffer large enough to hold the symbol map of any input BFD. */
244 int *symbol_map;
245 /* A buffer large enough to hold output symbols of any input BFD. */
246 struct external_nlist *output_syms;
247};
248
e135f41b
NC
249reloc_howto_type howto_table_pdp11[] =
250{
251 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
b34976b6
AM
252HOWTO( 0, 0, 1, 16, FALSE, 0, complain_overflow_signed,0,"16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
253HOWTO( 1, 0, 1, 16, TRUE, 0, complain_overflow_signed,0,"DISP16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
e135f41b
NC
254};
255
256#define TABLE_SIZE(TABLE) (sizeof(TABLE)/sizeof(TABLE[0]))
257
116c20d2
NC
258
259static bfd_boolean aout_link_check_archive_element (bfd *, struct bfd_link_info *, bfd_boolean *);
260static bfd_boolean aout_link_add_object_symbols (bfd *, struct bfd_link_info *);
261static bfd_boolean aout_link_add_symbols (bfd *, struct bfd_link_info *);
262static bfd_boolean aout_link_write_symbols (struct aout_final_link_info *, bfd *);
263
264
e135f41b 265reloc_howto_type *
116c20d2
NC
266NAME (aout, reloc_type_lookup) (bfd * abfd ATTRIBUTE_UNUSED,
267 bfd_reloc_code_real_type code)
e135f41b
NC
268{
269 switch (code)
270 {
271 case BFD_RELOC_16:
272 return &howto_table_pdp11[0];
273 case BFD_RELOC_16_PCREL:
274 return &howto_table_pdp11[1];
275 default:
116c20d2 276 return NULL;
e135f41b
NC
277 }
278}
279
157090f7
AM
280reloc_howto_type *
281NAME (aout, reloc_name_lookup) (bfd *abfd ATTRIBUTE_UNUSED,
282 const char *r_name)
283{
284 unsigned int i;
285
286 for (i = 0;
287 i < sizeof (howto_table_pdp11) / sizeof (howto_table_pdp11[0]);
288 i++)
289 if (howto_table_pdp11[i].name != NULL
290 && strcasecmp (howto_table_pdp11[i].name, r_name) == 0)
291 return &howto_table_pdp11[i];
292
293 return NULL;
294}
295
e135f41b 296static int
116c20d2 297pdp11_aout_write_headers (bfd *abfd, struct internal_exec *execp)
e135f41b
NC
298{
299 struct external_exec exec_bytes;
300 bfd_size_type text_size;
301 file_ptr text_end;
302
303 if (adata(abfd).magic == undecided_magic)
116c20d2 304 NAME (aout, adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
e135f41b
NC
305
306 execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;
307 execp->a_entry = bfd_get_start_address (abfd);
308
116c20d2
NC
309 if (obj_textsec (abfd)->reloc_count > 0
310 || obj_datasec (abfd)->reloc_count > 0)
e135f41b
NC
311 {
312 execp->a_trsize = execp->a_text;
313 execp->a_drsize = execp->a_data;
314 }
315 else
316 {
317 execp->a_trsize = 0;
318 execp->a_drsize = 0;
319 }
320
116c20d2 321 NAME (aout, swap_exec_header_out) (abfd, execp, & exec_bytes);
e135f41b
NC
322
323 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
b34976b6 324 return FALSE;
e135f41b 325
116c20d2 326 if (bfd_bwrite ((void *) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd)
e135f41b 327 != EXEC_BYTES_SIZE)
b34976b6 328 return FALSE;
e135f41b 329
116c20d2
NC
330 /* Now write out reloc info, followed by syms and strings. */
331 if (bfd_get_outsymbols (abfd) != NULL
e135f41b
NC
332 && bfd_get_symcount (abfd) != 0)
333 {
dc810e39 334 if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) != 0)
b34976b6 335 return FALSE;
e135f41b 336
116c20d2 337 if (! NAME (aout, write_syms) (abfd))
b34976b6 338 return FALSE;
e135f41b
NC
339 }
340
116c20d2
NC
341 if (obj_textsec (abfd)->reloc_count > 0
342 || obj_datasec (abfd)->reloc_count > 0)
e135f41b 343 {
116c20d2
NC
344 if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) != 0
345 || !NAME (aout, squirt_out_relocs) (abfd, obj_textsec (abfd))
346 || bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) != 0
347 || !NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd)))
b34976b6 348 return FALSE;
e135f41b
NC
349 }
350
b34976b6 351 return TRUE;
dc810e39 352}
e135f41b
NC
353
354/* Write an object file.
355 Section contents have already been written. We write the
356 file header, symbols, and relocation. */
357
b34976b6 358static bfd_boolean
116c20d2 359MY(write_object_contents) (bfd *abfd)
e135f41b
NC
360{
361 struct internal_exec *execp = exec_hdr (abfd);
362
363 /* We must make certain that the magic number has been set. This
364 will normally have been done by set_section_contents, but only if
365 there actually are some section contents. */
366 if (! abfd->output_has_begun)
367 {
368 bfd_size_type text_size;
369 file_ptr text_end;
370
116c20d2 371 NAME (aout, adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
e135f41b
NC
372 }
373
374 obj_reloc_entry_size (abfd) = RELOC_SIZE;
375
116c20d2 376 return WRITE_HEADERS (abfd, execp);
e135f41b
NC
377}
378
116c20d2
NC
379/* Swap the information in an executable header @var{raw_bytes} taken
380 from a raw byte stream memory image into the internal exec header
381 structure "execp". */
e135f41b
NC
382
383#ifndef NAME_swap_exec_header_in
384void
116c20d2
NC
385NAME (aout, swap_exec_header_in) (bfd *abfd,
386 struct external_exec *bytes,
387 struct internal_exec *execp)
e135f41b 388{
e135f41b
NC
389 /* The internal_exec structure has some fields that are unused in this
390 configuration (IE for i960), so ensure that all such uninitialized
391 fields are zero'd out. There are places where two of these structs
116c20d2
NC
392 are memcmp'd, and thus the contents do matter. */
393 memset ((void *) execp, 0, sizeof (struct internal_exec));
e135f41b
NC
394 /* Now fill in fields in the execp, from the bytes in the raw data. */
395 execp->a_info = GET_MAGIC (abfd, bytes->e_info);
396 execp->a_text = GET_WORD (abfd, bytes->e_text);
397 execp->a_data = GET_WORD (abfd, bytes->e_data);
398 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
399 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
400 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
401
402 if (GET_WORD (abfd, bytes->e_flag) & A_FLAG_RELOC_STRIPPED)
403 {
404 execp->a_trsize = 0;
405 execp->a_drsize = 0;
406 }
407 else
408 {
409 execp->a_trsize = execp->a_text;
410 execp->a_drsize = execp->a_data;
411 }
412}
116c20d2 413#define NAME_swap_exec_header_in NAME (aout, swap_exec_header_in)
e135f41b
NC
414#endif
415
116c20d2
NC
416/* Swap the information in an internal exec header structure
417 "execp" into the buffer "bytes" ready for writing to disk. */
e135f41b 418void
116c20d2
NC
419NAME (aout, swap_exec_header_out) (bfd *abfd,
420 struct internal_exec *execp,
421 struct external_exec *bytes)
e135f41b 422{
116c20d2 423 /* Now fill in fields in the raw data, from the fields in the exec struct. */
e135f41b
NC
424 PUT_MAGIC (abfd, execp->a_info, bytes->e_info);
425 PUT_WORD (abfd, execp->a_text, bytes->e_text);
426 PUT_WORD (abfd, execp->a_data, bytes->e_data);
427 PUT_WORD (abfd, execp->a_bss, bytes->e_bss);
428 PUT_WORD (abfd, execp->a_syms, bytes->e_syms);
429 PUT_WORD (abfd, execp->a_entry, bytes->e_entry);
430 PUT_WORD (abfd, 0, bytes->e_unused);
431
116c20d2
NC
432 if ((execp->a_trsize == 0 || execp->a_text == 0)
433 && (execp->a_drsize == 0 || execp->a_data == 0))
434 PUT_WORD (abfd, A_FLAG_RELOC_STRIPPED, bytes->e_flag);
435 else if (execp->a_trsize == execp->a_text
436 && execp->a_drsize == execp->a_data)
437 PUT_WORD (abfd, 0, bytes->e_flag);
e135f41b
NC
438 else
439 {
116c20d2 440 /* TODO: print a proper warning message. */
e135f41b
NC
441 fprintf (stderr, "BFD:%s:%d: internal error\n", __FILE__, __LINE__);
442 PUT_WORD (abfd, 0, bytes->e_flag);
443 }
444}
445
446/* Make all the section for an a.out file. */
447
b34976b6 448bfd_boolean
116c20d2 449NAME (aout, make_sections) (bfd *abfd)
e135f41b 450{
116c20d2 451 if (obj_textsec (abfd) == NULL && bfd_make_section (abfd, ".text") == NULL)
b34976b6 452 return FALSE;
116c20d2 453 if (obj_datasec (abfd) == NULL && bfd_make_section (abfd, ".data") == NULL)
b34976b6 454 return FALSE;
116c20d2 455 if (obj_bsssec (abfd) == NULL && bfd_make_section (abfd, ".bss") == NULL)
b34976b6
AM
456 return FALSE;
457 return TRUE;
e135f41b
NC
458}
459
116c20d2
NC
460/* Some a.out variant thinks that the file open in ABFD
461 checking is an a.out file. Do some more checking, and set up
462 for access if it really is. Call back to the calling
463 environment's "finish up" function just before returning, to
464 handle any last-minute setup. */
e135f41b
NC
465
466const bfd_target *
116c20d2
NC
467NAME (aout, some_aout_object_p) (bfd *abfd,
468 struct internal_exec *execp,
469 const bfd_target *(*callback_to_real_object_p) (bfd *))
e135f41b
NC
470{
471 struct aout_data_struct *rawptr, *oldrawptr;
472 const bfd_target *result;
dc810e39 473 bfd_size_type amt = sizeof (struct aout_data_struct);
e135f41b 474
116c20d2 475 rawptr = bfd_zalloc (abfd, amt);
e135f41b
NC
476 if (rawptr == NULL)
477 return 0;
478
479 oldrawptr = abfd->tdata.aout_data;
480 abfd->tdata.aout_data = rawptr;
481
482 /* Copy the contents of the old tdata struct.
483 In particular, we want the subformat, since for hpux it was set in
484 hp300hpux.c:swap_exec_header_in and will be used in
485 hp300hpux.c:callback. */
486 if (oldrawptr != NULL)
487 *abfd->tdata.aout_data = *oldrawptr;
488
489 abfd->tdata.aout_data->a.hdr = &rawptr->e;
116c20d2 490 *(abfd->tdata.aout_data->a.hdr) = *execp; /* Copy in the internal_exec struct. */
e135f41b
NC
491 execp = abfd->tdata.aout_data->a.hdr;
492
116c20d2 493 /* Set the file flags. */
e135f41b
NC
494 abfd->flags = BFD_NO_FLAGS;
495 if (execp->a_drsize || execp->a_trsize)
496 abfd->flags |= HAS_RELOC;
116c20d2 497 /* Setting of EXEC_P has been deferred to the bottom of this function. */
e135f41b
NC
498 if (execp->a_syms)
499 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
500 if (N_DYNAMIC(*execp))
501 abfd->flags |= DYNAMIC;
502
503 if (N_MAGIC (*execp) == ZMAGIC)
504 {
505 abfd->flags |= D_PAGED | WP_TEXT;
506 adata (abfd).magic = z_magic;
507 }
508 else if (N_MAGIC (*execp) == QMAGIC)
509 {
510 abfd->flags |= D_PAGED | WP_TEXT;
511 adata (abfd).magic = z_magic;
512 adata (abfd).subformat = q_magic_format;
513 }
514 else if (N_MAGIC (*execp) == NMAGIC)
515 {
516 abfd->flags |= WP_TEXT;
517 adata (abfd).magic = n_magic;
518 }
519 else if (N_MAGIC (*execp) == OMAGIC
520 || N_MAGIC (*execp) == BMAGIC)
521 adata (abfd).magic = o_magic;
522 else
523 {
524 /* Should have been checked with N_BADMAG before this routine
525 was called. */
526 abort ();
527 }
528
529 bfd_get_start_address (abfd) = execp->a_entry;
530
116c20d2 531 obj_aout_symbols (abfd) = NULL;
e135f41b
NC
532 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
533
534 /* The default relocation entry size is that of traditional V7 Unix. */
535 obj_reloc_entry_size (abfd) = RELOC_SIZE;
536
116c20d2 537 /* The default symbol entry size is that of traditional Unix. */
e135f41b
NC
538 obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
539
540#ifdef USE_MMAP
541 bfd_init_window (&obj_aout_sym_window (abfd));
542 bfd_init_window (&obj_aout_string_window (abfd));
543#endif
116c20d2 544
e135f41b
NC
545 obj_aout_external_syms (abfd) = NULL;
546 obj_aout_external_strings (abfd) = NULL;
547 obj_aout_sym_hashes (abfd) = NULL;
548
116c20d2 549 if (! NAME (aout, make_sections) (abfd))
e135f41b
NC
550 return NULL;
551
eea6121a
AM
552 obj_datasec (abfd)->size = execp->a_data;
553 obj_bsssec (abfd)->size = execp->a_bss;
e135f41b
NC
554
555 obj_textsec (abfd)->flags =
556 (execp->a_trsize != 0
557 ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
558 : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
559 obj_datasec (abfd)->flags =
560 (execp->a_drsize != 0
561 ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
562 : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
563 obj_bsssec (abfd)->flags = SEC_ALLOC;
564
565#ifdef THIS_IS_ONLY_DOCUMENTATION
566 /* The common code can't fill in these things because they depend
567 on either the start address of the text segment, the rounding
568 up of virtual addresses between segments, or the starting file
569 position of the text segment -- all of which varies among different
570 versions of a.out. */
571
572 /* Call back to the format-dependent code to fill in the rest of the
573 fields and do any further cleanup. Things that should be filled
574 in by the callback: */
e135f41b
NC
575 struct exec *execp = exec_hdr (abfd);
576
577 obj_textsec (abfd)->size = N_TXTSIZE(*execp);
116c20d2 578 /* Data and bss are already filled in since they're so standard. */
e135f41b 579
116c20d2 580 /* The virtual memory addresses of the sections. */
e135f41b
NC
581 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
582 obj_datasec (abfd)->vma = N_DATADDR(*execp);
583 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
584
116c20d2 585 /* The file offsets of the sections. */
e135f41b
NC
586 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
587 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
588
116c20d2 589 /* The file offsets of the relocation info. */
e135f41b
NC
590 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
591 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
592
593 /* The file offsets of the string table and symbol table. */
594 obj_str_filepos (abfd) = N_STROFF (*execp);
595 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
596
597 /* Determine the architecture and machine type of the object file. */
598 abfd->obj_arch = bfd_arch_obscure;
599
600 adata(abfd)->page_size = TARGET_PAGE_SIZE;
601 adata(abfd)->segment_size = SEGMENT_SIZE;
602 adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
603
604 return abfd->xvec;
605
606 /* The architecture is encoded in various ways in various a.out variants,
607 or is not encoded at all in some of them. The relocation size depends
608 on the architecture and the a.out variant. Finally, the return value
609 is the bfd_target vector in use. If an error occurs, return zero and
610 set bfd_error to the appropriate error code.
611
612 Formats such as b.out, which have additional fields in the a.out
613 header, should cope with them in this callback as well. */
116c20d2 614#endif /* DOCUMENTATION */
e135f41b
NC
615
616 result = (*callback_to_real_object_p)(abfd);
617
618 /* Now that the segment addresses have been worked out, take a better
619 guess at whether the file is executable. If the entry point
620 is within the text segment, assume it is. (This makes files
621 executable even if their entry point address is 0, as long as
622 their text starts at zero.).
623
624 This test had to be changed to deal with systems where the text segment
625 runs at a different location than the default. The problem is that the
626 entry address can appear to be outside the text segment, thus causing an
627 erroneous conclusion that the file isn't executable.
628
629 To fix this, we now accept any non-zero entry point as an indication of
630 executability. This will work most of the time, since only the linker
631 sets the entry point, and that is likely to be non-zero for most systems. */
632
633 if (execp->a_entry != 0
634 || (execp->a_entry >= obj_textsec(abfd)->vma
eea6121a 635 && execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->size))
e135f41b
NC
636 abfd->flags |= EXEC_P;
637#ifdef STAT_FOR_EXEC
638 else
639 {
640 struct stat stat_buf;
641
642 /* The original heuristic doesn't work in some important cases.
643 The a.out file has no information about the text start
644 address. For files (like kernels) linked to non-standard
645 addresses (ld -Ttext nnn) the entry point may not be between
646 the default text start (obj_textsec(abfd)->vma) and
647 (obj_textsec(abfd)->vma) + text size. This is not just a mach
648 issue. Many kernels are loaded at non standard addresses. */
649 if (abfd->iostream != NULL
650 && (abfd->flags & BFD_IN_MEMORY) == 0
651 && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
652 && ((stat_buf.st_mode & 0111) != 0))
653 abfd->flags |= EXEC_P;
654 }
655#endif /* STAT_FOR_EXEC */
656
0e71e495 657 if (!result)
e135f41b
NC
658 {
659 free (rawptr);
660 abfd->tdata.aout_data = oldrawptr;
661 }
662 return result;
663}
664
116c20d2 665/* Initialize ABFD for use with a.out files. */
e135f41b 666
b34976b6 667bfd_boolean
116c20d2 668NAME (aout, mkobject) (bfd *abfd)
e135f41b
NC
669{
670 struct aout_data_struct *rawptr;
dc810e39 671 bfd_size_type amt = sizeof (struct aout_data_struct);
e135f41b
NC
672
673 bfd_set_error (bfd_error_system_call);
674
116c20d2
NC
675 /* Use an intermediate variable for clarity. */
676 rawptr = bfd_zalloc (abfd, amt);
e135f41b
NC
677
678 if (rawptr == NULL)
b34976b6 679 return FALSE;
e135f41b
NC
680
681 abfd->tdata.aout_data = rawptr;
682 exec_hdr (abfd) = &(rawptr->e);
683
116c20d2
NC
684 obj_textsec (abfd) = NULL;
685 obj_datasec (abfd) = NULL;
686 obj_bsssec (abfd) = NULL;
e135f41b 687
b34976b6 688 return TRUE;
e135f41b
NC
689}
690
116c20d2
NC
691/* Keep track of machine architecture and machine type for
692 a.out's. Return the <<machine_type>> for a particular
693 architecture and machine, or <<M_UNKNOWN>> if that exact architecture
694 and machine can't be represented in a.out format.
e135f41b 695
116c20d2
NC
696 If the architecture is understood, machine type 0 (default)
697 is always understood. */
e135f41b
NC
698
699enum machine_type
116c20d2
NC
700NAME (aout, machine_type) (enum bfd_architecture arch,
701 unsigned long machine,
702 bfd_boolean *unknown)
e135f41b
NC
703{
704 enum machine_type arch_flags;
705
706 arch_flags = M_UNKNOWN;
b34976b6 707 *unknown = TRUE;
e135f41b
NC
708
709 switch (arch)
710 {
711 case bfd_arch_sparc:
712 if (machine == 0
713 || machine == bfd_mach_sparc
714 || machine == bfd_mach_sparc_sparclite
715 || machine == bfd_mach_sparc_v9)
716 arch_flags = M_SPARC;
717 else if (machine == bfd_mach_sparc_sparclet)
718 arch_flags = M_SPARCLET;
719 break;
720
721 case bfd_arch_m68k:
722 switch (machine)
723 {
724 case 0: arch_flags = M_68010; break;
b34976b6 725 case bfd_mach_m68000: arch_flags = M_UNKNOWN; *unknown = FALSE; break;
e135f41b
NC
726 case bfd_mach_m68010: arch_flags = M_68010; break;
727 case bfd_mach_m68020: arch_flags = M_68020; break;
728 default: arch_flags = M_UNKNOWN; break;
729 }
730 break;
731
732 case bfd_arch_i386:
250d94fd
AM
733 if (machine == 0
734 || machine == bfd_mach_i386_i386
735 || machine == bfd_mach_i386_i386_intel_syntax)
736 arch_flags = M_386;
e135f41b
NC
737 break;
738
e135f41b
NC
739 case bfd_arch_arm:
740 if (machine == 0) arch_flags = M_ARM;
741 break;
742
743 case bfd_arch_mips:
744 switch (machine)
745 {
746 case 0:
747 case 2000:
748 case bfd_mach_mips3000:
749 arch_flags = M_MIPS1;
750 break;
116c20d2 751 case bfd_mach_mips4000: /* MIPS3 */
e135f41b 752 case bfd_mach_mips4400:
116c20d2
NC
753 case bfd_mach_mips8000: /* MIPS4 */
754 case bfd_mach_mips6000: /* Real MIPS2: */
e135f41b
NC
755 arch_flags = M_MIPS2;
756 break;
757 default:
758 arch_flags = M_UNKNOWN;
759 break;
760 }
761 break;
762
763 case bfd_arch_ns32k:
764 switch (machine)
765 {
766 case 0: arch_flags = M_NS32532; break;
767 case 32032: arch_flags = M_NS32032; break;
768 case 32532: arch_flags = M_NS32532; break;
769 default: arch_flags = M_UNKNOWN; break;
770 }
771 break;
772
773 case bfd_arch_pdp11:
774 /* TODO: arch_flags = M_PDP11; */
b34976b6 775 *unknown = FALSE;
e135f41b
NC
776 break;
777
778 case bfd_arch_vax:
b34976b6 779 *unknown = FALSE;
e135f41b 780 break;
dc810e39 781
e135f41b
NC
782 default:
783 arch_flags = M_UNKNOWN;
784 }
785
786 if (arch_flags != M_UNKNOWN)
b34976b6 787 *unknown = FALSE;
e135f41b
NC
788
789 return arch_flags;
790}
791
116c20d2
NC
792/* Set the architecture and the machine of the ABFD to the
793 values ARCH and MACHINE. Verify that @ABFD's format
794 can support the architecture required. */
e135f41b 795
b34976b6 796bfd_boolean
116c20d2
NC
797NAME (aout, set_arch_mach) (bfd *abfd,
798 enum bfd_architecture arch,
799 unsigned long machine)
e135f41b
NC
800{
801 if (! bfd_default_set_arch_mach (abfd, arch, machine))
b34976b6 802 return FALSE;
e135f41b
NC
803
804 if (arch != bfd_arch_unknown)
805 {
b34976b6 806 bfd_boolean unknown;
e135f41b 807
116c20d2 808 NAME (aout, machine_type) (arch, machine, &unknown);
e135f41b 809 if (unknown)
b34976b6 810 return FALSE;
e135f41b
NC
811 }
812
813 obj_reloc_entry_size (abfd) = RELOC_SIZE;
814
815 return (*aout_backend_info(abfd)->set_sizes) (abfd);
816}
817
818static void
116c20d2 819adjust_o_magic (bfd *abfd, struct internal_exec *execp)
e135f41b
NC
820{
821 file_ptr pos = adata (abfd).exec_bytes_size;
822 bfd_vma vma = 0;
823 int pad = 0;
824
825 /* Text. */
826 obj_textsec (abfd)->filepos = pos;
827 if (! obj_textsec (abfd)->user_set_vma)
828 obj_textsec (abfd)->vma = vma;
829 else
830 vma = obj_textsec (abfd)->vma;
831
eea6121a
AM
832 pos += obj_textsec (abfd)->size;
833 vma += obj_textsec (abfd)->size;
e135f41b
NC
834
835 /* Data. */
836 if (!obj_datasec (abfd)->user_set_vma)
837 {
eea6121a 838 obj_textsec (abfd)->size += pad;
e135f41b
NC
839 pos += pad;
840 vma += pad;
841 obj_datasec (abfd)->vma = vma;
842 }
843 else
844 vma = obj_datasec (abfd)->vma;
845 obj_datasec (abfd)->filepos = pos;
eea6121a
AM
846 pos += obj_datasec (abfd)->size;
847 vma += obj_datasec (abfd)->size;
e135f41b
NC
848
849 /* BSS. */
850 if (! obj_bsssec (abfd)->user_set_vma)
851 {
eea6121a 852 obj_datasec (abfd)->size += pad;
e135f41b
NC
853 pos += pad;
854 vma += pad;
855 obj_bsssec (abfd)->vma = vma;
856 }
857 else
858 {
08da05b0 859 /* The VMA of the .bss section is set by the VMA of the
e135f41b
NC
860 .data section plus the size of the .data section. We may
861 need to add padding bytes to make this true. */
862 pad = obj_bsssec (abfd)->vma - vma;
863 if (pad > 0)
864 {
eea6121a 865 obj_datasec (abfd)->size += pad;
e135f41b
NC
866 pos += pad;
867 }
868 }
869 obj_bsssec (abfd)->filepos = pos;
870
871 /* Fix up the exec header. */
eea6121a
AM
872 execp->a_text = obj_textsec (abfd)->size;
873 execp->a_data = obj_datasec (abfd)->size;
874 execp->a_bss = obj_bsssec (abfd)->size;
e135f41b
NC
875 N_SET_MAGIC (*execp, OMAGIC);
876}
877
878static void
116c20d2 879adjust_z_magic (bfd *abfd, struct internal_exec *execp)
e135f41b
NC
880{
881 bfd_size_type data_pad, text_pad;
882 file_ptr text_end;
dc810e39 883 const struct aout_backend_data *abdp;
e135f41b 884 int ztih; /* Nonzero if text includes exec header. */
dc810e39 885
e135f41b
NC
886 abdp = aout_backend_info (abfd);
887
888 /* Text. */
889 ztih = (abdp != NULL
890 && (abdp->text_includes_header
891 || obj_aout_subformat (abfd) == q_magic_format));
892 obj_textsec(abfd)->filepos = (ztih
893 ? adata(abfd).exec_bytes_size
894 : adata(abfd).zmagic_disk_block_size);
895 if (! obj_textsec(abfd)->user_set_vma)
896 {
897 /* ?? Do we really need to check for relocs here? */
898 obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC)
899 ? 0
900 : (ztih
901 ? (abdp->default_text_vma
902 + adata (abfd).exec_bytes_size)
903 : abdp->default_text_vma));
904 text_pad = 0;
905 }
906 else
907 {
908 /* The .text section is being loaded at an unusual address. We
909 may need to pad it such that the .data section starts at a page
910 boundary. */
911 if (ztih)
912 text_pad = ((obj_textsec (abfd)->filepos - obj_textsec (abfd)->vma)
913 & (adata (abfd).page_size - 1));
914 else
915 text_pad = ((- obj_textsec (abfd)->vma)
916 & (adata (abfd).page_size - 1));
917 }
918
919 /* Find start of data. */
920 if (ztih)
921 {
eea6121a 922 text_end = obj_textsec (abfd)->filepos + obj_textsec (abfd)->size;
e135f41b
NC
923 text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
924 }
925 else
926 {
927 /* Note that if page_size == zmagic_disk_block_size, then
928 filepos == page_size, and this case is the same as the ztih
929 case. */
eea6121a 930 text_end = obj_textsec (abfd)->size;
e135f41b
NC
931 text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
932 text_end += obj_textsec (abfd)->filepos;
933 }
934
eea6121a 935 obj_textsec (abfd)->size += text_pad;
e135f41b
NC
936 text_end += text_pad;
937
938 /* Data. */
939 if (!obj_datasec(abfd)->user_set_vma)
940 {
941 bfd_vma vma;
eea6121a 942 vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->size;
e135f41b
NC
943 obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
944 }
945 if (abdp && abdp->zmagic_mapped_contiguous)
946 {
947 text_pad = (obj_datasec(abfd)->vma
948 - obj_textsec(abfd)->vma
eea6121a
AM
949 - obj_textsec(abfd)->size);
950 obj_textsec(abfd)->size += text_pad;
e135f41b
NC
951 }
952 obj_datasec (abfd)->filepos = (obj_textsec (abfd)->filepos
eea6121a 953 + obj_textsec (abfd)->size);
dc810e39 954
e135f41b 955 /* Fix up exec header while we're at it. */
eea6121a 956 execp->a_text = obj_textsec(abfd)->size;
e135f41b
NC
957 if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
958 execp->a_text += adata(abfd).exec_bytes_size;
959 if (obj_aout_subformat (abfd) == q_magic_format)
960 N_SET_MAGIC (*execp, QMAGIC);
961 else
962 N_SET_MAGIC (*execp, ZMAGIC);
963
964 /* Spec says data section should be rounded up to page boundary. */
eea6121a
AM
965 obj_datasec(abfd)->size
966 = align_power (obj_datasec(abfd)->size,
e135f41b 967 obj_bsssec(abfd)->alignment_power);
eea6121a 968 execp->a_data = BFD_ALIGN (obj_datasec(abfd)->size,
e135f41b 969 adata(abfd).page_size);
eea6121a 970 data_pad = execp->a_data - obj_datasec(abfd)->size;
e135f41b
NC
971
972 /* BSS. */
973 if (!obj_bsssec(abfd)->user_set_vma)
974 obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
eea6121a 975 + obj_datasec(abfd)->size);
e135f41b
NC
976 /* If the BSS immediately follows the data section and extra space
977 in the page is left after the data section, fudge data
978 in the header so that the bss section looks smaller by that
979 amount. We'll start the bss section there, and lie to the OS.
980 (Note that a linker script, as well as the above assignment,
981 could have explicitly set the BSS vma to immediately follow
982 the data section.) */
983 if (align_power (obj_bsssec(abfd)->vma, obj_bsssec(abfd)->alignment_power)
eea6121a
AM
984 == obj_datasec(abfd)->vma + obj_datasec(abfd)->size)
985 execp->a_bss = (data_pad > obj_bsssec(abfd)->size) ? 0 :
986 obj_bsssec(abfd)->size - data_pad;
e135f41b 987 else
eea6121a 988 execp->a_bss = obj_bsssec(abfd)->size;
e135f41b
NC
989}
990
991static void
116c20d2 992adjust_n_magic (bfd *abfd, struct internal_exec *execp)
e135f41b
NC
993{
994 file_ptr pos = adata(abfd).exec_bytes_size;
995 bfd_vma vma = 0;
996 int pad;
dc810e39 997
e135f41b
NC
998 /* Text. */
999 obj_textsec(abfd)->filepos = pos;
1000 if (!obj_textsec(abfd)->user_set_vma)
1001 obj_textsec(abfd)->vma = vma;
1002 else
1003 vma = obj_textsec(abfd)->vma;
eea6121a
AM
1004 pos += obj_textsec(abfd)->size;
1005 vma += obj_textsec(abfd)->size;
e135f41b
NC
1006
1007 /* Data. */
1008 obj_datasec(abfd)->filepos = pos;
1009 if (!obj_datasec(abfd)->user_set_vma)
1010 obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
1011 vma = obj_datasec(abfd)->vma;
dc810e39 1012
e135f41b 1013 /* Since BSS follows data immediately, see if it needs alignment. */
eea6121a 1014 vma += obj_datasec(abfd)->size;
e135f41b 1015 pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
eea6121a
AM
1016 obj_datasec(abfd)->size += pad;
1017 pos += obj_datasec(abfd)->size;
e135f41b
NC
1018
1019 /* BSS. */
1020 if (!obj_bsssec(abfd)->user_set_vma)
1021 obj_bsssec(abfd)->vma = vma;
1022 else
1023 vma = obj_bsssec(abfd)->vma;
1024
1025 /* Fix up exec header. */
eea6121a
AM
1026 execp->a_text = obj_textsec(abfd)->size;
1027 execp->a_data = obj_datasec(abfd)->size;
1028 execp->a_bss = obj_bsssec(abfd)->size;
e135f41b
NC
1029 N_SET_MAGIC (*execp, NMAGIC);
1030}
1031
b34976b6 1032bfd_boolean
116c20d2
NC
1033NAME (aout, adjust_sizes_and_vmas) (bfd *abfd,
1034 bfd_size_type *text_size,
1035 file_ptr * text_end ATTRIBUTE_UNUSED)
e135f41b
NC
1036{
1037 struct internal_exec *execp = exec_hdr (abfd);
1038
116c20d2 1039 if (! NAME (aout, make_sections) (abfd))
b34976b6 1040 return FALSE;
e135f41b
NC
1041
1042 if (adata(abfd).magic != undecided_magic)
b34976b6 1043 return TRUE;
e135f41b 1044
eea6121a
AM
1045 obj_textsec(abfd)->size =
1046 align_power(obj_textsec(abfd)->size,
e135f41b
NC
1047 obj_textsec(abfd)->alignment_power);
1048
eea6121a 1049 *text_size = obj_textsec (abfd)->size;
e135f41b
NC
1050 /* Rule (heuristic) for when to pad to a new page. Note that there
1051 are (at least) two ways demand-paged (ZMAGIC) files have been
1052 handled. Most Berkeley-based systems start the text segment at
1053 (TARGET_PAGE_SIZE). However, newer versions of SUNOS start the text
1054 segment right after the exec header; the latter is counted in the
1055 text segment size, and is paged in by the kernel with the rest of
1056 the text. */
1057
1058 /* This perhaps isn't the right way to do this, but made it simpler for me
1059 to understand enough to implement it. Better would probably be to go
1060 right from BFD flags to alignment/positioning characteristics. But the
1061 old code was sloppy enough about handling the flags, and had enough
1062 other magic, that it was a little hard for me to understand. I think
1063 I understand it better now, but I haven't time to do the cleanup this
1064 minute. */
1065
1066 if (abfd->flags & WP_TEXT)
1067 adata(abfd).magic = n_magic;
1068 else
1069 adata(abfd).magic = o_magic;
1070
1071#ifdef BFD_AOUT_DEBUG /* requires gcc2 */
1072#if __GNUC__ >= 2
1073 fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
1074 ({ char *str;
1075 switch (adata(abfd).magic) {
1076 case n_magic: str = "NMAGIC"; break;
1077 case o_magic: str = "OMAGIC"; break;
1078 case z_magic: str = "ZMAGIC"; break;
1079 default: abort ();
1080 }
1081 str;
1082 }),
eea6121a 1083 obj_textsec(abfd)->vma, obj_textsec(abfd)->size,
e135f41b 1084 obj_textsec(abfd)->alignment_power,
eea6121a 1085 obj_datasec(abfd)->vma, obj_datasec(abfd)->size,
e135f41b 1086 obj_datasec(abfd)->alignment_power,
eea6121a 1087 obj_bsssec(abfd)->vma, obj_bsssec(abfd)->size,
e135f41b
NC
1088 obj_bsssec(abfd)->alignment_power);
1089#endif
1090#endif
1091
1092 switch (adata(abfd).magic)
1093 {
1094 case o_magic:
1095 adjust_o_magic (abfd, execp);
1096 break;
1097 case z_magic:
1098 adjust_z_magic (abfd, execp);
1099 break;
1100 case n_magic:
1101 adjust_n_magic (abfd, execp);
1102 break;
1103 default:
1104 abort ();
1105 }
1106
1107#ifdef BFD_AOUT_DEBUG
1108 fprintf (stderr, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
eea6121a 1109 obj_textsec(abfd)->vma, obj_textsec(abfd)->size,
e135f41b 1110 obj_textsec(abfd)->filepos,
eea6121a 1111 obj_datasec(abfd)->vma, obj_datasec(abfd)->size,
e135f41b 1112 obj_datasec(abfd)->filepos,
eea6121a 1113 obj_bsssec(abfd)->vma, obj_bsssec(abfd)->size);
e135f41b
NC
1114#endif
1115
b34976b6 1116 return TRUE;
e135f41b
NC
1117}
1118
116c20d2 1119/* Called by the BFD in response to a bfd_make_section request. */
e135f41b 1120
b34976b6 1121bfd_boolean
116c20d2 1122NAME (aout, new_section_hook) (bfd *abfd, asection *newsect)
e135f41b 1123{
116c20d2 1124 /* Align to double at least. */
e135f41b
NC
1125 newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
1126
e135f41b
NC
1127 if (bfd_get_format (abfd) == bfd_object)
1128 {
1129 if (obj_textsec (abfd) == NULL
f592407e 1130 && !strcmp (newsect->name, ".text"))
e135f41b
NC
1131 {
1132 obj_textsec(abfd)= newsect;
1133 newsect->target_index = N_TEXT;
e135f41b 1134 }
f592407e
AM
1135 else if (obj_datasec (abfd) == NULL
1136 && !strcmp (newsect->name, ".data"))
1137 {
1138 obj_datasec (abfd) = newsect;
1139 newsect->target_index = N_DATA;
1140 }
1141 else if (obj_bsssec (abfd) == NULL
1142 && !strcmp (newsect->name, ".bss"))
1143 {
1144 obj_bsssec (abfd) = newsect;
1145 newsect->target_index = N_BSS;
1146 }
1147 }
e135f41b 1148
116c20d2 1149 /* We allow more than three sections internally. */
f592407e 1150 return _bfd_generic_new_section_hook (abfd, newsect);
e135f41b
NC
1151}
1152
b34976b6 1153bfd_boolean
116c20d2
NC
1154NAME (aout, set_section_contents) (bfd *abfd,
1155 sec_ptr section,
1156 const void * location,
1157 file_ptr offset,
1158 bfd_size_type count)
e135f41b
NC
1159{
1160 file_ptr text_end;
1161 bfd_size_type text_size;
1162
1163 if (! abfd->output_has_begun)
1164 {
116c20d2 1165 if (! NAME (aout, adjust_sizes_and_vmas) (abfd, & text_size, & text_end))
b34976b6 1166 return FALSE;
e135f41b
NC
1167 }
1168
1169 if (section == obj_bsssec (abfd))
1170 {
1171 bfd_set_error (bfd_error_no_contents);
b34976b6 1172 return FALSE;
e135f41b
NC
1173 }
1174
1175 if (section != obj_textsec (abfd)
1176 && section != obj_datasec (abfd))
1177 {
1178 (*_bfd_error_handler)
1179 ("%s: can not represent section `%s' in a.out object file format",
1180 bfd_get_filename (abfd), bfd_get_section_name (abfd, section));
1181 bfd_set_error (bfd_error_nonrepresentable_section);
b34976b6 1182 return FALSE;
e135f41b
NC
1183 }
1184
1185 if (count != 0)
1186 {
1187 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
dc810e39 1188 || bfd_bwrite (location, count, abfd) != count)
b34976b6 1189 return FALSE;
e135f41b
NC
1190 }
1191
b34976b6 1192 return TRUE;
e135f41b
NC
1193}
1194\f
1195/* Read the external symbols from an a.out file. */
1196
b34976b6 1197static bfd_boolean
116c20d2 1198aout_get_external_symbols (bfd *abfd)
e135f41b 1199{
116c20d2 1200 if (obj_aout_external_syms (abfd) == NULL)
e135f41b
NC
1201 {
1202 bfd_size_type count;
1203 struct external_nlist *syms;
1204
1205 count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
1206
1207#ifdef USE_MMAP
82e51918
AM
1208 if (! bfd_get_file_window (abfd, obj_sym_filepos (abfd),
1209 exec_hdr (abfd)->a_syms,
b34976b6
AM
1210 &obj_aout_sym_window (abfd), TRUE))
1211 return FALSE;
e135f41b
NC
1212 syms = (struct external_nlist *) obj_aout_sym_window (abfd).data;
1213#else
1214 /* We allocate using malloc to make the values easy to free
1215 later on. If we put them on the objalloc it might not be
1216 possible to free them. */
116c20d2
NC
1217 syms = bfd_malloc (count * EXTERNAL_NLIST_SIZE);
1218 if (syms == NULL && count != 0)
b34976b6 1219 return FALSE;
e135f41b
NC
1220
1221 if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
dc810e39 1222 || (bfd_bread (syms, exec_hdr (abfd)->a_syms, abfd)
e135f41b
NC
1223 != exec_hdr (abfd)->a_syms))
1224 {
1225 free (syms);
b34976b6 1226 return FALSE;
e135f41b
NC
1227 }
1228#endif
1229
1230 obj_aout_external_syms (abfd) = syms;
1231 obj_aout_external_sym_count (abfd) = count;
1232 }
dc810e39 1233
e135f41b
NC
1234 if (obj_aout_external_strings (abfd) == NULL
1235 && exec_hdr (abfd)->a_syms != 0)
1236 {
1237 unsigned char string_chars[BYTES_IN_LONG];
1238 bfd_size_type stringsize;
1239 char *strings;
1240
1241 /* Get the size of the strings. */
1242 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
116c20d2 1243 || (bfd_bread ((void *) string_chars, (bfd_size_type) BYTES_IN_LONG,
dc810e39 1244 abfd) != BYTES_IN_LONG))
b34976b6 1245 return FALSE;
dc810e39 1246 stringsize = H_GET_32 (abfd, string_chars);
e135f41b
NC
1247
1248#ifdef USE_MMAP
82e51918 1249 if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize,
b34976b6
AM
1250 &obj_aout_string_window (abfd), TRUE))
1251 return FALSE;
e135f41b
NC
1252 strings = (char *) obj_aout_string_window (abfd).data;
1253#else
116c20d2 1254 strings = bfd_malloc (stringsize + 1);
e135f41b 1255 if (strings == NULL)
b34976b6 1256 return FALSE;
e135f41b
NC
1257
1258 /* Skip space for the string count in the buffer for convenience
1259 when using indexes. */
dc810e39 1260 if (bfd_bread (strings + 4, stringsize - 4, abfd) != stringsize - 4)
e135f41b
NC
1261 {
1262 free (strings);
b34976b6 1263 return FALSE;
e135f41b
NC
1264 }
1265#endif
e135f41b
NC
1266 /* Ensure that a zero index yields an empty string. */
1267 strings[0] = '\0';
1268
1269 strings[stringsize - 1] = 0;
1270
1271 obj_aout_external_strings (abfd) = strings;
1272 obj_aout_external_string_size (abfd) = stringsize;
1273 }
1274
b34976b6 1275 return TRUE;
e135f41b
NC
1276}
1277
1278/* Translate an a.out symbol into a BFD symbol. The desc, other, type
1279 and symbol->value fields of CACHE_PTR will be set from the a.out
1280 nlist structure. This function is responsible for setting
1281 symbol->flags and symbol->section, and adjusting symbol->value. */
1282
b34976b6 1283static bfd_boolean
116c20d2
NC
1284translate_from_native_sym_flags (bfd *abfd,
1285 aout_symbol_type *cache_ptr)
e135f41b
NC
1286{
1287 flagword visible;
1288
1289 if (cache_ptr->type == N_FN)
1290 {
1291 asection *sec;
1292
1293 /* This is a debugging symbol. */
e135f41b
NC
1294 cache_ptr->symbol.flags = BSF_DEBUGGING;
1295
1296 /* Work out the symbol section. */
1297 switch (cache_ptr->type & N_TYPE)
1298 {
1299 case N_TEXT:
1300 case N_FN:
1301 sec = obj_textsec (abfd);
1302 break;
1303 case N_DATA:
1304 sec = obj_datasec (abfd);
1305 break;
1306 case N_BSS:
1307 sec = obj_bsssec (abfd);
1308 break;
1309 default:
1310 case N_ABS:
1311 sec = bfd_abs_section_ptr;
1312 break;
1313 }
1314
1315 cache_ptr->symbol.section = sec;
1316 cache_ptr->symbol.value -= sec->vma;
1317
b34976b6 1318 return TRUE;
e135f41b
NC
1319 }
1320
1321 /* Get the default visibility. This does not apply to all types, so
1322 we just hold it in a local variable to use if wanted. */
1323 if ((cache_ptr->type & N_EXT) == 0)
1324 visible = BSF_LOCAL;
1325 else
1326 visible = BSF_GLOBAL;
1327
1328 switch (cache_ptr->type)
1329 {
1330 default:
1331 case N_ABS: case N_ABS | N_EXT:
1332 cache_ptr->symbol.section = bfd_abs_section_ptr;
1333 cache_ptr->symbol.flags = visible;
1334 break;
1335
1336 case N_UNDF | N_EXT:
1337 if (cache_ptr->symbol.value != 0)
1338 {
1339 /* This is a common symbol. */
1340 cache_ptr->symbol.flags = BSF_GLOBAL;
1341 cache_ptr->symbol.section = bfd_com_section_ptr;
1342 }
1343 else
1344 {
1345 cache_ptr->symbol.flags = 0;
1346 cache_ptr->symbol.section = bfd_und_section_ptr;
1347 }
1348 break;
1349
1350 case N_TEXT: case N_TEXT | N_EXT:
1351 cache_ptr->symbol.section = obj_textsec (abfd);
1352 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1353 cache_ptr->symbol.flags = visible;
1354 break;
1355
1356 case N_DATA: case N_DATA | N_EXT:
1357 cache_ptr->symbol.section = obj_datasec (abfd);
1358 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1359 cache_ptr->symbol.flags = visible;
1360 break;
1361
1362 case N_BSS: case N_BSS | N_EXT:
1363 cache_ptr->symbol.section = obj_bsssec (abfd);
1364 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1365 cache_ptr->symbol.flags = visible;
1366 break;
1367 }
1368
b34976b6 1369 return TRUE;
e135f41b
NC
1370}
1371
1372/* Set the fields of SYM_POINTER according to CACHE_PTR. */
1373
b34976b6 1374static bfd_boolean
116c20d2
NC
1375translate_to_native_sym_flags (bfd *abfd,
1376 asymbol *cache_ptr,
1377 struct external_nlist *sym_pointer)
e135f41b
NC
1378{
1379 bfd_vma value = cache_ptr->value;
1380 asection *sec;
1381 bfd_vma off;
1382
1383 /* Mask out any existing type bits in case copying from one section
1384 to another. */
1385 sym_pointer->e_type[0] &= ~N_TYPE;
1386
1387 sec = bfd_get_section (cache_ptr);
1388 off = 0;
1389
1390 if (sec == NULL)
1391 {
1392 /* This case occurs, e.g., for the *DEBUG* section of a COFF
1393 file. */
1394 (*_bfd_error_handler)
d003868e
AM
1395 ("%B: can not represent section for symbol `%s' in a.out object file format",
1396 abfd, cache_ptr->name != NULL ? cache_ptr->name : "*unknown*");
e135f41b 1397 bfd_set_error (bfd_error_nonrepresentable_section);
b34976b6 1398 return FALSE;
e135f41b
NC
1399 }
1400
1401 if (sec->output_section != NULL)
1402 {
1403 off = sec->output_offset;
1404 sec = sec->output_section;
1405 }
1406
1407 if (bfd_is_abs_section (sec))
1408 sym_pointer->e_type[0] |= N_ABS;
1409 else if (sec == obj_textsec (abfd))
1410 sym_pointer->e_type[0] |= N_TEXT;
1411 else if (sec == obj_datasec (abfd))
1412 sym_pointer->e_type[0] |= N_DATA;
1413 else if (sec == obj_bsssec (abfd))
1414 sym_pointer->e_type[0] |= N_BSS;
1415 else if (bfd_is_und_section (sec))
1416 sym_pointer->e_type[0] = N_UNDF | N_EXT;
1417 else if (bfd_is_com_section (sec))
1418 sym_pointer->e_type[0] = N_UNDF | N_EXT;
1419 else
1420 {
1421 (*_bfd_error_handler)
d003868e
AM
1422 ("%B: can not represent section `%A' in a.out object file format",
1423 abfd, sec);
e135f41b 1424 bfd_set_error (bfd_error_nonrepresentable_section);
b34976b6 1425 return FALSE;
e135f41b
NC
1426 }
1427
1428 /* Turn the symbol from section relative to absolute again */
1429 value += sec->vma + off;
1430
1431 if ((cache_ptr->flags & BSF_DEBUGGING) != 0)
1432 sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
1433 else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
1434 sym_pointer->e_type[0] |= N_EXT;
1435
e135f41b
NC
1436 PUT_WORD(abfd, value, sym_pointer->e_value);
1437
b34976b6 1438 return TRUE;
e135f41b
NC
1439}
1440\f
1441/* Native-level interface to symbols. */
1442
1443asymbol *
116c20d2 1444NAME (aout, make_empty_symbol) (bfd *abfd)
e135f41b 1445{
dc810e39 1446 bfd_size_type amt = sizeof (aout_symbol_type);
116c20d2
NC
1447 aout_symbol_type *new = bfd_zalloc (abfd, amt);
1448
e135f41b
NC
1449 if (!new)
1450 return NULL;
1451 new->symbol.the_bfd = abfd;
1452
1453 return &new->symbol;
1454}
1455
1456/* Translate a set of internal symbols into external symbols. */
1457
b34976b6 1458bfd_boolean
116c20d2
NC
1459NAME (aout, translate_symbol_table) (bfd *abfd,
1460 aout_symbol_type *in,
1461 struct external_nlist *ext,
1462 bfd_size_type count,
1463 char *str,
1464 bfd_size_type strsize,
1465 bfd_boolean dynamic)
e135f41b
NC
1466{
1467 struct external_nlist *ext_end;
1468
1469 ext_end = ext + count;
1470 for (; ext < ext_end; ext++, in++)
1471 {
1472 bfd_vma x;
1473
1474 x = GET_WORD (abfd, ext->e_strx);
1475 in->symbol.the_bfd = abfd;
1476
1477 /* For the normal symbols, the zero index points at the number
1478 of bytes in the string table but is to be interpreted as the
1479 null string. For the dynamic symbols, the number of bytes in
1480 the string table is stored in the __DYNAMIC structure and the
1481 zero index points at an actual string. */
1482 if (x == 0 && ! dynamic)
1483 in->symbol.name = "";
1484 else if (x < strsize)
1485 in->symbol.name = str + x;
1486 else
b34976b6 1487 return FALSE;
e135f41b
NC
1488
1489 in->symbol.value = GET_SWORD (abfd, ext->e_value);
116c20d2 1490 /* TODO: is 0 a safe value here? */
e135f41b
NC
1491 in->desc = 0;
1492 in->other = 0;
dc810e39 1493 in->type = H_GET_8 (abfd, ext->e_type);
e135f41b
NC
1494 in->symbol.udata.p = NULL;
1495
1496 if (! translate_from_native_sym_flags (abfd, in))
b34976b6 1497 return FALSE;
e135f41b
NC
1498
1499 if (dynamic)
1500 in->symbol.flags |= BSF_DYNAMIC;
1501 }
1502
b34976b6 1503 return TRUE;
e135f41b
NC
1504}
1505
1506/* We read the symbols into a buffer, which is discarded when this
1507 function exits. We read the strings into a buffer large enough to
116c20d2 1508 hold them all plus all the cached symbol entries. */
e135f41b 1509
b34976b6 1510bfd_boolean
116c20d2 1511NAME (aout, slurp_symbol_table) (bfd *abfd)
e135f41b
NC
1512{
1513 struct external_nlist *old_external_syms;
1514 aout_symbol_type *cached;
dc810e39 1515 bfd_size_type cached_size;
e135f41b 1516
116c20d2
NC
1517 /* If there's no work to be done, don't do any. */
1518 if (obj_aout_symbols (abfd) != NULL)
b34976b6 1519 return TRUE;
e135f41b
NC
1520
1521 old_external_syms = obj_aout_external_syms (abfd);
1522
1523 if (! aout_get_external_symbols (abfd))
b34976b6 1524 return FALSE;
e135f41b 1525
dc810e39
AM
1526 cached_size = obj_aout_external_sym_count (abfd);
1527 cached_size *= sizeof (aout_symbol_type);
116c20d2 1528 cached = bfd_zmalloc (cached_size);
e135f41b 1529 if (cached == NULL && cached_size != 0)
b34976b6 1530 return FALSE;
e135f41b
NC
1531
1532 /* Convert from external symbol information to internal. */
116c20d2 1533 if (! (NAME (aout, translate_symbol_table)
e135f41b
NC
1534 (abfd, cached,
1535 obj_aout_external_syms (abfd),
1536 obj_aout_external_sym_count (abfd),
1537 obj_aout_external_strings (abfd),
1538 obj_aout_external_string_size (abfd),
b34976b6 1539 FALSE)))
e135f41b
NC
1540 {
1541 free (cached);
b34976b6 1542 return FALSE;
e135f41b
NC
1543 }
1544
1545 bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd);
1546
1547 obj_aout_symbols (abfd) = cached;
1548
1549 /* It is very likely that anybody who calls this function will not
1550 want the external symbol information, so if it was allocated
1551 because of our call to aout_get_external_symbols, we free it up
1552 right away to save space. */
116c20d2
NC
1553 if (old_external_syms == NULL
1554 && obj_aout_external_syms (abfd) != NULL)
e135f41b
NC
1555 {
1556#ifdef USE_MMAP
1557 bfd_free_window (&obj_aout_sym_window (abfd));
1558#else
1559 free (obj_aout_external_syms (abfd));
1560#endif
1561 obj_aout_external_syms (abfd) = NULL;
1562 }
1563
b34976b6 1564 return TRUE;
e135f41b
NC
1565}
1566\f
1567/* We use a hash table when writing out symbols so that we only write
1568 out a particular string once. This helps particularly when the
1569 linker writes out stabs debugging entries, because each different
1570 contributing object file tends to have many duplicate stabs
1571 strings.
1572
1573 This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
1574 if BFD_TRADITIONAL_FORMAT is set. */
1575
e135f41b
NC
1576/* Get the index of a string in a strtab, adding it if it is not
1577 already present. */
1578
1579static INLINE bfd_size_type
116c20d2
NC
1580add_to_stringtab (bfd *abfd,
1581 struct bfd_strtab_hash *tab,
1582 const char *str,
1583 bfd_boolean copy)
e135f41b 1584{
b34976b6 1585 bfd_boolean hash;
e135f41b
NC
1586 bfd_size_type index;
1587
1588 /* An index of 0 always means the empty string. */
1589 if (str == 0 || *str == '\0')
1590 return 0;
1591
1592 /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
1593 doesn't understand a hashed string table. */
b34976b6 1594 hash = TRUE;
e135f41b 1595 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
b34976b6 1596 hash = FALSE;
e135f41b
NC
1597
1598 index = _bfd_stringtab_add (tab, str, hash, copy);
1599
1600 if (index != (bfd_size_type) -1)
116c20d2
NC
1601 /* Add BYTES_IN_LONG to the return value to account for the
1602 space taken up by the string table size. */
1603 index += BYTES_IN_LONG;
e135f41b
NC
1604
1605 return index;
1606}
1607
1608/* Write out a strtab. ABFD is already at the right location in the
1609 file. */
1610
b34976b6 1611static bfd_boolean
116c20d2 1612emit_stringtab (bfd *abfd, struct bfd_strtab_hash *tab)
e135f41b
NC
1613{
1614 bfd_byte buffer[BYTES_IN_LONG];
1615
1616 /* The string table starts with the size. */
dc810e39 1617 H_PUT_32 (abfd, _bfd_stringtab_size (tab) + BYTES_IN_LONG, buffer);
116c20d2 1618 if (bfd_bwrite ((void *) buffer, (bfd_size_type) BYTES_IN_LONG, abfd)
dc810e39 1619 != BYTES_IN_LONG)
b34976b6 1620 return FALSE;
e135f41b
NC
1621
1622 return _bfd_stringtab_emit (abfd, tab);
1623}
1624\f
b34976b6 1625bfd_boolean
116c20d2 1626NAME (aout, write_syms) (bfd *abfd)
e135f41b
NC
1627{
1628 unsigned int count ;
1629 asymbol **generic = bfd_get_outsymbols (abfd);
1630 struct bfd_strtab_hash *strtab;
1631
1632 strtab = _bfd_stringtab_init ();
1633 if (strtab == NULL)
b34976b6 1634 return FALSE;
e135f41b
NC
1635
1636 for (count = 0; count < bfd_get_symcount (abfd); count++)
1637 {
1638 asymbol *g = generic[count];
1639 bfd_size_type indx;
1640 struct external_nlist nsp;
1641
dc810e39 1642 PUT_WORD (abfd, 0, nsp.e_unused);
e135f41b 1643
b34976b6 1644 indx = add_to_stringtab (abfd, strtab, g->name, FALSE);
e135f41b
NC
1645 if (indx == (bfd_size_type) -1)
1646 goto error_return;
dc810e39 1647 PUT_WORD (abfd, indx, nsp.e_strx);
e135f41b
NC
1648
1649 if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
dc810e39 1650 H_PUT_8 (abfd, aout_symbol(g)->type, nsp.e_type);
e135f41b 1651 else
dc810e39 1652 H_PUT_8 (abfd, 0, nsp.e_type);
e135f41b
NC
1653
1654 if (! translate_to_native_sym_flags (abfd, g, &nsp))
1655 goto error_return;
1656
dc810e39 1657 H_PUT_8 (abfd, 0, nsp.e_ovly);
e135f41b 1658
116c20d2 1659 if (bfd_bwrite ((void *)&nsp, (bfd_size_type) EXTERNAL_NLIST_SIZE, abfd)
e135f41b
NC
1660 != EXTERNAL_NLIST_SIZE)
1661 goto error_return;
1662
1663 /* NB: `KEEPIT' currently overlays `udata.p', so set this only
1664 here, at the end. */
1665 g->KEEPIT = count;
1666 }
1667
1668 if (! emit_stringtab (abfd, strtab))
1669 goto error_return;
1670
1671 _bfd_stringtab_free (strtab);
1672
b34976b6 1673 return TRUE;
e135f41b
NC
1674
1675error_return:
1676 _bfd_stringtab_free (strtab);
b34976b6 1677 return FALSE;
e135f41b
NC
1678}
1679
1680\f
1681long
116c20d2 1682NAME (aout, canonicalize_symtab) (bfd *abfd, asymbol **location)
e135f41b 1683{
116c20d2
NC
1684 unsigned int counter = 0;
1685 aout_symbol_type *symbase;
e135f41b 1686
116c20d2
NC
1687 if (!NAME (aout, slurp_symbol_table) (abfd))
1688 return -1;
e135f41b 1689
116c20d2
NC
1690 for (symbase = obj_aout_symbols (abfd); counter++ < bfd_get_symcount (abfd);)
1691 *(location++) = (asymbol *)(symbase++);
1692 *location++ =0;
1693 return bfd_get_symcount (abfd);
e135f41b
NC
1694}
1695
1696\f
116c20d2 1697/* Output extended relocation information to a file in target byte order. */
e135f41b 1698
116c20d2
NC
1699static void
1700pdp11_aout_swap_reloc_out (bfd *abfd, arelent *g, bfd_byte *natptr)
e135f41b
NC
1701{
1702 int r_index;
1703 int r_pcrel;
1704 int reloc_entry;
1705 int r_type;
1706 asymbol *sym = *(g->sym_ptr_ptr);
1707 asection *output_section = sym->section->output_section;
1708
1709 if (g->addend != 0)
1710 fprintf (stderr, "BFD: can't do this reloc addend stuff\n");
1711
1712 r_pcrel = g->howto->pc_relative;
1713
1714 if (bfd_is_abs_section (output_section))
1715 r_type = RABS;
1716 else if (output_section == obj_textsec (abfd))
1717 r_type = RTEXT;
1718 else if (output_section == obj_datasec (abfd))
1719 r_type = RDATA;
1720 else if (output_section == obj_bsssec (abfd))
1721 r_type = RBSS;
1722 else if (bfd_is_und_section (output_section))
1723 r_type = REXT;
1724 else if (bfd_is_com_section (output_section))
1725 r_type = REXT;
1726 else
1727 r_type = -1;
1728
1729 BFD_ASSERT (r_type != -1);
1730
1731 if (r_type == RABS)
1732 r_index = 0;
1733 else
1734 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
1735
e135f41b
NC
1736 reloc_entry = r_index << 4 | r_type | r_pcrel;
1737
9dadfa79 1738 PUT_WORD (abfd, reloc_entry, natptr);
e135f41b
NC
1739}
1740
1741/* BFD deals internally with all things based from the section they're
1742 in. so, something in 10 bytes into a text section with a base of
1743 50 would have a symbol (.text+10) and know .text vma was 50.
1744
1745 Aout keeps all it's symbols based from zero, so the symbol would
1746 contain 60. This macro subs the base of each section from the value
1747 to give the true offset from the section */
1748
1749
1750#define MOVE_ADDRESS(ad) \
1751 if (r_extern) \
1752 { \
1753 /* Undefined symbol. */ \
1754 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1755 cache_ptr->addend = ad; \
1756 } \
1757 else \
1758 { \
1759 /* Defined, section relative. replace symbol with pointer to \
1760 symbol which points to section. */ \
1761 switch (r_index) \
1762 { \
1763 case N_TEXT: \
1764 case N_TEXT | N_EXT: \
1765 cache_ptr->sym_ptr_ptr = obj_textsec (abfd)->symbol_ptr_ptr; \
1766 cache_ptr->addend = ad - su->textsec->vma; \
1767 break; \
1768 case N_DATA: \
1769 case N_DATA | N_EXT: \
1770 cache_ptr->sym_ptr_ptr = obj_datasec (abfd)->symbol_ptr_ptr; \
1771 cache_ptr->addend = ad - su->datasec->vma; \
1772 break; \
1773 case N_BSS: \
1774 case N_BSS | N_EXT: \
1775 cache_ptr->sym_ptr_ptr = obj_bsssec (abfd)->symbol_ptr_ptr; \
1776 cache_ptr->addend = ad - su->bsssec->vma; \
1777 break; \
1778 default: \
1779 case N_ABS: \
1780 case N_ABS | N_EXT: \
1781 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
1782 cache_ptr->addend = ad; \
1783 break; \
1784 } \
dc810e39 1785 }
e135f41b 1786
116c20d2
NC
1787static void
1788pdp11_aout_swap_reloc_in (bfd * abfd,
1789 bfd_byte * bytes,
1790 arelent * cache_ptr,
1791 bfd_size_type offset,
1792 asymbol ** symbols,
1793 bfd_size_type symcount)
e135f41b
NC
1794{
1795 struct aoutdata *su = &(abfd->tdata.aout_data->a);
1796 unsigned int r_index;
1797 int reloc_entry;
1798 int r_extern;
1799 int r_pcrel;
1800
116c20d2 1801 reloc_entry = GET_WORD (abfd, (void *) bytes);
e135f41b
NC
1802
1803 r_pcrel = reloc_entry & RELFLG;
1804
1805 cache_ptr->address = offset;
1806 cache_ptr->howto = howto_table_pdp11 + (r_pcrel ? 1 : 0);
1807
1808 if ((reloc_entry & RTYPE) == RABS)
1809 r_index = N_ABS;
1810 else
1811 r_index = RINDEX (reloc_entry);
1812
1813 /* r_extern reflects whether the symbol the reloc is against is
1814 local or global. */
1815 r_extern = (reloc_entry & RTYPE) == REXT;
1816
1817 if (r_extern && r_index > symcount)
1818 {
1819 /* We could arrange to return an error, but it might be useful
1820 to see the file even if it is bad. */
1821 r_extern = 0;
1822 r_index = N_ABS;
1823 }
1824
1825 MOVE_ADDRESS(0);
1826}
1827
1828/* Read and swap the relocs for a section. */
1829
b34976b6 1830bfd_boolean
116c20d2 1831NAME (aout, slurp_reloc_table) (bfd *abfd, sec_ptr asect, asymbol **symbols)
e135f41b 1832{
9dadfa79 1833 bfd_byte *rptr;
dc810e39 1834 bfd_size_type count;
e135f41b 1835 bfd_size_type reloc_size;
116c20d2 1836 void * relocs;
e135f41b
NC
1837 arelent *reloc_cache;
1838 size_t each_size;
1839 unsigned int counter = 0;
1840 arelent *cache_ptr;
1841
1842 if (asect->relocation)
b34976b6 1843 return TRUE;
e135f41b
NC
1844
1845 if (asect->flags & SEC_CONSTRUCTOR)
b34976b6 1846 return TRUE;
e135f41b
NC
1847
1848 if (asect == obj_datasec (abfd))
1849 reloc_size = exec_hdr(abfd)->a_drsize;
1850 else if (asect == obj_textsec (abfd))
1851 reloc_size = exec_hdr(abfd)->a_trsize;
1852 else if (asect == obj_bsssec (abfd))
1853 reloc_size = 0;
1854 else
1855 {
1856 bfd_set_error (bfd_error_invalid_operation);
b34976b6 1857 return FALSE;
e135f41b
NC
1858 }
1859
1860 if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
b34976b6 1861 return FALSE;
e135f41b
NC
1862
1863 each_size = obj_reloc_entry_size (abfd);
1864
dc810e39 1865 relocs = bfd_malloc (reloc_size);
e135f41b 1866 if (relocs == NULL && reloc_size != 0)
b34976b6 1867 return FALSE;
e135f41b 1868
dc810e39 1869 if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
e135f41b
NC
1870 {
1871 free (relocs);
b34976b6 1872 return FALSE;
e135f41b
NC
1873 }
1874
1875 count = reloc_size / each_size;
1876
116c20d2 1877 /* Count the number of NON-ZERO relocs, this is the count we want. */
e135f41b
NC
1878 {
1879 unsigned int real_count = 0;
1880
1881 for (counter = 0; counter < count; counter++)
1882 {
1883 int x;
1884
973ffd63 1885 x = GET_WORD (abfd, (char *) relocs + each_size * counter);
e135f41b
NC
1886 if (x != 0)
1887 real_count++;
1888 }
1889
1890 count = real_count;
1891 }
1892
116c20d2 1893 reloc_cache = bfd_zmalloc (count * sizeof (arelent));
e135f41b 1894 if (reloc_cache == NULL && count != 0)
b34976b6 1895 return FALSE;
e135f41b
NC
1896
1897 cache_ptr = reloc_cache;
1898
9dadfa79 1899 rptr = relocs;
e135f41b
NC
1900 for (counter = 0;
1901 counter < count;
9dadfa79 1902 counter++, rptr += RELOC_SIZE, cache_ptr++)
e135f41b 1903 {
116c20d2 1904 while (GET_WORD (abfd, (void *) rptr) == 0)
e135f41b 1905 {
9dadfa79 1906 rptr += RELOC_SIZE;
dc810e39 1907 if ((char *) rptr >= (char *) relocs + reloc_size)
e135f41b
NC
1908 goto done;
1909 }
1910
1911 pdp11_aout_swap_reloc_in (abfd, rptr, cache_ptr,
dc810e39
AM
1912 (bfd_size_type) ((char *) rptr - (char *) relocs),
1913 symbols,
1914 (bfd_size_type) bfd_get_symcount (abfd));
e135f41b
NC
1915 }
1916 done:
1917 /* Just in case, if rptr >= relocs + reloc_size should happen
116c20d2 1918 too early. */
e135f41b
NC
1919 BFD_ASSERT (counter == count);
1920
1921 free (relocs);
1922
1923 asect->relocation = reloc_cache;
1924 asect->reloc_count = cache_ptr - reloc_cache;
1925
b34976b6 1926 return TRUE;
e135f41b
NC
1927}
1928
1929/* Write out a relocation section into an object file. */
1930
b34976b6 1931bfd_boolean
116c20d2 1932NAME (aout, squirt_out_relocs) (bfd *abfd, asection *section)
e135f41b
NC
1933{
1934 arelent **generic;
1935 unsigned char *native;
1936 unsigned int count = section->reloc_count;
dc810e39 1937 bfd_size_type natsize;
e135f41b 1938
eea6121a 1939 natsize = section->size;
116c20d2 1940 native = bfd_zalloc (abfd, natsize);
e135f41b 1941 if (!native)
b34976b6 1942 return FALSE;
e135f41b 1943
e135f41b
NC
1944 generic = section->orelocation;
1945 if (generic != NULL)
1946 {
1947 while (count > 0)
1948 {
9dadfa79 1949 bfd_byte *r;
e135f41b 1950
9dadfa79 1951 r = native + (*generic)->address;
e135f41b
NC
1952 pdp11_aout_swap_reloc_out (abfd, *generic, r);
1953 count--;
1954 generic++;
1955 }
1956 }
1957
116c20d2 1958 if (bfd_bwrite ((void *) native, natsize, abfd) != natsize)
e135f41b 1959 {
dc810e39 1960 bfd_release (abfd, native);
b34976b6 1961 return FALSE;
e135f41b
NC
1962 }
1963
1964 bfd_release (abfd, native);
b34976b6 1965 return TRUE;
e135f41b
NC
1966}
1967
116c20d2
NC
1968/* This is stupid. This function should be a boolean predicate. */
1969
e135f41b 1970long
116c20d2
NC
1971NAME (aout, canonicalize_reloc) (bfd *abfd,
1972 sec_ptr section,
1973 arelent **relptr,
1974 asymbol **symbols)
e135f41b
NC
1975{
1976 arelent *tblptr = section->relocation;
1977 unsigned int count;
1978
1979 if (section == obj_bsssec (abfd))
1980 {
1981 *relptr = NULL;
1982 return 0;
1983 }
1984
116c20d2 1985 if (!(tblptr || NAME (aout, slurp_reloc_table)(abfd, section, symbols)))
e135f41b
NC
1986 return -1;
1987
1988 if (section->flags & SEC_CONSTRUCTOR)
1989 {
1990 arelent_chain *chain = section->constructor_chain;
1991
1992 for (count = 0; count < section->reloc_count; count ++)
1993 {
1994 *relptr ++ = &chain->relent;
1995 chain = chain->next;
1996 }
1997 }
1998 else
1999 {
2000 tblptr = section->relocation;
2001
2002 for (count = 0; count++ < section->reloc_count;)
2003 *relptr++ = tblptr++;
2004 }
2005
2006 *relptr = 0;
2007
2008 return section->reloc_count;
2009}
2010
2011long
116c20d2 2012NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect)
e135f41b
NC
2013{
2014 if (bfd_get_format (abfd) != bfd_object)
2015 {
2016 bfd_set_error (bfd_error_invalid_operation);
2017 return -1;
2018 }
2019
dc810e39 2020 if (asect->flags & SEC_CONSTRUCTOR)
116c20d2 2021 return (sizeof (arelent *) * (asect->reloc_count + 1));
e135f41b
NC
2022
2023 if (asect == obj_datasec (abfd))
2024 return (sizeof (arelent *)
116c20d2 2025 * ((exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd))
e135f41b
NC
2026 + 1));
2027
2028 if (asect == obj_textsec (abfd))
2029 return (sizeof (arelent *)
116c20d2 2030 * ((exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd))
e135f41b
NC
2031 + 1));
2032
2033 /* TODO: why are there two if statements for obj_bsssec()? */
2034
2035 if (asect == obj_bsssec (abfd))
2036 return sizeof (arelent *);
2037
2038 if (asect == obj_bsssec (abfd))
2039 return 0;
2040
2041 bfd_set_error (bfd_error_invalid_operation);
2042 return -1;
2043}
2044
2045\f
2046long
116c20d2 2047NAME (aout, get_symtab_upper_bound) (bfd *abfd)
e135f41b 2048{
116c20d2 2049 if (!NAME (aout, slurp_symbol_table) (abfd))
e135f41b
NC
2050 return -1;
2051
2052 return (bfd_get_symcount (abfd) + 1) * (sizeof (aout_symbol_type *));
2053}
2054
2055alent *
116c20d2
NC
2056NAME (aout, get_lineno) (bfd * abfd ATTRIBUTE_UNUSED,
2057 asymbol * symbol ATTRIBUTE_UNUSED)
e135f41b 2058{
116c20d2 2059 return NULL;
e135f41b
NC
2060}
2061
2062void
116c20d2
NC
2063NAME (aout, get_symbol_info) (bfd * abfd ATTRIBUTE_UNUSED,
2064 asymbol *symbol,
2065 symbol_info *ret)
e135f41b
NC
2066{
2067 bfd_symbol_info (symbol, ret);
2068
2069 if (ret->type == '?')
2070 {
2071 int type_code = aout_symbol(symbol)->type & 0xff;
2072 const char *stab_name = bfd_get_stab_name (type_code);
2073 static char buf[10];
2074
2075 if (stab_name == NULL)
2076 {
2077 sprintf(buf, "(%d)", type_code);
2078 stab_name = buf;
2079 }
2080 ret->type = '-';
116c20d2
NC
2081 ret->stab_type = type_code;
2082 ret->stab_other = (unsigned) (aout_symbol(symbol)->other & 0xff);
2083 ret->stab_desc = (unsigned) (aout_symbol(symbol)->desc & 0xffff);
2084 ret->stab_name = stab_name;
e135f41b
NC
2085 }
2086}
2087
e135f41b 2088void
116c20d2
NC
2089NAME (aout, print_symbol) (bfd * abfd,
2090 void * afile,
2091 asymbol *symbol,
2092 bfd_print_symbol_type how)
e135f41b 2093{
116c20d2 2094 FILE *file = (FILE *) afile;
e135f41b
NC
2095
2096 switch (how)
2097 {
2098 case bfd_print_symbol_name:
2099 if (symbol->name)
2100 fprintf(file,"%s", symbol->name);
2101 break;
2102 case bfd_print_symbol_more:
116c20d2
NC
2103 fprintf(file,"%4x %2x %2x",
2104 (unsigned) (aout_symbol (symbol)->desc & 0xffff),
2105 (unsigned) (aout_symbol (symbol)->other & 0xff),
2106 (unsigned) (aout_symbol (symbol)->type));
e135f41b
NC
2107 break;
2108 case bfd_print_symbol_all:
2109 {
dc810e39 2110 const char *section_name = symbol->section->name;
e135f41b 2111
116c20d2 2112 bfd_print_symbol_vandf (abfd, (void *) file, symbol);
e135f41b
NC
2113
2114 fprintf (file," %-5s %04x %02x %02x",
2115 section_name,
116c20d2
NC
2116 (unsigned) (aout_symbol (symbol)->desc & 0xffff),
2117 (unsigned) (aout_symbol (symbol)->other & 0xff),
2118 (unsigned) (aout_symbol (symbol)->type & 0xff));
e135f41b
NC
2119 if (symbol->name)
2120 fprintf(file," %s", symbol->name);
2121 }
2122 break;
2123 }
2124}
2125
2126/* If we don't have to allocate more than 1MB to hold the generic
2127 symbols, we use the generic minisymbol method: it's faster, since
2128 it only translates the symbols once, not multiple times. */
2129#define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
2130
2131/* Read minisymbols. For minisymbols, we use the unmodified a.out
2132 symbols. The minisymbol_to_symbol function translates these into
2133 BFD asymbol structures. */
2134
2135long
116c20d2
NC
2136NAME (aout, read_minisymbols) (bfd *abfd,
2137 bfd_boolean dynamic,
2138 void * *minisymsp,
2139 unsigned int *sizep)
e135f41b
NC
2140{
2141 if (dynamic)
116c20d2
NC
2142 /* We could handle the dynamic symbols here as well, but it's
2143 easier to hand them off. */
2144 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
e135f41b
NC
2145
2146 if (! aout_get_external_symbols (abfd))
2147 return -1;
2148
2149 if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2150 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2151
116c20d2 2152 *minisymsp = (void *) obj_aout_external_syms (abfd);
e135f41b
NC
2153
2154 /* By passing the external symbols back from this routine, we are
2155 giving up control over the memory block. Clear
2156 obj_aout_external_syms, so that we do not try to free it
2157 ourselves. */
2158 obj_aout_external_syms (abfd) = NULL;
2159
2160 *sizep = EXTERNAL_NLIST_SIZE;
2161 return obj_aout_external_sym_count (abfd);
2162}
2163
2164/* Convert a minisymbol to a BFD asymbol. A minisymbol is just an
2165 unmodified a.out symbol. The SYM argument is a structure returned
2166 by bfd_make_empty_symbol, which we fill in here. */
2167
2168asymbol *
116c20d2
NC
2169NAME (aout, minisymbol_to_symbol) (bfd *abfd,
2170 bfd_boolean dynamic,
2171 const void * minisym,
2172 asymbol *sym)
e135f41b
NC
2173{
2174 if (dynamic
2175 || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2176 return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
2177
2178 memset (sym, 0, sizeof (aout_symbol_type));
2179
2180 /* We call translate_symbol_table to translate a single symbol. */
116c20d2 2181 if (! (NAME (aout, translate_symbol_table)
e135f41b
NC
2182 (abfd,
2183 (aout_symbol_type *) sym,
2184 (struct external_nlist *) minisym,
2185 (bfd_size_type) 1,
2186 obj_aout_external_strings (abfd),
2187 obj_aout_external_string_size (abfd),
b34976b6 2188 FALSE)))
e135f41b
NC
2189 return NULL;
2190
2191 return sym;
2192}
2193
116c20d2
NC
2194/* Provided a BFD, a section and an offset into the section, calculate
2195 and return the name of the source file and the line nearest to the
2196 wanted location. */
e135f41b 2197
b34976b6 2198bfd_boolean
116c20d2
NC
2199NAME (aout, find_nearest_line) (bfd *abfd,
2200 asection *section,
2201 asymbol **symbols,
2202 bfd_vma offset,
2203 const char **filename_ptr,
2204 const char **functionname_ptr,
2205 unsigned int *line_ptr)
e135f41b 2206{
116c20d2 2207 /* Run down the file looking for the filename, function and linenumber. */
e135f41b 2208 asymbol **p;
dc810e39
AM
2209 const char *directory_name = NULL;
2210 const char *main_file_name = NULL;
2211 const char *current_file_name = NULL;
116c20d2 2212 const char *line_file_name = NULL; /* Value of current_file_name at line number. */
e135f41b
NC
2213 bfd_vma low_line_vma = 0;
2214 bfd_vma low_func_vma = 0;
2215 asymbol *func = 0;
2216 size_t filelen, funclen;
2217 char *buf;
2218
2219 *filename_ptr = abfd->filename;
2220 *functionname_ptr = 0;
2221 *line_ptr = 0;
2222
116c20d2 2223 if (symbols != NULL)
e135f41b
NC
2224 {
2225 for (p = symbols; *p; p++)
2226 {
2227 aout_symbol_type *q = (aout_symbol_type *)(*p);
2228 next:
2229 switch (q->type)
2230 {
2231 case N_TEXT:
2232 /* If this looks like a file name symbol, and it comes after
2233 the line number we have found so far, but before the
2234 offset, then we have probably not found the right line
2235 number. */
2236 if (q->symbol.value <= offset
2237 && ((q->symbol.value > low_line_vma
2238 && (line_file_name != NULL
2239 || *line_ptr != 0))
2240 || (q->symbol.value > low_func_vma
2241 && func != NULL)))
2242 {
2243 const char * symname;
2244
2245 symname = q->symbol.name;
2246 if (strcmp (symname + strlen (symname) - 2, ".o") == 0)
2247 {
2248 if (q->symbol.value > low_line_vma)
2249 {
2250 *line_ptr = 0;
2251 line_file_name = NULL;
2252 }
2253 if (q->symbol.value > low_func_vma)
2254 func = NULL;
2255 }
2256 }
2257 break;
2258
2259 case N_SO:
2260 /* If this symbol is less than the offset, but greater than
2261 the line number we have found so far, then we have not
2262 found the right line number. */
2263 if (q->symbol.value <= offset)
2264 {
2265 if (q->symbol.value > low_line_vma)
2266 {
2267 *line_ptr = 0;
2268 line_file_name = NULL;
2269 }
2270 if (q->symbol.value > low_func_vma)
2271 func = NULL;
2272 }
2273
2274 main_file_name = current_file_name = q->symbol.name;
116c20d2 2275 /* Look ahead to next symbol to check if that too is an N_SO. */
e135f41b
NC
2276 p++;
2277 if (*p == NULL)
2278 break;
2279 q = (aout_symbol_type *)(*p);
116c20d2 2280 if (q->type != (int) N_SO)
e135f41b
NC
2281 goto next;
2282
116c20d2 2283 /* Found a second N_SO First is directory; second is filename. */
e135f41b
NC
2284 directory_name = current_file_name;
2285 main_file_name = current_file_name = q->symbol.name;
2286 if (obj_textsec(abfd) != section)
2287 goto done;
2288 break;
2289 case N_SOL:
2290 current_file_name = q->symbol.name;
2291 break;
2292
2293 case N_SLINE:
2294 case N_DSLINE:
2295 case N_BSLINE:
2296 /* We'll keep this if it resolves nearer than the one we have
2297 already. */
2298 if (q->symbol.value >= low_line_vma
2299 && q->symbol.value <= offset)
2300 {
2301 *line_ptr = q->desc;
2302 low_line_vma = q->symbol.value;
2303 line_file_name = current_file_name;
2304 }
2305 break;
2306
2307 case N_FUN:
2308 {
116c20d2 2309 /* We'll keep this if it is nearer than the one we have already. */
e135f41b
NC
2310 if (q->symbol.value >= low_func_vma &&
2311 q->symbol.value <= offset)
2312 {
2313 low_func_vma = q->symbol.value;
116c20d2 2314 func = (asymbol *) q;
e135f41b
NC
2315 }
2316 else if (q->symbol.value > offset)
2317 goto done;
2318 }
2319 break;
2320 }
2321 }
2322 }
2323
2324 done:
2325 if (*line_ptr != 0)
2326 main_file_name = line_file_name;
2327
2328 if (main_file_name == NULL
2329 || main_file_name[0] == '/'
2330 || directory_name == NULL)
2331 filelen = 0;
2332 else
2333 filelen = strlen (directory_name) + strlen (main_file_name);
2334 if (func == NULL)
2335 funclen = 0;
2336 else
2337 funclen = strlen (bfd_asymbol_name (func));
2338
2339 if (adata (abfd).line_buf != NULL)
2340 free (adata (abfd).line_buf);
2341 if (filelen + funclen == 0)
2342 adata (abfd).line_buf = buf = NULL;
2343 else
2344 {
116c20d2 2345 buf = bfd_malloc ((bfd_size_type) filelen + funclen + 3);
e135f41b
NC
2346 adata (abfd).line_buf = buf;
2347 if (buf == NULL)
b34976b6 2348 return FALSE;
e135f41b
NC
2349 }
2350
2351 if (main_file_name != NULL)
2352 {
2353 if (main_file_name[0] == '/' || directory_name == NULL)
2354 *filename_ptr = main_file_name;
2355 else
2356 {
2357 sprintf (buf, "%s%s", directory_name, main_file_name);
2358 *filename_ptr = buf;
2359 buf += filelen + 1;
2360 }
2361 }
2362
2363 if (func)
2364 {
2365 const char *function = func->name;
dc810e39 2366 char *colon;
e135f41b
NC
2367
2368 /* The caller expects a symbol name. We actually have a
2369 function name, without the leading underscore. Put the
2370 underscore back in, so that the caller gets a symbol name. */
2371 if (bfd_get_symbol_leading_char (abfd) == '\0')
2372 strcpy (buf, function);
2373 else
2374 {
2375 buf[0] = bfd_get_symbol_leading_char (abfd);
2376 strcpy (buf + 1, function);
2377 }
2378
2379 /* Have to remove : stuff. */
dc810e39
AM
2380 colon = strchr (buf, ':');
2381 if (colon != NULL)
2382 *colon = '\0';
e135f41b
NC
2383 *functionname_ptr = buf;
2384 }
2385
b34976b6 2386 return TRUE;
e135f41b
NC
2387}
2388
2389int
a6b96beb
AM
2390NAME (aout, sizeof_headers) (bfd *abfd,
2391 struct bfd_link_info *info ATTRIBUTE_UNUSED)
e135f41b 2392{
116c20d2 2393 return adata (abfd).exec_bytes_size;
e135f41b
NC
2394}
2395
2396/* Free all information we have cached for this BFD. We can always
2397 read it again later if we need it. */
2398
b34976b6 2399bfd_boolean
116c20d2 2400NAME (aout, bfd_free_cached_info) (bfd *abfd)
e135f41b
NC
2401{
2402 asection *o;
2403
2404 if (bfd_get_format (abfd) != bfd_object)
b34976b6 2405 return TRUE;
e135f41b
NC
2406
2407#define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
2408 BFCI_FREE (obj_aout_symbols (abfd));
116c20d2 2409
e135f41b
NC
2410#ifdef USE_MMAP
2411 obj_aout_external_syms (abfd) = 0;
2412 bfd_free_window (&obj_aout_sym_window (abfd));
2413 bfd_free_window (&obj_aout_string_window (abfd));
2414 obj_aout_external_strings (abfd) = 0;
2415#else
2416 BFCI_FREE (obj_aout_external_syms (abfd));
2417 BFCI_FREE (obj_aout_external_strings (abfd));
2418#endif
116c20d2 2419 for (o = abfd->sections; o != NULL; o = o->next)
e135f41b
NC
2420 BFCI_FREE (o->relocation);
2421#undef BFCI_FREE
2422
b34976b6 2423 return TRUE;
e135f41b
NC
2424}
2425\f
e135f41b
NC
2426/* Routine to create an entry in an a.out link hash table. */
2427
2428struct bfd_hash_entry *
116c20d2
NC
2429NAME (aout, link_hash_newfunc) (struct bfd_hash_entry *entry,
2430 struct bfd_hash_table *table,
2431 const char *string)
e135f41b
NC
2432{
2433 struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
2434
2435 /* Allocate the structure if it has not already been allocated by a
2436 subclass. */
116c20d2
NC
2437 if (ret == NULL)
2438 ret = bfd_hash_allocate (table, sizeof (* ret));
2439 if (ret == NULL)
2440 return NULL;
e135f41b
NC
2441
2442 /* Call the allocation method of the superclass. */
116c20d2
NC
2443 ret = (struct aout_link_hash_entry *)
2444 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string);
e135f41b
NC
2445 if (ret)
2446 {
2447 /* Set local fields. */
b34976b6 2448 ret->written = FALSE;
e135f41b
NC
2449 ret->indx = -1;
2450 }
2451
2452 return (struct bfd_hash_entry *) ret;
2453}
2454
2455/* Initialize an a.out link hash table. */
2456
b34976b6 2457bfd_boolean
116c20d2
NC
2458NAME (aout, link_hash_table_init) (struct aout_link_hash_table *table,
2459 bfd *abfd,
2460 struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
2461 struct bfd_hash_table *,
66eb6687
AM
2462 const char *),
2463 unsigned int entsize)
e135f41b 2464{
66eb6687 2465 return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
e135f41b
NC
2466}
2467
2468/* Create an a.out link hash table. */
2469
2470struct bfd_link_hash_table *
116c20d2 2471NAME (aout, link_hash_table_create) (bfd *abfd)
e135f41b
NC
2472{
2473 struct aout_link_hash_table *ret;
dc810e39 2474 bfd_size_type amt = sizeof (struct aout_link_hash_table);
e135f41b 2475
116c20d2 2476 ret = bfd_alloc (abfd, amt);
e135f41b 2477 if (ret == NULL)
116c20d2
NC
2478 return NULL;
2479 if (! NAME (aout, link_hash_table_init) (ret, abfd,
66eb6687
AM
2480 NAME (aout, link_hash_newfunc),
2481 sizeof (struct aout_link_hash_entry)))
e135f41b
NC
2482 {
2483 free (ret);
116c20d2 2484 return NULL;
e135f41b
NC
2485 }
2486 return &ret->root;
2487}
2488
116c20d2
NC
2489/* Free up the internal symbols read from an a.out file. */
2490
2491static bfd_boolean
2492aout_link_free_symbols (bfd *abfd)
2493{
2494 if (obj_aout_external_syms (abfd) != NULL)
2495 {
2496#ifdef USE_MMAP
2497 bfd_free_window (&obj_aout_sym_window (abfd));
2498#else
2499 free ((void *) obj_aout_external_syms (abfd));
2500#endif
2501 obj_aout_external_syms (abfd) = NULL;
2502 }
2503
2504 if (obj_aout_external_strings (abfd) != NULL)
2505 {
2506#ifdef USE_MMAP
2507 bfd_free_window (&obj_aout_string_window (abfd));
2508#else
2509 free ((void *) obj_aout_external_strings (abfd));
2510#endif
2511 obj_aout_external_strings (abfd) = NULL;
2512 }
2513 return TRUE;
2514}
2515
e135f41b
NC
2516/* Given an a.out BFD, add symbols to the global hash table as
2517 appropriate. */
2518
b34976b6 2519bfd_boolean
116c20d2 2520NAME (aout, link_add_symbols) (bfd *abfd, struct bfd_link_info *info)
e135f41b
NC
2521{
2522 switch (bfd_get_format (abfd))
2523 {
2524 case bfd_object:
2525 return aout_link_add_object_symbols (abfd, info);
2526 case bfd_archive:
2527 return _bfd_generic_link_add_archive_symbols
2528 (abfd, info, aout_link_check_archive_element);
2529 default:
2530 bfd_set_error (bfd_error_wrong_format);
b34976b6 2531 return FALSE;
e135f41b
NC
2532 }
2533}
2534
2535/* Add symbols from an a.out object file. */
2536
b34976b6 2537static bfd_boolean
116c20d2 2538aout_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
e135f41b
NC
2539{
2540 if (! aout_get_external_symbols (abfd))
b34976b6 2541 return FALSE;
e135f41b 2542 if (! aout_link_add_symbols (abfd, info))
b34976b6 2543 return FALSE;
e135f41b
NC
2544 if (! info->keep_memory)
2545 {
2546 if (! aout_link_free_symbols (abfd))
b34976b6 2547 return FALSE;
e135f41b 2548 }
b34976b6 2549 return TRUE;
e135f41b
NC
2550}
2551
e135f41b
NC
2552/* Look through the internal symbols to see if this object file should
2553 be included in the link. We should include this object file if it
2554 defines any symbols which are currently undefined. If this object
2555 file defines a common symbol, then we may adjust the size of the
2556 known symbol but we do not include the object file in the link
2557 (unless there is some other reason to include it). */
2558
b34976b6 2559static bfd_boolean
116c20d2
NC
2560aout_link_check_ar_symbols (bfd *abfd,
2561 struct bfd_link_info *info,
2562 bfd_boolean *pneeded)
e135f41b 2563{
116c20d2 2564 struct external_nlist *p;
e135f41b
NC
2565 struct external_nlist *pend;
2566 char *strings;
2567
b34976b6 2568 *pneeded = FALSE;
e135f41b
NC
2569
2570 /* Look through all the symbols. */
2571 p = obj_aout_external_syms (abfd);
2572 pend = p + obj_aout_external_sym_count (abfd);
2573 strings = obj_aout_external_strings (abfd);
2574 for (; p < pend; p++)
2575 {
dc810e39 2576 int type = H_GET_8 (abfd, p->e_type);
e135f41b
NC
2577 const char *name;
2578 struct bfd_link_hash_entry *h;
2579
2580 /* Ignore symbols that are not externally visible. This is an
2581 optimization only, as we check the type more thoroughly
2582 below. */
2583 if ((type & N_EXT) == 0
2584 || type == N_FN)
2585 continue;
2586
2587 name = strings + GET_WORD (abfd, p->e_strx);
b34976b6 2588 h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
e135f41b
NC
2589
2590 /* We are only interested in symbols that are currently
2591 undefined or common. */
116c20d2 2592 if (h == NULL
e135f41b
NC
2593 || (h->type != bfd_link_hash_undefined
2594 && h->type != bfd_link_hash_common))
2595 continue;
2596
2597 if (type == (N_TEXT | N_EXT)
2598 || type == (N_DATA | N_EXT)
2599 || type == (N_BSS | N_EXT)
2600 || type == (N_ABS | N_EXT))
2601 {
2602 /* This object file defines this symbol. We must link it
2603 in. This is true regardless of whether the current
2604 definition of the symbol is undefined or common. If the
2605 current definition is common, we have a case in which we
2606 have already seen an object file including
2607 int a;
2608 and this object file from the archive includes
2609 int a = 5;
2610 In such a case we must include this object file.
2611
2612 FIXME: The SunOS 4.1.3 linker will pull in the archive
2613 element if the symbol is defined in the .data section,
2614 but not if it is defined in the .text section. That
2615 seems a bit crazy to me, and I haven't implemented it.
2616 However, it might be correct. */
2617 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
b34976b6
AM
2618 return FALSE;
2619 *pneeded = TRUE;
2620 return TRUE;
e135f41b
NC
2621 }
2622
2623 if (type == (N_UNDF | N_EXT))
2624 {
2625 bfd_vma value;
2626
2627 value = GET_WORD (abfd, p->e_value);
2628 if (value != 0)
2629 {
2630 /* This symbol is common in the object from the archive
2631 file. */
2632 if (h->type == bfd_link_hash_undefined)
2633 {
2634 bfd *symbfd;
2635 unsigned int power;
2636
2637 symbfd = h->u.undef.abfd;
116c20d2 2638 if (symbfd == NULL)
e135f41b
NC
2639 {
2640 /* This symbol was created as undefined from
2641 outside BFD. We assume that we should link
2642 in the object file. This is done for the -u
2643 option in the linker. */
116c20d2
NC
2644 if (! (*info->callbacks->add_archive_element)
2645 (info, abfd, name))
b34976b6
AM
2646 return FALSE;
2647 *pneeded = TRUE;
2648 return TRUE;
e135f41b
NC
2649 }
2650 /* Turn the current link symbol into a common
2651 symbol. It is already on the undefs list. */
2652 h->type = bfd_link_hash_common;
116c20d2
NC
2653 h->u.c.p = bfd_hash_allocate (&info->hash->table,
2654 sizeof (struct bfd_link_hash_common_entry));
e135f41b 2655 if (h->u.c.p == NULL)
b34976b6 2656 return FALSE;
e135f41b
NC
2657
2658 h->u.c.size = value;
2659
2660 /* FIXME: This isn't quite right. The maximum
2661 alignment of a common symbol should be set by the
2662 architecture of the output file, not of the input
2663 file. */
2664 power = bfd_log2 (value);
2665 if (power > bfd_get_arch_info (abfd)->section_align_power)
2666 power = bfd_get_arch_info (abfd)->section_align_power;
2667 h->u.c.p->alignment_power = power;
2668
2669 h->u.c.p->section = bfd_make_section_old_way (symbfd,
2670 "COMMON");
2671 }
2672 else
2673 {
2674 /* Adjust the size of the common symbol if
2675 necessary. */
2676 if (value > h->u.c.size)
2677 h->u.c.size = value;
2678 }
2679 }
2680 }
2681 }
2682
2683 /* We do not need this object file. */
b34976b6 2684 return TRUE;
e135f41b
NC
2685}
2686
116c20d2
NC
2687/* Check a single archive element to see if we need to include it in
2688 the link. *PNEEDED is set according to whether this element is
2689 needed in the link or not. This is called from
2690 _bfd_generic_link_add_archive_symbols. */
2691
2692static bfd_boolean
2693aout_link_check_archive_element (bfd *abfd,
2694 struct bfd_link_info *info,
2695 bfd_boolean *pneeded)
2696{
2697 if (! aout_get_external_symbols (abfd))
2698 return FALSE;
2699
2700 if (! aout_link_check_ar_symbols (abfd, info, pneeded))
2701 return FALSE;
2702
2703 if (*pneeded)
2704 {
2705 if (! aout_link_add_symbols (abfd, info))
2706 return FALSE;
2707 }
2708
2709 if (! info->keep_memory || ! *pneeded)
2710 {
2711 if (! aout_link_free_symbols (abfd))
2712 return FALSE;
2713 }
2714
2715 return TRUE;
2716}
2717
e135f41b
NC
2718/* Add all symbols from an object file to the hash table. */
2719
b34976b6 2720static bfd_boolean
116c20d2 2721aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
e135f41b 2722{
b34976b6 2723 bfd_boolean (*add_one_symbol)
116c20d2
NC
2724 (struct bfd_link_info *, bfd *, const char *, flagword, asection *,
2725 bfd_vma, const char *, bfd_boolean, bfd_boolean,
2726 struct bfd_link_hash_entry **);
e135f41b
NC
2727 struct external_nlist *syms;
2728 bfd_size_type sym_count;
2729 char *strings;
b34976b6 2730 bfd_boolean copy;
e135f41b 2731 struct aout_link_hash_entry **sym_hash;
116c20d2 2732 struct external_nlist *p;
e135f41b
NC
2733 struct external_nlist *pend;
2734
2735 syms = obj_aout_external_syms (abfd);
2736 sym_count = obj_aout_external_sym_count (abfd);
2737 strings = obj_aout_external_strings (abfd);
2738 if (info->keep_memory)
b34976b6 2739 copy = FALSE;
e135f41b 2740 else
b34976b6 2741 copy = TRUE;
e135f41b
NC
2742
2743 if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
2744 {
2745 if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
2746 (abfd, info, &syms, &sym_count, &strings)))
b34976b6 2747 return FALSE;
e135f41b
NC
2748 }
2749
2750 /* We keep a list of the linker hash table entries that correspond
2751 to particular symbols. We could just look them up in the hash
2752 table, but keeping the list is more efficient. Perhaps this
2753 should be conditional on info->keep_memory. */
116c20d2
NC
2754 sym_hash = bfd_alloc (abfd,
2755 sym_count * sizeof (struct aout_link_hash_entry *));
e135f41b 2756 if (sym_hash == NULL && sym_count != 0)
b34976b6 2757 return FALSE;
e135f41b
NC
2758 obj_aout_sym_hashes (abfd) = sym_hash;
2759
2760 add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
2761 if (add_one_symbol == NULL)
2762 add_one_symbol = _bfd_generic_link_add_one_symbol;
2763
2764 p = syms;
2765 pend = p + sym_count;
2766 for (; p < pend; p++, sym_hash++)
2767 {
2768 int type;
2769 const char *name;
2770 bfd_vma value;
2771 asection *section;
2772 flagword flags;
2773 const char *string;
2774
2775 *sym_hash = NULL;
2776
dc810e39 2777 type = H_GET_8 (abfd, p->e_type);
e135f41b 2778
e135f41b
NC
2779 name = strings + GET_WORD (abfd, p->e_strx);
2780 value = GET_WORD (abfd, p->e_value);
2781 flags = BSF_GLOBAL;
2782 string = NULL;
2783 switch (type)
2784 {
2785 default:
2786 abort ();
2787
2788 case N_UNDF:
2789 case N_ABS:
2790 case N_TEXT:
2791 case N_DATA:
2792 case N_BSS:
2793 case N_REG:
2794 case N_FN:
2795 /* Ignore symbols that are not externally visible. */
2796 continue;
2797
2798 case N_UNDF | N_EXT:
2799 if (value == 0)
2800 {
2801 section = bfd_und_section_ptr;
2802 flags = 0;
2803 }
2804 else
2805 section = bfd_com_section_ptr;
2806 break;
2807 case N_ABS | N_EXT:
2808 section = bfd_abs_section_ptr;
2809 break;
2810 case N_TEXT | N_EXT:
2811 section = obj_textsec (abfd);
2812 value -= bfd_get_section_vma (abfd, section);
2813 break;
2814 case N_DATA | N_EXT:
2815 /* Treat N_SETV symbols as N_DATA symbol; see comment in
2816 translate_from_native_sym_flags. */
2817 section = obj_datasec (abfd);
2818 value -= bfd_get_section_vma (abfd, section);
2819 break;
2820 case N_BSS | N_EXT:
2821 section = obj_bsssec (abfd);
2822 value -= bfd_get_section_vma (abfd, section);
2823 break;
2824 }
2825
2826 if (! ((*add_one_symbol)
b34976b6 2827 (info, abfd, name, flags, section, value, string, copy, FALSE,
e135f41b 2828 (struct bfd_link_hash_entry **) sym_hash)))
b34976b6 2829 return FALSE;
e135f41b
NC
2830
2831 /* Restrict the maximum alignment of a common symbol based on
2832 the architecture, since a.out has no way to represent
2833 alignment requirements of a section in a .o file. FIXME:
2834 This isn't quite right: it should use the architecture of the
2835 output file, not the input files. */
2836 if ((*sym_hash)->root.type == bfd_link_hash_common
2837 && ((*sym_hash)->root.u.c.p->alignment_power >
2838 bfd_get_arch_info (abfd)->section_align_power))
2839 (*sym_hash)->root.u.c.p->alignment_power =
2840 bfd_get_arch_info (abfd)->section_align_power;
2841
2842 /* If this is a set symbol, and we are not building sets, then
2843 it is possible for the hash entry to not have been set. In
2844 such a case, treat the symbol as not globally defined. */
2845 if ((*sym_hash)->root.type == bfd_link_hash_new)
2846 {
2847 BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
2848 *sym_hash = NULL;
2849 }
2850 }
2851
b34976b6 2852 return TRUE;
e135f41b
NC
2853}
2854\f
116c20d2 2855/* Look up an entry in an the header file hash table. */
e135f41b
NC
2856
2857#define aout_link_includes_lookup(table, string, create, copy) \
2858 ((struct aout_link_includes_entry *) \
2859 bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
2860
e135f41b
NC
2861/* The function to create a new entry in the header file hash table. */
2862
2863static struct bfd_hash_entry *
116c20d2
NC
2864aout_link_includes_newfunc (struct bfd_hash_entry *entry,
2865 struct bfd_hash_table *table,
2866 const char *string)
e135f41b 2867{
116c20d2 2868 struct aout_link_includes_entry * ret =
e135f41b
NC
2869 (struct aout_link_includes_entry *) entry;
2870
2871 /* Allocate the structure if it has not already been allocated by a
2872 subclass. */
116c20d2
NC
2873 if (ret == NULL)
2874 ret = bfd_hash_allocate (table,
2875 sizeof (struct aout_link_includes_entry));
2876 if (ret == NULL)
2877 return NULL;
e135f41b
NC
2878
2879 /* Call the allocation method of the superclass. */
2880 ret = ((struct aout_link_includes_entry *)
2881 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
2882 if (ret)
116c20d2
NC
2883 /* Set local fields. */
2884 ret->totals = NULL;
e135f41b
NC
2885
2886 return (struct bfd_hash_entry *) ret;
2887}
2888
116c20d2
NC
2889static bfd_boolean
2890aout_link_write_other_symbol (struct aout_link_hash_entry *h, void * data)
e135f41b 2891{
116c20d2
NC
2892 struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
2893 bfd *output_bfd;
2894 int type;
2895 bfd_vma val;
2896 struct external_nlist outsym;
2897 bfd_size_type indx;
2898 bfd_size_type amt;
e135f41b 2899
116c20d2
NC
2900 if (h->root.type == bfd_link_hash_warning)
2901 {
2902 h = (struct aout_link_hash_entry *) h->root.u.i.link;
2903 if (h->root.type == bfd_link_hash_new)
2904 return TRUE;
2905 }
e135f41b 2906
116c20d2 2907 output_bfd = finfo->output_bfd;
e135f41b 2908
116c20d2 2909 if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
e135f41b 2910 {
116c20d2
NC
2911 if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
2912 (output_bfd, finfo->info, h)))
e135f41b 2913 {
116c20d2
NC
2914 /* FIXME: No way to handle errors. */
2915 abort ();
e135f41b 2916 }
116c20d2 2917 }
e135f41b 2918
116c20d2
NC
2919 if (h->written)
2920 return TRUE;
e135f41b 2921
116c20d2 2922 h->written = TRUE;
e135f41b 2923
116c20d2
NC
2924 /* An indx of -2 means the symbol must be written. */
2925 if (h->indx != -2
2926 && (finfo->info->strip == strip_all
2927 || (finfo->info->strip == strip_some
2928 && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
2929 FALSE, FALSE) == NULL)))
2930 return TRUE;
e135f41b 2931
116c20d2 2932 switch (h->root.type)
e135f41b 2933 {
116c20d2
NC
2934 default:
2935 abort ();
2936 /* Avoid variable not initialized warnings. */
2937 return TRUE;
2938 case bfd_link_hash_new:
2939 /* This can happen for set symbols when sets are not being
2940 built. */
2941 return TRUE;
2942 case bfd_link_hash_undefined:
2943 type = N_UNDF | N_EXT;
2944 val = 0;
2945 break;
2946 case bfd_link_hash_defined:
2947 case bfd_link_hash_defweak:
2948 {
2949 asection *sec;
2950
2951 sec = h->root.u.def.section->output_section;
2952 BFD_ASSERT (bfd_is_abs_section (sec)
2953 || sec->owner == output_bfd);
2954 if (sec == obj_textsec (output_bfd))
2955 type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
2956 else if (sec == obj_datasec (output_bfd))
2957 type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
2958 else if (sec == obj_bsssec (output_bfd))
2959 type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
2960 else
2961 type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
2962 type |= N_EXT;
2963 val = (h->root.u.def.value
2964 + sec->vma
2965 + h->root.u.def.section->output_offset);
2966 }
2967 break;
2968 case bfd_link_hash_common:
2969 type = N_UNDF | N_EXT;
2970 val = h->root.u.c.size;
2971 break;
2972 case bfd_link_hash_undefweak:
2973 type = N_WEAKU;
2974 val = 0;
2975 case bfd_link_hash_indirect:
2976 case bfd_link_hash_warning:
2977 /* FIXME: Ignore these for now. The circumstances under which
2978 they should be written out are not clear to me. */
2979 return TRUE;
e135f41b
NC
2980 }
2981
116c20d2
NC
2982 H_PUT_8 (output_bfd, type, outsym.e_type);
2983 indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
2984 FALSE);
2985 if (indx == (bfd_size_type) -1)
2986 /* FIXME: No way to handle errors. */
2987 abort ();
e135f41b 2988
116c20d2
NC
2989 PUT_WORD (output_bfd, indx, outsym.e_strx);
2990 PUT_WORD (output_bfd, val, outsym.e_value);
e135f41b 2991
116c20d2
NC
2992 amt = EXTERNAL_NLIST_SIZE;
2993 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
2994 || bfd_bwrite ((void *) &outsym, amt, output_bfd) != amt)
2995 /* FIXME: No way to handle errors. */
2996 abort ();
e135f41b 2997
116c20d2
NC
2998 finfo->symoff += amt;
2999 h->indx = obj_aout_external_sym_count (output_bfd);
3000 ++obj_aout_external_sym_count (output_bfd);
e135f41b 3001
116c20d2
NC
3002 return TRUE;
3003}
e135f41b 3004
116c20d2 3005/* Handle a link order which is supposed to generate a reloc. */
e135f41b 3006
116c20d2
NC
3007static bfd_boolean
3008aout_link_reloc_link_order (struct aout_final_link_info *finfo,
3009 asection *o,
3010 struct bfd_link_order *p)
3011{
3012 struct bfd_link_order_reloc *pr;
3013 int r_index;
3014 int r_extern;
3015 reloc_howto_type *howto;
3016 file_ptr *reloff_ptr;
3017 struct reloc_std_external srel;
3018 void * rel_ptr;
3019 bfd_size_type rel_size;
e135f41b 3020
116c20d2 3021 pr = p->u.reloc.p;
e135f41b 3022
116c20d2 3023 if (p->type == bfd_section_reloc_link_order)
e135f41b 3024 {
116c20d2
NC
3025 r_extern = 0;
3026 if (bfd_is_abs_section (pr->u.section))
3027 r_index = N_ABS | N_EXT;
3028 else
e135f41b 3029 {
116c20d2
NC
3030 BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
3031 r_index = pr->u.section->target_index;
e135f41b
NC
3032 }
3033 }
116c20d2 3034 else
e135f41b 3035 {
116c20d2 3036 struct aout_link_hash_entry *h;
e135f41b 3037
116c20d2
NC
3038 BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
3039 r_extern = 1;
3040 h = ((struct aout_link_hash_entry *)
3041 bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
3042 pr->u.name, FALSE, FALSE, TRUE));
3043 if (h != NULL
3044 && h->indx >= 0)
3045 r_index = h->indx;
3046 else if (h != NULL)
3047 {
3048 /* We decided to strip this symbol, but it turns out that we
3049 can't. Note that we lose the other and desc information
3050 here. I don't think that will ever matter for a global
3051 symbol. */
3052 h->indx = -2;
3053 h->written = FALSE;
3054 if (! aout_link_write_other_symbol (h, (void *) finfo))
3055 return FALSE;
3056 r_index = h->indx;
e135f41b 3057 }
116c20d2 3058 else
e135f41b 3059 {
116c20d2
NC
3060 if (! ((*finfo->info->callbacks->unattached_reloc)
3061 (finfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0)))
3062 return FALSE;
3063 r_index = 0;
e135f41b
NC
3064 }
3065 }
3066
116c20d2
NC
3067 howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
3068 if (howto == 0)
e135f41b 3069 {
116c20d2
NC
3070 bfd_set_error (bfd_error_bad_value);
3071 return FALSE;
e135f41b
NC
3072 }
3073
116c20d2
NC
3074 if (o == obj_textsec (finfo->output_bfd))
3075 reloff_ptr = &finfo->treloff;
3076 else if (o == obj_datasec (finfo->output_bfd))
3077 reloff_ptr = &finfo->dreloff;
3078 else
3079 abort ();
e135f41b 3080
116c20d2
NC
3081#ifdef MY_put_reloc
3082 MY_put_reloc(finfo->output_bfd, r_extern, r_index, p->offset, howto,
3083 &srel);
3084#else
3085 {
3086 int r_pcrel;
3087 int r_baserel;
3088 int r_jmptable;
3089 int r_relative;
3090 int r_length;
e135f41b 3091
116c20d2 3092 fprintf (stderr, "TODO: line %d in bfd/pdp11.c\n", __LINE__);
e135f41b 3093
116c20d2
NC
3094 r_pcrel = howto->pc_relative;
3095 r_baserel = (howto->type & 8) != 0;
3096 r_jmptable = (howto->type & 16) != 0;
3097 r_relative = (howto->type & 32) != 0;
3098 r_length = howto->size;
e135f41b 3099
116c20d2
NC
3100 PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
3101 if (bfd_header_big_endian (finfo->output_bfd))
3102 {
3103 srel.r_index[0] = r_index >> 16;
3104 srel.r_index[1] = r_index >> 8;
3105 srel.r_index[2] = r_index;
3106 srel.r_type[0] =
3107 ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
3108 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
3109 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
3110 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
3111 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
3112 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
3113 }
3114 else
3115 {
3116 srel.r_index[2] = r_index >> 16;
3117 srel.r_index[1] = r_index >> 8;
3118 srel.r_index[0] = r_index;
3119 srel.r_type[0] =
3120 ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
3121 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
3122 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
3123 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
3124 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
3125 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
3126 }
3127 }
3128#endif
3129 rel_ptr = (void *) &srel;
e135f41b 3130
116c20d2
NC
3131 /* We have to write the addend into the object file, since
3132 standard a.out relocs are in place. It would be more
3133 reliable if we had the current contents of the file here,
3134 rather than assuming zeroes, but we can't read the file since
3135 it was opened using bfd_openw. */
3136 if (pr->addend != 0)
e135f41b 3137 {
116c20d2
NC
3138 bfd_size_type size;
3139 bfd_reloc_status_type r;
3140 bfd_byte *buf;
3141 bfd_boolean ok;
3142
3143 size = bfd_get_reloc_size (howto);
3144 buf = bfd_zmalloc (size);
3145 if (buf == NULL)
3146 return FALSE;
3147 r = MY_relocate_contents (howto, finfo->output_bfd,
3148 pr->addend, buf);
3149 switch (r)
3150 {
3151 case bfd_reloc_ok:
3152 break;
3153 default:
3154 case bfd_reloc_outofrange:
3155 abort ();
3156 case bfd_reloc_overflow:
3157 if (! ((*finfo->info->callbacks->reloc_overflow)
3158 (finfo->info, NULL,
3159 (p->type == bfd_section_reloc_link_order
3160 ? bfd_section_name (finfo->output_bfd,
3161 pr->u.section)
3162 : pr->u.name),
3163 howto->name, pr->addend, NULL,
3164 (asection *) NULL, (bfd_vma) 0)))
3165 {
3166 free (buf);
3167 return FALSE;
3168 }
3169 break;
3170 }
3171 ok = bfd_set_section_contents (finfo->output_bfd, o,
3172 (void *) buf,
3173 (file_ptr) p->offset,
3174 size);
3175 free (buf);
3176 if (! ok)
3177 return FALSE;
e135f41b
NC
3178 }
3179
116c20d2
NC
3180 rel_size = obj_reloc_entry_size (finfo->output_bfd);
3181 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
3182 || bfd_bwrite (rel_ptr, rel_size, finfo->output_bfd) != rel_size)
b34976b6 3183 return FALSE;
e135f41b 3184
116c20d2 3185 *reloff_ptr += rel_size;
e135f41b 3186
116c20d2
NC
3187 /* Assert that the relocs have not run into the symbols, and that n
3188 the text relocs have not run into the data relocs. */
3189 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
3190 && (reloff_ptr != &finfo->treloff
3191 || (*reloff_ptr
3192 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
e135f41b 3193
116c20d2
NC
3194 return TRUE;
3195}
e135f41b 3196
116c20d2
NC
3197/* Get the section corresponding to a reloc index. */
3198
3199static inline asection *
3200aout_reloc_type_to_section (bfd *abfd, int type)
3201{
3202 switch (type)
e135f41b 3203 {
116c20d2
NC
3204 case RTEXT: return obj_textsec (abfd);
3205 case RDATA: return obj_datasec (abfd);
3206 case RBSS: return obj_bsssec (abfd);
3207 case RABS: return bfd_abs_section_ptr;
3208 case REXT: return bfd_und_section_ptr;
3209 default: abort ();
e135f41b 3210 }
e135f41b
NC
3211}
3212
b34976b6 3213static bfd_boolean
116c20d2
NC
3214pdp11_aout_link_input_section (struct aout_final_link_info *finfo,
3215 bfd *input_bfd,
3216 asection *input_section,
3217 bfd_byte *relocs,
3218 bfd_size_type rel_size,
3219 bfd_byte *contents)
e135f41b 3220{
116c20d2
NC
3221 bfd_boolean (*check_dynamic_reloc)
3222 (struct bfd_link_info *, bfd *, asection *,
3223 struct aout_link_hash_entry *, void *, bfd_byte *, bfd_boolean *,
3224 bfd_vma *);
e135f41b 3225 bfd *output_bfd;
116c20d2
NC
3226 bfd_boolean relocatable;
3227 struct external_nlist *syms;
e135f41b 3228 char *strings;
116c20d2 3229 struct aout_link_hash_entry **sym_hashes;
e135f41b 3230 int *symbol_map;
116c20d2
NC
3231 bfd_size_type reloc_count;
3232 bfd_byte *rel;
3233 bfd_byte *rel_end;
e135f41b
NC
3234
3235 output_bfd = finfo->output_bfd;
116c20d2 3236 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
e135f41b 3237
116c20d2
NC
3238 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_SIZE);
3239 BFD_ASSERT (input_bfd->xvec->header_byteorder
3240 == output_bfd->xvec->header_byteorder);
e135f41b 3241
116c20d2
NC
3242 relocatable = finfo->info->relocatable;
3243 syms = obj_aout_external_syms (input_bfd);
3244 strings = obj_aout_external_strings (input_bfd);
3245 sym_hashes = obj_aout_sym_hashes (input_bfd);
e135f41b 3246 symbol_map = finfo->symbol_map;
116c20d2
NC
3247
3248 reloc_count = rel_size / RELOC_SIZE;
3249 rel = relocs;
3250 rel_end = rel + rel_size;
3251 for (; rel < rel_end; rel += RELOC_SIZE)
e135f41b 3252 {
116c20d2
NC
3253 bfd_vma r_addr;
3254 int r_index;
3255 int r_type;
3256 int r_pcrel;
3257 int r_extern;
3258 reloc_howto_type *howto;
3259 struct aout_link_hash_entry *h = NULL;
3260 bfd_vma relocation;
3261 bfd_reloc_status_type r;
3262 int reloc_entry;
e135f41b 3263
116c20d2
NC
3264 reloc_entry = GET_WORD (input_bfd, (void *) rel);
3265 if (reloc_entry == 0)
e135f41b
NC
3266 continue;
3267
116c20d2
NC
3268 {
3269 unsigned int howto_idx;
e135f41b 3270
116c20d2
NC
3271 r_index = (reloc_entry & RIDXMASK) >> 4;
3272 r_type = reloc_entry & RTYPE;
3273 r_pcrel = reloc_entry & RELFLG;
3274 r_addr = (char *) rel - (char *) relocs;
e135f41b 3275
116c20d2 3276 r_extern = (r_type == REXT);
e135f41b 3277
116c20d2
NC
3278 howto_idx = r_pcrel;
3279 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_pdp11));
3280 howto = howto_table_pdp11 + howto_idx;
3281 }
3282
3283 if (relocatable)
e135f41b 3284 {
116c20d2
NC
3285 /* We are generating a relocatable output file, and must
3286 modify the reloc accordingly. */
3287 if (r_extern)
3288 {
3289 /* If we know the symbol this relocation is against,
3290 convert it into a relocation against a section. This
3291 is what the native linker does. */
3292 h = sym_hashes[r_index];
3293 if (h != NULL
3294 && (h->root.type == bfd_link_hash_defined
3295 || h->root.type == bfd_link_hash_defweak))
3296 {
3297 asection *output_section;
e135f41b 3298
116c20d2
NC
3299 /* Compute a new r_index. */
3300 output_section = h->root.u.def.section->output_section;
e135f41b 3301 if (output_section == obj_textsec (output_bfd))
116c20d2 3302 r_type = N_TEXT;
e135f41b 3303 else if (output_section == obj_datasec (output_bfd))
116c20d2 3304 r_type = N_DATA;
e135f41b 3305 else if (output_section == obj_bsssec (output_bfd))
116c20d2 3306 r_type = N_BSS;
e135f41b 3307 else
116c20d2 3308 r_type = N_ABS;
e135f41b 3309
116c20d2
NC
3310 /* Add the symbol value and the section VMA to the
3311 addend stored in the contents. */
3312 relocation = (h->root.u.def.value
3313 + output_section->vma
3314 + h->root.u.def.section->output_offset);
e135f41b 3315 }
116c20d2 3316 else
e135f41b 3317 {
116c20d2
NC
3318 /* We must change r_index according to the symbol
3319 map. */
3320 r_index = symbol_map[r_index];
e135f41b 3321
116c20d2 3322 if (r_index == -1)
e135f41b 3323 {
116c20d2 3324 if (h != NULL)
e135f41b 3325 {
116c20d2
NC
3326 /* We decided to strip this symbol, but it
3327 turns out that we can't. Note that we
3328 lose the other and desc information here.
3329 I don't think that will ever matter for a
3330 global symbol. */
3331 if (h->indx < 0)
e135f41b 3332 {
116c20d2
NC
3333 h->indx = -2;
3334 h->written = FALSE;
3335 if (! aout_link_write_other_symbol (h,
3336 (void *) finfo))
3337 return FALSE;
e135f41b 3338 }
116c20d2
NC
3339 r_index = h->indx;
3340 }
3341 else
3342 {
3343 const char *name;
3344
3345 name = strings + GET_WORD (input_bfd,
3346 syms[r_index].e_strx);
3347 if (! ((*finfo->info->callbacks->unattached_reloc)
3348 (finfo->info, name, input_bfd, input_section,
3349 r_addr)))
3350 return FALSE;
3351 r_index = 0;
e135f41b
NC
3352 }
3353 }
116c20d2
NC
3354
3355 relocation = 0;
e135f41b
NC
3356 }
3357
116c20d2
NC
3358 /* Write out the new r_index value. */
3359 reloc_entry = GET_WORD (input_bfd, rel);
3360 reloc_entry &= RIDXMASK;
3361 reloc_entry |= r_index << 4;
3362 PUT_WORD (input_bfd, reloc_entry, rel);
3363 }
3364 else
3365 {
3366 asection *section;
3367
3368 /* This is a relocation against a section. We must
3369 adjust by the amount that the section moved. */
3370 section = aout_reloc_type_to_section (input_bfd, r_type);
3371 relocation = (section->output_section->vma
3372 + section->output_offset
3373 - section->vma);
3374 }
3375
3376 /* Change the address of the relocation. */
3377 fprintf (stderr, "TODO: change the address of the relocation\n");
3378
3379 /* Adjust a PC relative relocation by removing the reference
3380 to the original address in the section and including the
3381 reference to the new address. */
3382 if (r_pcrel)
3383 relocation -= (input_section->output_section->vma
3384 + input_section->output_offset
3385 - input_section->vma);
3386
3387#ifdef MY_relocatable_reloc
3388 MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
3389#endif
3390
3391 if (relocation == 0)
3392 r = bfd_reloc_ok;
3393 else
3394 r = MY_relocate_contents (howto,
3395 input_bfd, relocation,
3396 contents + r_addr);
3397 }
3398 else
3399 {
3400 bfd_boolean hundef;
3401
3402 /* We are generating an executable, and must do a full
3403 relocation. */
3404 hundef = FALSE;
3405 if (r_extern)
3406 {
3407 h = sym_hashes[r_index];
3408
3409 if (h != NULL
3410 && (h->root.type == bfd_link_hash_defined
3411 || h->root.type == bfd_link_hash_defweak))
e135f41b 3412 {
116c20d2
NC
3413 relocation = (h->root.u.def.value
3414 + h->root.u.def.section->output_section->vma
3415 + h->root.u.def.section->output_offset);
e135f41b 3416 }
116c20d2
NC
3417 else if (h != NULL
3418 && h->root.type == bfd_link_hash_undefweak)
3419 relocation = 0;
e135f41b
NC
3420 else
3421 {
116c20d2
NC
3422 hundef = TRUE;
3423 relocation = 0;
3424 }
3425 }
3426 else
3427 {
3428 asection *section;
e135f41b 3429
116c20d2
NC
3430 section = aout_reloc_type_to_section (input_bfd, r_type);
3431 relocation = (section->output_section->vma
3432 + section->output_offset
3433 - section->vma);
3434 if (r_pcrel)
3435 relocation += input_section->vma;
3436 }
e135f41b 3437
116c20d2
NC
3438 if (check_dynamic_reloc != NULL)
3439 {
3440 bfd_boolean skip;
e135f41b 3441
116c20d2
NC
3442 if (! ((*check_dynamic_reloc)
3443 (finfo->info, input_bfd, input_section, h,
3444 (void *) rel, contents, &skip, &relocation)))
3445 return FALSE;
3446 if (skip)
3447 continue;
3448 }
3449
3450 /* Now warn if a global symbol is undefined. We could not
3451 do this earlier, because check_dynamic_reloc might want
3452 to skip this reloc. */
3453 if (hundef && ! finfo->info->shared)
3454 {
3455 const char *name;
3456
3457 if (h != NULL)
3458 name = h->root.root.string;
3459 else
3460 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
3461 if (! ((*finfo->info->callbacks->undefined_symbol)
3462 (finfo->info, name, input_bfd, input_section,
3463 r_addr, TRUE)))
3464 return FALSE;
e135f41b 3465 }
116c20d2
NC
3466
3467 r = MY_final_link_relocate (howto,
3468 input_bfd, input_section,
3469 contents, r_addr, relocation,
3470 (bfd_vma) 0);
e135f41b
NC
3471 }
3472
116c20d2 3473 if (r != bfd_reloc_ok)
e135f41b 3474 {
116c20d2
NC
3475 switch (r)
3476 {
3477 default:
3478 case bfd_reloc_outofrange:
3479 abort ();
3480 case bfd_reloc_overflow:
3481 {
3482 const char *name;
3483
3484 if (h != NULL)
3485 name = NULL;
3486 else if (r_extern)
3487 name = strings + GET_WORD (input_bfd,
3488 syms[r_index].e_strx);
3489 else
3490 {
3491 asection *s;
3492
3493 s = aout_reloc_type_to_section (input_bfd, r_type);
3494 name = bfd_section_name (input_bfd, s);
3495 }
3496 if (! ((*finfo->info->callbacks->reloc_overflow)
3497 (finfo->info, (h ? &h->root : NULL), name,
3498 howto->name, (bfd_vma) 0, input_bfd,
3499 input_section, r_addr)))
3500 return FALSE;
3501 }
3502 break;
3503 }
e135f41b 3504 }
e135f41b
NC
3505 }
3506
116c20d2
NC
3507 return TRUE;
3508}
3509
3510/* Link an a.out section into the output file. */
3511
3512static bfd_boolean
3513aout_link_input_section (struct aout_final_link_info *finfo,
3514 bfd *input_bfd,
3515 asection *input_section,
3516 file_ptr *reloff_ptr,
3517 bfd_size_type rel_size)
3518{
3519 bfd_size_type input_size;
3520 void * relocs;
3521
3522 /* Get the section contents. */
3523 input_size = input_section->size;
3524 if (! bfd_get_section_contents (input_bfd, input_section,
3525 (void *) finfo->contents,
3526 (file_ptr) 0, input_size))
3527 return FALSE;
3528
3529 /* Read in the relocs if we haven't already done it. */
3530 if (aout_section_data (input_section) != NULL
3531 && aout_section_data (input_section)->relocs != NULL)
3532 relocs = aout_section_data (input_section)->relocs;
3533 else
e135f41b 3534 {
116c20d2
NC
3535 relocs = finfo->relocs;
3536 if (rel_size > 0)
3537 {
3538 if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
3539 || bfd_bread (relocs, rel_size, input_bfd) != rel_size)
3540 return FALSE;
3541 }
3542 }
e135f41b 3543
116c20d2
NC
3544 /* Relocate the section contents. */
3545 if (! pdp11_aout_link_input_section (finfo, input_bfd, input_section,
3546 (bfd_byte *) relocs,
3547 rel_size, finfo->contents))
3548 return FALSE;
3549
3550 /* Write out the section contents. */
3551 if (! bfd_set_section_contents (finfo->output_bfd,
3552 input_section->output_section,
3553 (void *) finfo->contents,
3554 (file_ptr) input_section->output_offset,
3555 input_size))
3556 return FALSE;
3557
3558 /* If we are producing relocatable output, the relocs were
3559 modified, and we now write them out. */
3560 if (finfo->info->relocatable && rel_size > 0)
3561 {
3562 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
3563 return FALSE;
3564 if (bfd_bwrite (relocs, rel_size, finfo->output_bfd) != rel_size)
3565 return FALSE;
3566 *reloff_ptr += rel_size;
3567
3568 /* Assert that the relocs have not run into the symbols, and
3569 that if these are the text relocs they have not run into the
3570 data relocs. */
3571 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
3572 && (reloff_ptr != &finfo->treloff
3573 || (*reloff_ptr
3574 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
3575 }
3576
3577 return TRUE;
3578}
3579
3580/* Link an a.out input BFD into the output file. */
3581
3582static bfd_boolean
3583aout_link_input_bfd (struct aout_final_link_info *finfo, bfd *input_bfd)
3584{
3585 bfd_size_type sym_count;
3586
3587 BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
3588
3589 /* If this is a dynamic object, it may need special handling. */
3590 if ((input_bfd->flags & DYNAMIC) != 0
3591 && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
3592 return ((*aout_backend_info (input_bfd)->link_dynamic_object)
3593 (finfo->info, input_bfd));
3594
3595 /* Get the symbols. We probably have them already, unless
3596 finfo->info->keep_memory is FALSE. */
3597 if (! aout_get_external_symbols (input_bfd))
3598 return FALSE;
3599
3600 sym_count = obj_aout_external_sym_count (input_bfd);
3601
3602 /* Write out the symbols and get a map of the new indices. The map
3603 is placed into finfo->symbol_map. */
3604 if (! aout_link_write_symbols (finfo, input_bfd))
3605 return FALSE;
3606
3607 /* Relocate and write out the sections. These functions use the
3608 symbol map created by aout_link_write_symbols. The linker_mark
3609 field will be set if these sections are to be included in the
3610 link, which will normally be the case. */
3611 if (obj_textsec (input_bfd)->linker_mark)
3612 {
3613 if (! aout_link_input_section (finfo, input_bfd,
3614 obj_textsec (input_bfd),
3615 &finfo->treloff,
3616 exec_hdr (input_bfd)->a_trsize))
3617 return FALSE;
3618 }
3619 if (obj_datasec (input_bfd)->linker_mark)
3620 {
3621 if (! aout_link_input_section (finfo, input_bfd,
3622 obj_datasec (input_bfd),
3623 &finfo->dreloff,
3624 exec_hdr (input_bfd)->a_drsize))
b34976b6 3625 return FALSE;
116c20d2
NC
3626 }
3627
3628 /* If we are not keeping memory, we don't need the symbols any
3629 longer. We still need them if we are keeping memory, because the
3630 strings in the hash table point into them. */
3631 if (! finfo->info->keep_memory)
3632 {
3633 if (! aout_link_free_symbols (input_bfd))
b34976b6 3634 return FALSE;
e135f41b
NC
3635 }
3636
b34976b6 3637 return TRUE;
e135f41b
NC
3638}
3639
116c20d2
NC
3640/* Do the final link step. This is called on the output BFD. The
3641 INFO structure should point to a list of BFDs linked through the
3642 link_next field which can be used to find each BFD which takes part
3643 in the output. Also, each section in ABFD should point to a list
3644 of bfd_link_order structures which list all the input sections for
3645 the output section. */
e135f41b 3646
116c20d2
NC
3647bfd_boolean
3648NAME (aout, final_link) (bfd *abfd,
3649 struct bfd_link_info *info,
3650 void (*callback) (bfd *, file_ptr *, file_ptr *, file_ptr *))
e135f41b 3651{
116c20d2
NC
3652 struct aout_final_link_info aout_info;
3653 bfd_boolean includes_hash_initialized = FALSE;
3654 bfd *sub;
3655 bfd_size_type trsize, drsize;
3656 bfd_size_type max_contents_size;
3657 bfd_size_type max_relocs_size;
3658 bfd_size_type max_sym_count;
3659 bfd_size_type text_size;
3660 file_ptr text_end;
3661 struct bfd_link_order *p;
3662 asection *o;
3663 bfd_boolean have_link_order_relocs;
e135f41b 3664
116c20d2
NC
3665 if (info->shared)
3666 abfd->flags |= DYNAMIC;
e92d460e 3667
116c20d2
NC
3668 aout_info.info = info;
3669 aout_info.output_bfd = abfd;
3670 aout_info.contents = NULL;
3671 aout_info.relocs = NULL;
3672 aout_info.symbol_map = NULL;
3673 aout_info.output_syms = NULL;
e135f41b 3674
66eb6687
AM
3675 if (!bfd_hash_table_init_n (&aout_info.includes.root,
3676 aout_link_includes_newfunc,
3677 sizeof (struct aout_link_includes_entry),
3678 251))
116c20d2
NC
3679 goto error_return;
3680 includes_hash_initialized = TRUE;
3681
3682 /* Figure out the largest section size. Also, if generating
3683 relocatable output, count the relocs. */
3684 trsize = 0;
3685 drsize = 0;
3686 max_contents_size = 0;
3687 max_relocs_size = 0;
3688 max_sym_count = 0;
3689 for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
e135f41b 3690 {
116c20d2
NC
3691 size_t sz;
3692
3693 if (info->relocatable)
e135f41b 3694 {
116c20d2
NC
3695 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3696 {
3697 trsize += exec_hdr (sub)->a_trsize;
3698 drsize += exec_hdr (sub)->a_drsize;
3699 }
3700 else
3701 {
3702 /* FIXME: We need to identify the .text and .data sections
3703 and call get_reloc_upper_bound and canonicalize_reloc to
3704 work out the number of relocs needed, and then multiply
3705 by the reloc size. */
3706 (*_bfd_error_handler)
3707 ("%s: relocatable link from %s to %s not supported",
3708 bfd_get_filename (abfd),
3709 sub->xvec->name, abfd->xvec->name);
3710 bfd_set_error (bfd_error_invalid_operation);
3711 goto error_return;
3712 }
e135f41b 3713 }
e135f41b 3714
116c20d2
NC
3715 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3716 {
3717 sz = obj_textsec (sub)->size;
3718 if (sz > max_contents_size)
3719 max_contents_size = sz;
3720 sz = obj_datasec (sub)->size;
3721 if (sz > max_contents_size)
3722 max_contents_size = sz;
e135f41b 3723
116c20d2
NC
3724 sz = exec_hdr (sub)->a_trsize;
3725 if (sz > max_relocs_size)
3726 max_relocs_size = sz;
3727 sz = exec_hdr (sub)->a_drsize;
3728 if (sz > max_relocs_size)
3729 max_relocs_size = sz;
e135f41b 3730
116c20d2
NC
3731 sz = obj_aout_external_sym_count (sub);
3732 if (sz > max_sym_count)
3733 max_sym_count = sz;
3734 }
e135f41b
NC
3735 }
3736
116c20d2 3737 if (info->relocatable)
e135f41b 3738 {
116c20d2
NC
3739 if (obj_textsec (abfd) != NULL)
3740 trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
8423293d 3741 ->map_head.link_order)
116c20d2
NC
3742 * obj_reloc_entry_size (abfd));
3743 if (obj_datasec (abfd) != NULL)
3744 drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
8423293d 3745 ->map_head.link_order)
116c20d2 3746 * obj_reloc_entry_size (abfd));
e135f41b 3747 }
e135f41b 3748
116c20d2
NC
3749 exec_hdr (abfd)->a_trsize = trsize;
3750 exec_hdr (abfd)->a_drsize = drsize;
3751 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
3752
3753 /* Adjust the section sizes and vmas according to the magic number.
3754 This sets a_text, a_data and a_bss in the exec_hdr and sets the
3755 filepos for each section. */
3756 if (! NAME (aout, adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
3757 goto error_return;
3758
3759 /* The relocation and symbol file positions differ among a.out
3760 targets. We are passed a callback routine from the backend
3761 specific code to handle this.
3762 FIXME: At this point we do not know how much space the symbol
3763 table will require. This will not work for any (nonstandard)
3764 a.out target that needs to know the symbol table size before it
3765 can compute the relocation file positions. This may or may not
3766 be the case for the hp300hpux target, for example. */
3767 (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
3768 &aout_info.symoff);
3769 obj_textsec (abfd)->rel_filepos = aout_info.treloff;
3770 obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
3771 obj_sym_filepos (abfd) = aout_info.symoff;
3772
3773 /* We keep a count of the symbols as we output them. */
3774 obj_aout_external_sym_count (abfd) = 0;
3775
3776 /* We accumulate the string table as we write out the symbols. */
3777 aout_info.strtab = _bfd_stringtab_init ();
3778 if (aout_info.strtab == NULL)
3779 goto error_return;
3780
3781 /* Allocate buffers to hold section contents and relocs. */
3782 aout_info.contents = bfd_malloc (max_contents_size);
3783 aout_info.relocs = bfd_malloc (max_relocs_size);
3784 aout_info.symbol_map = bfd_malloc (max_sym_count * sizeof (int *));
3785 aout_info.output_syms = bfd_malloc ((max_sym_count + 1)
3786 * sizeof (struct external_nlist));
3787 if ((aout_info.contents == NULL && max_contents_size != 0)
3788 || (aout_info.relocs == NULL && max_relocs_size != 0)
3789 || (aout_info.symbol_map == NULL && max_sym_count != 0)
3790 || aout_info.output_syms == NULL)
3791 goto error_return;
3792
3793 /* If we have a symbol named __DYNAMIC, force it out now. This is
3794 required by SunOS. Doing this here rather than in sunos.c is a
3795 hack, but it's easier than exporting everything which would be
3796 needed. */
3797 {
3798 struct aout_link_hash_entry *h;
3799
3800 h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
3801 FALSE, FALSE, FALSE);
3802 if (h != NULL)
3803 aout_link_write_other_symbol (h, &aout_info);
3804 }
3805
3806 /* The most time efficient way to do the link would be to read all
3807 the input object files into memory and then sort out the
3808 information into the output file. Unfortunately, that will
3809 probably use too much memory. Another method would be to step
3810 through everything that composes the text section and write it
3811 out, and then everything that composes the data section and write
3812 it out, and then write out the relocs, and then write out the
3813 symbols. Unfortunately, that requires reading stuff from each
3814 input file several times, and we will not be able to keep all the
3815 input files open simultaneously, and reopening them will be slow.
3816
3817 What we do is basically process one input file at a time. We do
3818 everything we need to do with an input file once--copy over the
3819 section contents, handle the relocation information, and write
3820 out the symbols--and then we throw away the information we read
3821 from it. This approach requires a lot of lseeks of the output
3822 file, which is unfortunate but still faster than reopening a lot
3823 of files.
3824
3825 We use the output_has_begun field of the input BFDs to see
3826 whether we have already handled it. */
3827 for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
3828 sub->output_has_begun = FALSE;
3829
3830 /* Mark all sections which are to be included in the link. This
3831 will normally be every section. We need to do this so that we
3832 can identify any sections which the linker has decided to not
3833 include. */
3834 for (o = abfd->sections; o != NULL; o = o->next)
e135f41b 3835 {
8423293d 3836 for (p = o->map_head.link_order; p != NULL; p = p->next)
116c20d2
NC
3837 if (p->type == bfd_indirect_link_order)
3838 p->u.indirect.section->linker_mark = TRUE;
e135f41b
NC
3839 }
3840
116c20d2
NC
3841 have_link_order_relocs = FALSE;
3842 for (o = abfd->sections; o != NULL; o = o->next)
3843 {
8423293d 3844 for (p = o->map_head.link_order;
116c20d2
NC
3845 p != NULL;
3846 p = p->next)
3847 {
3848 if (p->type == bfd_indirect_link_order
3849 && (bfd_get_flavour (p->u.indirect.section->owner)
3850 == bfd_target_aout_flavour))
3851 {
3852 bfd *input_bfd;
e135f41b 3853
116c20d2
NC
3854 input_bfd = p->u.indirect.section->owner;
3855 if (! input_bfd->output_has_begun)
3856 {
3857 if (! aout_link_input_bfd (&aout_info, input_bfd))
3858 goto error_return;
3859 input_bfd->output_has_begun = TRUE;
3860 }
3861 }
3862 else if (p->type == bfd_section_reloc_link_order
3863 || p->type == bfd_symbol_reloc_link_order)
3864 /* These are handled below. */
3865 have_link_order_relocs = TRUE;
3866 else
3867 {
3868 if (! _bfd_default_link_order (abfd, info, o, p))
3869 goto error_return;
3870 }
3871 }
3872 }
e135f41b 3873
116c20d2
NC
3874 /* Write out any symbols that we have not already written out. */
3875 aout_link_hash_traverse (aout_hash_table (info),
3876 aout_link_write_other_symbol,
3877 (void *) &aout_info);
e135f41b 3878
116c20d2
NC
3879 /* Now handle any relocs we were asked to create by the linker.
3880 These did not come from any input file. We must do these after
3881 we have written out all the symbols, so that we know the symbol
3882 indices to use. */
3883 if (have_link_order_relocs)
e135f41b 3884 {
116c20d2 3885 for (o = abfd->sections; o != NULL; o = o->next)
e135f41b 3886 {
8423293d 3887 for (p = o->map_head.link_order;
116c20d2
NC
3888 p != NULL;
3889 p = p->next)
3890 {
3891 if (p->type == bfd_section_reloc_link_order
3892 || p->type == bfd_symbol_reloc_link_order)
3893 {
3894 if (! aout_link_reloc_link_order (&aout_info, o, p))
3895 goto error_return;
3896 }
3897 }
e135f41b
NC
3898 }
3899 }
3900
116c20d2
NC
3901 if (aout_info.contents != NULL)
3902 {
3903 free (aout_info.contents);
3904 aout_info.contents = NULL;
3905 }
3906 if (aout_info.relocs != NULL)
3907 {
3908 free (aout_info.relocs);
3909 aout_info.relocs = NULL;
3910 }
3911 if (aout_info.symbol_map != NULL)
3912 {
3913 free (aout_info.symbol_map);
3914 aout_info.symbol_map = NULL;
3915 }
3916 if (aout_info.output_syms != NULL)
3917 {
3918 free (aout_info.output_syms);
3919 aout_info.output_syms = NULL;
3920 }
3921 if (includes_hash_initialized)
3922 {
3923 bfd_hash_table_free (&aout_info.includes.root);
3924 includes_hash_initialized = FALSE;
3925 }
e135f41b 3926
116c20d2
NC
3927 /* Finish up any dynamic linking we may be doing. */
3928 if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
3929 {
3930 if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
3931 goto error_return;
3932 }
e135f41b 3933
116c20d2
NC
3934 /* Update the header information. */
3935 abfd->symcount = obj_aout_external_sym_count (abfd);
3936 exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
3937 obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
3938 obj_textsec (abfd)->reloc_count =
3939 exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
3940 obj_datasec (abfd)->reloc_count =
3941 exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
3942
3943 /* Write out the string table, unless there are no symbols. */
3944 if (abfd->symcount > 0)
e135f41b 3945 {
116c20d2
NC
3946 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
3947 || ! emit_stringtab (abfd, aout_info.strtab))
3948 goto error_return;
3949 }
3950 else if (obj_textsec (abfd)->reloc_count == 0
3951 && obj_datasec (abfd)->reloc_count == 0)
3952 {
3953 bfd_byte b;
e135f41b 3954
116c20d2
NC
3955 b = 0;
3956 if (bfd_seek (abfd,
3957 (file_ptr) (obj_datasec (abfd)->filepos
3958 + exec_hdr (abfd)->a_data
3959 - 1),
3960 SEEK_SET) != 0
3961 || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
3962 goto error_return;
e135f41b
NC
3963 }
3964
b34976b6 3965 return TRUE;
e135f41b 3966
116c20d2
NC
3967 error_return:
3968 if (aout_info.contents != NULL)
3969 free (aout_info.contents);
3970 if (aout_info.relocs != NULL)
3971 free (aout_info.relocs);
3972 if (aout_info.symbol_map != NULL)
3973 free (aout_info.symbol_map);
3974 if (aout_info.output_syms != NULL)
3975 free (aout_info.output_syms);
3976 if (includes_hash_initialized)
3977 bfd_hash_table_free (&aout_info.includes.root);
3978 return FALSE;
e135f41b
NC
3979}
3980
116c20d2
NC
3981/* Adjust and write out the symbols for an a.out file. Set the new
3982 symbol indices into a symbol_map. */
3983
b34976b6 3984static bfd_boolean
116c20d2 3985aout_link_write_symbols (struct aout_final_link_info *finfo, bfd *input_bfd)
e135f41b 3986{
e135f41b 3987 bfd *output_bfd;
116c20d2 3988 bfd_size_type sym_count;
e135f41b 3989 char *strings;
116c20d2
NC
3990 enum bfd_link_strip strip;
3991 enum bfd_link_discard discard;
3992 struct external_nlist *outsym;
3993 bfd_size_type strtab_index;
3994 struct external_nlist *sym;
3995 struct external_nlist *sym_end;
3996 struct aout_link_hash_entry **sym_hash;
e135f41b 3997 int *symbol_map;
116c20d2
NC
3998 bfd_boolean pass;
3999 bfd_boolean skip_next;
e135f41b
NC
4000
4001 output_bfd = finfo->output_bfd;
116c20d2 4002 sym_count = obj_aout_external_sym_count (input_bfd);
e135f41b 4003 strings = obj_aout_external_strings (input_bfd);
116c20d2
NC
4004 strip = finfo->info->strip;
4005 discard = finfo->info->discard;
4006 outsym = finfo->output_syms;
e135f41b 4007
116c20d2
NC
4008 /* First write out a symbol for this object file, unless we are
4009 discarding such symbols. */
4010 if (strip != strip_all
4011 && (strip != strip_some
4012 || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
4013 FALSE, FALSE) != NULL)
4014 && discard != discard_all)
4015 {
4016 H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
4017 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4018 input_bfd->filename, FALSE);
4019 if (strtab_index == (bfd_size_type) -1)
4020 return FALSE;
4021 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4022 PUT_WORD (output_bfd,
4023 (bfd_get_section_vma (output_bfd,
4024 obj_textsec (input_bfd)->output_section)
4025 + obj_textsec (input_bfd)->output_offset),
4026 outsym->e_value);
4027 ++obj_aout_external_sym_count (output_bfd);
4028 ++outsym;
4029 }
4030
4031 pass = FALSE;
4032 skip_next = FALSE;
4033 sym = obj_aout_external_syms (input_bfd);
4034 sym_end = sym + sym_count;
4035 sym_hash = obj_aout_sym_hashes (input_bfd);
4036 symbol_map = finfo->symbol_map;
4037 memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
4038 for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
e135f41b 4039 {
116c20d2
NC
4040 const char *name;
4041 int type;
4042 struct aout_link_hash_entry *h;
4043 bfd_boolean skip;
4044 asection *symsec;
4045 bfd_vma val = 0;
4046 bfd_boolean copy;
e135f41b 4047
116c20d2
NC
4048 /* We set *symbol_map to 0 above for all symbols. If it has
4049 already been set to -1 for this symbol, it means that we are
4050 discarding it because it appears in a duplicate header file.
4051 See the N_BINCL code below. */
4052 if (*symbol_map == -1)
e135f41b
NC
4053 continue;
4054
116c20d2
NC
4055 /* Initialize *symbol_map to -1, which means that the symbol was
4056 not copied into the output file. We will change it later if
4057 we do copy the symbol over. */
4058 *symbol_map = -1;
e135f41b 4059
116c20d2
NC
4060 type = H_GET_8 (input_bfd, sym->e_type);
4061 name = strings + GET_WORD (input_bfd, sym->e_strx);
e135f41b 4062
116c20d2 4063 h = NULL;
e135f41b 4064
116c20d2 4065 if (pass)
e135f41b 4066 {
116c20d2
NC
4067 /* Pass this symbol through. It is the target of an
4068 indirect or warning symbol. */
4069 val = GET_WORD (input_bfd, sym->e_value);
4070 pass = FALSE;
4071 }
4072 else if (skip_next)
4073 {
4074 /* Skip this symbol, which is the target of an indirect
4075 symbol that we have changed to no longer be an indirect
4076 symbol. */
4077 skip_next = FALSE;
4078 continue;
4079 }
4080 else
4081 {
4082 struct aout_link_hash_entry *hresolve;
e135f41b 4083
116c20d2
NC
4084 /* We have saved the hash table entry for this symbol, if
4085 there is one. Note that we could just look it up again
4086 in the hash table, provided we first check that it is an
4087 external symbol. */
4088 h = *sym_hash;
e135f41b 4089
116c20d2
NC
4090 /* Use the name from the hash table, in case the symbol was
4091 wrapped. */
4092 if (h != NULL)
4093 name = h->root.root.string;
e135f41b 4094
116c20d2
NC
4095 /* If this is an indirect or warning symbol, then change
4096 hresolve to the base symbol. We also change *sym_hash so
4097 that the relocation routines relocate against the real
4098 symbol. */
4099 hresolve = h;
4100 if (h != NULL
4101 && (h->root.type == bfd_link_hash_indirect
4102 || h->root.type == bfd_link_hash_warning))
4103 {
4104 hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
4105 while (hresolve->root.type == bfd_link_hash_indirect
4106 || hresolve->root.type == bfd_link_hash_warning)
4107 hresolve = ((struct aout_link_hash_entry *)
4108 hresolve->root.u.i.link);
4109 *sym_hash = hresolve;
4110 }
e135f41b 4111
116c20d2
NC
4112 /* If the symbol has already been written out, skip it. */
4113 if (h != NULL
4114 && h->root.type != bfd_link_hash_warning
4115 && h->written)
4116 {
4117 if ((type & N_TYPE) == N_INDR
4118 || type == N_WARNING)
4119 skip_next = TRUE;
4120 *symbol_map = h->indx;
4121 continue;
4122 }
e135f41b 4123
116c20d2
NC
4124 /* See if we are stripping this symbol. */
4125 skip = FALSE;
4126 switch (strip)
4127 {
4128 case strip_none:
4129 break;
4130 case strip_debugger:
4131 if ((type & N_STAB) != 0)
4132 skip = TRUE;
4133 break;
4134 case strip_some:
4135 if (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE)
4136 == NULL)
4137 skip = TRUE;
4138 break;
4139 case strip_all:
4140 skip = TRUE;
4141 break;
e135f41b 4142 }
116c20d2 4143 if (skip)
e135f41b 4144 {
116c20d2
NC
4145 if (h != NULL)
4146 h->written = TRUE;
4147 continue;
4148 }
e135f41b 4149
116c20d2
NC
4150 /* Get the value of the symbol. */
4151 if ((type & N_TYPE) == N_TEXT
4152 || type == N_WEAKT)
4153 symsec = obj_textsec (input_bfd);
4154 else if ((type & N_TYPE) == N_DATA
4155 || type == N_WEAKD)
4156 symsec = obj_datasec (input_bfd);
4157 else if ((type & N_TYPE) == N_BSS
4158 || type == N_WEAKB)
4159 symsec = obj_bsssec (input_bfd);
4160 else if ((type & N_TYPE) == N_ABS
4161 || type == N_WEAKA)
4162 symsec = bfd_abs_section_ptr;
4163 else if (((type & N_TYPE) == N_INDR
4164 && (hresolve == NULL
4165 || (hresolve->root.type != bfd_link_hash_defined
4166 && hresolve->root.type != bfd_link_hash_defweak
4167 && hresolve->root.type != bfd_link_hash_common)))
4168 || type == N_WARNING)
4169 {
4170 /* Pass the next symbol through unchanged. The
4171 condition above for indirect symbols is so that if
4172 the indirect symbol was defined, we output it with
4173 the correct definition so the debugger will
4174 understand it. */
4175 pass = TRUE;
4176 val = GET_WORD (input_bfd, sym->e_value);
4177 symsec = NULL;
4178 }
4179 else if ((type & N_STAB) != 0)
4180 {
4181 val = GET_WORD (input_bfd, sym->e_value);
4182 symsec = NULL;
e135f41b 4183 }
116c20d2
NC
4184 else
4185 {
4186 /* If we get here with an indirect symbol, it means that
4187 we are outputting it with a real definition. In such
4188 a case we do not want to output the next symbol,
4189 which is the target of the indirection. */
4190 if ((type & N_TYPE) == N_INDR)
4191 skip_next = TRUE;
e135f41b 4192
116c20d2 4193 symsec = NULL;
e135f41b 4194
116c20d2
NC
4195 /* We need to get the value from the hash table. We use
4196 hresolve so that if we have defined an indirect
4197 symbol we output the final definition. */
4198 if (h == NULL)
4199 {
4200 switch (type & N_TYPE)
4201 {
4202 case N_SETT:
4203 symsec = obj_textsec (input_bfd);
4204 break;
4205 case N_SETD:
4206 symsec = obj_datasec (input_bfd);
4207 break;
4208 case N_SETB:
4209 symsec = obj_bsssec (input_bfd);
4210 break;
4211 case N_SETA:
4212 symsec = bfd_abs_section_ptr;
4213 break;
4214 default:
4215 val = 0;
4216 break;
4217 }
4218 }
4219 else if (hresolve->root.type == bfd_link_hash_defined
4220 || hresolve->root.type == bfd_link_hash_defweak)
4221 {
4222 asection *input_section;
4223 asection *output_section;
e135f41b 4224
116c20d2
NC
4225 /* This case usually means a common symbol which was
4226 turned into a defined symbol. */
4227 input_section = hresolve->root.u.def.section;
4228 output_section = input_section->output_section;
4229 BFD_ASSERT (bfd_is_abs_section (output_section)
4230 || output_section->owner == output_bfd);
4231 val = (hresolve->root.u.def.value
4232 + bfd_get_section_vma (output_bfd, output_section)
4233 + input_section->output_offset);
e135f41b 4234
116c20d2
NC
4235 /* Get the correct type based on the section. If
4236 this is a constructed set, force it to be
4237 globally visible. */
4238 if (type == N_SETT
4239 || type == N_SETD
4240 || type == N_SETB
4241 || type == N_SETA)
4242 type |= N_EXT;
e135f41b 4243
116c20d2 4244 type &=~ N_TYPE;
e135f41b 4245
116c20d2
NC
4246 if (output_section == obj_textsec (output_bfd))
4247 type |= (hresolve->root.type == bfd_link_hash_defined
4248 ? N_TEXT
4249 : N_WEAKT);
4250 else if (output_section == obj_datasec (output_bfd))
4251 type |= (hresolve->root.type == bfd_link_hash_defined
4252 ? N_DATA
4253 : N_WEAKD);
4254 else if (output_section == obj_bsssec (output_bfd))
4255 type |= (hresolve->root.type == bfd_link_hash_defined
4256 ? N_BSS
4257 : N_WEAKB);
4258 else
4259 type |= (hresolve->root.type == bfd_link_hash_defined
4260 ? N_ABS
4261 : N_WEAKA);
e135f41b 4262 }
116c20d2
NC
4263 else if (hresolve->root.type == bfd_link_hash_common)
4264 val = hresolve->root.u.c.size;
4265 else if (hresolve->root.type == bfd_link_hash_undefweak)
e135f41b 4266 {
116c20d2
NC
4267 val = 0;
4268 type = N_WEAKU;
e135f41b 4269 }
116c20d2
NC
4270 else
4271 val = 0;
e135f41b 4272 }
116c20d2
NC
4273 if (symsec != NULL)
4274 val = (symsec->output_section->vma
4275 + symsec->output_offset
4276 + (GET_WORD (input_bfd, sym->e_value)
4277 - symsec->vma));
e135f41b 4278
116c20d2
NC
4279 /* If this is a global symbol set the written flag, and if
4280 it is a local symbol see if we should discard it. */
4281 if (h != NULL)
e135f41b 4282 {
116c20d2
NC
4283 h->written = TRUE;
4284 h->indx = obj_aout_external_sym_count (output_bfd);
e135f41b 4285 }
116c20d2
NC
4286 else if ((type & N_TYPE) != N_SETT
4287 && (type & N_TYPE) != N_SETD
4288 && (type & N_TYPE) != N_SETB
4289 && (type & N_TYPE) != N_SETA)
e135f41b 4290 {
116c20d2
NC
4291 switch (discard)
4292 {
4293 case discard_none:
4294 case discard_sec_merge:
4295 break;
4296 case discard_l:
4297 if ((type & N_STAB) == 0
4298 && bfd_is_local_label_name (input_bfd, name))
4299 skip = TRUE;
4300 break;
4301 case discard_all:
4302 skip = TRUE;
4303 break;
4304 }
4305 if (skip)
4306 {
4307 pass = FALSE;
4308 continue;
4309 }
e135f41b
NC
4310 }
4311
116c20d2
NC
4312 /* An N_BINCL symbol indicates the start of the stabs
4313 entries for a header file. We need to scan ahead to the
4314 next N_EINCL symbol, ignoring nesting, adding up all the
4315 characters in the symbol names, not including the file
4316 numbers in types (the first number after an open
4317 parenthesis). */
4318 if (type == N_BINCL)
e135f41b 4319 {
116c20d2
NC
4320 struct external_nlist *incl_sym;
4321 int nest;
4322 struct aout_link_includes_entry *incl_entry;
4323 struct aout_link_includes_totals *t;
e135f41b 4324
116c20d2
NC
4325 val = 0;
4326 nest = 0;
4327 for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
4328 {
4329 int incl_type;
e135f41b 4330
116c20d2
NC
4331 incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
4332 if (incl_type == N_EINCL)
4333 {
4334 if (nest == 0)
4335 break;
4336 --nest;
4337 }
4338 else if (incl_type == N_BINCL)
4339 ++nest;
4340 else if (nest == 0)
4341 {
4342 const char *s;
e135f41b 4343
116c20d2
NC
4344 s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
4345 for (; *s != '\0'; s++)
4346 {
4347 val += *s;
4348 if (*s == '(')
4349 {
4350 /* Skip the file number. */
4351 ++s;
4352 while (ISDIGIT (*s))
4353 ++s;
4354 --s;
4355 }
4356 }
4357 }
4358 }
e135f41b 4359
116c20d2
NC
4360 /* If we have already included a header file with the
4361 same value, then replace this one with an N_EXCL
4362 symbol. */
4363 copy = ! finfo->info->keep_memory;
4364 incl_entry = aout_link_includes_lookup (&finfo->includes,
4365 name, TRUE, copy);
4366 if (incl_entry == NULL)
4367 return FALSE;
4368 for (t = incl_entry->totals; t != NULL; t = t->next)
4369 if (t->total == val)
4370 break;
4371 if (t == NULL)
4372 {
4373 /* This is the first time we have seen this header
4374 file with this set of stabs strings. */
4375 t = bfd_hash_allocate (&finfo->includes.root,
4376 sizeof *t);
4377 if (t == NULL)
4378 return FALSE;
4379 t->total = val;
4380 t->next = incl_entry->totals;
4381 incl_entry->totals = t;
4382 }
4383 else
4384 {
4385 int *incl_map;
e135f41b 4386
116c20d2
NC
4387 /* This is a duplicate header file. We must change
4388 it to be an N_EXCL entry, and mark all the
4389 included symbols to prevent outputting them. */
4390 type = N_EXCL;
e135f41b 4391
116c20d2
NC
4392 nest = 0;
4393 for (incl_sym = sym + 1, incl_map = symbol_map + 1;
4394 incl_sym < sym_end;
4395 incl_sym++, incl_map++)
4396 {
4397 int incl_type;
e135f41b 4398
116c20d2
NC
4399 incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
4400 if (incl_type == N_EINCL)
4401 {
4402 if (nest == 0)
4403 {
4404 *incl_map = -1;
4405 break;
4406 }
4407 --nest;
4408 }
4409 else if (incl_type == N_BINCL)
4410 ++nest;
4411 else if (nest == 0)
4412 *incl_map = -1;
4413 }
4414 }
4415 }
e135f41b 4416 }
e135f41b 4417
116c20d2
NC
4418 /* Copy this symbol into the list of symbols we are going to
4419 write out. */
4420 H_PUT_8 (output_bfd, type, outsym->e_type);
4421 copy = FALSE;
4422 if (! finfo->info->keep_memory)
e135f41b 4423 {
116c20d2
NC
4424 /* name points into a string table which we are going to
4425 free. If there is a hash table entry, use that string.
4426 Otherwise, copy name into memory. */
4427 if (h != NULL)
4428 name = h->root.root.string;
4429 else
4430 copy = TRUE;
e135f41b 4431 }
116c20d2
NC
4432 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4433 name, copy);
4434 if (strtab_index == (bfd_size_type) -1)
4435 return FALSE;
4436 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4437 PUT_WORD (output_bfd, val, outsym->e_value);
4438 *symbol_map = obj_aout_external_sym_count (output_bfd);
4439 ++obj_aout_external_sym_count (output_bfd);
4440 ++outsym;
e135f41b
NC
4441 }
4442
116c20d2
NC
4443 /* Write out the output symbols we have just constructed. */
4444 if (outsym > finfo->output_syms)
e135f41b
NC
4445 {
4446 bfd_size_type size;
e135f41b 4447
116c20d2 4448 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
b34976b6 4449 return FALSE;
116c20d2
NC
4450 size = outsym - finfo->output_syms;
4451 size *= EXTERNAL_NLIST_SIZE;
4452 if (bfd_bwrite ((void *) finfo->output_syms, size, output_bfd) != size)
b34976b6 4453 return FALSE;
116c20d2 4454 finfo->symoff += size;
e135f41b
NC
4455 }
4456
b34976b6 4457 return TRUE;
e135f41b 4458}
116c20d2
NC
4459
4460/* Write out a symbol that was not associated with an a.out input
4461 object. */
e135f41b 4462
edeb6e24
AM
4463static bfd_vma
4464bfd_getp32 (const void *p)
e135f41b 4465{
edeb6e24
AM
4466 const bfd_byte *addr = p;
4467 unsigned long v;
116c20d2 4468
edeb6e24
AM
4469 v = (unsigned long) addr[1] << 24;
4470 v |= (unsigned long) addr[0] << 16;
4471 v |= (unsigned long) addr[3] << 8;
4472 v |= (unsigned long) addr[2];
4473 return v;
e135f41b
NC
4474}
4475
4476#define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000)
4477
edeb6e24
AM
4478static bfd_signed_vma
4479bfd_getp_signed_32 (const void *p)
e135f41b 4480{
edeb6e24
AM
4481 const bfd_byte *addr = p;
4482 unsigned long v;
116c20d2 4483
edeb6e24
AM
4484 v = (unsigned long) addr[1] << 24;
4485 v |= (unsigned long) addr[0] << 16;
4486 v |= (unsigned long) addr[3] << 8;
4487 v |= (unsigned long) addr[2];
4488 return COERCE32 (v);
e135f41b
NC
4489}
4490
edeb6e24
AM
4491static void
4492bfd_putp32 (bfd_vma data, void *p)
e135f41b 4493{
edeb6e24 4494 bfd_byte *addr = p;
116c20d2 4495
edeb6e24
AM
4496 addr[0] = (data >> 16) & 0xff;
4497 addr[1] = (data >> 24) & 0xff;
4498 addr[2] = (data >> 0) & 0xff;
4499 addr[3] = (data >> 8) & 0xff;
e135f41b 4500}
116c20d2
NC
4501
4502const bfd_target MY (vec) =
4503{
4504 TARGETNAME, /* Name. */
4505 bfd_target_aout_flavour,
4506 BFD_ENDIAN_LITTLE, /* Target byte order (little). */
4507 BFD_ENDIAN_LITTLE, /* Target headers byte order (little). */
4508 (HAS_RELOC | EXEC_P | /* Object flags. */
4509 HAS_LINENO | HAS_DEBUG |
4510 HAS_SYMS | HAS_LOCALS | WP_TEXT),
4511 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
4512 MY_symbol_leading_char,
4513 AR_PAD_CHAR, /* AR_pad_char. */
4514 15, /* AR_max_namelen. */
4515 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
4516 bfd_getp32, bfd_getp_signed_32, bfd_putp32,
4517 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */
4518 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
4519 bfd_getp32, bfd_getp_signed_32, bfd_putp32,
4520 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers. */
4521 {_bfd_dummy_target, MY_object_p, /* bfd_check_format. */
4522 bfd_generic_archive_p, MY_core_file_p},
4523 {bfd_false, MY_mkobject, /* bfd_set_format. */
4524 _bfd_generic_mkarchive, bfd_false},
4525 {bfd_false, MY_write_object_contents, /* bfd_write_contents. */
4526 _bfd_write_archive_contents, bfd_false},
4527
4528 BFD_JUMP_TABLE_GENERIC (MY),
4529 BFD_JUMP_TABLE_COPY (MY),
4530 BFD_JUMP_TABLE_CORE (MY),
4531 BFD_JUMP_TABLE_ARCHIVE (MY),
4532 BFD_JUMP_TABLE_SYMBOLS (MY),
4533 BFD_JUMP_TABLE_RELOCS (MY),
4534 BFD_JUMP_TABLE_WRITE (MY),
4535 BFD_JUMP_TABLE_LINK (MY),
4536 BFD_JUMP_TABLE_DYNAMIC (MY),
4537
4538 /* Alternative_target. */
4539 NULL,
4540
4541 (void *) MY_backend_data
4542};
This page took 0.639455 seconds and 4 git commands to generate.