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