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