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