]> Git Repo - binutils.git/blame - bfd/aoutx.h
Make writing to files work properly. (Fixes to BFD are also needed.)
[binutils.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)
706 { /* set by bfd.c handler */
707 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
708 {
709 bfd_error = invalid_operation;
710 return false;
711 }
712/* if (abfd->flags & D_PAGED) {
713 obj_textsec(abfd)->filepos = 0;
714 }
715 else*/ {
716 obj_textsec(abfd)->filepos = EXEC_BYTES_SIZE;
717 }
718 obj_textsec(abfd)->size = align_power(obj_textsec(abfd)->size,
719 obj_textsec(abfd)->alignment_power);
720 obj_datasec(abfd)->filepos = obj_textsec (abfd)->size + EXEC_BYTES_SIZE;
721 obj_datasec(abfd)->size = align_power(obj_datasec(abfd)->size,
722 obj_datasec(abfd)->alignment_power);
723
724
725 }
726 /* regardless, once we know what we're doing, we might as well get going */
727 if (section != obj_bsssec(abfd))
728 {
729 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
730
731 if (count) {
732 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
733 true : false;
734 }
735 return false;
736 }
737 return true;
738}
739\f
740/* Classify stabs symbols */
741
742#define sym_in_text_section(sym) \
743(((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
744
745#define sym_in_data_section(sym) \
746(((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
747
748#define sym_in_bss_section(sym) \
749(((sym)->type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
750
751/* Symbol is undefined if type is N_UNDF|N_EXT and if it has
752zero in the "value" field. Nonzeroes there are fortrancommon
753symbols. */
754#define sym_is_undefined(sym) \
755((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
756
757/* Symbol is a global definition if N_EXT is on and if it has
758a nonzero type field. */
759#define sym_is_global_defn(sym) \
760(((sym)->type & N_EXT) && (sym)->type & N_TYPE)
761
762/* Symbol is debugger info if any bits outside N_TYPE or N_EXT
763are on. */
764#define sym_is_debugger_info(sym) \
765((sym)->type & ~(N_EXT | N_TYPE))
766
767#define sym_is_fortrancommon(sym) \
768(((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
769
770/* Symbol is absolute if it has N_ABS set */
771#define sym_is_absolute(sym) \
772(((sym)->type & N_TYPE)== N_ABS)
773
774
775#define sym_is_indirect(sym) \
776(((sym)->type & N_ABS)== N_ABS)
777
778/* Only in their own functions for ease of debugging; when sym flags have
779stabilised these should be inlined into their (single) caller */
780
781static void
782DEFUN(translate_from_native_sym_flags,(sym_pointer, cache_ptr, abfd),
783 struct external_nlist *sym_pointer AND
784 aout_symbol_type *cache_ptr AND
785 bfd *abfd)
c618de01
SC
786 {
787 switch (cache_ptr->type & N_TYPE) {
788 case N_SETA:
789 case N_SETT:
790 case N_SETD:
791 case N_SETB:
792 {
793 char *copy = bfd_alloc(abfd, strlen(cache_ptr->symbol.name)+1);
794 asection *section ;
795 arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
796 strcpy(copy, cache_ptr->symbol.name);
797 section = bfd_make_section(abfd,copy);
798 switch ( (cache_ptr->type & N_TYPE) ) {
799 case N_SETA:
800 section->flags = SEC_CONSTRUCTOR;
801 reloc->relent.section = (asection *)NULL;
802 cache_ptr->symbol.section = (asection *)NULL;
803 break;
804 case N_SETT:
805 section->flags = SEC_CONSTRUCTOR_TEXT;
806 reloc->relent.section = (asection *)obj_textsec(abfd);
807 cache_ptr->symbol.value -= reloc->relent.section->vma;
808 break;
809 case N_SETD:
810 section->flags = SEC_CONSTRUCTOR_DATA;
811 reloc->relent.section = (asection *)obj_datasec(abfd);
812 cache_ptr->symbol.value -= reloc->relent.section->vma;
813 break;
814 case N_SETB:
815 section->flags = SEC_CONSTRUCTOR_BSS;
816 reloc->relent.section = (asection *)obj_bsssec(abfd);
817 cache_ptr->symbol.value -= reloc->relent.section->vma;
818 break;
819 }
820 cache_ptr->symbol.section = reloc->relent.section;
821 reloc->relent.addend = cache_ptr->symbol.value ;
7ed4093a 822
c618de01
SC
823 /* We modify the symbol to belong to a section depending upon the
824 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
825 really care, and add to the size of the section to contain a
826 pointer to the symbol. Build a reloc entry to relocate to this
827 symbol attached to this section. */
828
829
830 section->reloc_count++;
831 section->alignment_power = 2;
832 reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
833 reloc->next = section->constructor_chain;
834 section->constructor_chain = reloc;
835 reloc->relent.address = section->size;
836 section->size += sizeof(int *);
837
838 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
839 cache_ptr->symbol.flags |= BSF_DEBUGGING | BSF_CONSTRUCTOR;
840 }
841 break;
7ed4093a 842 default:
88dfcd68
SC
843 if (cache_ptr->type == N_WARNING)
844 {
845 /* This symbol is the text of a warning message, the next symbol
846 is the symbol to associate the warning with */
847 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
848 cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
849 /* We furgle with the next symbol in place. We don't want it to be undefined, we'll trample the type */
850 (sym_pointer+1)->e_type[0] = 0xff;
851 break;
852 }
c618de01 853 if ((cache_ptr->type | N_EXT) == (N_INDR | N_EXT)) {
88dfcd68
SC
854 /* Two symbols in a row for an INDR message. The first symbol
855 contains the name we will match, the second symbol contains the
856 name the first name is translated into. It is supplied to us
857 undefined. This is good, since we want to pull in any files which
858 define it */
859 cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT;
860 cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
861 break;
862 }
863
864
7ed4093a
SC
865 if (sym_is_debugger_info (cache_ptr)) {
866 cache_ptr->symbol.flags = BSF_DEBUGGING ;
867 /* Work out the section correct for this symbol */
868 switch (cache_ptr->type & N_TYPE)
869 {
870 case N_TEXT:
871 case N_FN:
872 cache_ptr->symbol.section = obj_textsec (abfd);
873 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
874 break;
875 case N_DATA:
876 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
877 cache_ptr->symbol.section = obj_datasec (abfd);
878 break;
879 case N_BSS :
880 cache_ptr->symbol.section = obj_bsssec (abfd);
881 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
882 break;
883 case N_ABS:
884 default:
885 cache_ptr->symbol.section = 0;
886 break;
887 }
888 }
889 else {
88dfcd68 890
7ed4093a
SC
891 if (sym_is_fortrancommon (cache_ptr))
892 {
893 cache_ptr->symbol.flags = BSF_FORT_COMM;
894 cache_ptr->symbol.section = (asection *)NULL;
895 }
896 else {
897 if (sym_is_undefined (cache_ptr)) {
898 cache_ptr->symbol.flags = BSF_UNDEFINED;
899 }
900 else if (sym_is_global_defn (cache_ptr)) {
901 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
902 }
88dfcd68 903
7ed4093a
SC
904 else if (sym_is_absolute (cache_ptr)) {
905 cache_ptr->symbol.flags = BSF_ABSOLUTE;
906 }
907 else {
908 cache_ptr->symbol.flags = BSF_LOCAL;
909 }
88dfcd68 910
7ed4093a
SC
911 /* In a.out, the value of a symbol is always relative to the
912 * start of the file, if this is a data symbol we'll subtract
913 * the size of the text section to get the section relative
914 * value. If this is a bss symbol (which would be strange)
915 * we'll subtract the size of the previous two sections
916 * to find the section relative address.
917 */
88dfcd68 918
7ed4093a
SC
919 if (sym_in_text_section (cache_ptr)) {
920 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
921 cache_ptr->symbol.section = obj_textsec (abfd);
922 }
923 else if (sym_in_data_section (cache_ptr)){
924 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
925 cache_ptr->symbol.section = obj_datasec (abfd);
926 }
927 else if (sym_in_bss_section(cache_ptr)) {
928 cache_ptr->symbol.section = obj_bsssec (abfd);
929 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
930 }
931 else {
932 cache_ptr->symbol.section = (asection *)NULL;
933 cache_ptr->symbol.flags |= BSF_ABSOLUTE;
934 }
935 }
936 }
937 }
938}
939
940static void
941DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
942 struct external_nlist *sym_pointer AND
943 asymbol *cache_ptr AND
944 bfd *abfd)
945{
946 bfd_vma value = cache_ptr->value;
947
948 if (bfd_get_section(cache_ptr)) {
949 if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
950 sym_pointer->e_type[0] |= N_BSS;
951 }
952 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
953 sym_pointer->e_type[0] |= N_DATA;
954 }
955 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
956 sym_pointer->e_type[0] |= N_TEXT;
957 }
958 else {
959 bfd_error_vector.nonrepresentable_section(abfd,
960 bfd_get_output_section(cache_ptr)->name);
961 }
962 /* Turn the symbol from section relative to absolute again */
963
964 value +=
965 cache_ptr->section->output_section->vma
966 + cache_ptr->section->output_offset ;
967 }
968 else {
969 sym_pointer->e_type[0] |= N_ABS;
970 }
88dfcd68
SC
971 if (cache_ptr->flags & (BSF_WARNING)) {
972 (sym_pointer+1)->e_type[0] = 1;
973 }
7ed4093a
SC
974 if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
975 sym_pointer->e_type[0] = (N_UNDF | N_EXT);
976 }
977 else {
978 if (cache_ptr->flags & BSF_ABSOLUTE) {
979 sym_pointer->e_type[0] |= N_ABS;
980 }
981
982 if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
983 sym_pointer->e_type[0] |= N_EXT;
984 }
985 if (cache_ptr->flags & BSF_DEBUGGING) {
986 sym_pointer->e_type [0]= ((aout_symbol_type *)cache_ptr)->type;
987 }
988 }
989 PUT_WORD(abfd, value, sym_pointer->e_value);
990}
991\f
992/* Native-level interface to symbols. */
993
994/* We read the symbols into a buffer, which is discarded when this
995function exits. We read the strings into a buffer large enough to
996hold them all plus all the cached symbol entries. */
997
998asymbol *
999DEFUN(NAME(aout,make_empty_symbol),(abfd),
1000 bfd *abfd)
1001 {
1002 aout_symbol_type *new =
1003 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1004 new->symbol.the_bfd = abfd;
1005
1006 return &new->symbol;
1007 }
1008
1009boolean
1010DEFUN(NAME(aout,slurp_symbol_table),(abfd),
1011 bfd *abfd)
1012 {
1013 bfd_size_type symbol_size;
1014 bfd_size_type string_size;
1015 unsigned char string_chars[BYTES_IN_WORD];
1016 struct external_nlist *syms;
1017 char *strings;
1018 aout_symbol_type *cached;
1019
1020 /* If there's no work to be done, don't do any */
1021 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1022 symbol_size = exec_hdr(abfd)->a_syms;
1023 if (symbol_size == 0) {
1024 bfd_error = no_symbols;
1025 return false;
1026 }
1027
1028 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1029 if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
1030 return false;
1031 string_size = GET_WORD (abfd, string_chars);
1032
1033 strings =(char *) bfd_alloc(abfd, string_size + 1);
1034 cached = (aout_symbol_type *)
1035 bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
67c060c3
SC
1036
1037 /* malloc this, so we can free it if simply. The symbol caching
1038 might want to allocate onto the bfd's obstack */
1039 syms = (struct external_nlist *) malloc(symbol_size);
7ed4093a
SC
1040 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1041 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
1042 bailout:
67c060c3 1043 if (syms) free (syms);
7ed4093a
SC
1044 if (cached) bfd_release (abfd, cached);
1045 if (strings)bfd_release (abfd, strings);
1046 return false;
1047 }
1048
1049 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1050 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
1051 goto bailout;
1052 }
1053
1054 /* OK, now walk the new symtable, cacheing symbol properties */
1055 {
1056 register struct external_nlist *sym_pointer;
1057 register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
1058 register aout_symbol_type *cache_ptr = cached;
1059
1060 /* Run through table and copy values */
1061 for (sym_pointer = syms, cache_ptr = cached;
1062 sym_pointer < sym_end; sym_pointer++, cache_ptr++)
1063 {
1064 bfd_vma x = GET_WORD(abfd, sym_pointer->e_strx);
1065 cache_ptr->symbol.the_bfd = abfd;
1066 if (x)
1067 cache_ptr->symbol.name = x + strings;
1068 else
1069 cache_ptr->symbol.name = (char *)NULL;
1070
1071 cache_ptr->symbol.value = GET_SWORD(abfd, sym_pointer->e_value);
1072 cache_ptr->desc = bfd_get_16(abfd, sym_pointer->e_desc);
1073 cache_ptr->other =bfd_get_8(abfd, sym_pointer->e_other);
1074 cache_ptr->type = bfd_get_8(abfd, sym_pointer->e_type);
1075 cache_ptr->symbol.udata = 0;
1076 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1077 }
1078 }
1079
1080 obj_aout_symbols (abfd) = cached;
67c060c3 1081 free((PTR)syms);
7ed4093a
SC
1082
1083 return true;
1084 }
1085
1086
1087void
1088DEFUN(NAME(aout,write_syms),(abfd),
1089 bfd *abfd)
1090 {
1091 unsigned int count ;
1092 asymbol **generic = bfd_get_outsymbols (abfd);
1093
1094 bfd_size_type stindex = BYTES_IN_WORD; /* initial string length */
1095
1096 for (count = 0; count < bfd_get_symcount (abfd); count++) {
1097 asymbol *g = generic[count];
1098 struct external_nlist nsp;
1099
1100
1101 if (g->name) {
1102 unsigned int length = strlen(g->name) +1;
1103 PUT_WORD (abfd, stindex, (unsigned char *)nsp.e_strx);
1104 stindex += length;
1105 }
1106 else {
1107 PUT_WORD (abfd, 0, (unsigned char *)nsp.e_strx);
1108 }
1109
1110 if (g->the_bfd->xvec->flavour == abfd->xvec->flavour)
1111 {
1112 bfd_h_put_16(abfd, aout_symbol(g)->desc, nsp.e_desc);
1113 bfd_h_put_8(abfd, aout_symbol(g)->other, nsp.e_other);
1114 bfd_h_put_8(abfd, aout_symbol(g)->type, nsp.e_type);
1115 }
1116 else
1117 {
1118 bfd_h_put_16(abfd,0, nsp.e_desc);
1119 bfd_h_put_8(abfd, 0, nsp.e_other);
1120 bfd_h_put_8(abfd, 0, nsp.e_type);
1121 }
1122
1123
1124
7d003262 1125 translate_to_native_sym_flags (&nsp, g, abfd);
7ed4093a
SC
1126
1127 bfd_write((PTR)&nsp,1,EXTERNAL_LIST_SIZE, abfd);
1128 }
1129
1130
1131 /* Now output the strings. Be sure to put string length into correct
1132 * byte ordering before writing it.
1133 */
1134 {
1135 char buffer[BYTES_IN_WORD];
1136 PUT_WORD (abfd, stindex, (unsigned char *)buffer);
1137
1138 bfd_write((PTR)buffer, 1, BYTES_IN_WORD, abfd);
1139 }
1140 generic = bfd_get_outsymbols(abfd);
1141 for (count = 0; count < bfd_get_symcount(abfd); count++)
1142 {
1143 asymbol *g = *(generic++);
1144
1145 if (g->name)
1146 {
1147 size_t length = strlen(g->name)+1;
1148 bfd_write((PTR)g->name, 1, length, abfd);
1149 }
1150 if ((g->flags & BSF_FAKE)==0) {
c618de01 1151 g->KEEPIT = (KEEPITTYPE) count;
7ed4093a
SC
1152 }
1153 }
1154 }
1155
1156
1157
1158unsigned int
1159DEFUN(NAME(aout,get_symtab),(abfd, location),
1160 bfd *abfd AND
1161 asymbol **location)
1162 {
1163 unsigned int counter = 0;
1164 aout_symbol_type *symbase;
1165
1166 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1167
1168 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1169 *(location++) = (asymbol *)( symbase++);
1170 *location++ =0;
1171 return bfd_get_symcount(abfd);
1172 }
1173
1174\f
1175/* Standard reloc stuff */
1176/* Output standard relocation information to a file in target byte order. */
1177
1178void
1179DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1180 bfd *abfd AND
1181 arelent *g AND
1182 struct reloc_std_external *natptr)
1183 {
1184 int r_index;
1185 int r_extern;
1186 unsigned int r_length;
1187 int r_pcrel;
1188 int r_baserel, r_jmptable, r_relative;
1189 unsigned int r_addend;
1190
1191 PUT_WORD(abfd, g->address, natptr->r_address);
1192
1193 r_length = g->howto->size ; /* Size as a power of two */
1194 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
1195 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
1196 r_baserel = 0;
1197 r_jmptable = 0;
1198 r_relative = 0;
1199
1200 r_addend = g->addend; /* Start here, see how it goes */
1201
1202 /* name was clobbered by aout_write_syms to be symbol index */
1203
1204 if (g->sym_ptr_ptr != NULL)
1205 {
1206 if ((*(g->sym_ptr_ptr))->section) {
1207 /* put the section offset into the addend for output */
1208 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1209 }
1210
c618de01 1211 r_index = ((*(g->sym_ptr_ptr))->KEEPIT);
7ed4093a
SC
1212 r_extern = 1;
1213 }
1214 else {
1215 r_extern = 0;
1216 if (g->section == NULL) {
1217 /* It is possible to have a reloc with nothing, we generate an
1218 abs + 0 */
1219 r_addend = 0;
1220 r_index = N_ABS | N_EXT;
1221 }
1222 else if(g->section->output_section == obj_textsec(abfd)) {
1223 r_index = N_TEXT | N_EXT;
1224 r_addend += g->section->output_section->vma;
1225 }
1226 else if (g->section->output_section == obj_datasec(abfd)) {
1227 r_index = N_DATA | N_EXT;
1228 r_addend += g->section->output_section->vma;
1229 }
1230 else if (g->section->output_section == obj_bsssec(abfd)) {
1231 r_index = N_BSS | N_EXT ;
1232 r_addend += g->section->output_section->vma;
1233 }
1234 else {
1235 BFD_ASSERT(0);
1236 }
1237 }
1238
1239 /* now the fun stuff */
1240 if (abfd->xvec->header_byteorder_big_p != false) {
1241 natptr->r_index[0] = r_index >> 16;
1242 natptr->r_index[1] = r_index >> 8;
1243 natptr->r_index[2] = r_index;
1244 natptr->r_type[0] =
1245 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
1246 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
1247 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
1248 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
1249 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
1250 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
1251 } else {
1252 natptr->r_index[2] = r_index >> 16;
1253 natptr->r_index[1] = r_index >> 8;
1254 natptr->r_index[0] = r_index;
1255 natptr->r_type[0] =
1256 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
1257 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
1258 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
1259 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1260 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1261 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
1262 }
1263 }
1264
1265
1266/* Extended stuff */
1267/* Output extended relocation information to a file in target byte order. */
1268
1269void
1270DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
1271 bfd *abfd AND
1272 arelent *g AND
1273 register struct reloc_ext_external *natptr)
1274 {
1275 int r_index;
1276 int r_extern;
1277 unsigned int r_type;
1278 unsigned int r_addend;
1279
1280 PUT_WORD (abfd, g->address, natptr->r_address);
1281
1282 /* Find a type in the output format which matches the input howto -
1283 at the moment we assume input format == output format FIXME!! */
1284 r_type = (enum reloc_type) g->howto->type;
1285
1286 r_addend = g->addend; /* Start here, see how it goes */
1287
1288 /* name was clobbered by aout_write_syms to be symbol index*/
1289
1290 if (g->sym_ptr_ptr != NULL)
1291 {
1292 if ((*(g->sym_ptr_ptr))->section) {
1293 /* put the section offset into the addend for output */
1294 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1295 }
1296
c618de01 1297 r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
7ed4093a
SC
1298 r_extern = 1;
1299 }
1300 else {
1301 r_extern = 0;
1302 if (g->section == NULL) {
1303 BFD_ASSERT(0);
1304 r_index = N_ABS | N_EXT;
1305 }
1306 else if(g->section->output_section == obj_textsec(abfd)) {
1307 r_index = N_TEXT | N_EXT;
1308 r_addend += g->section->output_section->vma;
1309 }
1310 else if (g->section->output_section == obj_datasec(abfd)) {
1311 r_index = N_DATA | N_EXT;
1312 r_addend += g->section->output_section->vma;
1313 }
1314 else if (g->section->output_section == obj_bsssec(abfd)) {
1315 r_index = N_BSS | N_EXT ;
1316 r_addend += g->section->output_section->vma;
1317 }
1318 else {
1319 BFD_ASSERT(0);
1320 }
1321 }
1322
1323 /* now the fun stuff */
1324 if (abfd->xvec->header_byteorder_big_p != false) {
1325 natptr->r_index[0] = r_index >> 16;
1326 natptr->r_index[1] = r_index >> 8;
1327 natptr->r_index[2] = r_index;
1328 natptr->r_type[0] =
1329 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1330 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1331 } else {
1332 natptr->r_index[2] = r_index >> 16;
1333 natptr->r_index[1] = r_index >> 8;
1334 natptr->r_index[0] = r_index;
1335 natptr->r_type[0] =
1336 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1337 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1338 }
1339
1340 PUT_WORD (abfd, r_addend, natptr->r_addend);
1341}
1342
1343#define MOVE_ADDRESS(ad) \
1344 if (r_extern) { \
1345 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1346 cache_ptr->section = (asection *)NULL; \
1347 cache_ptr->addend = ad; \
1348 } else { \
1349 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1350 switch (r_index) { \
1351 case N_TEXT: \
1352 case N_TEXT | N_EXT: \
1353 cache_ptr->section = obj_textsec(abfd); \
1354 cache_ptr->addend = ad - su->textsec->vma; \
1355 break; \
1356 case N_DATA: \
1357 case N_DATA | N_EXT: \
1358 cache_ptr->section = obj_datasec(abfd); \
1359 cache_ptr->addend = ad - su->datasec->vma; \
1360 break; \
1361 case N_BSS: \
1362 case N_BSS | N_EXT: \
1363 cache_ptr->section = obj_bsssec(abfd); \
1364 cache_ptr->addend = ad - su->bsssec->vma; \
1365 break; \
1366 case N_ABS: \
1367 case N_ABS | N_EXT: \
1368 cache_ptr->section = NULL; /* No section */ \
1369 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1370 BFD_ASSERT(1); \
1371 break; \
1372 default: \
1373 cache_ptr->section = NULL; /* No section */ \
1374 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1375 BFD_ASSERT(1); \
1376 break; \
1377 } \
1378 } \
1379
1380void
1381DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
1382 bfd *abfd AND
1383 struct reloc_ext_external *bytes AND
1384 arelent *cache_ptr AND
1385 asymbol **symbols)
1386{
1387 int r_index;
1388 int r_extern;
1389 unsigned int r_type;
1390 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1391
1392 cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
1393
1394 /* now the fun stuff */
1395 if (abfd->xvec->header_byteorder_big_p != false) {
1396 r_index = (bytes->r_index[0] << 16)
1397 | (bytes->r_index[1] << 8)
1398 | bytes->r_index[2];
1399 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
1400 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
1401 >> RELOC_EXT_BITS_TYPE_SH_BIG;
1402 } else {
1403 r_index = (bytes->r_index[2] << 16)
1404 | (bytes->r_index[1] << 8)
1405 | bytes->r_index[0];
1406 r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1407 r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1408 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1409 }
1410
1411 cache_ptr->howto = howto_table_ext + r_type;
1412 MOVE_ADDRESS(GET_SWORD(abfd,bytes->r_addend));
1413}
1414
1415void
1416DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
1417 bfd *abfd AND
1418 struct reloc_std_external *bytes AND
1419 arelent *cache_ptr AND
1420 asymbol **symbols)
1421{
1422 int r_index;
1423 int r_extern;
1424 unsigned int r_length;
1425 int r_pcrel;
1426 int r_baserel, r_jmptable, r_relative;
1427 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1428
1429 cache_ptr->address = (int32_type)(bfd_h_get_32 (abfd, bytes->r_address));
1430
1431 /* now the fun stuff */
1432 if (abfd->xvec->header_byteorder_big_p != false) {
1433 r_index = (bytes->r_index[0] << 16)
1434 | (bytes->r_index[1] << 8)
1435 | bytes->r_index[2];
1436 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
1437 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
1438 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
1439 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1440 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
1441 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
1442 >> RELOC_STD_BITS_LENGTH_SH_BIG;
1443 } else {
1444 r_index = (bytes->r_index[2] << 16)
1445 | (bytes->r_index[1] << 8)
1446 | bytes->r_index[0];
1447 r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1448 r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
1449 r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1450 r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1451 r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1452 r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
1453 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1454 }
1455
1456 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
1457 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1458
1459 MOVE_ADDRESS(0);
1460}
1461
1462/* Reloc hackery */
1463
1464boolean
1465DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
1466 bfd *abfd AND
1467 sec_ptr asect AND
1468 asymbol **symbols)
1469{
1470 unsigned int count;
1471 bfd_size_type reloc_size;
1472 PTR relocs;
1473 arelent *reloc_cache;
1474 size_t each_size;
1475
1476 if (asect->relocation) return true;
1477
1478 if (asect->flags & SEC_CONSTRUCTOR) return true;
1479
1480 if (asect == obj_datasec (abfd)) {
1481 reloc_size = exec_hdr(abfd)->a_drsize;
1482 goto doit;
1483 }
1484
1485 if (asect == obj_textsec (abfd)) {
1486 reloc_size = exec_hdr(abfd)->a_trsize;
1487 goto doit;
1488 }
1489
1490 bfd_error = invalid_operation;
1491 return false;
1492
1493 doit:
1494 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1495 each_size = obj_reloc_entry_size (abfd);
1496
1497 count = reloc_size / each_size;
1498
1499
1500 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1501 (arelent)));
1502 if (!reloc_cache) {
1503nomem:
1504 bfd_error = no_memory;
1505 return false;
1506 }
1507
1508 relocs = (PTR) bfd_alloc (abfd, reloc_size);
1509 if (!relocs) {
1510 bfd_release (abfd, reloc_cache);
1511 goto nomem;
1512 }
1513
1514 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1515 bfd_release (abfd, relocs);
1516 bfd_release (abfd, reloc_cache);
1517 bfd_error = system_call_error;
1518 return false;
1519 }
1520
1521 if (each_size == RELOC_EXT_SIZE) {
1522 register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
1523 unsigned int counter = 0;
1524 arelent *cache_ptr = reloc_cache;
1525
1526 for (; counter < count; counter++, rptr++, cache_ptr++) {
1527 NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
1528 }
1529 } else {
1530 register struct reloc_std_external *rptr = (struct reloc_std_external*) relocs;
1531 unsigned int counter = 0;
1532 arelent *cache_ptr = reloc_cache;
1533
1534 for (; counter < count; counter++, rptr++, cache_ptr++) {
1535 NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
1536 }
1537
1538 }
1539
1540 bfd_release (abfd,relocs);
1541 asect->relocation = reloc_cache;
1542 asect->reloc_count = count;
1543 return true;
1544}
1545
1546
1547
1548/* Write out a relocation section into an object file. */
1549
1550boolean
1551DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
1552 bfd *abfd AND
1553 asection *section)
1554{
1555 arelent **generic;
1556 unsigned char *native, *natptr;
1557 size_t each_size;
1558
1559 unsigned int count = section->reloc_count;
1560 size_t natsize;
1561
1562 if (count == 0) return true;
1563
1564 each_size = obj_reloc_entry_size (abfd);
1565 natsize = each_size * count;
1566 native = (unsigned char *) bfd_zalloc (abfd, natsize);
1567 if (!native) {
1568 bfd_error = no_memory;
1569 return false;
1570 }
1571
1572 generic = section->orelocation;
1573
1574 if (each_size == RELOC_EXT_SIZE)
1575 {
1576 for (natptr = native;
1577 count != 0;
1578 --count, natptr += each_size, ++generic)
1579 NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
1580 }
1581 else
1582 {
1583 for (natptr = native;
1584 count != 0;
1585 --count, natptr += each_size, ++generic)
1586 NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
1587 }
1588
1589 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1590 bfd_release(abfd, native);
1591 return false;
1592 }
1593 bfd_release (abfd, native);
1594
1595 return true;
1596}
1597
1598/* This is stupid. This function should be a boolean predicate */
1599unsigned int
1600DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
1601 bfd *abfd AND
1602 sec_ptr section AND
1603 arelent **relptr AND
1604 asymbol **symbols)
1605{
1606 arelent *tblptr = section->relocation;
1607 unsigned int count;
1608
1609 if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
1610 return 0;
1611
1612 if (section->flags & SEC_CONSTRUCTOR) {
1613 arelent_chain *chain = section->constructor_chain;
1614 for (count = 0; count < section->reloc_count; count ++) {
1615 *relptr ++ = &chain->relent;
1616 chain = chain->next;
1617 }
1618 }
1619 else {
1620 tblptr = section->relocation;
1621 if (!tblptr) return 0;
1622
1623 for (count = 0; count++ < section->reloc_count;)
1624 {
1625 *relptr++ = tblptr++;
1626 }
1627 }
1628 *relptr = 0;
1629
1630 return section->reloc_count;
1631}
1632
1633unsigned int
1634DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
1635 bfd *abfd AND
1636 sec_ptr asect)
1637{
1638 if (bfd_get_format (abfd) != bfd_object) {
1639 bfd_error = invalid_operation;
1640 return 0;
1641 }
1642 if (asect->flags & SEC_CONSTRUCTOR) {
1643 return (sizeof (arelent *) * (asect->reloc_count+1));
1644 }
1645
1646
1647 if (asect == obj_datasec (abfd))
1648 return (sizeof (arelent *) *
1649 ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
1650 +1));
1651
1652 if (asect == obj_textsec (abfd))
1653 return (sizeof (arelent *) *
1654 ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
1655 +1));
1656
1657 bfd_error = invalid_operation;
1658 return 0;
1659}
1660
1661\f
1662 unsigned int
1663DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
1664 bfd *abfd)
1665{
1666 if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1667
1668 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1669}
1670 alent *
1671DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
1672 bfd *ignore_abfd AND
1673 asymbol *ignore_symbol)
1674{
1675return (alent *)NULL;
1676}
1677
1678
1679void
1680DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
1681 bfd *ignore_abfd AND
1682 PTR afile AND
1683 asymbol *symbol AND
1684 bfd_print_symbol_enum_type how)
1685{
1686 FILE *file = (FILE *)afile;
1687
1688 switch (how) {
1689 case bfd_print_symbol_name_enum:
1690 fprintf(file,"%s", symbol->name);
1691 break;
1692 case bfd_print_symbol_type_enum:
1693 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1694 (unsigned)(aout_symbol(symbol)->other & 0xff),
1695 (unsigned)(aout_symbol(symbol)->type));
1696 break;
1697 case bfd_print_symbol_all_enum:
1698 {
1699 CONST char *section_name = symbol->section == (asection *)NULL ?
1700 "*abs" : symbol->section->name;
1701
1702 bfd_print_symbol_vandf((PTR)file,symbol);
1703
1704 fprintf(file," %-5s %04x %02x %02x %s",
1705 section_name,
1706 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1707 (unsigned)(aout_symbol(symbol)->other & 0xff),
1708 (unsigned)(aout_symbol(symbol)->type & 0xff),
1709 symbol->name);
1710 }
1711 break;
1712 }
1713}
1714
1715/*
6724ff46 1716 provided a BFD, a section and an offset into the section, calculate
7ed4093a
SC
1717 and return the name of the source file and the line nearest to the
1718 wanted location.
1719*/
1720
1721boolean
1722DEFUN(NAME(aout,find_nearest_line),(abfd,
1723 section,
1724 symbols,
1725 offset,
1726 filename_ptr,
1727 functionname_ptr,
1728 line_ptr),
1729 bfd *abfd AND
1730 asection *section AND
1731 asymbol **symbols AND
1732 bfd_vma offset AND
1733 CONST char **filename_ptr AND
1734 CONST char **functionname_ptr AND
1735 unsigned int *line_ptr)
1736{
1737 /* Run down the file looking for the filename, function and linenumber */
1738 asymbol **p;
1739 static char buffer[100];
1740 bfd_vma high_line_vma = ~0;
1741 bfd_vma low_func_vma = 0;
1742 asymbol *func = 0;
1743 *filename_ptr = abfd->filename;
1744 *functionname_ptr = 0;
1745 *line_ptr = 0;
1746 if (symbols != (asymbol **)NULL) {
1747 for (p = symbols; *p; p++) {
1748 aout_symbol_type *q = (aout_symbol_type *)(*p);
1749 switch (q->type){
1750 case N_SO:
1751 *filename_ptr = q->symbol.name;
1752 if (obj_textsec(abfd) != section) {
1753 return true;
1754 }
1755 break;
1756 case N_SLINE:
1757
1758 case N_DSLINE:
1759 case N_BSLINE:
1760 /* We'll keep this if it resolves nearer than the one we have already */
1761 if (q->symbol.value >= offset &&
1762 q->symbol.value < high_line_vma) {
1763 *line_ptr = q->desc;
1764 high_line_vma = q->symbol.value;
1765 }
1766 break;
1767 case N_FUN:
1768 {
1769 /* We'll keep this if it is nearer than the one we have already */
1770 if (q->symbol.value >= low_func_vma &&
1771 q->symbol.value <= offset) {
1772 low_func_vma = q->symbol.value;
1773 func = (asymbol *)q;
1774 }
1775 if (*line_ptr && func) {
1776 CONST char *function = func->name;
1777 char *p;
1778 strncpy(buffer, function, sizeof(buffer)-1);
1779 buffer[sizeof(buffer)-1] = 0;
1780 /* Have to remove : stuff */
1781 p = strchr(buffer,':');
6f715d66 1782 if (p != NULL) { *p = NULL; }
7ed4093a
SC
1783 *functionname_ptr = buffer;
1784 return true;
1785
1786 }
1787 }
1788 break;
1789 }
1790 }
1791 }
1792
1793 return true;
1794
1795}
1796
1797int
1798DEFUN(NAME(aout,sizeof_headers),(ignore_abfd, execable),
1799 bfd *ignore_abfd AND
1800 boolean execable)
1801{
1802 return EXEC_BYTES_SIZE;
1803}
This page took 0.23774 seconds and 4 git commands to generate.