doc cleanup
[deliverable/binutils-gdb.git] / bfd / aoutx.h
1 /* BFD semi-generic back-end for a.out binaries.
2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3 Written by Cygnus Support.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 /*
22 SECTION
23 a.out backends
24
25
26 DESCRIPTION
27
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.
32
33 The support is split into a basic support file @file{aoutx.h}
34 and other files which derive functions from the base. One
35 derivation file is @file{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.
39
40 This information is further split out into more specific files
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
43 demonstration of a 64 bit a.out format.
44
45 The base file @file{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 @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.
50
51 As an example, this is what goes on to make the back end for a
52 sun4, from @file{aout32.c}:
53
54 | #define ARCH_SIZE 32
55 | #include "aoutx.h"
56
57 Which exports names:
58
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 | ...
65
66 from @file{sunos.c}:
67
68 | #define ARCH 32
69 | #define TARGET_NAME "a.out-sunos-big"
70 | #define VECNAME sunos_big_vec
71 | #include "aoutf1.h"
72
73 requires all the names from @file{aout32.c}, and produces the jump vector
74
75 | sunos_big_vec
76
77 The file @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.
86
87 When porting it to run on a new system, you must supply:
88
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
95
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
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
100 to use <<host-aout.c>., specify:
101
102 | TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
103 | TDEPFILES= host-aout.o trad-core.o
104
105 in the <<config/mt-XXX>> file, and modify @file{configure.in} to use the
106 <<mt-XXX>> file (by setting "<<bfd_target=XXX>>") when your
107 configuration is selected.
108
109 */
110
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
120 #define KEEPIT flags
121 #define KEEPITTYPE int
122
123 #include <assert.h>
124 #include <string.h> /* For strchr and friends */
125 #include "bfd.h"
126 #include <sysdep.h>
127 #include <ansidecl.h>
128
129 struct external_exec;
130 #include "libaout.h"
131 #include "libbfd.h"
132 #include "aout/aout64.h"
133 #include "aout/stab_gnu.h"
134 #include "aout/ar.h"
135
136 extern void (*bfd_error_trap)();
137
138 /*
139 SUBSECTION
140 relocations
141
142 DESCRIPTION
143 The file @file{aoutx.h} provides for both the @emph{standard}
144 and @emph{extended} forms of a.out relocation records.
145
146 The standard records contain 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.
150
151 */
152 #define CTOR_TABLE_RELOC_IDX 2
153
154 #define howto_table_ext NAME(aout,ext_howto_table)
155 #define howto_table_std NAME(aout,std_howto_table)
156
157 reloc_howto_type howto_table_ext[] =
158 {
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),
184 };
185
186 /* Convert standard reloc records to "arelent" format (incl byte swap). */
187
188 reloc_howto_type howto_table_std[] = {
189 /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
190 HOWTO( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false),
191 HOWTO( 1, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false),
192 HOWTO( 2, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false),
193 HOWTO( 3, 0, 4, 64, false, 0, complain_overflow_bitfield,0,"64", true, 0xdeaddead,0xdeaddead, false),
194 HOWTO( 4, 0, 0, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, false),
195 HOWTO( 5, 0, 1, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
196 HOWTO( 6, 0, 2, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, false),
197 HOWTO( 7, 0, 4, 64, true, 0, complain_overflow_signed, 0,"DISP64", true, 0xfeedface,0xfeedface, false),
198 { -1 },
199 HOWTO( 9, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"BASE16", false,0xffffffff,0xffffffff, false),
200 HOWTO(10, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"BASE32", false,0xffffffff,0xffffffff, false),
201 };
202
203 #define TABLE_SIZE(TABLE) (sizeof(TABLE)/sizeof(TABLE[0]))
204
205 CONST struct reloc_howto_struct *
206 DEFUN(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);
227 EXT (BFD_RELOC_SPARC_WDISP22, 7);
228 default: return (CONST struct reloc_howto_struct *) 0;
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);
239 STD (BFD_RELOC_16_BASEREL, 9);
240 STD (BFD_RELOC_32_BASEREL, 10);
241 default: return (CONST struct reloc_howto_struct *) 0;
242 }
243 }
244
245 extern bfd_error_vector_type bfd_error_vector;
246
247 /*
248 SUBSECTION
249 Internal Entry Points
250
251 DESCRIPTION
252 @file{aoutx.h} exports several routines for accessing the
253 contents of an a.out file, which are gathered and exported in
254 turn by various format specific files (eg sunos.c).
255
256 */
257
258 /*
259 FUNCTION
260 aout_@var{size}_swap_exec_header_in
261
262 SYNOPSIS
263 void aout_@var{size}_swap_exec_header_in,
264 (bfd *abfd,
265 struct external_exec *raw_bytes,
266 struct internal_exec *execp);
267
268 DESCRIPTION
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}.
272 */
273
274 #ifndef NAME_swap_exec_header_in
275 void
276 DEFUN(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
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));
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 }
298 #define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in)
299 #endif
300
301 /*
302 FUNCTION
303 aout_@var{size}_swap_exec_header_out
304
305 SYNOPSIS
306 void aout_@var{size}_swap_exec_header_out
307 (bfd *abfd,
308 struct internal_exec *execp,
309 struct external_exec *raw_bytes);
310
311 DESCRIPTION
312 Swap the information in an internal exec header structure
313 @var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
314 */
315 void
316 DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
317 bfd *abfd AND
318 struct internal_exec *execp AND
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
334
335
336 /*
337 FUNCTION
338 aout_@var{size}_some_aout_object_p
339
340 SYNOPSIS
341 bfd_target *aout_@var{size}_some_aout_object_p
342 (bfd *abfd,
343 bfd_target *(*callback_to_real_object_p)());
344
345 DESCRIPTION
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.
351 */
352
353 bfd_target *
354 DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
355 bfd *abfd AND
356 struct internal_exec *execp AND
357 bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *)))
358 {
359 struct aout_data_struct *rawptr, *oldrawptr;
360 bfd_target *result;
361
362 rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
363 if (rawptr == NULL) {
364 bfd_error = no_memory;
365 return 0;
366 }
367
368 oldrawptr = abfd->tdata.aout_data;
369 abfd->tdata.aout_data = rawptr;
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
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;
381
382 /* Set the file flags */
383 abfd->flags = NO_FLAGS;
384 if (execp->a_drsize || execp->a_trsize)
385 abfd->flags |= HAS_RELOC;
386 /* Setting of EXEC_P has been deferred to the bottom of this function */
387 if (execp->a_syms)
388 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
389
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;
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
408 /* The default relocation entry size is that of traditional V7 Unix. */
409 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
410
411 /* The default symbol entry size is that of traditional Unix. */
412 obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
413
414 /* Create the sections. This is raunchy, but bfd_close wants to reclaim
415 them. */
416
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
426
427 obj_datasec (abfd)->_raw_size = execp->a_data;
428 obj_bsssec (abfd)->_raw_size = execp->a_bss;
429
430 obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
431 (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC) :
432 (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
433 obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
434 (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC) :
435 (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
436 obj_bsssec (abfd)->flags = SEC_ALLOC;
437
438 #ifdef THIS_IS_ONLY_DOCUMENTATION
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
441 up of virtual addersses between segments, or the starting file
442 position of the text segment -- all of which varies among different
443 versions of a.out. */
444
445 /* Call back to the format-dependent code to fill in the rest of the
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
451 obj_textsec (abfd)->size = N_TXTSIZE(*execp);
452 obj_textsec (abfd)->raw_size = N_TXTSIZE(*execp);
453 /* data and bss are already filled in since they're so standard */
454
455 /* The virtual memory addresses of the sections */
456 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
457 obj_datasec (abfd)->vma = N_DATADDR(*execp);
458 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
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
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
479 adata(abfd)->page_size = PAGE_SIZE;
480 adata(abfd)->segment_size = SEGMENT_SIZE;
481 adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
482
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.
490
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
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
501 their text starts at zero.)
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) &&
506 (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
507 abfd->flags |= EXEC_P;
508 if (result)
509 {
510 #if 0 /* These should be set correctly anyways. */
511 abfd->sections = obj_textsec (abfd);
512 obj_textsec (abfd)->next = obj_datasec (abfd);
513 obj_datasec (abfd)->next = obj_bsssec (abfd);
514 #endif
515 }
516 else
517 {
518 free (rawptr);
519 abfd->tdata.aout_data = oldrawptr;
520 }
521 return result;
522 }
523
524 /*
525 FUNCTION
526 aout_@var{size}_mkobject
527
528 SYNOPSIS
529 boolean aout_@var{size}_mkobject, (bfd *abfd);
530
531 DESCRIPTION
532 Initialize BFD @var{abfd} for use with a.out files.
533 */
534
535 boolean
536 DEFUN(NAME(aout,mkobject),(abfd),
537 bfd *abfd)
538 {
539 struct aout_data_struct *rawptr;
540
541 bfd_error = system_call_error;
542
543 /* Use an intermediate variable for clarity */
544 rawptr = (struct aout_data_struct *)bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
545
546 if (rawptr == NULL) {
547 bfd_error = no_memory;
548 return false;
549 }
550
551 abfd->tdata.aout_data = rawptr;
552 exec_hdr (abfd) = &(rawptr->e);
553
554 /* For simplicity's sake we just make all the sections right here. */
555
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");
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);
565
566 return true;
567 }
568
569
570 /*
571 FUNCTION
572 aout_@var{size}_machine_type
573
574 SYNOPSIS
575 enum machine_type aout_@var{size}_machine_type
576 (enum bfd_architecture arch,
577 unsigned long machine));
578
579 DESCRIPTION
580 Keep track of machine architecture and machine type for
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.
584
585 If the architecture is understood, machine type 0 (default)
586 is always understood.
587 */
588
589 enum machine_type
590 DEFUN(NAME(aout,machine_type),(arch, machine),
591 enum bfd_architecture arch AND
592 unsigned long machine)
593 {
594 enum machine_type arch_flags;
595
596 arch_flags = M_UNKNOWN;
597
598 switch (arch) {
599 case bfd_arch_sparc:
600 if (machine == 0) arch_flags = M_SPARC;
601 break;
602
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;
612
613 case bfd_arch_i386:
614 if (machine == 0) arch_flags = M_386;
615 break;
616
617 case bfd_arch_a29k:
618 if (machine == 0) arch_flags = M_29K;
619 break;
620
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
633 default:
634 arch_flags = M_UNKNOWN;
635 }
636 return arch_flags;
637 }
638
639
640 /*
641 FUNCTION
642 aout_@var{size}_set_arch_mach
643
644 SYNOPSIS
645 boolean aout_@var{size}_set_arch_mach,
646 (bfd *,
647 enum bfd_architecture arch,
648 unsigned long machine));
649
650 DESCRIPTION
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.
654 */
655
656 boolean
657 DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
658 bfd *abfd AND
659 enum bfd_architecture arch AND
660 unsigned long machine)
661 {
662 if (! bfd_default_set_arch_mach (abfd, arch, machine))
663 return false;
664
665 if (arch != bfd_arch_unknown &&
666 NAME(aout,machine_type) (arch, machine) == M_UNKNOWN)
667 return false; /* We can't represent this type */
668
669 /* Determine the size of a relocation entry */
670 switch (arch) {
671 case bfd_arch_sparc:
672 case bfd_arch_a29k:
673 case bfd_arch_mips:
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
681 return (*aout_backend_info(abfd)->set_sizes) (abfd);
682 }
683
684 boolean
685 DEFUN (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);
689 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
690 {
691 bfd_error = invalid_operation;
692 return false;
693 }
694 if (adata(abfd).magic != undecided_magic) return true;
695 obj_textsec(abfd)->_raw_size =
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)
718 /* Whether or not WP_TEXT is set -- let D_PAGED override. */
719 /* @@ What about QMAGIC? */
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;
751 int pad = 0;
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 {
758 #if 0 /* ?? Does alignment in the file image really matter? */
759 pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma;
760 #endif
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 {
771 #if 0
772 pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
773 #endif
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;
834 if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
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;
847
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 {
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
900 return true;
901 }
902
903 /*
904 FUNCTION
905 aout_@var{size}_new_section_hook
906
907 SYNOPSIS
908 boolean aout_@var{size}_new_section_hook,
909 (bfd *abfd,
910 asection *newsect));
911
912 DESCRIPTION
913 Called by the BFD in response to a @code{bfd_make_section}
914 request.
915 */
916 boolean
917 DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
918 bfd *abfd AND
919 asection *newsect)
920 {
921 /* align to double at least */
922 newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
923
924
925 if (bfd_get_format (abfd) == bfd_object)
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 }
932
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 }
938
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 }
946
947 /* We allow more than three sections internally */
948 return true;
949 }
950
951 boolean
952 DEFUN(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)
958 {
959 file_ptr text_end;
960 bfd_size_type text_size;
961
962 if (abfd->output_has_begun == false)
963 {
964 if (NAME(aout,adjust_sizes_and_vmas) (abfd,
965 &text_size,
966 &text_end) == false)
967 return false;
968 }
969
970 /* regardless, once we know what we're doing, we might as well get going */
971 if (section != obj_bsssec(abfd))
972 {
973 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
974
975 if (count) {
976 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
977 true : false;
978 }
979 return true;
980 }
981 return true;
982 }
983 \f
984 /* Classify stabs symbols */
985
986 #define sym_in_text_section(sym) \
987 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
988
989 #define sym_in_data_section(sym) \
990 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
991
992 #define sym_in_bss_section(sym) \
993 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
994
995 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
996 zero in the "value" field. Nonzeroes there are fortrancommon
997 symbols. */
998 #define sym_is_undefined(sym) \
999 ((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
1000
1001 /* Symbol is a global definition if N_EXT is on and if it has
1002 a nonzero type field. */
1003 #define sym_is_global_defn(sym) \
1004 (((sym)->type & N_EXT) && (sym)->type & N_TYPE)
1005
1006 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
1007 are on. */
1008 #define sym_is_debugger_info(sym) \
1009 (((sym)->type & ~(N_EXT | N_TYPE)) || (sym)->type == N_FN)
1010
1011 #define sym_is_fortrancommon(sym) \
1012 (((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
1013
1014 /* Symbol is absolute if it has N_ABS set */
1015 #define sym_is_absolute(sym) \
1016 (((sym)->type & N_TYPE)== N_ABS)
1017
1018
1019 #define sym_is_indirect(sym) \
1020 (((sym)->type & N_ABS)== N_ABS)
1021
1022 /* Only in their own functions for ease of debugging; when sym flags have
1023 stabilised these should be inlined into their (single) caller */
1024
1025 static void
1026 DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd),
1027 struct external_nlist *sym_pointer AND
1028 aout_symbol_type * cache_ptr AND
1029 bfd * abfd)
1030 {
1031 cache_ptr->symbol.section = 0;
1032 switch (cache_ptr->type & N_TYPE)
1033 {
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))
1054 {
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 }
1074
1075 /* Build a relocation pointing into the constuctor section
1076 pointing at the symbol in the set vector specified */
1077
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;
1081
1082
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. */
1088
1089 section->flags = SEC_CONSTRUCTOR;
1090
1091
1092 section->reloc_count++;
1093 section->alignment_power = 2;
1094
1095 reloc->next = section->constructor_chain;
1096 section->constructor_chain = reloc;
1097 reloc->relent.address = section->_raw_size;
1098 section->_raw_size += sizeof (int *);
1099
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;
1124 break;
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)
1150 {
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;
1155 break;
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
1183 }
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))
1194 {
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;
1216 }
1217
1218 if (sym_is_global_defn (cache_ptr))
1219 {
1220 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1221 }
1222 else
1223 {
1224 cache_ptr->symbol.flags = BSF_LOCAL;
1225 }
1226 }
1227 }
1228 if (cache_ptr->symbol.section == 0)
1229 abort ();
1230 }
1231
1232
1233
1234 static void
1235 DEFUN(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
1242 /* mask out any existing type bits in case copying from one section
1243 to another */
1244 sym_pointer->e_type[0] &= ~N_TYPE;
1245
1246
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;
1254 }
1255 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
1256 sym_pointer->e_type[0] |= N_DATA;
1257 }
1258 else if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
1259 sym_pointer->e_type[0] |= N_BSS;
1260 }
1261 else if (bfd_get_output_section(cache_ptr) == &bfd_und_section)
1262 {
1263 sym_pointer->e_type[0] = (N_UNDF | N_EXT);
1264 }
1265 else if (bfd_get_output_section(cache_ptr) == &bfd_ind_section)
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);
1271 }
1272 else {
1273 if (cache_ptr->section->output_section)
1274 {
1275
1276 bfd_error_vector.nonrepresentable_section(abfd,
1277 bfd_get_output_section(cache_ptr)->name);
1278 }
1279 else
1280 {
1281 bfd_error_vector.nonrepresentable_section(abfd,
1282 cache_ptr->section->name);
1283
1284 }
1285
1286 }
1287 /* Turn the symbol from section relative to absolute again */
1288
1289 value += cache_ptr->section->output_section->vma + cache_ptr->section->output_offset ;
1290
1291
1292 if (cache_ptr->flags & (BSF_WARNING)) {
1293 (sym_pointer+1)->e_type[0] = 1;
1294 }
1295
1296 if (cache_ptr->flags & BSF_DEBUGGING) {
1297 sym_pointer->e_type[0] = ((aout_symbol_type *)cache_ptr)->type;
1298 }
1299 else if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1300 sym_pointer->e_type[0] |= N_EXT;
1301 }
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;
1312 }
1313
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
1320 function exits. We read the strings into a buffer large enough to
1321 hold them all plus all the cached symbol entries. */
1322
1323 asymbol *
1324 DEFUN(NAME(aout,make_empty_symbol),(abfd),
1325 bfd *abfd)
1326 {
1327 aout_symbol_type *new =
1328 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1329 new->symbol.the_bfd = abfd;
1330
1331 return &new->symbol;
1332 }
1333
1334 boolean
1335 DEFUN(NAME(aout,slurp_symbol_table),(abfd),
1336 bfd *abfd)
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;
1344
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;
1348 if (symbol_size == 0)
1349 {
1350 bfd_error = no_symbols;
1351 return false;
1352 }
1353
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);
1358
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 */
1365 syms = (struct external_nlist *) bfd_xmalloc(symbol_size);
1366 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
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
1379 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1380 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size)
1381 {
1382 goto bailout;
1383 }
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;
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;
1394 sym_pointer < sym_end; sym_pointer ++, cache_ptr++)
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;
1410 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1411 }
1412 }
1413
1414 obj_aout_symbols (abfd) = cached;
1415 free((PTR)syms);
1416
1417 return true;
1418 }
1419
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
1441 struct stringtab_entry {
1442 /* Hash value for this string. Only useful so long as we aren't doing
1443 substring matches. */
1444 unsigned int hash;
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
1470 struct 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
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
1534 static INLINE unsigned int
1535 hash (string, len)
1536 unsigned char *string;
1537 register unsigned int len;
1538 {
1539 register unsigned int sum = 0;
1540
1541 if (len > HASHMAXLEN)
1542 {
1543 HASH_CHAR (len);
1544 len = HASHMAXLEN;
1545 }
1546
1547 while (len--)
1548 {
1549 HASH_CHAR (*string++);
1550 }
1551 return sum;
1552 }
1553
1554 static INLINE void
1555 stringtab_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
1575 static INLINE int
1576 compare (entry, str, hash)
1577 struct stringtab_entry *entry;
1578 CONST char *str;
1579 unsigned int hash;
1580 {
1581 return hash - entry->hash;
1582 }
1583
1584 #ifdef GATHER_STATISTICS
1585 /* Don't want to have to link in math library with all bfd applications... */
1586 static INLINE double
1587 log2 (num)
1588 int num;
1589 {
1590 double d = num;
1591 int n = 0;
1592 while (d >= 2.0)
1593 n++, d /= 2.0;
1594 return ((d > 1.41) ? 0.5 : 0) + n;
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. */
1602 static bfd_size_type
1603 add_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;
1610 register struct stringtab_entry *entry;
1611 unsigned int hashval, len;
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. */
1649 hashval = hash (str, len) ^ tab->hash_zero;
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 {
1660 register int cmp;
1661
1662 entry = *ep;
1663 #ifdef GATHER_STATISTICS
1664 tab->n_compares++;
1665 #endif
1666 cmp = compare (entry, str, hashval);
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
1673 {
1674 if (entry->string == str)
1675 {
1676 #ifdef GATHER_STATISTICS
1677 tab->pointer_matches++;
1678 #endif
1679 goto match;
1680 }
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))
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 }
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:
1711 entry = (struct stringtab_entry *)
1712 bfd_alloc_by_size_t (abfd, sizeof (struct stringtab_entry));
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
1738 static void
1739 emit_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. */
1784 fprintf (stderr,
1785 "\t average %f comparisons per symbol (%f * log2 nstrings)\n",
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 }
1806
1807 void
1808 DEFUN(NAME(aout,write_syms),(abfd),
1809 bfd *abfd)
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 {
1819 asymbol *g = generic[count];
1820 struct external_nlist nsp;
1821
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);
1827
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 }
1834 else
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 }
1840
1841 translate_to_native_sym_flags (&nsp, g, abfd);
1842
1843 bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd);
1844
1845 /* NB: `KEEPIT' currently overlays `flags', so set this only
1846 here, at the end. */
1847 g->KEEPIT = count;
1848 }
1849
1850 emit_strtab (abfd, &strtab);
1851 }
1852
1853 \f
1854 unsigned int
1855 DEFUN(NAME(aout,get_symtab),(abfd, location),
1856 bfd *abfd AND
1857 asymbol **location)
1858 {
1859 unsigned int counter = 0;
1860 aout_symbol_type *symbase;
1861
1862 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1863
1864 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1865 *(location++) = (asymbol *)( symbase++);
1866 *location++ =0;
1867 return bfd_get_symcount (abfd);
1868 }
1869
1870 \f
1871 /* Standard reloc stuff */
1872 /* Output standard relocation information to a file in target byte order. */
1873
1874 void
1875 DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1876 bfd *abfd AND
1877 arelent *g AND
1878 struct reloc_std_external *natptr)
1879 {
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;
1888
1889 PUT_WORD(abfd, g->address, natptr->r_address);
1890
1891 r_length = g->howto->size ; /* Size as a power of two */
1892 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
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 */
1896 r_jmptable = 0;
1897 r_relative = 0;
1898
1899 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1900
1901 /* name was clobbered by aout_write_syms to be symbol index */
1902
1903 /* If this relocation is relative to a symbol then set the
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 */
1910
1911
1912 if (bfd_is_com_section (output_section)
1913 || output_section == &bfd_abs_section
1914 || output_section == &bfd_und_section)
1915 {
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 }
1923 else
1924 {
1925 /* Fill in symbol */
1926 r_extern = 1;
1927 r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
1928
1929 }
1930 }
1931 else
1932 {
1933 /* Just an ordinary section */
1934 r_extern = 0;
1935 r_index = output_section->target_index;
1936 }
1937
1938 /* now the fun stuff */
1939 if (abfd->xvec->header_byteorder_big_p != false) {
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] =
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);
1950 } else {
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)
1956 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
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 }
1962 }
1963
1964
1965 /* Extended stuff */
1966 /* Output extended relocation information to a file in target byte order. */
1967
1968 void
1969 DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
1970 bfd *abfd AND
1971 arelent *g AND
1972 register struct reloc_ext_external *natptr)
1973 {
1974 int r_index;
1975 int r_extern;
1976 unsigned int r_type;
1977 unsigned int r_addend;
1978 asymbol *sym = *(g->sym_ptr_ptr);
1979 asection *output_section = sym->section->output_section;
1980
1981 PUT_WORD (abfd, g->address, natptr->r_address);
1982
1983 r_type = (unsigned int) g->howto->type;
1984
1985 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1986
1987 /* If this relocation is relative to a symbol then set the
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.
1992 check for that here. */
1993
1994 if (bfd_is_com_section (output_section)
1995 || output_section == &bfd_abs_section
1996 || output_section == &bfd_und_section)
1997 {
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 }
2005 else
2006 {
2007 r_extern = 1;
2008 r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
2009 }
2010 }
2011 else
2012 {
2013 /* Just an ordinary section */
2014 r_extern = 0;
2015 r_index = output_section->target_index;
2016 }
2017
2018 /* now the fun stuff */
2019 if (abfd->xvec->header_byteorder_big_p != false) {
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] =
2024 ((r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
2025 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
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 }
2034
2035 PUT_WORD (abfd, r_addend, natptr->r_addend);
2036 }
2037
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
2040 50 would have a symbol (.text+10) and know .text vma was 50.
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
2047 #define MOVE_ADDRESS(ad) \
2048 if (r_extern) { \
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 */ \
2055 switch (r_index) { \
2056 case N_TEXT: \
2057 case N_TEXT | N_EXT: \
2058 cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
2059 cache_ptr->addend = ad - su->textsec->vma; \
2060 break; \
2061 case N_DATA: \
2062 case N_DATA | N_EXT: \
2063 cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
2064 cache_ptr->addend = ad - su->datasec->vma; \
2065 break; \
2066 case N_BSS: \
2067 case N_BSS | N_EXT: \
2068 cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
2069 cache_ptr->addend = ad - su->bsssec->vma; \
2070 break; \
2071 default: \
2072 case N_ABS: \
2073 case N_ABS | N_EXT: \
2074 cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; \
2075 cache_ptr->addend = ad; \
2076 break; \
2077 } \
2078 } \
2079
2080 void
2081 DEFUN(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;
2090 struct aoutdata *su = &(abfd->tdata.aout_data->a);
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) {
2096 r_index = (bytes->r_index[0] << 16)
2097 | (bytes->r_index[1] << 8)
2098 | bytes->r_index[2];
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 {
2103 r_index = (bytes->r_index[2] << 16)
2104 | (bytes->r_index[1] << 8)
2105 | bytes->r_index[0];
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;
2112 MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
2113 }
2114
2115 void
2116 DEFUN(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;
2127 struct aoutdata *su = &(abfd->tdata.aout_data->a);
2128 int howto_idx;
2129
2130 cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
2131
2132 /* now the fun stuff */
2133 if (abfd->xvec->header_byteorder_big_p != false) {
2134 r_index = (bytes->r_index[0] << 16)
2135 | (bytes->r_index[1] << 8)
2136 | bytes->r_index[2];
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));
2142 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
2143 >> RELOC_STD_BITS_LENGTH_SH_BIG;
2144 } else {
2145 r_index = (bytes->r_index[2] << 16)
2146 | (bytes->r_index[1] << 8)
2147 | bytes->r_index[0];
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));
2153 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
2154 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
2155 }
2156
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 */
2164
2165 MOVE_ADDRESS(0);
2166 }
2167
2168 /* Reloc hackery */
2169
2170 boolean
2171 DEFUN(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;
2188 } else if (asect == obj_textsec (abfd)) {
2189 reloc_size = exec_hdr(abfd)->a_trsize;
2190 } else {
2191 bfd_error = invalid_operation;
2192 return false;
2193 }
2194
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) {
2204 nomem:
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 {
2231 register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
2232 unsigned int counter = 0;
2233 arelent *cache_ptr = reloc_cache;
2234
2235 for (; counter < count; counter++, rptr++, cache_ptr++) {
2236 NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
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
2251 boolean
2252 DEFUN(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
2275 if (each_size == RELOC_EXT_SIZE)
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 }
2282 else
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 */
2300 unsigned int
2301 DEFUN(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
2324 for (count = 0; count++ < section->reloc_count;)
2325 {
2326 *relptr++ = tblptr++;
2327 }
2328 }
2329 *relptr = 0;
2330
2331 return section->reloc_count;
2332 }
2333
2334 unsigned int
2335 DEFUN(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
2364 DEFUN(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 *
2372 DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
2373 bfd *ignore_abfd AND
2374 asymbol *ignore_symbol)
2375 {
2376 return (alent *)NULL;
2377 }
2378
2379 void
2380 DEFUN(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 }
2404
2405 void
2406 DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
2407 bfd *ignore_abfd AND
2408 PTR afile AND
2409 asymbol *symbol AND
2410 bfd_print_symbol_type how)
2411 {
2412 FILE *file = (FILE *)afile;
2413
2414 switch (how) {
2415 case bfd_print_symbol_name:
2416 if (symbol->name)
2417 fprintf(file,"%s", symbol->name);
2418 break;
2419 case bfd_print_symbol_more:
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;
2424 case bfd_print_symbol_all:
2425 {
2426 CONST char *section_name = symbol->section->name;
2427
2428
2429 bfd_print_symbol_vandf((PTR)file,symbol);
2430
2431 fprintf(file," %-5s %04x %02x %02x",
2432 section_name,
2433 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
2434 (unsigned)(aout_symbol(symbol)->other & 0xff),
2435 (unsigned)(aout_symbol(symbol)->type & 0xff));
2436 if (symbol->name)
2437 fprintf(file," %s", symbol->name);
2438 }
2439 break;
2440 }
2441 }
2442
2443 /*
2444 provided a BFD, a section and an offset into the section, calculate
2445 and return the name of the source file and the line nearest to the
2446 wanted location.
2447 */
2448
2449 boolean
2450 DEFUN(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];
2468 static char filename_buffer[200];
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. */
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);
2482 next:
2483 switch (q->type){
2484 case N_SO:
2485 main_file_name = current_file_name = q->symbol.name;
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);
2491 if (q->type != (int)N_SO)
2492 goto next;
2493
2494 /* Found a second N_SO First is directory; second is filename. */
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;
2502 break;
2503
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;
2513 line_file_name = current_file_name;
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,':');
2531 if (p != NULL) { *p = '\0'; }
2532 *functionname_ptr = buffer;
2533 goto done;
2534
2535 }
2536 }
2537 break;
2538 }
2539 }
2540 }
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 }
2554 return true;
2555
2556 }
2557
2558 int
2559 DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
2560 bfd *abfd AND
2561 boolean execable)
2562 {
2563 return adata(abfd).exec_bytes_size;
2564 }
This page took 0.085378 seconds and 4 git commands to generate.