Don't crash if with_minimal_bfd is the empty string.
[deliverable/binutils-gdb.git] / bfd / aoutx.h
CommitLineData
1f29e30b 1/* BFD semi-generic back-end for a.out binaries.
a99c3d70 2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
88dfcd68 3 Written by Cygnus Support.
7ed4093a 4
88dfcd68 5This file is part of BFD, the Binary File Descriptor library.
7ed4093a 6
88dfcd68 7This program is free software; you can redistribute it and/or modify
7ed4093a 8it under the terms of the GNU General Public License as published by
88dfcd68
SC
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
7ed4093a 11
88dfcd68 12This program is distributed in the hope that it will be useful,
7ed4093a
SC
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
88dfcd68
SC
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
7ed4093a 20
4e41b5aa
SC
21/*
22SECTION
23 a.out backends
6f715d66 24
6f715d66 25
4e41b5aa 26DESCRIPTION
6f715d66 27
4e41b5aa
SC
28 BFD supports a number of different flavours of a.out format,
29 though the major differences are only the sizes of the
30 structures on disk, and the shape of the relocation
31 information.
6f715d66 32
4e41b5aa
SC
33 The support is split into a basic support file @code{aoutx.h}
34 and other files which derive functions from the base. One
35 derivation file is @code{aoutf1.h} (for a.out flavour 1), and
36 adds to the basic a.out functions support for sun3, sun4, 386
37 and 29k a.out files, to create a target jump vector for a
38 specific target.
6f715d66 39
4e41b5aa
SC
40 This information is further split out into more specific files
41 for each machine, including @code{sunos.c} for sun3 and sun4,
42 @code{newsos3.c} for the Sony NEWS, and @code{demo64.c} for a
43 demonstration of a 64 bit a.out format.
44
45 The base file @code{aoutx.h} defines general mechanisms for
46 reading and writing records to and from disk, and various
47 other methods which BFD requires. It is included by
48 @code{aout32.c} and @code{aout64.c} to form the names
49 aout_32_swap_exec_header_in, aout_64_swap_exec_header_in, etc.
50
51 As an example, this is what goes on to make the back end for a
52 sun4, from aout32.c
53
3f7607af
PB
54| #define ARCH_SIZE 32
55| #include "aoutx.h"
4e41b5aa
SC
56
57 Which exports names:
58
3f7607af
PB
59| ...
60| aout_32_canonicalize_reloc
61| aout_32_find_nearest_line
62| aout_32_get_lineno
63| aout_32_get_reloc_upper_bound
64| ...
6f715d66 65
4e41b5aa
SC
66 from sunos.c
67
3f7607af
PB
68| #define ARCH 32
69| #define TARGET_NAME "a.out-sunos-big"
70| #define VECNAME sunos_big_vec
71| #include "aoutf1.h"
4e41b5aa
SC
72
73 requires all the names from aout32.c, and produces the jump vector
6f715d66 74
3f7607af 75| sunos_big_vec
c6705697 76
4e41b5aa
SC
77 The file host-aout.c is a special case. It is for a large set
78 of hosts that use ``more or less standard'' a.out files, and
79 for which cross-debugging is not interesting. It uses the
80 standard 32-bit a.out support routines, but determines the
81 file offsets and addresses of the text, data, and BSS
82 sections, the machine architecture and machine type, and the
83 entry point address, in a host-dependent manner. Once these
84 values have been determined, generic code is used to handle
85 the object file.
c6705697 86
4e41b5aa
SC
87 When porting it to run on a new system, you must supply:
88
3f7607af
PB
89| HOST_PAGE_SIZE
90| HOST_SEGMENT_SIZE
91| HOST_MACHINE_ARCH (optional)
92| HOST_MACHINE_MACHINE (optional)
93| HOST_TEXT_START_ADDR
94| HOST_STACK_END_ADDR
c6705697 95
3f7607af
PB
96 in the file <<../include/sys/h-XXX.h>> (for your host). These
97 values, plus the structures and macros defined in <<a.out.h>> on
4e41b5aa
SC
98 your host system, will produce a BFD target that will access
99 ordinary a.out files on your host. To configure a new machine
3f7607af 100 to use <<host-aout.c>., specify:
c6705697 101
3f7607af
PB
102| TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
103| TDEPFILES= host-aout.o trad-core.o
c6705697 104
3f7607af
PB
105 in the <<config/mt-XXX>> file, and modify configure.in to use the
106 <<mt-XXX>> file (by setting "<<bfd_target=XXX>>") when your
4e41b5aa 107 configuration is selected.
c6705697 108
6f715d66
SC
109*/
110
ce07dd7c
KR
111/* Some assumptions:
112 * Any BFD with D_PAGED set is ZMAGIC, and vice versa.
113 Doesn't matter what the setting of WP_TEXT is on output, but it'll
114 get set on input.
115 * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC.
116 * Any BFD with both flags clear is OMAGIC.
117 (Just want to make these explicit, so the conditions tested in this
118 file make sense if you're more familiar with a.out than with BFD.) */
119
c618de01
SC
120#define KEEPIT flags
121#define KEEPITTYPE int
67c060c3 122
0f213cc2 123#include <assert.h>
a99c3d70 124#include <string.h> /* For strchr and friends */
67c060c3 125#include "bfd.h"
7ed4093a
SC
126#include <sysdep.h>
127#include <ansidecl.h>
128
9e2dad8e 129struct external_exec;
6f715d66 130#include "libaout.h"
7ed4093a 131#include "libbfd.h"
c3eb25fc
SC
132#include "aout/aout64.h"
133#include "aout/stab_gnu.h"
134#include "aout/ar.h"
7ed4093a 135
ce07dd7c 136extern void (*bfd_error_trap)();
7ed4093a 137
4e41b5aa
SC
138/*
139SUBSECTION
140 relocations
141
142DESCRIPTION
143 The file @code{aoutx.h} caters for both the @emph{standard}
144 and @emph{extended} forms of a.out relocation records.
145
146 The standard records are characterised by containing only an
147 address, a symbol index and a type field. The extended records
148 (used on 29ks and sparcs) also have a full integer for an
149 addend.
7ed4093a 150
6f715d66 151*/
7ed4093a 152#define CTOR_TABLE_RELOC_IDX 2
67c060c3 153
ce07dd7c
KR
154#define howto_table_ext NAME(aout,ext_howto_table)
155#define howto_table_std NAME(aout,std_howto_table)
67c060c3 156
ce07dd7c 157reloc_howto_type howto_table_ext[] =
7ed4093a 158{
3caa6924
DM
159/* type rightshift size bitsize pc_ bit absol compl spec name partial_ src_ dst_ pcrel_
160 rela pos ute ain_on ial_ inplace mask mask offset
161 tive _overf fn */
162 HOWTO(RELOC_8, 0, 0, 8, false, 0, true, true,0,"8", false, 0,0x000000ff, false),
163 HOWTO(RELOC_16, 0, 1, 16, false, 0, true, true,0,"16", false, 0,0x0000ffff, false),
164 HOWTO(RELOC_32, 0, 2, 32, false, 0, true, true,0,"32", false, 0,0xffffffff, false),
7ed4093a
SC
165 HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, false, true,0,"DISP8", false, 0,0x000000ff, false),
166 HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, false, true,0,"DISP16", false, 0,0x0000ffff, false),
167 HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, false, true,0,"DISP32", false, 0,0xffffffff, false),
168 HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, false, true,0,"WDISP30", false, 0,0x3fffffff, false),
169 HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, false, true,0,"WDISP22", false, 0,0x003fffff, false),
170 HOWTO(RELOC_HI22, 10, 2, 22, false, 0, false, true,0,"HI22", false, 0,0x003fffff, false),
3caa6924
DM
171 HOWTO(RELOC_22, 0, 2, 22, false, 0, false, true,0,"22", false, 0,0x003fffff, false),
172 HOWTO(RELOC_13, 0, 2, 13, false, 0, false, true,0,"13", false, 0,0x00001fff, false),
173 HOWTO(RELOC_LO10, 0, 2, 10, false, 0, false, true,0,"LO10", false, 0,0x000003ff, false),
7ed4093a
SC
174 HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false),
175 HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false),
176 HOWTO(RELOC_BASE10, 0, 2, 16, false, 0, false, true,0,"BASE10", false, 0,0x0000ffff, false),
177 HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, false, true,0,"BASE13", false, 0,0x00001fff, false),
178 HOWTO(RELOC_BASE22, 0, 2, 0, false, 0, false, true,0,"BASE22", false, 0,0x00000000, false),
179 HOWTO(RELOC_PC10, 0, 2, 10, false, 0, false, true,0,"PC10", false, 0,0x000003ff, false),
180 HOWTO(RELOC_PC22, 0, 2, 22, false, 0, false, true,0,"PC22", false, 0,0x003fffff, false),
181 HOWTO(RELOC_JMP_TBL,0, 2, 32, false, 0, false, true,0,"JMP_TBL", false, 0,0xffffffff, false),
182 HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false),
183 HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false),
184 HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false),
3caa6924 185 HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, false, true,0,"RELATIVE", false, 0,0x00000000, false),
7ed4093a
SC
186};
187
188/* Convert standard reloc records to "arelent" format (incl byte swap). */
189
ce07dd7c 190reloc_howto_type howto_table_std[] = {
7ed4093a
SC
191 /* type rs size bsz pcrel bitpos abs ovrf sf name part_inpl readmask setmask pcdone */
192HOWTO( 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff,0x000000ff, false),
193HOWTO( 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff,0x0000ffff, false),
194HOWTO( 2, 0, 2, 32, false, 0, true, true,0,"32", true, 0xffffffff,0xffffffff, false),
195HOWTO( 3, 0, 3, 64, false, 0, true, true,0,"64", true, 0xdeaddead,0xdeaddead, false),
196HOWTO( 4, 0, 0, 8, true, 0, false, true,0,"DISP8", true, 0x000000ff,0x000000ff, false),
197HOWTO( 5, 0, 1, 16, true, 0, false, true,0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
198HOWTO( 6, 0, 2, 32, true, 0, false, true,0,"DISP32", true, 0xffffffff,0xffffffff, false),
199HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedface,0xfeedface, false),
200};
201
214f8f23
KR
202CONST struct reloc_howto_struct *
203DEFUN(NAME(aout,reloc_type_lookup),(abfd,code),
204 bfd *abfd AND
205 bfd_reloc_code_real_type code)
206{
207#define EXT(i,j) case i: return &howto_table_ext[j]
208#define STD(i,j) case i: return &howto_table_std[j]
209 int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
210 if (code == BFD_RELOC_CTOR)
211 switch (bfd_get_arch_info (abfd)->bits_per_address)
212 {
213 case 32:
214 code = BFD_RELOC_32;
215 break;
216 }
217 if (ext)
218 switch (code)
219 {
220 EXT (BFD_RELOC_32, 2);
221 EXT (BFD_RELOC_HI22, 8);
222 EXT (BFD_RELOC_LO10, 11);
223 EXT (BFD_RELOC_32_PCREL_S2, 6);
a99c3d70 224 default: return (CONST struct reloc_howto_struct *) 0;
214f8f23
KR
225 }
226 else
227 /* std relocs */
228 switch (code)
229 {
230 STD (BFD_RELOC_16, 1);
231 STD (BFD_RELOC_32, 2);
232 STD (BFD_RELOC_8_PCREL, 4);
233 STD (BFD_RELOC_16_PCREL, 5);
234 STD (BFD_RELOC_32_PCREL, 6);
a99c3d70 235 default: return (CONST struct reloc_howto_struct *) 0;
214f8f23 236 }
214f8f23 237}
7ed4093a 238
ce07dd7c 239extern bfd_error_vector_type bfd_error_vector;
6f715d66 240
4e41b5aa
SC
241/*
242SUBSECTION
243 Internal Entry Points
244
245DESCRIPTION
246 @code{aoutx.h} exports several routines for accessing the
247 contents of an a.out file, which are gathered and exported in
248 turn by various format specific files (eg sunos.c).
249
6f715d66
SC
250*/
251
4e41b5aa
SC
252/*
253FUNCTION
254 aout_<size>_swap_exec_header_in
255
256DESCRIPTION
257 Swaps the information in an executable header taken from a raw
258 byte stream memory image, into the internal exec_header
259 structure.
260
fa2b89f1 261SYNOPSIS
4e41b5aa
SC
262 void aout_<size>_swap_exec_header_in,
263 (bfd *abfd,
264 struct external_exec *raw_bytes,
265 struct internal_exec *execp);
6f715d66
SC
266*/
267
34dd8ba3 268#ifndef NAME_swap_exec_header_in
7ed4093a
SC
269void
270DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
271 bfd *abfd AND
272 struct external_exec *raw_bytes AND
273 struct internal_exec *execp)
274{
275 struct external_exec *bytes = (struct external_exec *)raw_bytes;
276
55c0061e
FF
277 /* The internal_exec structure has some fields that are unused in this
278 configuration (IE for i960), so ensure that all such uninitialized
279 fields are zero'd out. There are places where two of these structs
280 are memcmp'd, and thus the contents do matter. */
281 memset (execp, 0, sizeof (struct internal_exec));
7ed4093a
SC
282 /* Now fill in fields in the execp, from the bytes in the raw data. */
283 execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
284 execp->a_text = GET_WORD (abfd, bytes->e_text);
285 execp->a_data = GET_WORD (abfd, bytes->e_data);
286 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
287 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
288 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
289 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
290 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
291}
34dd8ba3
JG
292#define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in)
293#endif
7ed4093a 294
4e41b5aa
SC
295/*
296FUNCTION
297 aout_<size>_swap_exec_header_out
298
299DESCRIPTION
300 Swaps the information in an internal exec header structure
301 into the supplied buffer ready for writing to disk.
302
fa2b89f1 303SYNOPSIS
4e41b5aa 304 void aout_<size>_swap_exec_header_out
6f715d66
SC
305 (bfd *abfd,
306 struct internal_exec *execp,
4e41b5aa 307 struct external_exec *raw_bytes);
6f715d66 308*/
7ed4093a
SC
309void
310DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
311 bfd *abfd AND
312 struct internal_exec *execp AND
313 struct external_exec *raw_bytes)
314{
315 struct external_exec *bytes = (struct external_exec *)raw_bytes;
316
317 /* Now fill in fields in the raw data, from the fields in the exec struct. */
318 bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
319 PUT_WORD (abfd, execp->a_text , bytes->e_text);
320 PUT_WORD (abfd, execp->a_data , bytes->e_data);
321 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
322 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
323 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
324 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
325 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
326}
327
7ed4093a 328
6f715d66 329
4e41b5aa
SC
330/*
331FUNCTION
332 aout_<size>_some_aout_object_p
6f715d66 333
4e41b5aa
SC
334DESCRIPTION
335 Some A.OUT variant thinks that the file whose format we're
336 checking is an a.out file. Do some more checking, and set up
337 for access if it really is. Call back to the calling
338 environments "finish up" function just before returning, to
339 handle any last-minute setup.
6f715d66 340
fa2b89f1 341SYNOPSIS
4e41b5aa 342 bfd_target *aout_<size>_some_aout_object_p
6f715d66 343 (bfd *abfd,
4e41b5aa 344 bfd_target *(*callback_to_real_object_p)());
6f715d66 345*/
7ed4093a
SC
346
347bfd_target *
7b02b4ed 348DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
7ed4093a 349 bfd *abfd AND
7b02b4ed 350 struct internal_exec *execp AND
b86f998b 351 bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *)))
7ed4093a 352{
214f8f23 353 struct aout_data_struct *rawptr, *oldrawptr;
e6e265ce 354 bfd_target *result;
7ed4093a 355
6db82ea7 356 rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
7ed4093a
SC
357 if (rawptr == NULL) {
358 bfd_error = no_memory;
359 return 0;
360 }
361
214f8f23 362 oldrawptr = abfd->tdata.aout_data;
6db82ea7
SC
363 abfd->tdata.aout_data = rawptr;
364 abfd->tdata.aout_data->a.hdr = &rawptr->e;
365 *(abfd->tdata.aout_data->a.hdr) = *execp; /* Copy in the internal_exec struct */
366 execp = abfd->tdata.aout_data->a.hdr;
7ed4093a
SC
367
368 /* Set the file flags */
369 abfd->flags = NO_FLAGS;
370 if (execp->a_drsize || execp->a_trsize)
371 abfd->flags |= HAS_RELOC;
e6e265ce 372 /* Setting of EXEC_P has been deferred to the bottom of this function */
7ed4093a
SC
373 if (execp->a_syms)
374 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
375
ce07dd7c
KR
376 if (N_MAGIC (*execp) == ZMAGIC)
377 {
378 abfd->flags |= D_PAGED|WP_TEXT;
379 adata(abfd).magic = z_magic;
380 }
381 else if (N_MAGIC (*execp) == NMAGIC)
382 {
383 abfd->flags |= WP_TEXT;
384 adata(abfd).magic = n_magic;
385 }
386 else
387 adata(abfd).magic = o_magic;
7ed4093a
SC
388
389 bfd_get_start_address (abfd) = execp->a_entry;
390
391 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
392 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
393
7ed4093a
SC
394 /* The default relocation entry size is that of traditional V7 Unix. */
395 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
396
7b02b4ed
JG
397 /* The default symbol entry size is that of traditional Unix. */
398 obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
399
7ed4093a
SC
400 /* create the sections. This is raunchy, but bfd_close wants to reclaim
401 them */
6db82ea7 402
214f8f23
KR
403 obj_textsec (abfd) = bfd_make_section_old_way (abfd, ".text");
404 obj_datasec (abfd) = bfd_make_section_old_way (abfd, ".data");
405 obj_bsssec (abfd) = bfd_make_section_old_way (abfd, ".bss");
406
407#if 0
408 (void)bfd_make_section (abfd, ".text");
409 (void)bfd_make_section (abfd, ".data");
410 (void)bfd_make_section (abfd, ".bss");
411#endif
7ed4093a 412
6db82ea7
SC
413 obj_datasec (abfd)->_raw_size = execp->a_data;
414 obj_bsssec (abfd)->_raw_size = execp->a_bss;
7ed4093a 415
7ed4093a 416 obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
d047d16a
JG
417 (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC) :
418 (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
7ed4093a 419 obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
d047d16a
JG
420 (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC) :
421 (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
7ed4093a
SC
422 obj_bsssec (abfd)->flags = SEC_ALLOC;
423
424#ifdef THIS_IS_ONLY_DOCUMENTATION
98d43107
JG
425 /* The common code can't fill in these things because they depend
426 on either the start address of the text segment, the rounding
427 up of virtual addersses between segments, or the starting file
428 position of the text segment -- all of which varies among different
429 versions of a.out. */
430
7ed4093a
SC
431 /* Call back to the format-dependent code to fill in the rest of the
432 fields and do any further cleanup. Things that should be filled
433 in by the callback: */
434
435 struct exec *execp = exec_hdr (abfd);
436
98d43107 437 obj_textsec (abfd)->size = N_TXTSIZE(*execp);
6db82ea7 438 obj_textsec (abfd)->raw_size = N_TXTSIZE(*execp);
98d43107
JG
439 /* data and bss are already filled in since they're so standard */
440
7ed4093a 441 /* The virtual memory addresses of the sections */
7ed4093a 442 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
98d43107
JG
443 obj_datasec (abfd)->vma = N_DATADDR(*execp);
444 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
7ed4093a
SC
445
446 /* The file offsets of the sections */
447 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
448 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
449
450 /* The file offsets of the relocation info */
451 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
452 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
453
454 /* The file offsets of the string table and symbol table. */
455 obj_str_filepos (abfd) = N_STROFF (*execp);
456 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
457
7ed4093a
SC
458 /* Determine the architecture and machine type of the object file. */
459 switch (N_MACHTYPE (*exec_hdr (abfd))) {
460 default:
461 abfd->obj_arch = bfd_arch_obscure;
462 break;
463 }
464
7b02b4ed
JG
465 adata(abfd)->page_size = PAGE_SIZE;
466 adata(abfd)->segment_size = SEGMENT_SIZE;
467 adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
468
7ed4093a
SC
469 return abfd->xvec;
470
471 /* The architecture is encoded in various ways in various a.out variants,
472 or is not encoded at all in some of them. The relocation size depends
473 on the architecture and the a.out variant. Finally, the return value
474 is the bfd_target vector in use. If an error occurs, return zero and
475 set bfd_error to the appropriate error code.
476
477 Formats such as b.out, which have additional fields in the a.out
478 header, should cope with them in this callback as well. */
479#endif /* DOCUMENTATION */
480
e6e265ce
JG
481 result = (*callback_to_real_object_p)(abfd);
482
483 /* Now that the segment addresses have been worked out, take a better
484 guess at whether the file is executable. If the entry point
485 is within the text segment, assume it is. (This makes files
486 executable even if their entry point address is 0, as long as
487 their text starts at zero.)
488
489 At some point we should probably break down and stat the file and
490 declare it executable if (one of) its 'x' bits are on... */
491 if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
6db82ea7 492 (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
e6e265ce 493 abfd->flags |= EXEC_P;
214f8f23
KR
494 if (result)
495 {
1f29e30b 496#if 0 /* These should be set correctly anyways. */
214f8f23
KR
497 abfd->sections = obj_textsec (abfd);
498 obj_textsec (abfd)->next = obj_datasec (abfd);
499 obj_datasec (abfd)->next = obj_bsssec (abfd);
1f29e30b 500#endif
214f8f23
KR
501 }
502 else
503 {
504 free (rawptr);
505 abfd->tdata.aout_data = oldrawptr;
506 }
e6e265ce 507 return result;
7ed4093a
SC
508}
509
4e41b5aa
SC
510/*
511FUNCTION
512 aout_<size>_mkobject
6f715d66 513
4e41b5aa
SC
514DESCRIPTION
515 This routine initializes a BFD for use with a.out files.
6f715d66 516
fa2b89f1 517SYNOPSIS
4e41b5aa 518 boolean aout_<size>_mkobject, (bfd *);
6f715d66 519*/
7ed4093a
SC
520
521boolean
522DEFUN(NAME(aout,mkobject),(abfd),
523 bfd *abfd)
524{
6db82ea7 525 struct aout_data_struct *rawptr;
7ed4093a
SC
526
527 bfd_error = system_call_error;
528
529 /* Use an intermediate variable for clarity */
6db82ea7 530 rawptr = (struct aout_data_struct *)bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
7ed4093a
SC
531
532 if (rawptr == NULL) {
533 bfd_error = no_memory;
534 return false;
535 }
536
6db82ea7 537 abfd->tdata.aout_data = rawptr;
7ed4093a
SC
538 exec_hdr (abfd) = &(rawptr->e);
539
540 /* For simplicity's sake we just make all the sections right here. */
541
542 obj_textsec (abfd) = (asection *)NULL;
543 obj_datasec (abfd) = (asection *)NULL;
544 obj_bsssec (abfd) = (asection *)NULL;
545 bfd_make_section (abfd, ".text");
546 bfd_make_section (abfd, ".data");
547 bfd_make_section (abfd, ".bss");
6db82ea7
SC
548 bfd_make_section (abfd, BFD_ABS_SECTION_NAME);
549 bfd_make_section (abfd, BFD_UND_SECTION_NAME);
550 bfd_make_section (abfd, BFD_COM_SECTION_NAME);
7ed4093a
SC
551
552 return true;
553}
554
6f715d66 555
4e41b5aa
SC
556/*
557FUNCTION
558 aout_<size>_machine_type
6f715d66 559
4e41b5aa
SC
560DESCRIPTION
561 Keep track of machine architecture and machine type for
562 a.out's. Return the machine_type for a particular
563 arch&machine, or M_UNKNOWN if that exact arch&machine can't be
564 represented in a.out format.
7ed4093a 565
4e41b5aa
SC
566 If the architecture is understood, machine type 0 (default)
567 should always be understood.
6f715d66 568
fa2b89f1 569SYNOPSIS
4e41b5aa 570 enum machine_type aout_<size>_machine_type
6f715d66
SC
571 (enum bfd_architecture arch,
572 unsigned long machine));
573*/
7ed4093a
SC
574
575enum machine_type
576DEFUN(NAME(aout,machine_type),(arch, machine),
577 enum bfd_architecture arch AND
578 unsigned long machine)
579{
580 enum machine_type arch_flags;
581
582 arch_flags = M_UNKNOWN;
583
584 switch (arch) {
585 case bfd_arch_sparc:
586 if (machine == 0) arch_flags = M_SPARC;
587 break;
588
589 case bfd_arch_m68k:
590 switch (machine) {
591 case 0: arch_flags = M_68010; break;
592 case 68000: arch_flags = M_UNKNOWN; break;
593 case 68010: arch_flags = M_68010; break;
594 case 68020: arch_flags = M_68020; break;
595 default: arch_flags = M_UNKNOWN; break;
596 }
597 break;
598
599 case bfd_arch_i386:
600 if (machine == 0) arch_flags = M_386;
601 break;
602
603 case bfd_arch_a29k:
604 if (machine == 0) arch_flags = M_29K;
605 break;
606
5cd3dcff
KR
607 case bfd_arch_mips:
608 switch (machine) {
609 case 0:
610 case 2000:
611 case 3000: arch_flags = M_MIPS1; break;
612 case 4000:
613 case 4400:
614 case 6000: arch_flags = M_MIPS2; break;
615 default: arch_flags = M_UNKNOWN; break;
616 }
617 break;
618
7ed4093a
SC
619 default:
620 arch_flags = M_UNKNOWN;
7ed4093a
SC
621 }
622 return arch_flags;
623}
624
9e2dad8e 625
4e41b5aa
SC
626/*
627FUNCTION
628 aout_<size>_set_arch_mach
6f715d66 629
4e41b5aa
SC
630DESCRIPTION
631 Sets the architecture and the machine of the BFD to those
632 values supplied. Verifies that the format can support the
633 architecture required.
6f715d66 634
fa2b89f1 635SYNOPSIS
4e41b5aa 636 boolean aout_<size>_set_arch_mach,
6f715d66
SC
637 (bfd *,
638 enum bfd_architecture,
639 unsigned long machine));
640*/
641
7ed4093a
SC
642boolean
643DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
644 bfd *abfd AND
645 enum bfd_architecture arch AND
646 unsigned long machine)
647{
9e2dad8e 648 bfd_default_set_arch_mach(abfd, arch, machine);
7ed4093a
SC
649 if (arch != bfd_arch_unknown &&
650 NAME(aout,machine_type) (arch, machine) == M_UNKNOWN)
651 return false; /* We can't represent this type */
ce07dd7c 652
214f8f23
KR
653 /* Determine the size of a relocation entry */
654 switch (arch) {
655 case bfd_arch_sparc:
656 case bfd_arch_a29k:
5cd3dcff 657 case bfd_arch_mips:
214f8f23
KR
658 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
659 break;
660 default:
661 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
662 break;
663 }
664
2768b3f7 665 return (*aout_backend_info(abfd)->set_sizes) (abfd);
7ed4093a 666}
7ed4093a 667
ce07dd7c
KR
668boolean
669DEFUN (NAME (aout,adjust_sizes_and_vmas), (abfd, text_size, text_end),
670 bfd *abfd AND bfd_size_type *text_size AND file_ptr *text_end)
671{
672 struct internal_exec *execp = exec_hdr (abfd);
673 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
674 {
675 bfd_error = invalid_operation;
676 return false;
677 }
678 if (adata(abfd).magic != undecided_magic) return true;
679 obj_textsec(abfd)->_raw_size =
680 align_power(obj_textsec(abfd)->_raw_size,
681 obj_textsec(abfd)->alignment_power);
682
683 *text_size = obj_textsec (abfd)->_raw_size;
684 /* Rule (heuristic) for when to pad to a new page. Note that there
685 * are (at least) two ways demand-paged (ZMAGIC) files have been
686 * handled. Most Berkeley-based systems start the text segment at
687 * (PAGE_SIZE). However, newer versions of SUNOS start the text
688 * segment right after the exec header; the latter is counted in the
689 * text segment size, and is paged in by the kernel with the rest of
690 * the text. */
691
692 /* This perhaps isn't the right way to do this, but made it simpler for me
693 to understand enough to implement it. Better would probably be to go
694 right from BFD flags to alignment/positioning characteristics. But the
695 old code was sloppy enough about handling the flags, and had enough
696 other magic, that it was a little hard for me to understand. I think
697 I understand it better now, but I haven't time to do the cleanup this
698 minute. */
699 if (adata(abfd).magic == undecided_magic)
700 {
701 if (abfd->flags & D_PAGED)
702 /* whether or not WP_TEXT is set */
703 adata(abfd).magic = z_magic;
704 else if (abfd->flags & WP_TEXT)
705 adata(abfd).magic = n_magic;
706 else
707 adata(abfd).magic = o_magic;
708 }
709
710#ifdef BFD_AOUT_DEBUG /* requires gcc2 */
711#if __GNUC__ >= 2
712 fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
713 ({ char *str;
714 switch (adata(abfd).magic) {
715 case n_magic: str = "NMAGIC"; break;
716 case o_magic: str = "OMAGIC"; break;
717 case z_magic: str = "ZMAGIC"; break;
718 default: abort ();
719 }
720 str;
721 }),
722 obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size, obj_textsec(abfd)->alignment_power,
723 obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size, obj_datasec(abfd)->alignment_power,
724 obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size, obj_bsssec(abfd)->alignment_power);
725#endif
726#endif
727
728 switch (adata(abfd).magic)
729 {
730 case o_magic:
731 {
732 file_ptr pos = adata (abfd).exec_bytes_size;
733 bfd_vma vma = 0;
214f8f23 734 int pad = 0;
ce07dd7c
KR
735
736 obj_textsec(abfd)->filepos = pos;
737 pos += obj_textsec(abfd)->_raw_size;
738 vma += obj_textsec(abfd)->_raw_size;
739 if (!obj_datasec(abfd)->user_set_vma)
740 {
214f8f23 741#if 0 /* ?? Does alignment in the file image really matter? */
ce07dd7c 742 pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma;
214f8f23 743#endif
ce07dd7c
KR
744 obj_textsec(abfd)->_raw_size += pad;
745 pos += pad;
746 vma += pad;
747 obj_datasec(abfd)->vma = vma;
748 }
749 obj_datasec(abfd)->filepos = pos;
750 pos += obj_datasec(abfd)->_raw_size;
751 vma += obj_datasec(abfd)->_raw_size;
752 if (!obj_bsssec(abfd)->user_set_vma)
753 {
214f8f23 754#if 0
ce07dd7c 755 pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
214f8f23 756#endif
ce07dd7c
KR
757 obj_datasec(abfd)->_raw_size += pad;
758 pos += pad;
759 vma += pad;
760 obj_bsssec(abfd)->vma = vma;
761 }
762 obj_bsssec(abfd)->filepos = pos;
763 execp->a_text = obj_textsec(abfd)->_raw_size;
764 execp->a_data = obj_datasec(abfd)->_raw_size;
765 execp->a_bss = obj_bsssec(abfd)->_raw_size;
766 N_SET_MAGIC (*execp, OMAGIC);
767 }
768 break;
769 case z_magic:
770 {
771 bfd_size_type data_pad, text_pad;
772 file_ptr text_end;
773 CONST struct aout_backend_data *abdp;
774 int ztih;
775 bfd_vma data_vma;
776
777 abdp = aout_backend_info (abfd);
778 ztih = abdp && abdp->text_includes_header;
779 obj_textsec(abfd)->filepos = (ztih
780 ? adata(abfd).exec_bytes_size
781 : adata(abfd).page_size);
782 if (! obj_textsec(abfd)->user_set_vma)
783 /* ?? Do we really need to check for relocs here? */
784 obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC)
785 ? 0
786 : (ztih
787 ? (abdp->default_text_vma
788 + adata(abfd).exec_bytes_size)
789 : abdp->default_text_vma));
790 /* Could take strange alignment of text section into account here? */
791
792 /* Find start of data. */
793 text_end = obj_textsec(abfd)->filepos + obj_textsec(abfd)->_raw_size;
794 text_pad = BFD_ALIGN (text_end, adata(abfd).page_size) - text_end;
795 obj_textsec(abfd)->_raw_size += text_pad;
796 text_end += text_pad;
797
798 if (!obj_datasec(abfd)->user_set_vma)
799 {
800 bfd_vma vma;
801 vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size;
802 obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
803 }
804 data_vma = obj_datasec(abfd)->vma;
805 if (abdp && abdp->zmagic_mapped_contiguous)
806 {
807 text_pad = (obj_datasec(abfd)->vma
808 - obj_textsec(abfd)->vma
809 - obj_textsec(abfd)->_raw_size);
810 obj_textsec(abfd)->_raw_size += text_pad;
811 }
812 obj_datasec(abfd)->filepos = (obj_textsec(abfd)->filepos
813 + obj_textsec(abfd)->_raw_size);
814
815 /* Fix up exec header while we're at it. */
816 execp->a_text = obj_textsec(abfd)->_raw_size;
7f90aa8b 817 if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
ce07dd7c
KR
818 execp->a_text += adata(abfd).exec_bytes_size;
819 N_SET_MAGIC (*execp, ZMAGIC);
820 /* Spec says data section should be rounded up to page boundary. */
821 /* If extra space in page is left after data section, fudge data
822 in the header so that the bss section looks smaller by that
823 amount. We'll start the bss section there, and lie to the OS. */
824 obj_datasec(abfd)->_raw_size
825 = align_power (obj_datasec(abfd)->_raw_size,
826 obj_bsssec(abfd)->alignment_power);
827 execp->a_data = BFD_ALIGN (obj_datasec(abfd)->_raw_size,
828 adata(abfd).page_size);
829 data_pad = execp->a_data - obj_datasec(abfd)->_raw_size;
a99c3d70 830
ce07dd7c
KR
831 if (!obj_bsssec(abfd)->user_set_vma)
832 obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
833 + obj_datasec(abfd)->_raw_size);
834 if (data_pad > obj_bsssec(abfd)->_raw_size)
835 execp->a_bss = 0;
836 else
837 execp->a_bss = obj_bsssec(abfd)->_raw_size - data_pad;
838 }
839 break;
840 case n_magic:
841 {
ce07dd7c
KR
842 file_ptr pos = adata(abfd).exec_bytes_size;
843 bfd_vma vma = 0;
844 int pad;
845
846 obj_textsec(abfd)->filepos = pos;
847 if (!obj_textsec(abfd)->user_set_vma)
848 obj_textsec(abfd)->vma = vma;
849 else
850 vma = obj_textsec(abfd)->vma;
851 pos += obj_textsec(abfd)->_raw_size;
852 vma += obj_textsec(abfd)->_raw_size;
853 obj_datasec(abfd)->filepos = pos;
854 if (!obj_datasec(abfd)->user_set_vma)
855 obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
856 vma = obj_datasec(abfd)->vma;
857
858 /* Since BSS follows data immediately, see if it needs alignment. */
859 vma += obj_datasec(abfd)->_raw_size;
860 pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
861 obj_datasec(abfd)->_raw_size += pad;
862 pos += obj_datasec(abfd)->_raw_size;
863
864 if (!obj_bsssec(abfd)->user_set_vma)
865 obj_bsssec(abfd)->vma = vma;
866 else
867 vma = obj_bsssec(abfd)->vma;
868 }
869 execp->a_text = obj_textsec(abfd)->_raw_size;
870 execp->a_data = obj_datasec(abfd)->_raw_size;
871 execp->a_bss = obj_bsssec(abfd)->_raw_size;
872 N_SET_MAGIC (*execp, NMAGIC);
873 break;
874 default:
875 abort ();
876 }
877#ifdef BFD_AOUT_DEBUG
878 fprintf (stderr, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
879 obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size, obj_textsec(abfd)->filepos,
880 obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size, obj_datasec(abfd)->filepos,
881 obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size);
882#endif
d047d16a 883 return true;
ce07dd7c
KR
884}
885
4e41b5aa
SC
886/*
887FUNCTION
fa2b89f1 888 aout_<size>_new_section_hook
9e2dad8e 889
4e41b5aa
SC
890DESCRIPTION
891 Called by the BFD in response to a @code{bfd_make_section}
892 request.
893
fa2b89f1 894SYNOPSIS
4e41b5aa 895 boolean aout_<size>_new_section_hook,
9e2dad8e
JG
896 (bfd *abfd,
897 asection *newsect));
6f715d66 898*/
7ed4093a 899boolean
3f7607af 900DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
9e2dad8e
JG
901 bfd *abfd AND
902 asection *newsect)
7ed4093a 903{
6db82ea7
SC
904 /* align to double at least */
905 newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
3f7607af 906
7ed4093a 907
6db82ea7
SC
908 if (bfd_get_format (abfd) == bfd_object)
909 {
910 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
911 obj_textsec(abfd)= newsect;
912 newsect->target_index = N_TEXT | N_EXT;
913 return true;
914 }
7ed4093a 915
6db82ea7
SC
916 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
917 obj_datasec(abfd) = newsect;
918 newsect->target_index = N_DATA | N_EXT;
919 return true;
920 }
7ed4093a 921
6db82ea7
SC
922 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
923 obj_bsssec(abfd) = newsect;
924 newsect->target_index = N_BSS | N_EXT;
925 return true;
926 }
927
928 }
7ed4093a 929
6db82ea7
SC
930 /* We allow more than three sections internally */
931 return true;
7ed4093a
SC
932}
933
934boolean
9e2dad8e
JG
935 DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
936 bfd *abfd AND
937 sec_ptr section AND
938 PTR location AND
939 file_ptr offset AND
940 bfd_size_type count)
7ed4093a 941{
7b02b4ed 942 file_ptr text_end;
7b02b4ed 943 bfd_size_type text_size;
ce07dd7c 944
7ed4093a 945 if (abfd->output_has_begun == false)
9e2dad8e
JG
946 { /* set by bfd.c handler */
947 switch (abfd->direction)
948 {
949 case read_direction:
950 case no_direction:
951 bfd_error = invalid_operation;
952 return false;
ce07dd7c
KR
953
954 case write_direction:
955 if (NAME(aout,adjust_sizes_and_vmas) (abfd,
956 &text_size,
957 &text_end) == false)
958 return false;
9e2dad8e
JG
959 case both_direction:
960 break;
12e7087f 961 }
9e2dad8e 962 }
12e7087f 963
7ed4093a
SC
964 /* regardless, once we know what we're doing, we might as well get going */
965 if (section != obj_bsssec(abfd))
966 {
967 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
9e2dad8e 968
7ed4093a
SC
969 if (count) {
970 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
971 true : false;
972 }
6db82ea7 973 return true;
7ed4093a
SC
974 }
975 return true;
976}
977\f
978/* Classify stabs symbols */
979
980#define sym_in_text_section(sym) \
9e2dad8e 981 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
7ed4093a
SC
982
983#define sym_in_data_section(sym) \
9e2dad8e 984 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
7ed4093a
SC
985
986#define sym_in_bss_section(sym) \
9e2dad8e 987 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
7ed4093a
SC
988
989/* Symbol is undefined if type is N_UNDF|N_EXT and if it has
9e2dad8e
JG
990 zero in the "value" field. Nonzeroes there are fortrancommon
991 symbols. */
7ed4093a 992#define sym_is_undefined(sym) \
9e2dad8e 993 ((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
7ed4093a
SC
994
995/* Symbol is a global definition if N_EXT is on and if it has
9e2dad8e 996 a nonzero type field. */
7ed4093a 997#define sym_is_global_defn(sym) \
9e2dad8e 998 (((sym)->type & N_EXT) && (sym)->type & N_TYPE)
7ed4093a
SC
999
1000/* Symbol is debugger info if any bits outside N_TYPE or N_EXT
9e2dad8e 1001 are on. */
7ed4093a 1002#define sym_is_debugger_info(sym) \
9e2dad8e 1003 ((sym)->type & ~(N_EXT | N_TYPE))
7ed4093a
SC
1004
1005#define sym_is_fortrancommon(sym) \
9e2dad8e 1006 (((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
7ed4093a
SC
1007
1008/* Symbol is absolute if it has N_ABS set */
1009#define sym_is_absolute(sym) \
9e2dad8e 1010 (((sym)->type & N_TYPE)== N_ABS)
7ed4093a
SC
1011
1012
1013#define sym_is_indirect(sym) \
9e2dad8e 1014 (((sym)->type & N_ABS)== N_ABS)
7ed4093a
SC
1015
1016/* Only in their own functions for ease of debugging; when sym flags have
9e2dad8e
JG
1017 stabilised these should be inlined into their (single) caller */
1018
7ed4093a 1019static void
a99c3d70
JG
1020DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd, statep),
1021 struct external_nlist *sym_pointer AND
1022 aout_symbol_type * cache_ptr AND
1023 bfd * abfd AND
1024 int *statep)
9e2dad8e 1025{
0f213cc2 1026 cache_ptr->symbol.section = 0;
a99c3d70 1027 if (*statep)
6db82ea7 1028 {
a99c3d70
JG
1029 /* This is an indirect symbol */
1030 cache_ptr->symbol.flags = BSF_DEBUGGING;
1031 cache_ptr->symbol.section = &bfd_und_section;
1032 *statep = 0;
6db82ea7 1033 }
a99c3d70 1034 else
6db82ea7 1035 {
a99c3d70 1036 switch (cache_ptr->type & N_TYPE)
6db82ea7 1037 {
a99c3d70
JG
1038 case N_SETA:
1039 case N_SETT:
1040 case N_SETD:
1041 case N_SETB:
1042 {
1043 char *copy = bfd_alloc (abfd, strlen (cache_ptr->symbol.name) + 1);
1044 asection *section;
1045 asection *into_section;
1046
1047 arelent_chain *reloc = (arelent_chain *) bfd_alloc (abfd, sizeof (arelent_chain));
1048 strcpy (copy, cache_ptr->symbol.name);
1049
1050 /* Make sure that this bfd has a section with the right contructor
1051 name */
1052 section = bfd_get_section_by_name (abfd, copy);
1053 if (!section)
1054 section = bfd_make_section (abfd, copy);
1055
1056 /* Build a relocation entry for the constructor */
1057 switch ((cache_ptr->type & N_TYPE))
1058 {
1059 case N_SETA:
1060 into_section = &bfd_abs_section;
34dd8ba3 1061 cache_ptr->type = N_ABS;
a99c3d70
JG
1062 break;
1063 case N_SETT:
1064 into_section = (asection *) obj_textsec (abfd);
34dd8ba3 1065 cache_ptr->type = N_TEXT;
a99c3d70
JG
1066 break;
1067 case N_SETD:
1068 into_section = (asection *) obj_datasec (abfd);
34dd8ba3 1069 cache_ptr->type = N_DATA;
a99c3d70
JG
1070 break;
1071 case N_SETB:
1072 into_section = (asection *) obj_bsssec (abfd);
34dd8ba3 1073 cache_ptr->type = N_BSS;
a99c3d70
JG
1074 break;
1075 default:
1076 abort ();
1077 }
88dfcd68 1078
a99c3d70
JG
1079 /* Build a relocation pointing into the constuctor section
1080 pointing at the symbol in the set vector specified */
6db82ea7 1081
a99c3d70
JG
1082 reloc->relent.addend = cache_ptr->symbol.value;
1083 cache_ptr->symbol.section = into_section->symbol->section;
1084 reloc->relent.sym_ptr_ptr = into_section->symbol_ptr_ptr;
6db82ea7
SC
1085
1086
a99c3d70
JG
1087 /* We modify the symbol to belong to a section depending upon the
1088 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
1089 really care, and add to the size of the section to contain a
1090 pointer to the symbol. Build a reloc entry to relocate to this
1091 symbol attached to this section. */
1092
1093 section->flags = SEC_CONSTRUCTOR;
1094
1095
1096 section->reloc_count++;
1097 section->alignment_power = 2;
1098
1099 reloc->next = section->constructor_chain;
1100 section->constructor_chain = reloc;
1101 reloc->relent.address = section->_raw_size;
1102 section->_raw_size += sizeof (int *);
1103
34dd8ba3
JG
1104 reloc->relent.howto
1105 = (obj_reloc_entry_size(abfd) == RELOC_EXT_SIZE
1106 ? howto_table_ext : howto_table_std)
1107 + CTOR_TABLE_RELOC_IDX;
1108 cache_ptr->symbol.flags |= BSF_CONSTRUCTOR;
6db82ea7 1109 }
a99c3d70
JG
1110 break;
1111 default:
1112 if (cache_ptr->type == N_WARNING)
1113 {
1114 /* This symbol is the text of a warning message, the next symbol
1115 is the symbol to associate the warning with */
1116 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
c48ff89f
KR
1117
1118 /* @@ Stuffing pointers into integers is a no-no.
1119 We can usually get away with it if the integer is
1120 large enough though. */
1121 if (sizeof (cache_ptr + 1) > sizeof (bfd_vma))
1122 abort ();
a99c3d70 1123 cache_ptr->symbol.value = (bfd_vma) ((cache_ptr + 1));
c48ff89f 1124
a99c3d70
JG
1125 /* We furgle with the next symbol in place.
1126 We don't want it to be undefined, we'll trample the type */
1127 (sym_pointer + 1)->e_type[0] = 0xff;
1128 break;
1129 }
1130 if ((cache_ptr->type | N_EXT) == (N_INDR | N_EXT))
1131 {
1132 /* Two symbols in a row for an INDR message. The first symbol
0f213cc2
KR
1133 contains the name we will match, the second symbol contains
1134 the name the first name is translated into. It is supplied to
1135 us undefined. This is good, since we want to pull in any files
1136 which define it */
a99c3d70 1137 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT;
c48ff89f
KR
1138
1139 /* @@ Stuffing pointers into integers is a no-no.
1140 We can usually get away with it if the integer is
1141 large enough though. */
1142 if (sizeof (cache_ptr + 1) > sizeof (bfd_vma))
1143 abort ();
1144
a99c3d70
JG
1145 cache_ptr->symbol.value = (bfd_vma) ((cache_ptr + 1));
1146 cache_ptr->symbol.section = &bfd_ind_section;
1147 *statep = 1;
1148 }
1149
1150 else if (sym_is_debugger_info (cache_ptr))
1151 {
1152 cache_ptr->symbol.flags = BSF_DEBUGGING;
1153 /* Work out the section correct for this symbol */
1154 switch (cache_ptr->type & N_TYPE)
1155 {
1156 case N_TEXT:
1157 case N_FN:
1158 cache_ptr->symbol.section = obj_textsec (abfd);
1159 cache_ptr->symbol.value -= obj_textsec (abfd)->vma;
1160 break;
1161 case N_DATA:
1162 cache_ptr->symbol.value -= obj_datasec (abfd)->vma;
1163 cache_ptr->symbol.section = obj_datasec (abfd);
1164 break;
1165 case N_BSS:
1166 cache_ptr->symbol.section = obj_bsssec (abfd);
1167 cache_ptr->symbol.value -= obj_bsssec (abfd)->vma;
1168 break;
1169 default:
1170 case N_ABS:
1171
1172 cache_ptr->symbol.section = &bfd_abs_section;
1173 break;
1174 }
1175 }
1176 else
1177 {
1178
1179 if (sym_is_fortrancommon (cache_ptr))
1180 {
1181 cache_ptr->symbol.flags = 0;
1182 cache_ptr->symbol.section = &bfd_com_section;
1183 }
1184 else
1185 {
1186
1187
1188 }
1189
1190 /* In a.out, the value of a symbol is always relative to the
1191 * start of the file, if this is a data symbol we'll subtract
1192 * the size of the text section to get the section relative
1193 * value. If this is a bss symbol (which would be strange)
1194 * we'll subtract the size of the previous two sections
1195 * to find the section relative address.
1196 */
1197
1198 if (sym_in_text_section (cache_ptr))
1199 {
1200 cache_ptr->symbol.value -= obj_textsec (abfd)->vma;
1201 cache_ptr->symbol.section = obj_textsec (abfd);
1202 }
1203 else if (sym_in_data_section (cache_ptr))
1204 {
1205 cache_ptr->symbol.value -= obj_datasec (abfd)->vma;
1206 cache_ptr->symbol.section = obj_datasec (abfd);
1207 }
1208 else if (sym_in_bss_section (cache_ptr))
1209 {
1210 cache_ptr->symbol.section = obj_bsssec (abfd);
1211 cache_ptr->symbol.value -= obj_bsssec (abfd)->vma;
1212 }
1213 else if (sym_is_undefined (cache_ptr))
1214 {
1215 cache_ptr->symbol.flags = 0;
1216 cache_ptr->symbol.section = &bfd_und_section;
1217 }
1218 else if (sym_is_absolute (cache_ptr))
1219 {
1220 cache_ptr->symbol.section = &bfd_abs_section;
1221 }
1222
1223 if (sym_is_global_defn (cache_ptr))
1224 {
1225 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1226 }
1227 else
1228 {
1229 cache_ptr->symbol.flags = BSF_LOCAL;
1230 }
1231 }
7ed4093a 1232 }
a99c3d70 1233 }
0f213cc2
KR
1234 if (cache_ptr->symbol.section == 0)
1235 abort ();
7ed4093a
SC
1236}
1237
6db82ea7
SC
1238
1239
7ed4093a
SC
1240static void
1241DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
1242 struct external_nlist *sym_pointer AND
1243 asymbol *cache_ptr AND
1244 bfd *abfd)
1245{
1246 bfd_vma value = cache_ptr->value;
1247
10dea9ed
DHW
1248 /* mask out any existing type bits in case copying from one section
1249 to another */
1250 sym_pointer->e_type[0] &= ~N_TYPE;
a99c3d70 1251
10dea9ed 1252
3caa6924
DM
1253 /* We attempt to order these tests by decreasing frequency of success,
1254 according to tcov when linking the linker. */
1255 if (bfd_get_output_section(cache_ptr) == &bfd_abs_section) {
1256 sym_pointer->e_type[0] |= N_ABS;
1257 }
1258 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
1259 sym_pointer->e_type[0] |= N_TEXT;
a99c3d70 1260 }
6db82ea7 1261 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
a99c3d70
JG
1262 sym_pointer->e_type[0] |= N_DATA;
1263 }
3caa6924
DM
1264 else if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
1265 sym_pointer->e_type[0] |= N_BSS;
7ed4093a 1266 }
6db82ea7 1267 else if (bfd_get_output_section(cache_ptr) == &bfd_und_section)
a99c3d70 1268 {
6db82ea7 1269 sym_pointer->e_type[0] = (N_UNDF | N_EXT);
a99c3d70
JG
1270 }
1271 else if (bfd_get_output_section(cache_ptr) == &bfd_ind_section)
1272 {
1273 sym_pointer->e_type[0] = N_INDR;
1274 }
1275 else if (bfd_is_com_section (bfd_get_output_section (cache_ptr))) {
1276 sym_pointer->e_type[0] = (N_UNDF | N_EXT);
1277 }
6db82ea7 1278 else {
a99c3d70 1279 if (cache_ptr->section->output_section)
e7b4046c
SC
1280 {
1281
1282 bfd_error_vector.nonrepresentable_section(abfd,
1283 bfd_get_output_section(cache_ptr)->name);
1284 }
a99c3d70 1285 else
e7b4046c
SC
1286 {
1287 bfd_error_vector.nonrepresentable_section(abfd,
1288 cache_ptr->section->name);
1289
1290 }
1291
a99c3d70 1292 }
6db82ea7 1293 /* Turn the symbol from section relative to absolute again */
7ed4093a 1294
6db82ea7
SC
1295 value += cache_ptr->section->output_section->vma + cache_ptr->section->output_offset ;
1296
1297
1298 if (cache_ptr->flags & (BSF_WARNING)) {
a99c3d70
JG
1299 (sym_pointer+1)->e_type[0] = 1;
1300 }
6db82ea7 1301
6db82ea7 1302 if (cache_ptr->flags & BSF_DEBUGGING) {
34dd8ba3
JG
1303 sym_pointer->e_type[0] = ((aout_symbol_type *)cache_ptr)->type;
1304 }
3caa6924
DM
1305 else if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1306 sym_pointer->e_type[0] |= N_EXT;
1307 }
34dd8ba3
JG
1308 if (cache_ptr->flags & BSF_CONSTRUCTOR) {
1309 int type = ((aout_symbol_type *)cache_ptr)->type;
1310 switch (type)
1311 {
1312 case N_ABS: type = N_SETA; break;
1313 case N_TEXT: type = N_SETT; break;
1314 case N_DATA: type = N_SETD; break;
1315 case N_BSS: type = N_SETB; break;
1316 }
1317 sym_pointer->e_type[0] = type;
a99c3d70 1318 }
6db82ea7 1319
7ed4093a
SC
1320 PUT_WORD(abfd, value, sym_pointer->e_value);
1321}
1322\f
1323/* Native-level interface to symbols. */
1324
1325/* We read the symbols into a buffer, which is discarded when this
1326function exits. We read the strings into a buffer large enough to
1327hold them all plus all the cached symbol entries. */
1328
1329asymbol *
1330DEFUN(NAME(aout,make_empty_symbol),(abfd),
1331 bfd *abfd)
9e2dad8e
JG
1332{
1333 aout_symbol_type *new =
1334 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1335 new->symbol.the_bfd = abfd;
fa2b89f1 1336
9e2dad8e
JG
1337 return &new->symbol;
1338}
7ed4093a
SC
1339
1340boolean
1341DEFUN(NAME(aout,slurp_symbol_table),(abfd),
1342 bfd *abfd)
9e2dad8e
JG
1343{
1344 bfd_size_type symbol_size;
1345 bfd_size_type string_size;
1346 unsigned char string_chars[BYTES_IN_WORD];
1347 struct external_nlist *syms;
1348 char *strings;
1349 aout_symbol_type *cached;
0f213cc2 1350
9e2dad8e
JG
1351 /* If there's no work to be done, don't do any */
1352 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1353 symbol_size = exec_hdr(abfd)->a_syms;
0f213cc2
KR
1354 if (symbol_size == 0)
1355 {
1356 bfd_error = no_symbols;
1357 return false;
1358 }
1359
9e2dad8e
JG
1360 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1361 if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
1362 return false;
1363 string_size = GET_WORD (abfd, string_chars);
0f213cc2 1364
9e2dad8e
JG
1365 strings =(char *) bfd_alloc(abfd, string_size + 1);
1366 cached = (aout_symbol_type *)
1367 bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
1368
1369 /* malloc this, so we can free it if simply. The symbol caching
1370 might want to allocate onto the bfd's obstack */
98d43107 1371 syms = (struct external_nlist *) bfd_xmalloc(symbol_size);
9e2dad8e 1372 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
0f213cc2
KR
1373 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size)
1374 {
1375 bailout:
1376 if (syms)
1377 free (syms);
1378 if (cached)
1379 bfd_release (abfd, cached);
1380 if (strings)
1381 bfd_release (abfd, strings);
1382 return false;
1383 }
1384
9e2dad8e 1385 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
0f213cc2 1386 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size)
9e2dad8e 1387 {
0f213cc2 1388 goto bailout;
9e2dad8e 1389 }
0f213cc2
KR
1390 strings[string_size] = 0; /* Just in case. */
1391
1392 /* OK, now walk the new symtable, cacheing symbol properties */
1393 {
1394 register struct external_nlist *sym_pointer;
1395 int state = 0;
1396 register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
1397 register aout_symbol_type *cache_ptr = cached;
1398
1399 /* Run through table and copy values */
1400 for (sym_pointer = syms, cache_ptr = cached;
1401 sym_pointer < sym_end; sym_pointer ++, cache_ptr++)
1402 {
1403 long x = GET_WORD(abfd, sym_pointer->e_strx);
1404 cache_ptr->symbol.the_bfd = abfd;
1405 if (x == 0)
1406 cache_ptr->symbol.name = "";
1407 else if (x >= 0 && x < string_size)
1408 cache_ptr->symbol.name = x + strings;
1409 else
1410 goto bailout;
1411
1412 cache_ptr->symbol.value = GET_SWORD(abfd, sym_pointer->e_value);
1413 cache_ptr->desc = bfd_h_get_16(abfd, sym_pointer->e_desc);
1414 cache_ptr->other = bfd_h_get_8(abfd, sym_pointer->e_other);
1415 cache_ptr->type = bfd_h_get_8(abfd, sym_pointer->e_type);
1416 cache_ptr->symbol.udata = 0;
1417 translate_from_native_sym_flags (sym_pointer, cache_ptr,
1418 abfd, &state);
1419 }
1420 }
1421
9e2dad8e
JG
1422 obj_aout_symbols (abfd) = cached;
1423 free((PTR)syms);
0f213cc2 1424
9e2dad8e
JG
1425 return true;
1426}
7ed4093a 1427
0f213cc2
KR
1428\f
1429/* Possible improvements:
1430 + look for strings matching trailing substrings of other strings
1431 + better data structures? balanced trees?
1432 + smaller per-string or per-symbol data? re-use some of the symbol's
1433 data fields?
1434 + also look at reducing memory use elsewhere -- maybe if we didn't have to
1435 construct the entire symbol table at once, we could get by with smaller
1436 amounts of VM? (What effect does that have on the string table
1437 reductions?)
1438 + rip this out of here, put it into its own file in bfd or libiberty, so
1439 coff and elf can use it too. I'll work on this soon, but have more
1440 pressing tasks right now.
1441
1442 A hash table might(?) be more efficient for handling exactly the cases that
1443 are handled now, but for trailing substring matches, I think we want to
1444 examine the `nearest' values (reverse-)lexically, not merely impose a strict
1445 order, nor look only for exact-match or not-match. I don't think a hash
1446 table would be very useful for that, and I don't feel like fleshing out two
1447 completely different implementations. [raeburn:930419.0331EDT] */
1448
1449#if __GNUC__ >= 2
1450#define INLINE __inline__
1451#else
1452#define INLINE
1453#endif
1454
1455struct stringtab_entry {
1456 /* Hash value for this string. Only useful so long as we aren't doing
1457 substring matches. */
3caa6924 1458 unsigned int hash;
0f213cc2
KR
1459
1460 /* Next node to look at, depending on whether the hash value of the string
1461 being searched for is less than or greater than the hash value of the
1462 current node. For now, `equal to' is lumped in with `greater than', for
1463 space efficiency. It's not a common enough case to warrant another field
1464 to be used for all nodes. */
1465 struct stringtab_entry *less;
1466 struct stringtab_entry *greater;
1467
1468 /* The string itself. */
1469 CONST char *string;
1470
1471 /* The index allocated for this string. */
1472 bfd_size_type index;
1473
1474#ifdef GATHER_STATISTICS
1475 /* How many references have there been to this string? (Not currently used;
1476 could be dumped out for anaylsis, if anyone's interested.) */
1477 unsigned long count;
1478#endif
1479
1480 /* Next node in linked list, in suggested output order. */
1481 struct stringtab_entry *next_to_output;
1482};
1483
1484struct stringtab_data {
1485 /* Tree of string table entries. */
1486 struct stringtab_entry *strings;
1487
1488 /* Fudge factor used to center top node of tree. */
1489 int hash_zero;
1490
1491 /* Next index value to issue. */
1492 bfd_size_type index;
1493
1494 /* Index used for empty strings. Cached here because checking for them
1495 is really easy, and we can avoid searching the tree. */
1496 bfd_size_type empty_string_index;
1497
1498 /* These fields indicate the two ends of a singly-linked list that indicates
1499 the order strings should be written out in. Use this order, and no
1500 seeking will need to be done, so output efficiency should be maximized. */
1501 struct stringtab_entry **end;
1502 struct stringtab_entry *output_order;
1503
1504#ifdef GATHER_STATISTICS
1505 /* Number of strings which duplicate strings already in the table. */
1506 unsigned long duplicates;
1507
1508 /* Number of bytes saved by not having to write all the duplicate strings. */
1509 unsigned long bytes_saved;
1510
1511 /* Number of zero-length strings. Currently, these all turn into
1512 references to the null byte at the end of the first string. In some
1513 cases (possibly not all? explore this...), it should be possible to
1514 simply write out a zero index value. */
1515 unsigned long empty_strings;
1516
1517 /* Number of times the hash values matched but the strings were different.
1518 Note that this includes the number of times the other string(s) occurs, so
1519 there may only be two strings hashing to the same value, even if this
1520 number is very large. */
1521 unsigned long bad_hash_matches;
1522
1523 /* Null strings aren't counted in this one.
1524 This will probably only be nonzero if we've got an input file
1525 which was produced by `ld -r' (i.e., it's already been processed
1526 through this code). Under some operating systems, native tools
1527 may make all empty strings have the same index; but the pointer
1528 check won't catch those, because to get to that stage we'd already
1529 have to compute the checksum, which requires reading the string,
1530 so we short-circuit that case with empty_string_index above. */
1531 unsigned long pointer_matches;
1532
1533 /* Number of comparisons done. I figure with the algorithms in use below,
1534 the average number of comparisons done (per symbol) should be roughly
1535 log-base-2 of the number of unique strings. */
1536 unsigned long n_compares;
1537#endif
1538};
1539
1540/* Some utility functions for the string table code. */
1541
3caa6924
DM
1542/* For speed, only hash on the first this many bytes of strings.
1543 This number was chosen by profiling ld linking itself, with -g. */
1544#define HASHMAXLEN 25
1545
1546#define HASH_CHAR(c) (sum ^= sum >> 20, sum ^= sum << 7, sum += (c))
1547
1548static INLINE unsigned int
1549hash (string, len)
1550 unsigned char *string;
1551 register unsigned int len;
0f213cc2 1552{
3caa6924
DM
1553 register unsigned int sum = 0;
1554
1555 if (len > HASHMAXLEN)
0f213cc2 1556 {
3caa6924
DM
1557 HASH_CHAR (len);
1558 len = HASHMAXLEN;
1559 }
1560
1561 while (len--)
1562 {
1563 HASH_CHAR (*string++);
0f213cc2
KR
1564 }
1565 return sum;
1566}
1567
1568static INLINE void
1569stringtab_init (tab)
1570 struct stringtab_data *tab;
1571{
1572 tab->strings = 0;
1573 tab->output_order = 0;
1574 tab->end = &tab->output_order;
1575
1576 /* Initial string table length includes size of length field. */
1577 tab->index = BYTES_IN_WORD;
1578 tab->empty_string_index = -1;
1579#ifdef GATHER_STATISTICS
1580 tab->duplicates = 0;
1581 tab->empty_strings = 0;
1582 tab->bad_hash_matches = 0;
1583 tab->pointer_matches = 0;
1584 tab->bytes_saved = 0;
1585 tab->n_compares = 0;
1586#endif
1587}
1588
1589static INLINE int
1590compare (entry, str, hash)
1591 struct stringtab_entry *entry;
1592 CONST char *str;
3caa6924 1593 unsigned int hash;
0f213cc2 1594{
3caa6924 1595 return hash - entry->hash;
0f213cc2
KR
1596}
1597
1598#ifdef GATHER_STATISTICS
1599/* Don't want to have to link in math library with all bfd applications... */
1600static INLINE double
1601log2 (num)
1602 int num;
1603{
1604 double d = num;
1605#if defined (__i386__) && __GNUC__ >= 2
1606 asm ("fyl2x" : "=t" (d) : "0" (d), "u" (1.0));
1607 return d;
1608#else
1609 int n = 0;
1610 while (d >= 2.0)
1611 n++, d /= 2.0;
1612 return ((d > 1.41) ? 0.5 : 0) + n;
1613#endif
1614}
1615#endif
1616
1617/* Main string table routines. */
1618/* Returns index in string table. Whether or not this actually adds an
1619 entry into the string table should be irrelevant -- it just has to
1620 return a valid index. */
1621static bfd_size_type
1622add_to_stringtab (abfd, str, tab, check)
1623 bfd *abfd;
1624 CONST char *str;
1625 struct stringtab_data *tab;
1626 int check;
1627{
1628 struct stringtab_entry **ep;
3caa6924
DM
1629 register struct stringtab_entry *entry;
1630 unsigned int hashval, len;
0f213cc2
KR
1631
1632 if (str[0] == 0)
1633 {
1634 bfd_size_type index;
1635 CONST bfd_size_type minus_one = -1;
1636
1637#ifdef GATHER_STATISTICS
1638 tab->empty_strings++;
1639#endif
1640 index = tab->empty_string_index;
1641 if (index != minus_one)
1642 {
1643 got_empty:
1644#ifdef GATHER_STATISTICS
1645 tab->bytes_saved++;
1646 tab->duplicates++;
1647#endif
1648 return index;
1649 }
1650
1651 /* Need to find it. */
1652 entry = tab->strings;
1653 if (entry)
1654 {
1655 index = entry->index + strlen (entry->string);
1656 tab->empty_string_index = index;
1657 goto got_empty;
1658 }
1659 len = 0;
1660 }
1661 else
1662 len = strlen (str);
1663
1664 /* The hash_zero value is chosen such that the first symbol gets a value of
1665 zero. With a balanced tree, this wouldn't be very useful, but without it,
1666 we might get a more even split at the top level, instead of skewing it
1667 badly should hash("/usr/lib/crt0.o") (or whatever) be far from zero. */
3caa6924 1668 hashval = hash (str, len) ^ tab->hash_zero;
0f213cc2
KR
1669 ep = &tab->strings;
1670 if (!*ep)
1671 {
1672 tab->hash_zero = hashval;
1673 hashval = 0;
1674 goto add_it;
1675 }
1676
1677 while (*ep)
1678 {
3caa6924
DM
1679 register int cmp;
1680
0f213cc2
KR
1681 entry = *ep;
1682#ifdef GATHER_STATISTICS
1683 tab->n_compares++;
1684#endif
1685 cmp = compare (entry, str, hashval);
3caa6924
DM
1686 /* The not-equal cases are more frequent, so check them first. */
1687 if (cmp > 0)
1688 ep = &entry->greater;
1689 else if (cmp < 0)
1690 ep = &entry->less;
1691 else
0f213cc2
KR
1692 {
1693 if (entry->string == str)
1694 {
1695#ifdef GATHER_STATISTICS
1696 tab->pointer_matches++;
1697#endif
1698 goto match;
1699 }
3caa6924
DM
1700 /* Compare the first bytes to save a function call if they
1701 don't match. */
1702 if (entry->string[0] == str[0] && !strcmp (entry->string, str))
0f213cc2
KR
1703 {
1704 match:
1705#ifdef GATHER_STATISTICS
1706 entry->count++;
1707 tab->bytes_saved += len + 1;
1708 tab->duplicates++;
1709#endif
1710 /* If we're in the linker, and the new string is from a new
1711 input file which might have already had these reductions
1712 run over it, we want to keep the new string pointer. I
1713 don't think we're likely to see any (or nearly as many,
1714 at least) cases where a later string is in the same location
1715 as an earlier one rather than this one. */
1716 entry->string = str;
1717 return entry->index;
1718 }
1719#ifdef GATHER_STATISTICS
1720 tab->bad_hash_matches++;
1721#endif
1722 ep = &entry->greater;
1723 }
0f213cc2
KR
1724 }
1725
1726 /* If we get here, nothing that's in the table already matched.
1727 EP points to the `next' field at the end of the chain; stick a
1728 new entry on here. */
1729 add_it:
3caa6924
DM
1730 entry = (struct stringtab_entry *)
1731 bfd_alloc_by_size_t (abfd, sizeof (struct stringtab_entry));
0f213cc2
KR
1732
1733 entry->less = entry->greater = 0;
1734 entry->hash = hashval;
1735 entry->index = tab->index;
1736 entry->string = str;
1737 entry->next_to_output = 0;
1738#ifdef GATHER_STATISTICS
1739 entry->count = 1;
1740#endif
1741
1742 assert (*tab->end == 0);
1743 *(tab->end) = entry;
1744 tab->end = &entry->next_to_output;
1745 assert (*tab->end == 0);
1746
1747 {
1748 tab->index += len + 1;
1749 if (len == 0)
1750 tab->empty_string_index = entry->index;
1751 }
1752 assert (*ep == 0);
1753 *ep = entry;
1754 return entry->index;
1755}
1756
1757static void
1758emit_strtab (abfd, tab)
1759 bfd *abfd;
1760 struct stringtab_data *tab;
1761{
1762 struct stringtab_entry *entry;
1763#ifdef GATHER_STATISTICS
1764 int count = 0;
1765#endif
1766
1767 /* Be sure to put string length into correct byte ordering before writing
1768 it out. */
1769 char buffer[BYTES_IN_WORD];
1770
1771 PUT_WORD (abfd, tab->index, (unsigned char *) buffer);
1772 bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd);
1773
1774 for (entry = tab->output_order; entry; entry = entry->next_to_output)
1775 {
1776 bfd_write ((PTR) entry->string, 1, strlen (entry->string) + 1, abfd);
1777#ifdef GATHER_STATISTICS
1778 count++;
1779#endif
1780 }
1781
1782#ifdef GATHER_STATISTICS
1783 /* Short form only, for now.
1784 To do: Specify output file. Conditionalize on environment? Detailed
1785 analysis if desired. */
1786 {
1787 int n_syms = bfd_get_symcount (abfd);
1788
1789 fprintf (stderr, "String table data for output file:\n");
1790 fprintf (stderr, " %8d symbols output\n", n_syms);
1791 fprintf (stderr, " %8d duplicate strings\n", tab->duplicates);
1792 fprintf (stderr, " %8d empty strings\n", tab->empty_strings);
1793 fprintf (stderr, " %8d unique strings output\n", count);
1794 fprintf (stderr, " %8d pointer matches\n", tab->pointer_matches);
1795 fprintf (stderr, " %8d bytes saved\n", tab->bytes_saved);
1796 fprintf (stderr, " %8d bad hash matches\n", tab->bad_hash_matches);
1797 fprintf (stderr, " %8d hash-val comparisons\n", tab->n_compares);
1798 if (n_syms)
1799 {
1800 double n_compares = tab->n_compares;
1801 double avg_compares = n_compares / n_syms;
1802 /* The second value here should usually be near one. */
3caa6924
DM
1803 fprintf (stderr,
1804 "\t average %f comparisons per symbol (%f * log2 nstrings)\n",
0f213cc2
KR
1805 avg_compares, avg_compares / log2 (count));
1806 }
1807 }
1808#endif
1809
1810/* Old code:
1811 unsigned int count;
1812 generic = bfd_get_outsymbols(abfd);
1813 for (count = 0; count < bfd_get_symcount(abfd); count++)
1814 {
1815 asymbol *g = *(generic++);
1816
1817 if (g->name)
1818 {
1819 size_t length = strlen(g->name)+1;
1820 bfd_write((PTR)g->name, 1, length, abfd);
1821 }
1822 g->KEEPIT = (KEEPITTYPE) count;
1823 } */
1824}
7ed4093a
SC
1825
1826void
1827DEFUN(NAME(aout,write_syms),(abfd),
1828 bfd *abfd)
0f213cc2
KR
1829{
1830 unsigned int count ;
1831 asymbol **generic = bfd_get_outsymbols (abfd);
1832 struct stringtab_data strtab;
1833
1834 stringtab_init (&strtab);
1835
1836 for (count = 0; count < bfd_get_symcount (abfd); count++)
1837 {
7ed4093a
SC
1838 asymbol *g = generic[count];
1839 struct external_nlist nsp;
6db82ea7 1840
0f213cc2
KR
1841 if (g->name)
1842 PUT_WORD (abfd, add_to_stringtab (abfd, g->name, &strtab),
1843 (unsigned char *) nsp.e_strx);
1844 else
1845 PUT_WORD (abfd, 0, (unsigned char *)nsp.e_strx);
6db82ea7 1846
0f213cc2
KR
1847 if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
1848 {
1849 bfd_h_put_16(abfd, aout_symbol(g)->desc, nsp.e_desc);
1850 bfd_h_put_8(abfd, aout_symbol(g)->other, nsp.e_other);
1851 bfd_h_put_8(abfd, aout_symbol(g)->type, nsp.e_type);
1852 }
7ed4093a 1853 else
0f213cc2
KR
1854 {
1855 bfd_h_put_16(abfd,0, nsp.e_desc);
1856 bfd_h_put_8(abfd, 0, nsp.e_other);
1857 bfd_h_put_8(abfd, 0, nsp.e_type);
1858 }
7b02b4ed 1859
7d003262 1860 translate_to_native_sym_flags (&nsp, g, abfd);
7b02b4ed
JG
1861
1862 bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd);
7ed4093a 1863
0f213cc2
KR
1864 /* NB: `KEEPIT' currently overlays `flags', so set this only
1865 here, at the end. */
1866 g->KEEPIT = count;
1867 }
7ed4093a 1868
0f213cc2
KR
1869 emit_strtab (abfd, &strtab);
1870}
7ed4093a 1871
0f213cc2 1872\f
7ed4093a
SC
1873unsigned int
1874DEFUN(NAME(aout,get_symtab),(abfd, location),
1875 bfd *abfd AND
1876 asymbol **location)
3f7607af 1877{
7ed4093a
SC
1878 unsigned int counter = 0;
1879 aout_symbol_type *symbase;
ce07dd7c 1880
7ed4093a 1881 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
ce07dd7c 1882
7ed4093a
SC
1883 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1884 *(location++) = (asymbol *)( symbase++);
1885 *location++ =0;
ce07dd7c 1886 return bfd_get_symcount (abfd);
3f7607af 1887}
7ed4093a
SC
1888
1889\f
1890/* Standard reloc stuff */
1891/* Output standard relocation information to a file in target byte order. */
1892
1893void
1894DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1895 bfd *abfd AND
1896 arelent *g AND
1897 struct reloc_std_external *natptr)
3f7607af 1898{
6db82ea7
SC
1899 int r_index;
1900 asymbol *sym = *(g->sym_ptr_ptr);
1901 int r_extern;
1902 unsigned int r_length;
1903 int r_pcrel;
1904 int r_baserel, r_jmptable, r_relative;
1905 unsigned int r_addend;
1906 asection *output_section = sym->section->output_section;
ce07dd7c 1907
6db82ea7 1908 PUT_WORD(abfd, g->address, natptr->r_address);
ce07dd7c 1909
6db82ea7
SC
1910 r_length = g->howto->size ; /* Size as a power of two */
1911 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
1912 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
1913 r_baserel = 0;
1914 r_jmptable = 0;
1915 r_relative = 0;
7ed4093a 1916
6db82ea7 1917 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
7ed4093a 1918
6db82ea7
SC
1919 /* name was clobbered by aout_write_syms to be symbol index */
1920
2768b3f7
SC
1921 /* If this relocation is relative to a symbol then set the
1922 r_index to the symbols index, and the r_extern bit.
1923
1924 Absolute symbols can come in in two ways, either as an offset
1925 from the abs section, or as a symbol which has an abs value.
1926 check for that here
1927 */
1928
1929
382f2a3d 1930 if (bfd_is_com_section (output_section)
ce07dd7c
KR
1931 || output_section == &bfd_abs_section
1932 || output_section == &bfd_und_section)
1933 {
2768b3f7
SC
1934 if (bfd_abs_section.symbol == sym)
1935 {
1936 /* Whoops, looked like an abs symbol, but is really an offset
1937 from the abs section */
1938 r_index = 0;
1939 r_extern = 0;
1940 }
1941 else
1942 {
1943 /* Fill in symbol */
1944 r_extern = 1;
1945 r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
1946
1947 }
ce07dd7c 1948 }
6db82ea7 1949 else
ce07dd7c
KR
1950 {
1951 /* Just an ordinary section */
1952 r_extern = 0;
1953 r_index = output_section->target_index;
1954 }
1955
6db82ea7
SC
1956 /* now the fun stuff */
1957 if (abfd->xvec->header_byteorder_big_p != false) {
7ed4093a
SC
1958 natptr->r_index[0] = r_index >> 16;
1959 natptr->r_index[1] = r_index >> 8;
1960 natptr->r_index[2] = r_index;
1961 natptr->r_type[0] =
6db82ea7
SC
1962 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
1963 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
1964 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
1965 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
1966 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
1967 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
7ed4093a 1968 } else {
6db82ea7
SC
1969 natptr->r_index[2] = r_index >> 16;
1970 natptr->r_index[1] = r_index >> 8;
1971 natptr->r_index[0] = r_index;
1972 natptr->r_type[0] =
1973 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
7ed4093a 1974 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
6db82ea7
SC
1975 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
1976 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1977 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1978 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
1979 }
3f7607af 1980}
7ed4093a
SC
1981
1982
1983/* Extended stuff */
1984/* Output extended relocation information to a file in target byte order. */
1985
1986void
1987DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
1988 bfd *abfd AND
1989 arelent *g AND
1990 register struct reloc_ext_external *natptr)
3f7607af 1991{
6db82ea7
SC
1992 int r_index;
1993 int r_extern;
1994 unsigned int r_type;
1995 unsigned int r_addend;
1996 asymbol *sym = *(g->sym_ptr_ptr);
1997 asection *output_section = sym->section->output_section;
1998
1999 PUT_WORD (abfd, g->address, natptr->r_address);
7ed4093a 2000
6db82ea7 2001 r_type = (unsigned int) g->howto->type;
7ed4093a 2002
6db82ea7 2003 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
7ed4093a 2004
7ed4093a 2005
2768b3f7
SC
2006 /* If this relocation is relative to a symbol then set the
2007 r_index to the symbols index, and the r_extern bit.
2008
2009 Absolute symbols can come in in two ways, either as an offset
2010 from the abs section, or as a symbol which has an abs value.
2011 check for that here
2012 */
2013
382f2a3d 2014 if (bfd_is_com_section (output_section)
2768b3f7 2015 || output_section == &bfd_abs_section
0f213cc2 2016 || output_section == &bfd_und_section)
6db82ea7 2017 {
2768b3f7
SC
2018 if (bfd_abs_section.symbol == sym)
2019 {
2020 /* Whoops, looked like an abs symbol, but is really an offset
2021 from the abs section */
2022 r_index = 0;
2023 r_extern = 0;
2024 }
2025 else
2026 {
2027 r_extern = 1;
2028 r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
2029 }
6db82ea7
SC
2030 }
2031 else
2032 {
2033 /* Just an ordinary section */
2034 r_extern = 0;
2035 r_index = output_section->target_index;
2036 }
2037
2038
7ed4093a
SC
2039 /* now the fun stuff */
2040 if (abfd->xvec->header_byteorder_big_p != false) {
2768b3f7
SC
2041 natptr->r_index[0] = r_index >> 16;
2042 natptr->r_index[1] = r_index >> 8;
2043 natptr->r_index[2] = r_index;
2044 natptr->r_type[0] =
2045 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
2046 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
2047 } else {
2048 natptr->r_index[2] = r_index >> 16;
2049 natptr->r_index[1] = r_index >> 8;
2050 natptr->r_index[0] = r_index;
2051 natptr->r_type[0] =
2052 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
2053 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
2054 }
7ed4093a
SC
2055
2056 PUT_WORD (abfd, r_addend, natptr->r_addend);
2057}
2058
6db82ea7
SC
2059/* BFD deals internally with all things based from the section they're
2060 in. so, something in 10 bytes into a text section with a base of
2061 50 would have a symbol (.text+10) and know .text vma was 50.
2062
2063 Aout keeps all it's symbols based from zero, so the symbol would
2064 contain 60. This macro subs the base of each section from the value
2065 to give the true offset from the section */
2066
2067
7ed4093a
SC
2068#define MOVE_ADDRESS(ad) \
2069 if (r_extern) { \
6db82ea7
SC
2070 /* undefined symbol */ \
2071 cache_ptr->sym_ptr_ptr = symbols + r_index; \
2072 cache_ptr->addend = ad; \
2073 } else { \
2074 /* defined, section relative. replace symbol with pointer to \
2075 symbol which points to section */ \
7ed4093a
SC
2076 switch (r_index) { \
2077 case N_TEXT: \
2078 case N_TEXT | N_EXT: \
6db82ea7 2079 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
7ed4093a
SC
2080 cache_ptr->addend = ad - su->textsec->vma; \
2081 break; \
2082 case N_DATA: \
2083 case N_DATA | N_EXT: \
6db82ea7 2084 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
7ed4093a
SC
2085 cache_ptr->addend = ad - su->datasec->vma; \
2086 break; \
2087 case N_BSS: \
2088 case N_BSS | N_EXT: \
6db82ea7 2089 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
7ed4093a
SC
2090 cache_ptr->addend = ad - su->bsssec->vma; \
2091 break; \
6db82ea7 2092 default: \
7ed4093a
SC
2093 case N_ABS: \
2094 case N_ABS | N_EXT: \
6db82ea7
SC
2095 cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; \
2096 cache_ptr->addend = ad; \
7ed4093a
SC
2097 break; \
2098 } \
2099 } \
2100
2101void
2102DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
2103 bfd *abfd AND
2104 struct reloc_ext_external *bytes AND
2105 arelent *cache_ptr AND
2106 asymbol **symbols)
2107{
2108 int r_index;
2109 int r_extern;
2110 unsigned int r_type;
6db82ea7 2111 struct aoutdata *su = &(abfd->tdata.aout_data->a);
7ed4093a
SC
2112
2113 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
2114
2115 /* now the fun stuff */
2116 if (abfd->xvec->header_byteorder_big_p != false) {
382f2a3d
ILT
2117 r_index = (bytes->r_index[0] << 16)
2118 | (bytes->r_index[1] << 8)
2119 | bytes->r_index[2];
7ed4093a
SC
2120 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
2121 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2122 >> RELOC_EXT_BITS_TYPE_SH_BIG;
2123 } else {
382f2a3d
ILT
2124 r_index = (bytes->r_index[2] << 16)
2125 | (bytes->r_index[1] << 8)
2126 | bytes->r_index[0];
7ed4093a
SC
2127 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
2128 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2129 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
2130 }
2131
2132 cache_ptr->howto = howto_table_ext + r_type;
6db82ea7 2133 MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
7ed4093a
SC
2134}
2135
2136void
2137DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
2138 bfd *abfd AND
2139 struct reloc_std_external *bytes AND
2140 arelent *cache_ptr AND
2141 asymbol **symbols)
2142{
2143 int r_index;
2144 int r_extern;
2145 unsigned int r_length;
2146 int r_pcrel;
2147 int r_baserel, r_jmptable, r_relative;
6db82ea7 2148 struct aoutdata *su = &(abfd->tdata.aout_data->a);
7ed4093a 2149
34dd8ba3 2150 cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
7ed4093a
SC
2151
2152 /* now the fun stuff */
2153 if (abfd->xvec->header_byteorder_big_p != false) {
382f2a3d
ILT
2154 r_index = (bytes->r_index[0] << 16)
2155 | (bytes->r_index[1] << 8)
2156 | bytes->r_index[2];
7ed4093a
SC
2157 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
2158 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2159 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2160 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2161 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
2162 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
2163 >> RELOC_STD_BITS_LENGTH_SH_BIG;
2164 } else {
382f2a3d
ILT
2165 r_index = (bytes->r_index[2] << 16)
2166 | (bytes->r_index[1] << 8)
2167 | bytes->r_index[0];
7ed4093a
SC
2168 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
2169 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2170 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2171 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2172 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
2173 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
2174 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
2175 }
2176
2177 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
2178 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
2179
2180 MOVE_ADDRESS(0);
2181}
2182
2183/* Reloc hackery */
2184
2185boolean
2186DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
2187 bfd *abfd AND
2188 sec_ptr asect AND
2189 asymbol **symbols)
2190{
2191 unsigned int count;
2192 bfd_size_type reloc_size;
2193 PTR relocs;
2194 arelent *reloc_cache;
2195 size_t each_size;
2196
2197 if (asect->relocation) return true;
2198
2199 if (asect->flags & SEC_CONSTRUCTOR) return true;
2200
2201 if (asect == obj_datasec (abfd)) {
2202 reloc_size = exec_hdr(abfd)->a_drsize;
2203 goto doit;
2204 }
2205
2206 if (asect == obj_textsec (abfd)) {
2207 reloc_size = exec_hdr(abfd)->a_trsize;
2208 goto doit;
2209 }
2210
2211 bfd_error = invalid_operation;
2212 return false;
2213
2214 doit:
2215 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
2216 each_size = obj_reloc_entry_size (abfd);
2217
2218 count = reloc_size / each_size;
2219
2220
2221 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
2222 (arelent)));
2223 if (!reloc_cache) {
2224nomem:
2225 bfd_error = no_memory;
2226 return false;
2227 }
2228
2229 relocs = (PTR) bfd_alloc (abfd, reloc_size);
2230 if (!relocs) {
2231 bfd_release (abfd, reloc_cache);
2232 goto nomem;
2233 }
2234
2235 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
2236 bfd_release (abfd, relocs);
2237 bfd_release (abfd, reloc_cache);
2238 bfd_error = system_call_error;
2239 return false;
2240 }
2241
2242 if (each_size == RELOC_EXT_SIZE) {
2243 register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
2244 unsigned int counter = 0;
2245 arelent *cache_ptr = reloc_cache;
2246
2247 for (; counter < count; counter++, rptr++, cache_ptr++) {
2248 NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
2249 }
2250 } else {
2251 register struct reloc_std_external *rptr = (struct reloc_std_external*) relocs;
2252 unsigned int counter = 0;
2253 arelent *cache_ptr = reloc_cache;
2254
2255 for (; counter < count; counter++, rptr++, cache_ptr++) {
2256 NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
2257 }
2258
2259 }
2260
2261 bfd_release (abfd,relocs);
2262 asect->relocation = reloc_cache;
2263 asect->reloc_count = count;
2264 return true;
2265}
2266
2267
2268
2269/* Write out a relocation section into an object file. */
2270
2271boolean
2272DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
2273 bfd *abfd AND
2274 asection *section)
2275{
2276 arelent **generic;
2277 unsigned char *native, *natptr;
2278 size_t each_size;
2279
2280 unsigned int count = section->reloc_count;
2281 size_t natsize;
2282
2283 if (count == 0) return true;
2284
2285 each_size = obj_reloc_entry_size (abfd);
2286 natsize = each_size * count;
2287 native = (unsigned char *) bfd_zalloc (abfd, natsize);
2288 if (!native) {
2289 bfd_error = no_memory;
2290 return false;
2291 }
2292
2293 generic = section->orelocation;
2294
2295 if (each_size == RELOC_EXT_SIZE)
2296 {
2297 for (natptr = native;
2298 count != 0;
2299 --count, natptr += each_size, ++generic)
2300 NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
2301 }
2302 else
2303 {
2304 for (natptr = native;
2305 count != 0;
2306 --count, natptr += each_size, ++generic)
2307 NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
2308 }
2309
2310 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
2311 bfd_release(abfd, native);
2312 return false;
2313 }
2314 bfd_release (abfd, native);
2315
2316 return true;
2317}
2318
2319/* This is stupid. This function should be a boolean predicate */
2320unsigned int
2321DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
2322 bfd *abfd AND
2323 sec_ptr section AND
2324 arelent **relptr AND
2325 asymbol **symbols)
2326{
2327 arelent *tblptr = section->relocation;
2328 unsigned int count;
2329
2330 if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
2331 return 0;
2332
2333 if (section->flags & SEC_CONSTRUCTOR) {
2334 arelent_chain *chain = section->constructor_chain;
2335 for (count = 0; count < section->reloc_count; count ++) {
2336 *relptr ++ = &chain->relent;
2337 chain = chain->next;
2338 }
2339 }
2340 else {
2341 tblptr = section->relocation;
2342 if (!tblptr) return 0;
2343
2344 for (count = 0; count++ < section->reloc_count;)
2345 {
2346 *relptr++ = tblptr++;
2347 }
2348 }
2349 *relptr = 0;
2350
2351 return section->reloc_count;
2352}
2353
2354unsigned int
2355DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
2356 bfd *abfd AND
2357 sec_ptr asect)
2358{
2359 if (bfd_get_format (abfd) != bfd_object) {
2360 bfd_error = invalid_operation;
2361 return 0;
2362 }
2363 if (asect->flags & SEC_CONSTRUCTOR) {
2364 return (sizeof (arelent *) * (asect->reloc_count+1));
2365 }
2366
2367
2368 if (asect == obj_datasec (abfd))
2369 return (sizeof (arelent *) *
2370 ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
2371 +1));
2372
2373 if (asect == obj_textsec (abfd))
2374 return (sizeof (arelent *) *
2375 ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
2376 +1));
2377
2378 bfd_error = invalid_operation;
2379 return 0;
2380}
2381
2382\f
2383 unsigned int
2384DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
2385 bfd *abfd)
2386{
2387 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
2388
2389 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2390}
2391 alent *
2392DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
2393 bfd *ignore_abfd AND
2394 asymbol *ignore_symbol)
2395{
2396return (alent *)NULL;
2397}
2398
34dd8ba3
JG
2399void
2400DEFUN(NAME(aout,get_symbol_info),(ignore_abfd, symbol, ret),
2401 bfd *ignore_abfd AND
2402 asymbol *symbol AND
2403 symbol_info *ret)
2404{
2405 bfd_symbol_info (symbol, ret);
2406
2407 if (ret->type == '?')
2408 {
2409 int type_code = aout_symbol(symbol)->type & 0xff;
2410 CONST char *stab_name = aout_stab_name(type_code);
2411 static char buf[10];
2412
2413 if (stab_name == NULL)
2414 {
2415 sprintf(buf, "(%d)", type_code);
2416 stab_name = buf;
2417 }
2418 ret->type = '-';
2419 ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff);
2420 ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff);
2421 ret->stab_name = stab_name;
2422 }
2423}
7ed4093a
SC
2424
2425void
2426DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
2427 bfd *ignore_abfd AND
2428 PTR afile AND
2429 asymbol *symbol AND
9e2dad8e 2430 bfd_print_symbol_type how)
7ed4093a
SC
2431{
2432 FILE *file = (FILE *)afile;
2433
2434 switch (how) {
9e2dad8e 2435 case bfd_print_symbol_name:
fb3be09b
JG
2436 if (symbol->name)
2437 fprintf(file,"%s", symbol->name);
7ed4093a 2438 break;
9e2dad8e 2439 case bfd_print_symbol_more:
7ed4093a
SC
2440 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
2441 (unsigned)(aout_symbol(symbol)->other & 0xff),
2442 (unsigned)(aout_symbol(symbol)->type));
2443 break;
9e2dad8e 2444 case bfd_print_symbol_all:
7ed4093a 2445 {
6db82ea7
SC
2446 CONST char *section_name = symbol->section->name;
2447
7ed4093a
SC
2448
2449 bfd_print_symbol_vandf((PTR)file,symbol);
2450
fb3be09b 2451 fprintf(file," %-5s %04x %02x %02x",
7ed4093a
SC
2452 section_name,
2453 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
2454 (unsigned)(aout_symbol(symbol)->other & 0xff),
9e2dad8e 2455 (unsigned)(aout_symbol(symbol)->type & 0xff));
fb3be09b
JG
2456 if (symbol->name)
2457 fprintf(file," %s", symbol->name);
7ed4093a
SC
2458 }
2459 break;
2460 }
2461}
2462
2463/*
6724ff46 2464 provided a BFD, a section and an offset into the section, calculate
7ed4093a
SC
2465 and return the name of the source file and the line nearest to the
2466 wanted location.
2467*/
2468
2469boolean
2470DEFUN(NAME(aout,find_nearest_line),(abfd,
2471 section,
2472 symbols,
2473 offset,
2474 filename_ptr,
2475 functionname_ptr,
2476 line_ptr),
2477 bfd *abfd AND
2478 asection *section AND
2479 asymbol **symbols AND
2480 bfd_vma offset AND
2481 CONST char **filename_ptr AND
2482 CONST char **functionname_ptr AND
2483 unsigned int *line_ptr)
2484{
2485 /* Run down the file looking for the filename, function and linenumber */
2486 asymbol **p;
2487 static char buffer[100];
98d43107 2488 static char filename_buffer[200];
6db82ea7
SC
2489 CONST char *directory_name = NULL;
2490 CONST char *main_file_name = NULL;
2491 CONST char *current_file_name = NULL;
2492 CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */
7ed4093a
SC
2493 bfd_vma high_line_vma = ~0;
2494 bfd_vma low_func_vma = 0;
2495 asymbol *func = 0;
2496 *filename_ptr = abfd->filename;
2497 *functionname_ptr = 0;
2498 *line_ptr = 0;
2499 if (symbols != (asymbol **)NULL) {
2500 for (p = symbols; *p; p++) {
2501 aout_symbol_type *q = (aout_symbol_type *)(*p);
98d43107 2502 next:
7ed4093a
SC
2503 switch (q->type){
2504 case N_SO:
3f7607af 2505 main_file_name = current_file_name = q->symbol.name;
98d43107
JG
2506 /* Look ahead to next symbol to check if that too is an N_SO. */
2507 p++;
2508 if (*p == NULL)
2509 break;
2510 q = (aout_symbol_type *)(*p);
6db82ea7 2511 if (q->type != (int)N_SO)
98d43107
JG
2512 goto next;
2513
2514 /* Found a second N_SO First is directory; second is filename. */
3f7607af
PB
2515 directory_name = current_file_name;
2516 main_file_name = current_file_name = q->symbol.name;
2517 if (obj_textsec(abfd) != section)
2518 goto done;
2519 break;
2520 case N_SOL:
2521 current_file_name = q->symbol.name;
7ed4093a 2522 break;
3f7607af 2523
7ed4093a
SC
2524 case N_SLINE:
2525
2526 case N_DSLINE:
2527 case N_BSLINE:
2528 /* We'll keep this if it resolves nearer than the one we have already */
2529 if (q->symbol.value >= offset &&
2530 q->symbol.value < high_line_vma) {
2531 *line_ptr = q->desc;
2532 high_line_vma = q->symbol.value;
3f7607af 2533 line_file_name = current_file_name;
7ed4093a
SC
2534 }
2535 break;
2536 case N_FUN:
2537 {
2538 /* We'll keep this if it is nearer than the one we have already */
2539 if (q->symbol.value >= low_func_vma &&
2540 q->symbol.value <= offset) {
2541 low_func_vma = q->symbol.value;
2542 func = (asymbol *)q;
2543 }
2544 if (*line_ptr && func) {
2545 CONST char *function = func->name;
2546 char *p;
2547 strncpy(buffer, function, sizeof(buffer)-1);
2548 buffer[sizeof(buffer)-1] = 0;
2549 /* Have to remove : stuff */
2550 p = strchr(buffer,':');
7b02b4ed 2551 if (p != NULL) { *p = '\0'; }
7ed4093a 2552 *functionname_ptr = buffer;
3f7607af 2553 goto done;
7ed4093a
SC
2554
2555 }
2556 }
2557 break;
2558 }
2559 }
2560 }
3f7607af
PB
2561
2562 done:
2563 if (*line_ptr)
2564 main_file_name = line_file_name;
2565 if (main_file_name) {
2566 if (main_file_name[0] == '/' || directory_name == NULL)
2567 *filename_ptr = main_file_name;
2568 else {
2569 sprintf(filename_buffer, "%.140s%.50s",
2570 directory_name, main_file_name);
2571 *filename_ptr = filename_buffer;
2572 }
2573 }
7ed4093a
SC
2574 return true;
2575
2576}
2577
2578int
cbdc7909
JG
2579DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
2580 bfd *abfd AND
9e2dad8e 2581 boolean execable)
7ed4093a 2582{
6db82ea7 2583 return adata(abfd).exec_bytes_size;
7ed4093a 2584}
This page took 0.189256 seconds and 4 git commands to generate.