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