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