* cpu-h8300.c: Add support for MEMIND addressing mode
[deliverable/binutils-gdb.git] / bfd / aoutx.h
CommitLineData
88dfcd68
SC
1/* BFD semi-generic back-end for a.out binaries
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
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
6f715d66
SC
21/*doc*
22@section a.out backends
23
24BFD supports a number of different flavours of a.out format, though
25the major differences are only the sizes of the structures on disk,
26and the shape of the relocation information.
27
28The support is split into a basic support file @code{aoutx.h} and
29other files which derive functions from the base. One derivation file
30is @code{aoutf1.h} (for a.out flavour 1), and adds to the basic a.out
31functions support for sun3, sun4, 386 and 29k a.out files, to create a
32target jump vector for a specific target.
33
34This information is further split out into more specific files for each
7b02b4ed
JG
35machine, including @code{sunos.c} for sun3 and sun4, @code{newsos3.c} for
36the Sony NEWS, and @code{demo64.c} for a demonstration of a 64 bit a.out
37format.
6f715d66
SC
38
39The base file @code{aoutx.h} defines general mechanisms for reading
40and writing records to and from disk, and various other methods which
6724ff46 41BFD requires. It is included by @code{aout32.c} and @code{aout64.c} to
6f715d66
SC
42form the names aout_32_swap_exec_header_in,
43aout_64_swap_exec_header_in, etc.
44
45As an example, this is what goes on to make the back end for a sun4, from aout32.c
46
47@example
48 #define ARCH_SIZE 32
49 #include "aoutx.h"
50@end example
51
52Which exports names:
53@example
54 ...
55 aout_32_canonicalize_reloc
56 aout_32_find_nearest_line
57 aout_32_get_lineno
58 aout_32_get_reloc_upper_bound
59 ...
60@end example
61
62from sunos.c
63
64@example
65 #define ARCH 32
66 #define TARGET_NAME "a.out-sunos-big"
67 #define VECNAME sunos_big_vec
68 #include "aoutf1.h"
69@end example
70requires all the names from aout32.c, and produces the jump vector
71
72@example
73 sunos_big_vec
74@end example
75
c6705697
SC
76The file host-aout.c is a special case. It is for a large set of hosts
77that use ``more or less standard'' a.out files, and for which cross-debugging
78is not interesting. It uses the standard 32-bit a.out support routines,
79but determines the file offsets and addresses of the text, data,
80and BSS sections, the machine architecture and machine type,
81and the entry point address, in a host-dependent manner. Once these
82values have been determined, generic code is used to handle the
83object file.
84
85When porting it to run on a new system, you must supply:
86
87 HOST_PAGE_SIZE
88 HOST_SEGMENT_SIZE
89 HOST_MACHINE_ARCH (optional)
90 HOST_MACHINE_MACHINE (optional)
91 HOST_TEXT_START_ADDR
92 HOST_STACK_END_ADDR
93
94in the file ../include/sys/h-XXX.h (for your host). These values, plus
95the structures and macros defined in <a.out.h> on your host system, will
96produce a BFD target that will access ordinary a.out files on your host.
97
98To configure a new machine to use host-aout.c, specify:
99
db138ce2 100TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
c6705697
SC
101TDEPFILES= host-aout.o trad-core.o
102
db138ce2
JG
103in the config/mt-XXX file, and modify configure.in to use the
104mt-XXX file (by setting "bfd_target=XXX") when your configuration is
c6705697
SC
105selected.
106
6f715d66
SC
107*/
108
c618de01
SC
109#define KEEPIT flags
110#define KEEPITTYPE int
67c060c3
SC
111
112#include "bfd.h"
7ed4093a
SC
113#include <sysdep.h>
114#include <ansidecl.h>
115
9e2dad8e 116struct external_exec;
6f715d66 117#include "libaout.h"
7ed4093a 118#include "libbfd.h"
c3eb25fc
SC
119#include "aout/aout64.h"
120#include "aout/stab_gnu.h"
121#include "aout/ar.h"
7ed4093a
SC
122
123void (*bfd_error_trap)();
124
6f715d66
SC
125/*doc*
126@subsection relocations
127The file @code{aoutx.h} caters for both the @emph{standard} and
128@emph{extended} forms of a.out relocation records.
7ed4093a 129
6f715d66
SC
130The standard records are characterised by containing only an address,
131a symbol index and a type field. The extended records (used on 29ks
132and sparcs) also have a full integer for an addend.
133*/
7ed4093a 134#define CTOR_TABLE_RELOC_IDX 2
67c060c3 135
67c060c3 136
7ed4093a
SC
137static reloc_howto_type howto_table_ext[] =
138{
139 HOWTO(RELOC_8, 0, 0, 8, false, 0, true, true,0,"8", false, 0,0x000000ff, false),
140 HOWTO(RELOC_16, 0, 1, 16, false, 0, true, true,0,"16", false, 0,0x0000ffff, false),
141 HOWTO(RELOC_32, 0, 2, 32, false, 0, true, true,0,"32", false, 0,0xffffffff, false),
142 HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, false, true,0,"DISP8", false, 0,0x000000ff, false),
143 HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, false, true,0,"DISP16", false, 0,0x0000ffff, false),
144 HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, false, true,0,"DISP32", false, 0,0xffffffff, false),
145 HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, false, true,0,"WDISP30", false, 0,0x3fffffff, false),
146 HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, false, true,0,"WDISP22", false, 0,0x003fffff, false),
147 HOWTO(RELOC_HI22, 10, 2, 22, false, 0, false, true,0,"HI22", false, 0,0x003fffff, false),
148 HOWTO(RELOC_22, 0, 2, 22, false, 0, false, true,0,"22", false, 0,0x003fffff, false),
149 HOWTO(RELOC_13, 0, 2, 13, false, 0, false, true,0,"13", false, 0,0x00001fff, false),
150 HOWTO(RELOC_LO10, 0, 2, 10, false, 0, false, true,0,"LO10", false, 0,0x000003ff, false),
151 HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false),
152 HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false),
153 HOWTO(RELOC_BASE10, 0, 2, 16, false, 0, false, true,0,"BASE10", false, 0,0x0000ffff, false),
154 HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, false, true,0,"BASE13", false, 0,0x00001fff, false),
155 HOWTO(RELOC_BASE22, 0, 2, 0, false, 0, false, true,0,"BASE22", false, 0,0x00000000, false),
156 HOWTO(RELOC_PC10, 0, 2, 10, false, 0, false, true,0,"PC10", false, 0,0x000003ff, false),
157 HOWTO(RELOC_PC22, 0, 2, 22, false, 0, false, true,0,"PC22", false, 0,0x003fffff, false),
158 HOWTO(RELOC_JMP_TBL,0, 2, 32, false, 0, false, true,0,"JMP_TBL", false, 0,0xffffffff, false),
159 HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false),
160 HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false),
161 HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false),
67c060c3
SC
162 HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, false, true,0,"RELATIVE", false, 0,0x00000000, false),
163
7ed4093a
SC
164};
165
166/* Convert standard reloc records to "arelent" format (incl byte swap). */
167
168static reloc_howto_type howto_table_std[] = {
169 /* type rs size bsz pcrel bitpos abs ovrf sf name part_inpl readmask setmask pcdone */
170HOWTO( 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff,0x000000ff, false),
171HOWTO( 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff,0x0000ffff, false),
172HOWTO( 2, 0, 2, 32, false, 0, true, true,0,"32", true, 0xffffffff,0xffffffff, false),
173HOWTO( 3, 0, 3, 64, false, 0, true, true,0,"64", true, 0xdeaddead,0xdeaddead, false),
174HOWTO( 4, 0, 0, 8, true, 0, false, true,0,"DISP8", true, 0x000000ff,0x000000ff, false),
175HOWTO( 5, 0, 1, 16, true, 0, false, true,0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
176HOWTO( 6, 0, 2, 32, true, 0, false, true,0,"DISP32", true, 0xffffffff,0xffffffff, false),
177HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedface,0xfeedface, false),
178};
179
180
181bfd_error_vector_type bfd_error_vector;
6f715d66
SC
182
183/*doc*
184@subsection Internal Entry Points
185@code{aoutx.h} exports several routines for accessing the contents of
186an a.out file, which are gathered and exported in turn by various
187format specific files (eg sunos.c).
188*/
189
190/*doc*
191*i aout_<size>_swap_exec_header_in
192Swaps the information in an executable header taken from a raw byte stream memory image,
193into the internal exec_header structure.
194*; PROTO(void, aout_<size>_swap_exec_header_in,
195 (bfd *abfd,
196 struct external_exec *raw_bytes,
197 struct internal_exec *execp));
198*/
199
7ed4093a
SC
200void
201DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
202 bfd *abfd AND
203 struct external_exec *raw_bytes AND
204 struct internal_exec *execp)
205{
206 struct external_exec *bytes = (struct external_exec *)raw_bytes;
207
208 /* Now fill in fields in the execp, from the bytes in the raw data. */
209 execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
210 execp->a_text = GET_WORD (abfd, bytes->e_text);
211 execp->a_data = GET_WORD (abfd, bytes->e_data);
212 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
213 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
214 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
215 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
216 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
217}
218
6f715d66
SC
219/*doc*
220*i aout_<size>_swap_exec_header_out
221Swaps the information in an internal exec header structure into the
222supplied buffer ready for writing to disk.
223*; PROTO(void, aout_<size>_swap_exec_header_out,
224 (bfd *abfd,
225 struct internal_exec *execp,
226 struct external_exec *raw_bytes));
227*/
7ed4093a
SC
228void
229DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
230 bfd *abfd AND
231 struct internal_exec *execp AND
232 struct external_exec *raw_bytes)
233{
234 struct external_exec *bytes = (struct external_exec *)raw_bytes;
235
236 /* Now fill in fields in the raw data, from the fields in the exec struct. */
237 bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
238 PUT_WORD (abfd, execp->a_text , bytes->e_text);
239 PUT_WORD (abfd, execp->a_data , bytes->e_data);
240 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
241 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
242 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
243 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
244 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
245}
246
247struct container {
248 struct aoutdata a;
249 struct internal_exec e;
250};
251
6f715d66
SC
252
253/*doc*
254*i aout_<size>_some_aout_object_p
255
256Some A.OUT variant thinks that the file whose format we're checking
257is an a.out file. Do some more checking, and set up for access if
258it really is. Call back to the calling environments "finish up"
259function just before returning, to handle any last-minute setup.
260
261*; PROTO(bfd_target *, aout_<size>_some_aout_object_p,
262 (bfd *abfd,
263 bfd_target *(*callback_to_real_object_p)()));
264*/
7ed4093a
SC
265
266bfd_target *
7b02b4ed 267DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
7ed4093a 268 bfd *abfd AND
7b02b4ed 269 struct internal_exec *execp AND
7ed4093a
SC
270 bfd_target *(*callback_to_real_object_p) ())
271{
7ed4093a 272 struct container *rawptr;
e6e265ce 273 bfd_target *result;
7ed4093a 274
7ed4093a 275 rawptr = (struct container *) bfd_zalloc (abfd, sizeof (struct container));
7ed4093a
SC
276 if (rawptr == NULL) {
277 bfd_error = no_memory;
278 return 0;
279 }
280
7b02b4ed
JG
281 set_tdata (abfd, &rawptr->a);
282 exec_hdr (abfd) = &rawptr->e;
283 *exec_hdr (abfd) = *execp; /* Copy in the internal_exec struct */
284 execp = exec_hdr (abfd); /* Switch to using the newly malloc'd one */
7ed4093a
SC
285
286 /* Set the file flags */
287 abfd->flags = NO_FLAGS;
288 if (execp->a_drsize || execp->a_trsize)
289 abfd->flags |= HAS_RELOC;
e6e265ce 290 /* Setting of EXEC_P has been deferred to the bottom of this function */
7ed4093a
SC
291 if (execp->a_syms)
292 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
293
294 if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
295 if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
296
297 bfd_get_start_address (abfd) = execp->a_entry;
298
299 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
300 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
301
302 /* Set the default architecture and machine type. These can be
303 overridden in the callback routine. */
9e2dad8e
JG
304
305 bfd_default_set_arch_mach(abfd, bfd_arch_unknown, 0);
7ed4093a
SC
306
307 /* The default relocation entry size is that of traditional V7 Unix. */
308 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
309
7b02b4ed
JG
310 /* The default symbol entry size is that of traditional Unix. */
311 obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
312
7ed4093a
SC
313 /* create the sections. This is raunchy, but bfd_close wants to reclaim
314 them */
315 obj_textsec (abfd) = (asection *)NULL;
316 obj_datasec (abfd) = (asection *)NULL;
317 obj_bsssec (abfd) = (asection *)NULL;
318 (void)bfd_make_section(abfd, ".text");
319 (void)bfd_make_section(abfd, ".data");
320 (void)bfd_make_section(abfd, ".bss");
321
322 abfd->sections = obj_textsec (abfd);
323 obj_textsec (abfd)->next = obj_datasec (abfd);
324 obj_datasec (abfd)->next = obj_bsssec (abfd);
325
326 obj_datasec (abfd)->size = execp->a_data;
327 obj_bsssec (abfd)->size = execp->a_bss;
7ed4093a 328
7ed4093a 329 obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
7b02b4ed
JG
330 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
331 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
7ed4093a 332 obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
7b02b4ed
JG
333 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
334 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
7ed4093a
SC
335 obj_bsssec (abfd)->flags = SEC_ALLOC;
336
337#ifdef THIS_IS_ONLY_DOCUMENTATION
98d43107
JG
338 /* The common code can't fill in these things because they depend
339 on either the start address of the text segment, the rounding
340 up of virtual addersses between segments, or the starting file
341 position of the text segment -- all of which varies among different
342 versions of a.out. */
343
7ed4093a
SC
344 /* Call back to the format-dependent code to fill in the rest of the
345 fields and do any further cleanup. Things that should be filled
346 in by the callback: */
347
348 struct exec *execp = exec_hdr (abfd);
349
98d43107
JG
350 obj_textsec (abfd)->size = N_TXTSIZE(*execp);
351 /* data and bss are already filled in since they're so standard */
352
7ed4093a 353 /* The virtual memory addresses of the sections */
7ed4093a 354 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
98d43107
JG
355 obj_datasec (abfd)->vma = N_DATADDR(*execp);
356 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
7ed4093a
SC
357
358 /* The file offsets of the sections */
359 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
360 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
361
362 /* The file offsets of the relocation info */
363 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
364 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
365
366 /* The file offsets of the string table and symbol table. */
367 obj_str_filepos (abfd) = N_STROFF (*execp);
368 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
369
7ed4093a
SC
370 /* Determine the architecture and machine type of the object file. */
371 switch (N_MACHTYPE (*exec_hdr (abfd))) {
372 default:
373 abfd->obj_arch = bfd_arch_obscure;
374 break;
375 }
376
377 /* Determine the size of a relocation entry */
378 switch (abfd->obj_arch) {
379 case bfd_arch_sparc:
380 case bfd_arch_a29k:
381 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
382 default:
383 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
384 }
385
7b02b4ed
JG
386 adata(abfd)->page_size = PAGE_SIZE;
387 adata(abfd)->segment_size = SEGMENT_SIZE;
388 adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
389
7ed4093a
SC
390 return abfd->xvec;
391
392 /* The architecture is encoded in various ways in various a.out variants,
393 or is not encoded at all in some of them. The relocation size depends
394 on the architecture and the a.out variant. Finally, the return value
395 is the bfd_target vector in use. If an error occurs, return zero and
396 set bfd_error to the appropriate error code.
397
398 Formats such as b.out, which have additional fields in the a.out
399 header, should cope with them in this callback as well. */
400#endif /* DOCUMENTATION */
401
e6e265ce
JG
402 result = (*callback_to_real_object_p)(abfd);
403
404 /* Now that the segment addresses have been worked out, take a better
405 guess at whether the file is executable. If the entry point
406 is within the text segment, assume it is. (This makes files
407 executable even if their entry point address is 0, as long as
408 their text starts at zero.)
409
410 At some point we should probably break down and stat the file and
411 declare it executable if (one of) its 'x' bits are on... */
412 if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
413 (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->size))
414 abfd->flags |= EXEC_P;
415 return result;
7ed4093a
SC
416}
417
6f715d66
SC
418/*doc*
419*i aout_<size>_mkobject
420
6724ff46 421This routine initializes a BFD for use with a.out files.
6f715d66
SC
422
423*; PROTO(boolean, aout_<size>_mkobject, (bfd *));
424*/
7ed4093a
SC
425
426boolean
427DEFUN(NAME(aout,mkobject),(abfd),
428 bfd *abfd)
429{
430 struct container *rawptr;
431
432 bfd_error = system_call_error;
433
434 /* Use an intermediate variable for clarity */
435 rawptr = (struct container *)bfd_zalloc (abfd, sizeof (struct container));
436
437 if (rawptr == NULL) {
438 bfd_error = no_memory;
439 return false;
440 }
441
442 set_tdata (abfd, rawptr);
443 exec_hdr (abfd) = &(rawptr->e);
444
445 /* For simplicity's sake we just make all the sections right here. */
446
447 obj_textsec (abfd) = (asection *)NULL;
448 obj_datasec (abfd) = (asection *)NULL;
449 obj_bsssec (abfd) = (asection *)NULL;
450 bfd_make_section (abfd, ".text");
451 bfd_make_section (abfd, ".data");
452 bfd_make_section (abfd, ".bss");
453
454 return true;
455}
456
6f715d66
SC
457
458/*doc*
459*i aout_<size>_machine_type
460
461Keep track of machine architecture and machine type for a.out's.
7ed4093a
SC
462Return the machine_type for a particular arch&machine, or M_UNKNOWN
463if that exact arch&machine can't be represented in a.out format.
464
465If the architecture is understood, machine type 0 (default) should
6f715d66
SC
466always be understood.
467
468*; PROTO(enum machine_type, aout_<size>_machine_type,
469 (enum bfd_architecture arch,
470 unsigned long machine));
471*/
7ed4093a
SC
472
473enum machine_type
474DEFUN(NAME(aout,machine_type),(arch, machine),
475 enum bfd_architecture arch AND
476 unsigned long machine)
477{
478 enum machine_type arch_flags;
479
480 arch_flags = M_UNKNOWN;
481
482 switch (arch) {
483 case bfd_arch_sparc:
484 if (machine == 0) arch_flags = M_SPARC;
485 break;
486
487 case bfd_arch_m68k:
488 switch (machine) {
489 case 0: arch_flags = M_68010; break;
490 case 68000: arch_flags = M_UNKNOWN; break;
491 case 68010: arch_flags = M_68010; break;
492 case 68020: arch_flags = M_68020; break;
493 default: arch_flags = M_UNKNOWN; break;
494 }
495 break;
496
497 case bfd_arch_i386:
498 if (machine == 0) arch_flags = M_386;
499 break;
500
501 case bfd_arch_a29k:
502 if (machine == 0) arch_flags = M_29K;
503 break;
504
505 default:
506 arch_flags = M_UNKNOWN;
507 break;
508 }
509 return arch_flags;
510}
511
9e2dad8e 512
6f715d66
SC
513/*doc*
514*i aout_<size>_set_arch_mach
515
6724ff46 516Sets the architecture and the machine of the BFD to those values
6f715d66
SC
517supplied. Verifies that the format can support the architecture
518required.
519
520*; PROTO(boolean, aout_<size>_set_arch_mach,
521 (bfd *,
522 enum bfd_architecture,
523 unsigned long machine));
524*/
525
7ed4093a
SC
526boolean
527DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
528 bfd *abfd AND
529 enum bfd_architecture arch AND
530 unsigned long machine)
531{
9e2dad8e 532 bfd_default_set_arch_mach(abfd, arch, machine);
7ed4093a
SC
533 if (arch != bfd_arch_unknown &&
534 NAME(aout,machine_type) (arch, machine) == M_UNKNOWN)
535 return false; /* We can't represent this type */
536 return true; /* We're easy ... */
537}
7ed4093a 538
6f715d66 539/*doc*
9e2dad8e
JG
540 *i aout_<size>new_section_hook
541
542 Called by the BFD in response to a @code{bfd_make_section} request.
543 *; PROTO(boolean, aout_<size>_new_section_hook,
544 (bfd *abfd,
545 asection *newsect));
6f715d66 546*/
7ed4093a 547boolean
9e2dad8e
JG
548 DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
549 bfd *abfd AND
550 asection *newsect)
7ed4093a
SC
551{
552 /* align to double at least */
553 newsect->alignment_power = 3;
554
555 if (bfd_get_format (abfd) == bfd_object) {
556 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
557 obj_textsec(abfd)= newsect;
558 return true;
559 }
560
561 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
562 obj_datasec(abfd) = newsect;
563 return true;
564 }
565
566 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
567 obj_bsssec(abfd) = newsect;
568 return true;
569 }
570 }
571
572 /* We allow more than three sections internally */
573 return true;
574}
575
576boolean
9e2dad8e
JG
577 DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
578 bfd *abfd AND
579 sec_ptr section AND
580 PTR location AND
581 file_ptr offset AND
582 bfd_size_type count)
7ed4093a 583{
7b02b4ed
JG
584 file_ptr text_end;
585 bfd_size_type text_header_size; /* exec_bytes_size if if included in
586 text size. */
587 bfd_size_type text_size;
7ed4093a 588 if (abfd->output_has_begun == false)
9e2dad8e
JG
589 { /* set by bfd.c handler */
590 switch (abfd->direction)
591 {
592 case read_direction:
593 case no_direction:
594 bfd_error = invalid_operation;
595 return false;
596
597 case both_direction:
598 break;
599
600 case write_direction:
601 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
602 {
603 bfd_error = invalid_operation;
604 return false;
605 }
7b02b4ed
JG
606 obj_textsec(abfd)->size =
607 align_power(obj_textsec(abfd)->size,
608 obj_textsec(abfd)->alignment_power);
609 text_size = obj_textsec (abfd)->size;
610 /* Rule (heuristic) for when to pad to a new page.
611 * Note that there are (at least) two ways demand-paged
612 * (ZMAGIC) files have been handled. Most Berkeley-based systems
613 * start the text segment at (PAGE_SIZE). However, newer
614 * versions of SUNOS start the text segment right after the
615 * exec header; the latter is counted in the text segment size,
616 * and is paged in by the kernel with the rest of the text. */
617 if (!(abfd->flags & D_PAGED))
618 { /* Not demand-paged. */
619 obj_textsec(abfd)->filepos = adata(abfd)->exec_bytes_size;
620 }
621 else if (obj_textsec(abfd)->vma % adata(abfd)->page_size
622 < adata(abfd)->exec_bytes_size)
623 { /* Old-style demand-paged. */
624 obj_textsec(abfd)->filepos = adata(abfd)->page_size;
625 }
626 else
627 { /* Sunos-style demand-paged. */
628 obj_textsec(abfd)->filepos = adata(abfd)->exec_bytes_size;
629 text_size += adata(abfd)->exec_bytes_size;
630 }
631 text_end = obj_textsec(abfd)->size + obj_textsec(abfd)->filepos;
632 if (abfd->flags & (D_PAGED|WP_TEXT))
633 {
634 bfd_size_type text_pad =
8c4a1ace
JG
635 BFD_ALIGN(text_size, adata(abfd)->segment_size)
636 - text_size;
7b02b4ed
JG
637 text_end += text_pad;
638 obj_textsec(abfd)->size += text_pad;
12e7087f 639 }
7b02b4ed
JG
640 obj_datasec(abfd)->filepos = text_end;
641 obj_datasec(abfd)->size =
642 align_power(obj_datasec(abfd)->size,
643 obj_datasec(abfd)->alignment_power);
12e7087f 644 }
9e2dad8e 645 }
12e7087f 646
7ed4093a
SC
647 /* regardless, once we know what we're doing, we might as well get going */
648 if (section != obj_bsssec(abfd))
649 {
650 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
9e2dad8e 651
7ed4093a
SC
652 if (count) {
653 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
654 true : false;
655 }
656 return false;
657 }
658 return true;
659}
660\f
661/* Classify stabs symbols */
662
663#define sym_in_text_section(sym) \
9e2dad8e 664 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
7ed4093a
SC
665
666#define sym_in_data_section(sym) \
9e2dad8e 667 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
7ed4093a
SC
668
669#define sym_in_bss_section(sym) \
9e2dad8e 670 (((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
7ed4093a
SC
671
672/* Symbol is undefined if type is N_UNDF|N_EXT and if it has
9e2dad8e
JG
673 zero in the "value" field. Nonzeroes there are fortrancommon
674 symbols. */
7ed4093a 675#define sym_is_undefined(sym) \
9e2dad8e 676 ((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
7ed4093a
SC
677
678/* Symbol is a global definition if N_EXT is on and if it has
9e2dad8e 679 a nonzero type field. */
7ed4093a 680#define sym_is_global_defn(sym) \
9e2dad8e 681 (((sym)->type & N_EXT) && (sym)->type & N_TYPE)
7ed4093a
SC
682
683/* Symbol is debugger info if any bits outside N_TYPE or N_EXT
9e2dad8e 684 are on. */
7ed4093a 685#define sym_is_debugger_info(sym) \
9e2dad8e 686 ((sym)->type & ~(N_EXT | N_TYPE))
7ed4093a
SC
687
688#define sym_is_fortrancommon(sym) \
9e2dad8e 689 (((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
7ed4093a
SC
690
691/* Symbol is absolute if it has N_ABS set */
692#define sym_is_absolute(sym) \
9e2dad8e 693 (((sym)->type & N_TYPE)== N_ABS)
7ed4093a
SC
694
695
696#define sym_is_indirect(sym) \
9e2dad8e 697 (((sym)->type & N_ABS)== N_ABS)
7ed4093a
SC
698
699/* Only in their own functions for ease of debugging; when sym flags have
9e2dad8e
JG
700 stabilised these should be inlined into their (single) caller */
701
7ed4093a
SC
702static void
703DEFUN(translate_from_native_sym_flags,(sym_pointer, cache_ptr, abfd),
9e2dad8e
JG
704struct external_nlist *sym_pointer AND
705aout_symbol_type *cache_ptr AND
706bfd *abfd)
707{
708 switch (cache_ptr->type & N_TYPE) {
709 case N_SETA:
710 case N_SETT:
711 case N_SETD:
712 case N_SETB:
713 {
714 char *copy = bfd_alloc(abfd, strlen(cache_ptr->symbol.name)+1);
715 asection *section ;
716 arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
717 strcpy(copy, cache_ptr->symbol.name);
cbdc7909
JG
718 section = bfd_get_section_by_name (abfd, copy);
719 if (!section)
720 section = bfd_make_section(abfd,copy);
721
9e2dad8e
JG
722 switch ( (cache_ptr->type & N_TYPE) ) {
723 case N_SETA:
724 section->flags = SEC_CONSTRUCTOR;
725 reloc->relent.section = (asection *)NULL;
726 cache_ptr->symbol.section = (asection *)NULL;
727 break;
728 case N_SETT:
729 section->flags = SEC_CONSTRUCTOR_TEXT;
730 reloc->relent.section = (asection *)obj_textsec(abfd);
731 cache_ptr->symbol.value -= reloc->relent.section->vma;
732 break;
733 case N_SETD:
734 section->flags = SEC_CONSTRUCTOR_DATA;
735 reloc->relent.section = (asection *)obj_datasec(abfd);
736 cache_ptr->symbol.value -= reloc->relent.section->vma;
737 break;
738 case N_SETB:
739 section->flags = SEC_CONSTRUCTOR_BSS;
740 reloc->relent.section = (asection *)obj_bsssec(abfd);
741 cache_ptr->symbol.value -= reloc->relent.section->vma;
742 break;
743 }
744 cache_ptr->symbol.section = reloc->relent.section;
745 reloc->relent.addend = cache_ptr->symbol.value ;
7ed4093a 746
9e2dad8e
JG
747 /* We modify the symbol to belong to a section depending upon the
748 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
749 really care, and add to the size of the section to contain a
750 pointer to the symbol. Build a reloc entry to relocate to this
751 symbol attached to this section. */
c618de01
SC
752
753
9e2dad8e
JG
754 section->reloc_count++;
755 section->alignment_power = 2;
756 reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
757 reloc->next = section->constructor_chain;
758 section->constructor_chain = reloc;
759 reloc->relent.address = section->size;
760 section->size += sizeof(int *);
c618de01 761
9e2dad8e
JG
762 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
763 cache_ptr->symbol.flags |= BSF_DEBUGGING | BSF_CONSTRUCTOR;
764 }
765 break;
7ed4093a 766 default:
88dfcd68
SC
767 if (cache_ptr->type == N_WARNING)
768 {
9e2dad8e
JG
769 /* This symbol is the text of a warning message, the next symbol
770 is the symbol to associate the warning with */
771 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
772 cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
773 /* We furgle with the next symbol in place. We don't want it to be undefined, we'll trample the type */
774 (sym_pointer+1)->e_type[0] = 0xff;
775 break;
776 }
c618de01 777 if ((cache_ptr->type | N_EXT) == (N_INDR | N_EXT)) {
88dfcd68
SC
778 /* Two symbols in a row for an INDR message. The first symbol
779 contains the name we will match, the second symbol contains the
780 name the first name is translated into. It is supplied to us
781 undefined. This is good, since we want to pull in any files which
782 define it */
783 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT;
784 cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
785 break;
786 }
787
788
7ed4093a
SC
789 if (sym_is_debugger_info (cache_ptr)) {
790 cache_ptr->symbol.flags = BSF_DEBUGGING ;
791 /* Work out the section correct for this symbol */
792 switch (cache_ptr->type & N_TYPE)
793 {
794 case N_TEXT:
795 case N_FN:
796 cache_ptr->symbol.section = obj_textsec (abfd);
797 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
798 break;
799 case N_DATA:
800 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
801 cache_ptr->symbol.section = obj_datasec (abfd);
802 break;
803 case N_BSS :
804 cache_ptr->symbol.section = obj_bsssec (abfd);
805 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
806 break;
807 case N_ABS:
808 default:
809 cache_ptr->symbol.section = 0;
810 break;
811 }
812 }
813 else {
88dfcd68 814
7ed4093a
SC
815 if (sym_is_fortrancommon (cache_ptr))
816 {
817 cache_ptr->symbol.flags = BSF_FORT_COMM;
818 cache_ptr->symbol.section = (asection *)NULL;
819 }
820 else {
821 if (sym_is_undefined (cache_ptr)) {
822 cache_ptr->symbol.flags = BSF_UNDEFINED;
823 }
824 else if (sym_is_global_defn (cache_ptr)) {
825 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
826 }
88dfcd68 827
7ed4093a
SC
828 else if (sym_is_absolute (cache_ptr)) {
829 cache_ptr->symbol.flags = BSF_ABSOLUTE;
830 }
831 else {
832 cache_ptr->symbol.flags = BSF_LOCAL;
833 }
88dfcd68 834
7ed4093a
SC
835 /* In a.out, the value of a symbol is always relative to the
836 * start of the file, if this is a data symbol we'll subtract
837 * the size of the text section to get the section relative
838 * value. If this is a bss symbol (which would be strange)
839 * we'll subtract the size of the previous two sections
840 * to find the section relative address.
841 */
88dfcd68 842
7ed4093a
SC
843 if (sym_in_text_section (cache_ptr)) {
844 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
845 cache_ptr->symbol.section = obj_textsec (abfd);
846 }
847 else if (sym_in_data_section (cache_ptr)){
848 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
849 cache_ptr->symbol.section = obj_datasec (abfd);
850 }
851 else if (sym_in_bss_section(cache_ptr)) {
852 cache_ptr->symbol.section = obj_bsssec (abfd);
853 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
854 }
855 else {
856 cache_ptr->symbol.section = (asection *)NULL;
857 cache_ptr->symbol.flags |= BSF_ABSOLUTE;
858 }
859 }
860 }
861 }
862}
863
864static void
865DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
866 struct external_nlist *sym_pointer AND
867 asymbol *cache_ptr AND
868 bfd *abfd)
869{
870 bfd_vma value = cache_ptr->value;
871
872 if (bfd_get_section(cache_ptr)) {
873 if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
874 sym_pointer->e_type[0] |= N_BSS;
875 }
876 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
877 sym_pointer->e_type[0] |= N_DATA;
878 }
879 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
880 sym_pointer->e_type[0] |= N_TEXT;
881 }
882 else {
883 bfd_error_vector.nonrepresentable_section(abfd,
884 bfd_get_output_section(cache_ptr)->name);
885 }
886 /* Turn the symbol from section relative to absolute again */
887
888 value +=
889 cache_ptr->section->output_section->vma
890 + cache_ptr->section->output_offset ;
891 }
892 else {
893 sym_pointer->e_type[0] |= N_ABS;
894 }
88dfcd68
SC
895 if (cache_ptr->flags & (BSF_WARNING)) {
896 (sym_pointer+1)->e_type[0] = 1;
897 }
7ed4093a
SC
898 if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
899 sym_pointer->e_type[0] = (N_UNDF | N_EXT);
900 }
901 else {
902 if (cache_ptr->flags & BSF_ABSOLUTE) {
903 sym_pointer->e_type[0] |= N_ABS;
904 }
905
906 if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
907 sym_pointer->e_type[0] |= N_EXT;
908 }
909 if (cache_ptr->flags & BSF_DEBUGGING) {
910 sym_pointer->e_type [0]= ((aout_symbol_type *)cache_ptr)->type;
911 }
912 }
913 PUT_WORD(abfd, value, sym_pointer->e_value);
914}
915\f
916/* Native-level interface to symbols. */
917
918/* We read the symbols into a buffer, which is discarded when this
919function exits. We read the strings into a buffer large enough to
920hold them all plus all the cached symbol entries. */
921
922asymbol *
923DEFUN(NAME(aout,make_empty_symbol),(abfd),
924 bfd *abfd)
9e2dad8e
JG
925{
926 aout_symbol_type *new =
927 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
928 new->symbol.the_bfd = abfd;
7ed4093a 929
9e2dad8e
JG
930 return &new->symbol;
931}
7ed4093a
SC
932
933boolean
934DEFUN(NAME(aout,slurp_symbol_table),(abfd),
935 bfd *abfd)
9e2dad8e
JG
936{
937 bfd_size_type symbol_size;
938 bfd_size_type string_size;
939 unsigned char string_chars[BYTES_IN_WORD];
940 struct external_nlist *syms;
941 char *strings;
942 aout_symbol_type *cached;
7ed4093a 943
9e2dad8e
JG
944 /* If there's no work to be done, don't do any */
945 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
946 symbol_size = exec_hdr(abfd)->a_syms;
947 if (symbol_size == 0) {
948 bfd_error = no_symbols;
949 return false;
950 }
7ed4093a 951
9e2dad8e
JG
952 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
953 if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
954 return false;
955 string_size = GET_WORD (abfd, string_chars);
7ed4093a 956
9e2dad8e
JG
957 strings =(char *) bfd_alloc(abfd, string_size + 1);
958 cached = (aout_symbol_type *)
959 bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
960
961 /* malloc this, so we can free it if simply. The symbol caching
962 might want to allocate onto the bfd's obstack */
98d43107 963 syms = (struct external_nlist *) bfd_xmalloc(symbol_size);
9e2dad8e
JG
964 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
965 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
966 bailout:
967 if (syms) free (syms);
968 if (cached) bfd_release (abfd, cached);
969 if (strings)bfd_release (abfd, strings);
970 return false;
971 }
7ed4093a 972
9e2dad8e
JG
973 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
974 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
975 goto bailout;
976 }
7ed4093a 977
9e2dad8e
JG
978 /* OK, now walk the new symtable, cacheing symbol properties */
979 {
980 register struct external_nlist *sym_pointer;
981 register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
982 register aout_symbol_type *cache_ptr = cached;
7ed4093a 983
9e2dad8e
JG
984 /* Run through table and copy values */
985 for (sym_pointer = syms, cache_ptr = cached;
986 sym_pointer < sym_end; sym_pointer++, cache_ptr++)
987 {
988 bfd_vma x = GET_WORD(abfd, sym_pointer->e_strx);
989 cache_ptr->symbol.the_bfd = abfd;
990 if (x)
991 cache_ptr->symbol.name = x + strings;
992 else
993 cache_ptr->symbol.name = (char *)NULL;
7ed4093a 994
9e2dad8e
JG
995 cache_ptr->symbol.value = GET_SWORD(abfd, sym_pointer->e_value);
996 cache_ptr->desc = bfd_get_16(abfd, sym_pointer->e_desc);
997 cache_ptr->other =bfd_get_8(abfd, sym_pointer->e_other);
998 cache_ptr->type = bfd_get_8(abfd, sym_pointer->e_type);
999 cache_ptr->symbol.udata = 0;
1000 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1001 }
1002 }
7ed4093a 1003
9e2dad8e
JG
1004 obj_aout_symbols (abfd) = cached;
1005 free((PTR)syms);
7ed4093a 1006
9e2dad8e
JG
1007 return true;
1008}
7ed4093a
SC
1009
1010
1011void
1012DEFUN(NAME(aout,write_syms),(abfd),
1013 bfd *abfd)
1014 {
1015 unsigned int count ;
1016 asymbol **generic = bfd_get_outsymbols (abfd);
1017
1018 bfd_size_type stindex = BYTES_IN_WORD; /* initial string length */
1019
1020 for (count = 0; count < bfd_get_symcount (abfd); count++) {
1021 asymbol *g = generic[count];
1022 struct external_nlist nsp;
1023
7ed4093a
SC
1024 if (g->name) {
1025 unsigned int length = strlen(g->name) +1;
1026 PUT_WORD (abfd, stindex, (unsigned char *)nsp.e_strx);
1027 stindex += length;
1028 }
1029 else {
1030 PUT_WORD (abfd, 0, (unsigned char *)nsp.e_strx);
1031 }
1032
1033 if (g->the_bfd->xvec->flavour == abfd->xvec->flavour)
1034 {
1035 bfd_h_put_16(abfd, aout_symbol(g)->desc, nsp.e_desc);
1036 bfd_h_put_8(abfd, aout_symbol(g)->other, nsp.e_other);
1037 bfd_h_put_8(abfd, aout_symbol(g)->type, nsp.e_type);
1038 }
1039 else
1040 {
1041 bfd_h_put_16(abfd,0, nsp.e_desc);
1042 bfd_h_put_8(abfd, 0, nsp.e_other);
1043 bfd_h_put_8(abfd, 0, nsp.e_type);
1044 }
7b02b4ed 1045
7d003262 1046 translate_to_native_sym_flags (&nsp, g, abfd);
7b02b4ed
JG
1047
1048 bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd);
7ed4093a
SC
1049 }
1050
7ed4093a 1051 /* Now output the strings. Be sure to put string length into correct
7b02b4ed 1052 byte ordering before writing it. */
7ed4093a
SC
1053 {
1054 char buffer[BYTES_IN_WORD];
1055 PUT_WORD (abfd, stindex, (unsigned char *)buffer);
1056
1057 bfd_write((PTR)buffer, 1, BYTES_IN_WORD, abfd);
1058 }
1059 generic = bfd_get_outsymbols(abfd);
1060 for (count = 0; count < bfd_get_symcount(abfd); count++)
1061 {
1062 asymbol *g = *(generic++);
1063
1064 if (g->name)
1065 {
1066 size_t length = strlen(g->name)+1;
1067 bfd_write((PTR)g->name, 1, length, abfd);
1068 }
1069 if ((g->flags & BSF_FAKE)==0) {
c618de01 1070 g->KEEPIT = (KEEPITTYPE) count;
7ed4093a
SC
1071 }
1072 }
1073 }
1074
1075
1076
1077unsigned int
1078DEFUN(NAME(aout,get_symtab),(abfd, location),
1079 bfd *abfd AND
1080 asymbol **location)
1081 {
1082 unsigned int counter = 0;
1083 aout_symbol_type *symbase;
1084
1085 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1086
1087 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1088 *(location++) = (asymbol *)( symbase++);
1089 *location++ =0;
1090 return bfd_get_symcount(abfd);
1091 }
1092
1093\f
1094/* Standard reloc stuff */
1095/* Output standard relocation information to a file in target byte order. */
1096
1097void
1098DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1099 bfd *abfd AND
1100 arelent *g AND
1101 struct reloc_std_external *natptr)
1102 {
1103 int r_index;
1104 int r_extern;
1105 unsigned int r_length;
1106 int r_pcrel;
1107 int r_baserel, r_jmptable, r_relative;
1108 unsigned int r_addend;
1109
1110 PUT_WORD(abfd, g->address, natptr->r_address);
1111
1112 r_length = g->howto->size ; /* Size as a power of two */
1113 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
1114 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
1115 r_baserel = 0;
1116 r_jmptable = 0;
1117 r_relative = 0;
1118
1119 r_addend = g->addend; /* Start here, see how it goes */
1120
1121 /* name was clobbered by aout_write_syms to be symbol index */
1122
1123 if (g->sym_ptr_ptr != NULL)
1124 {
1125 if ((*(g->sym_ptr_ptr))->section) {
1126 /* put the section offset into the addend for output */
1127 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1128 }
1129
c618de01 1130 r_index = ((*(g->sym_ptr_ptr))->KEEPIT);
7ed4093a
SC
1131 r_extern = 1;
1132 }
1133 else {
1134 r_extern = 0;
1135 if (g->section == NULL) {
1136 /* It is possible to have a reloc with nothing, we generate an
1137 abs + 0 */
1138 r_addend = 0;
1139 r_index = N_ABS | N_EXT;
1140 }
1141 else if(g->section->output_section == obj_textsec(abfd)) {
1142 r_index = N_TEXT | N_EXT;
1143 r_addend += g->section->output_section->vma;
1144 }
1145 else if (g->section->output_section == obj_datasec(abfd)) {
1146 r_index = N_DATA | N_EXT;
1147 r_addend += g->section->output_section->vma;
1148 }
1149 else if (g->section->output_section == obj_bsssec(abfd)) {
1150 r_index = N_BSS | N_EXT ;
1151 r_addend += g->section->output_section->vma;
1152 }
1153 else {
1154 BFD_ASSERT(0);
fb3be09b 1155 r_index = N_ABS | N_EXT;
7ed4093a
SC
1156 }
1157 }
1158
1159 /* now the fun stuff */
1160 if (abfd->xvec->header_byteorder_big_p != false) {
1161 natptr->r_index[0] = r_index >> 16;
1162 natptr->r_index[1] = r_index >> 8;
1163 natptr->r_index[2] = r_index;
1164 natptr->r_type[0] =
1165 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
1166 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
1167 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
1168 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
1169 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
1170 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
1171 } else {
1172 natptr->r_index[2] = r_index >> 16;
1173 natptr->r_index[1] = r_index >> 8;
1174 natptr->r_index[0] = r_index;
1175 natptr->r_type[0] =
1176 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
1177 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
1178 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
1179 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1180 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1181 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
1182 }
1183 }
1184
1185
1186/* Extended stuff */
1187/* Output extended relocation information to a file in target byte order. */
1188
1189void
1190DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
1191 bfd *abfd AND
1192 arelent *g AND
1193 register struct reloc_ext_external *natptr)
1194 {
1195 int r_index;
1196 int r_extern;
1197 unsigned int r_type;
1198 unsigned int r_addend;
1199
1200 PUT_WORD (abfd, g->address, natptr->r_address);
1201
1202 /* Find a type in the output format which matches the input howto -
1203 at the moment we assume input format == output format FIXME!! */
1204 r_type = (enum reloc_type) g->howto->type;
1205
1206 r_addend = g->addend; /* Start here, see how it goes */
1207
1208 /* name was clobbered by aout_write_syms to be symbol index*/
1209
1210 if (g->sym_ptr_ptr != NULL)
1211 {
1212 if ((*(g->sym_ptr_ptr))->section) {
1213 /* put the section offset into the addend for output */
1214 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1215 }
1216
c618de01 1217 r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
7ed4093a
SC
1218 r_extern = 1;
1219 }
1220 else {
1221 r_extern = 0;
1222 if (g->section == NULL) {
1223 BFD_ASSERT(0);
1224 r_index = N_ABS | N_EXT;
1225 }
1226 else if(g->section->output_section == obj_textsec(abfd)) {
1227 r_index = N_TEXT | N_EXT;
1228 r_addend += g->section->output_section->vma;
1229 }
1230 else if (g->section->output_section == obj_datasec(abfd)) {
1231 r_index = N_DATA | N_EXT;
1232 r_addend += g->section->output_section->vma;
1233 }
1234 else if (g->section->output_section == obj_bsssec(abfd)) {
1235 r_index = N_BSS | N_EXT ;
1236 r_addend += g->section->output_section->vma;
1237 }
1238 else {
1239 BFD_ASSERT(0);
fb3be09b 1240 r_index = N_ABS | N_EXT;
7ed4093a
SC
1241 }
1242 }
1243
1244 /* now the fun stuff */
1245 if (abfd->xvec->header_byteorder_big_p != false) {
1246 natptr->r_index[0] = r_index >> 16;
1247 natptr->r_index[1] = r_index >> 8;
1248 natptr->r_index[2] = r_index;
1249 natptr->r_type[0] =
1250 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1251 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1252 } else {
1253 natptr->r_index[2] = r_index >> 16;
1254 natptr->r_index[1] = r_index >> 8;
1255 natptr->r_index[0] = r_index;
1256 natptr->r_type[0] =
1257 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1258 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1259 }
1260
1261 PUT_WORD (abfd, r_addend, natptr->r_addend);
1262}
1263
1264#define MOVE_ADDRESS(ad) \
1265 if (r_extern) { \
1266 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1267 cache_ptr->section = (asection *)NULL; \
1268 cache_ptr->addend = ad; \
1269 } else { \
1270 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1271 switch (r_index) { \
1272 case N_TEXT: \
1273 case N_TEXT | N_EXT: \
1274 cache_ptr->section = obj_textsec(abfd); \
1275 cache_ptr->addend = ad - su->textsec->vma; \
1276 break; \
1277 case N_DATA: \
1278 case N_DATA | N_EXT: \
1279 cache_ptr->section = obj_datasec(abfd); \
1280 cache_ptr->addend = ad - su->datasec->vma; \
1281 break; \
1282 case N_BSS: \
1283 case N_BSS | N_EXT: \
1284 cache_ptr->section = obj_bsssec(abfd); \
1285 cache_ptr->addend = ad - su->bsssec->vma; \
1286 break; \
1287 case N_ABS: \
1288 case N_ABS | N_EXT: \
1289 cache_ptr->section = NULL; /* No section */ \
1290 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1291 BFD_ASSERT(1); \
1292 break; \
1293 default: \
1294 cache_ptr->section = NULL; /* No section */ \
1295 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1296 BFD_ASSERT(1); \
1297 break; \
1298 } \
1299 } \
1300
1301void
1302DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
1303 bfd *abfd AND
1304 struct reloc_ext_external *bytes AND
1305 arelent *cache_ptr AND
1306 asymbol **symbols)
1307{
1308 int r_index;
1309 int r_extern;
1310 unsigned int r_type;
1311 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1312
1313 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
1314
1315 /* now the fun stuff */
1316 if (abfd->xvec->header_byteorder_big_p != false) {
1317 r_index = (bytes->r_index[0] << 16)
1318 | (bytes->r_index[1] << 8)
1319 | bytes->r_index[2];
1320 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
1321 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
1322 >> RELOC_EXT_BITS_TYPE_SH_BIG;
1323 } else {
1324 r_index = (bytes->r_index[2] << 16)
1325 | (bytes->r_index[1] << 8)
1326 | bytes->r_index[0];
1327 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1328 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1329 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1330 }
1331
1332 cache_ptr->howto = howto_table_ext + r_type;
1333 MOVE_ADDRESS(GET_SWORD(abfd,bytes->r_addend));
1334}
1335
1336void
1337DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
1338 bfd *abfd AND
1339 struct reloc_std_external *bytes AND
1340 arelent *cache_ptr AND
1341 asymbol **symbols)
1342{
1343 int r_index;
1344 int r_extern;
1345 unsigned int r_length;
1346 int r_pcrel;
1347 int r_baserel, r_jmptable, r_relative;
1348 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1349
1350 cache_ptr->address = (int32_type)(bfd_h_get_32 (abfd, bytes->r_address));
1351
1352 /* now the fun stuff */
1353 if (abfd->xvec->header_byteorder_big_p != false) {
1354 r_index = (bytes->r_index[0] << 16)
1355 | (bytes->r_index[1] << 8)
1356 | bytes->r_index[2];
1357 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
1358 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
1359 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
1360 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1361 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
1362 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
1363 >> RELOC_STD_BITS_LENGTH_SH_BIG;
1364 } else {
1365 r_index = (bytes->r_index[2] << 16)
1366 | (bytes->r_index[1] << 8)
1367 | bytes->r_index[0];
1368 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1369 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
1370 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1371 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1372 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1373 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
1374 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1375 }
1376
1377 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
1378 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1379
1380 MOVE_ADDRESS(0);
1381}
1382
1383/* Reloc hackery */
1384
1385boolean
1386DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
1387 bfd *abfd AND
1388 sec_ptr asect AND
1389 asymbol **symbols)
1390{
1391 unsigned int count;
1392 bfd_size_type reloc_size;
1393 PTR relocs;
1394 arelent *reloc_cache;
1395 size_t each_size;
1396
1397 if (asect->relocation) return true;
1398
1399 if (asect->flags & SEC_CONSTRUCTOR) return true;
1400
1401 if (asect == obj_datasec (abfd)) {
1402 reloc_size = exec_hdr(abfd)->a_drsize;
1403 goto doit;
1404 }
1405
1406 if (asect == obj_textsec (abfd)) {
1407 reloc_size = exec_hdr(abfd)->a_trsize;
1408 goto doit;
1409 }
1410
1411 bfd_error = invalid_operation;
1412 return false;
1413
1414 doit:
1415 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1416 each_size = obj_reloc_entry_size (abfd);
1417
1418 count = reloc_size / each_size;
1419
1420
1421 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1422 (arelent)));
1423 if (!reloc_cache) {
1424nomem:
1425 bfd_error = no_memory;
1426 return false;
1427 }
1428
1429 relocs = (PTR) bfd_alloc (abfd, reloc_size);
1430 if (!relocs) {
1431 bfd_release (abfd, reloc_cache);
1432 goto nomem;
1433 }
1434
1435 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1436 bfd_release (abfd, relocs);
1437 bfd_release (abfd, reloc_cache);
1438 bfd_error = system_call_error;
1439 return false;
1440 }
1441
1442 if (each_size == RELOC_EXT_SIZE) {
1443 register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
1444 unsigned int counter = 0;
1445 arelent *cache_ptr = reloc_cache;
1446
1447 for (; counter < count; counter++, rptr++, cache_ptr++) {
1448 NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
1449 }
1450 } else {
1451 register struct reloc_std_external *rptr = (struct reloc_std_external*) relocs;
1452 unsigned int counter = 0;
1453 arelent *cache_ptr = reloc_cache;
1454
1455 for (; counter < count; counter++, rptr++, cache_ptr++) {
1456 NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
1457 }
1458
1459 }
1460
1461 bfd_release (abfd,relocs);
1462 asect->relocation = reloc_cache;
1463 asect->reloc_count = count;
1464 return true;
1465}
1466
1467
1468
1469/* Write out a relocation section into an object file. */
1470
1471boolean
1472DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
1473 bfd *abfd AND
1474 asection *section)
1475{
1476 arelent **generic;
1477 unsigned char *native, *natptr;
1478 size_t each_size;
1479
1480 unsigned int count = section->reloc_count;
1481 size_t natsize;
1482
1483 if (count == 0) return true;
1484
1485 each_size = obj_reloc_entry_size (abfd);
1486 natsize = each_size * count;
1487 native = (unsigned char *) bfd_zalloc (abfd, natsize);
1488 if (!native) {
1489 bfd_error = no_memory;
1490 return false;
1491 }
1492
1493 generic = section->orelocation;
1494
1495 if (each_size == RELOC_EXT_SIZE)
1496 {
1497 for (natptr = native;
1498 count != 0;
1499 --count, natptr += each_size, ++generic)
1500 NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
1501 }
1502 else
1503 {
1504 for (natptr = native;
1505 count != 0;
1506 --count, natptr += each_size, ++generic)
1507 NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
1508 }
1509
1510 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1511 bfd_release(abfd, native);
1512 return false;
1513 }
1514 bfd_release (abfd, native);
1515
1516 return true;
1517}
1518
1519/* This is stupid. This function should be a boolean predicate */
1520unsigned int
1521DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
1522 bfd *abfd AND
1523 sec_ptr section AND
1524 arelent **relptr AND
1525 asymbol **symbols)
1526{
1527 arelent *tblptr = section->relocation;
1528 unsigned int count;
1529
1530 if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
1531 return 0;
1532
1533 if (section->flags & SEC_CONSTRUCTOR) {
1534 arelent_chain *chain = section->constructor_chain;
1535 for (count = 0; count < section->reloc_count; count ++) {
1536 *relptr ++ = &chain->relent;
1537 chain = chain->next;
1538 }
1539 }
1540 else {
1541 tblptr = section->relocation;
1542 if (!tblptr) return 0;
1543
1544 for (count = 0; count++ < section->reloc_count;)
1545 {
1546 *relptr++ = tblptr++;
1547 }
1548 }
1549 *relptr = 0;
1550
1551 return section->reloc_count;
1552}
1553
1554unsigned int
1555DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
1556 bfd *abfd AND
1557 sec_ptr asect)
1558{
1559 if (bfd_get_format (abfd) != bfd_object) {
1560 bfd_error = invalid_operation;
1561 return 0;
1562 }
1563 if (asect->flags & SEC_CONSTRUCTOR) {
1564 return (sizeof (arelent *) * (asect->reloc_count+1));
1565 }
1566
1567
1568 if (asect == obj_datasec (abfd))
1569 return (sizeof (arelent *) *
1570 ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
1571 +1));
1572
1573 if (asect == obj_textsec (abfd))
1574 return (sizeof (arelent *) *
1575 ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
1576 +1));
1577
1578 bfd_error = invalid_operation;
1579 return 0;
1580}
1581
1582\f
1583 unsigned int
1584DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
1585 bfd *abfd)
1586{
1587 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1588
1589 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1590}
1591 alent *
1592DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
1593 bfd *ignore_abfd AND
1594 asymbol *ignore_symbol)
1595{
1596return (alent *)NULL;
1597}
1598
1599
1600void
1601DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
1602 bfd *ignore_abfd AND
1603 PTR afile AND
1604 asymbol *symbol AND
9e2dad8e 1605 bfd_print_symbol_type how)
7ed4093a
SC
1606{
1607 FILE *file = (FILE *)afile;
1608
1609 switch (how) {
9e2dad8e 1610 case bfd_print_symbol_name:
fb3be09b
JG
1611 if (symbol->name)
1612 fprintf(file,"%s", symbol->name);
7ed4093a 1613 break;
9e2dad8e 1614 case bfd_print_symbol_more:
7ed4093a
SC
1615 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1616 (unsigned)(aout_symbol(symbol)->other & 0xff),
1617 (unsigned)(aout_symbol(symbol)->type));
1618 break;
9e2dad8e 1619 case bfd_print_symbol_all:
7ed4093a
SC
1620 {
1621 CONST char *section_name = symbol->section == (asection *)NULL ?
f8adc62d 1622 (CONST char *)"*abs" : symbol->section->name;
7ed4093a
SC
1623
1624 bfd_print_symbol_vandf((PTR)file,symbol);
1625
fb3be09b 1626 fprintf(file," %-5s %04x %02x %02x",
7ed4093a
SC
1627 section_name,
1628 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1629 (unsigned)(aout_symbol(symbol)->other & 0xff),
9e2dad8e 1630 (unsigned)(aout_symbol(symbol)->type & 0xff));
fb3be09b
JG
1631 if (symbol->name)
1632 fprintf(file," %s", symbol->name);
7ed4093a
SC
1633 }
1634 break;
98d43107
JG
1635 case bfd_print_symbol_nm:
1636 {
1637 int section_code = bfd_decode_symclass (symbol);
1638
1639 if (section_code == 'U')
1640 fprintf(file, " ");
1641 else if (symbol->section != (asection *)NULL)
1642 fprintf_vma(file, symbol->value+symbol->section->vma);
1643 else
1644 fprintf_vma(file, symbol->value);
1645 if (section_code == '?')
1646 {
1647 int type_code = aout_symbol(symbol)->type & 0xff;
7de245d3 1648 char *stab_name = aout_stab_name(type_code);
98d43107
JG
1649 char buf[10];
1650 if (stab_name == NULL)
1651 {
1652 sprintf(buf, "(%d)", type_code);
1653 stab_name = buf;
1654 }
1655 fprintf(file," - %02x %04x %5s",
1656 (unsigned)(aout_symbol(symbol)->other & 0xff),
1657 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1658 stab_name);
1659 }
1660 else
1661 fprintf(file," %c", section_code);
1662 if (symbol->name)
1663 fprintf(file," %s", symbol->name);
1664 }
1665 break;
7ed4093a
SC
1666 }
1667}
1668
1669/*
6724ff46 1670 provided a BFD, a section and an offset into the section, calculate
7ed4093a
SC
1671 and return the name of the source file and the line nearest to the
1672 wanted location.
1673*/
1674
1675boolean
1676DEFUN(NAME(aout,find_nearest_line),(abfd,
1677 section,
1678 symbols,
1679 offset,
1680 filename_ptr,
1681 functionname_ptr,
1682 line_ptr),
1683 bfd *abfd AND
1684 asection *section AND
1685 asymbol **symbols AND
1686 bfd_vma offset AND
1687 CONST char **filename_ptr AND
1688 CONST char **functionname_ptr AND
1689 unsigned int *line_ptr)
1690{
1691 /* Run down the file looking for the filename, function and linenumber */
1692 asymbol **p;
1693 static char buffer[100];
98d43107 1694 static char filename_buffer[200];
7ed4093a
SC
1695 bfd_vma high_line_vma = ~0;
1696 bfd_vma low_func_vma = 0;
1697 asymbol *func = 0;
1698 *filename_ptr = abfd->filename;
1699 *functionname_ptr = 0;
1700 *line_ptr = 0;
1701 if (symbols != (asymbol **)NULL) {
1702 for (p = symbols; *p; p++) {
1703 aout_symbol_type *q = (aout_symbol_type *)(*p);
98d43107 1704 next:
7ed4093a
SC
1705 switch (q->type){
1706 case N_SO:
1707 *filename_ptr = q->symbol.name;
98d43107
JG
1708 /* Look ahead to next symbol to check if that too is an N_SO. */
1709 p++;
1710 if (*p == NULL)
1711 break;
1712 q = (aout_symbol_type *)(*p);
1713 if (q->type != N_SO)
1714 goto next;
1715
1716 /* Found a second N_SO First is directory; second is filename. */
1717 if (q->symbol.name[0] == '/')
1718 *filename_ptr = q->symbol.name;
1719 else
1720 {
1721 sprintf(filename_buffer, "%.140s%.50s",
1722 *filename_ptr, q->symbol.name);
1723 *filename_ptr = filename_buffer;
1724 }
1725
7ed4093a
SC
1726 if (obj_textsec(abfd) != section) {
1727 return true;
1728 }
1729 break;
1730 case N_SLINE:
1731
1732 case N_DSLINE:
1733 case N_BSLINE:
1734 /* We'll keep this if it resolves nearer than the one we have already */
1735 if (q->symbol.value >= offset &&
1736 q->symbol.value < high_line_vma) {
1737 *line_ptr = q->desc;
1738 high_line_vma = q->symbol.value;
1739 }
1740 break;
1741 case N_FUN:
1742 {
1743 /* We'll keep this if it is nearer than the one we have already */
1744 if (q->symbol.value >= low_func_vma &&
1745 q->symbol.value <= offset) {
1746 low_func_vma = q->symbol.value;
1747 func = (asymbol *)q;
1748 }
1749 if (*line_ptr && func) {
1750 CONST char *function = func->name;
1751 char *p;
1752 strncpy(buffer, function, sizeof(buffer)-1);
1753 buffer[sizeof(buffer)-1] = 0;
1754 /* Have to remove : stuff */
1755 p = strchr(buffer,':');
7b02b4ed 1756 if (p != NULL) { *p = '\0'; }
7ed4093a
SC
1757 *functionname_ptr = buffer;
1758 return true;
1759
1760 }
1761 }
1762 break;
1763 }
1764 }
1765 }
1766
1767 return true;
1768
1769}
1770
1771int
cbdc7909
JG
1772DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
1773 bfd *abfd AND
9e2dad8e 1774 boolean execable)
7ed4093a 1775{
cbdc7909 1776 return adata(abfd)->exec_bytes_size;
7ed4093a 1777}
This page took 0.108122 seconds and 4 git commands to generate.