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