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