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