*** empty log message ***
[deliverable/binutils-gdb.git] / bfd / aout.c
CommitLineData
e2aed73b 1/* BFD semi-generic back-end for a.out binaries */
4a81b561
DHW
2
3/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
4
5This file is part of BFD, the Binary File Diddler.
6
7BFD is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 1, or (at your option)
10any later version.
11
12BFD is distributed in the hope that it will be useful,
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
18along with BFD; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
7ed4093a 21
c93595dd 22#include <ansidecl.h>
7ed4093a 23#include <sysdep.h>
4a81b561
DHW
24#include "bfd.h"
25#include "libbfd.h"
4a81b561 26
4a81b561
DHW
27#include "a.out.gnu.h"
28#include "stab.gnu.h"
29#include "ar.h"
30#include "liba.out.h" /* BFD a.out internal data structures */
31
fc723380
JG
32void (*bfd_error_trap)();
33
34/*SUPPRESS558*/
35/*SUPPRESS529*/
4a81b561
DHW
36
37#define CTOR_TABLE_RELOC_IDX 2
aa802a32 38static reloc_howto_type howto_table_ext[] =
4a81b561 39{
4cddd1c9
SC
40 HOWTO(RELOC_8, 0, 0, 8, false, 0, true, true,0,"8", false, 0,0x000000ff, false),
41 HOWTO(RELOC_16, 0, 1, 16, false, 0, true, true,0,"16", false, 0,0x0000ffff, false),
42 HOWTO(RELOC_32, 0, 2, 32, false, 0, true, true,0,"32", false, 0,0xffffffff, false),
43 HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, false, true,0,"DISP8", false, 0,0x000000ff, false),
44 HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, false, true,0,"DISP16", false, 0,0x0000ffff, false),
45 HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, false, true,0,"DISP32", false, 0,0xffffffff, false),
46 HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, false, true,0,"WDISP30", false, 0,0x3fffffff, false),
47 HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, false, true,0,"WDISP22", false, 0,0x003fffff, false),
48 HOWTO(RELOC_HI22, 10, 2, 22, false, 0, false, true,0,"HI22", false, 0,0x003fffff, false),
49 HOWTO(RELOC_22, 0, 2, 22, false, 0, false, true,0,"22", false, 0,0x003fffff, false),
50 HOWTO(RELOC_13, 0, 2, 13, false, 0, false, true,0,"13", false, 0,0x00001fff, false),
51 HOWTO(RELOC_LO10, 0, 2, 10, false, 0, false, true,0,"LO10", false, 0,0x000003ff, false),
52 HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false),
53 HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false),
54 HOWTO(RELOC_BASE10, 0, 2, 16, false, 0, false, true,0,"BASE10", false, 0,0x0000ffff, false),
55 HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, false, true,0,"BASE13", false, 0,0x00001fff, false),
56 HOWTO(RELOC_BASE22, 0, 2, 0, false, 0, false, true,0,"BASE22", false, 0,0x00000000, false),
57 HOWTO(RELOC_PC10, 0, 2, 10, false, 0, false, true,0,"PC10", false, 0,0x000003ff, false),
58 HOWTO(RELOC_PC22, 0, 2, 22, false, 0, false, true,0,"PC22", false, 0,0x003fffff, false),
59 HOWTO(RELOC_JMP_TBL,0, 2, 32, false, 0, false, true,0,"JMP_TBL", false, 0,0xffffffff, false),
60 HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false),
61 HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false),
62 HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false),
63 HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, false, true,0,"RELATIVE", false, 0,0x00000000, false),
64 HOWTO(RELOC_JUMPTARG,2, 13, 16, true, 0, false, true,0,"JUMPTARG", false, 0,0x0000ffff, false),
65 HOWTO(RELOC_CONST, 0, 13, 16, false, 0, false, true,0,"CONST", false, 0,0x0000ffff, false),
66 HOWTO(RELOC_CONSTH, 16, 13, 16, false, 0, false, true,0,"CONSTH", false, 0,0x0000ffff, false),
4a81b561
DHW
67};
68
c93595dd
SC
69/* Convert standard reloc records to "arelent" format (incl byte swap). */
70
aa802a32 71static reloc_howto_type howto_table_std[] = {
fc723380 72 /* type rs size bsz pcrel bitpos abs ovrf sf name part_inpl readmask setmask pcdone */
4cddd1c9
SC
73HOWTO( 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff,0x000000ff, false),
74HOWTO( 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff,0x0000ffff, false),
75HOWTO( 2, 0, 2, 32, false, 0, true, true,0,"32", true, 0xffffffff,0xffffffff, false),
76HOWTO( 3, 0, 3, 64, false, 0, true, true,0,"64", true, 0xdeaddead,0xdeaddead, false),
77HOWTO( 4, 0, 0, 8, true, 0, false, true,0,"DISP8", true, 0x000000ff,0x000000ff, false),
78HOWTO( 5, 0, 1, 16, true, 0, false, true,0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
79HOWTO( 6, 0, 2, 32, true, 0, false, true,0,"DISP32", true, 0xffffffff,0xffffffff, false),
80HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedface,0xfeedface, false),
c93595dd
SC
81};
82
aa802a32
SC
83
84bfd_error_vector_type bfd_error_vector;
c93595dd 85
e2aed73b 86void
aa802a32
SC
87DEFUN(bfd_aout_swap_exec_header_in,(abfd, raw_bytes, execp),
88 bfd *abfd AND
89 unsigned char *raw_bytes AND
90 struct exec *execp)
c93595dd
SC
91{
92 struct exec_bytes *bytes = (struct exec_bytes *)raw_bytes;
93
94 /* Now fill in fields in the execp, from the bytes in the raw data. */
95 execp->a_info = bfd_h_getlong (abfd, bytes->a_info);
96 execp->a_text = bfd_h_getlong (abfd, bytes->a_text);
97 execp->a_data = bfd_h_getlong (abfd, bytes->a_data);
98 execp->a_bss = bfd_h_getlong (abfd, bytes->a_bss);
99 execp->a_syms = bfd_h_getlong (abfd, bytes->a_syms);
100 execp->a_entry = bfd_h_getlong (abfd, bytes->a_entry);
101 execp->a_trsize = bfd_h_getlong (abfd, bytes->a_trsize);
102 execp->a_drsize = bfd_h_getlong (abfd, bytes->a_drsize);
103}
104
e2aed73b 105void
aa802a32
SC
106DEFUN(bfd_aout_swap_exec_header_out,(abfd, execp, raw_bytes),
107 bfd *abfd AND
108 struct exec *execp AND
109 unsigned char *raw_bytes)
c93595dd
SC
110{
111 struct exec_bytes *bytes = (struct exec_bytes *)raw_bytes;
112
113 /* Now fill in fields in the raw data, from the fields in the exec struct. */
114 bfd_h_putlong (abfd, execp->a_info , bytes->a_info);
115 bfd_h_putlong (abfd, execp->a_text , bytes->a_text);
116 bfd_h_putlong (abfd, execp->a_data , bytes->a_data);
117 bfd_h_putlong (abfd, execp->a_bss , bytes->a_bss);
118 bfd_h_putlong (abfd, execp->a_syms , bytes->a_syms);
119 bfd_h_putlong (abfd, execp->a_entry , bytes->a_entry);
120 bfd_h_putlong (abfd, execp->a_trsize, bytes->a_trsize);
121 bfd_h_putlong (abfd, execp->a_drsize, bytes->a_drsize);
122}
123
e2aed73b
JG
124/* Some A.OUT variant thinks that the file whose format we're checking
125 is an a.out file. Do some more checking, and set up for access if
126 it really is. Call back to the calling environment's "finish up"
127 function just before returning, to handle any last-minute setup. */
128
4a81b561 129bfd_target *
e2aed73b 130some_aout_object_p (abfd, callback_to_real_object_p)
4a81b561 131 bfd *abfd;
e2aed73b 132 bfd_target *(*callback_to_real_object_p) ();
4a81b561 133{
c93595dd
SC
134 unsigned char exec_bytes[EXEC_BYTES_SIZE]; /* Raw bytes of exec hdr */
135 struct exec *execp;
9846338e 136 PTR rawptr;
4a81b561 137
e2aed73b
JG
138 if (bfd_seek (abfd, 0L, false) < 0) {
139 bfd_error = system_call_error;
4a81b561 140 return 0;
e2aed73b 141 }
4a81b561 142
9846338e 143 if (bfd_read ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
c93595dd 144 != EXEC_BYTES_SIZE) {
4a81b561
DHW
145 bfd_error = wrong_format;
146 return 0;
147 }
148
149 /* Use an intermediate variable for clarity */
e2aed73b 150 rawptr = (PTR) bfd_zalloc (abfd, sizeof (struct aoutdata) + sizeof (struct exec));
4a81b561
DHW
151
152 if (rawptr == NULL) {
153 bfd_error = no_memory;
154 return 0;
155 }
156
e2aed73b 157 set_tdata (abfd, ((struct aoutdata *) rawptr));
c93595dd 158 exec_hdr (abfd) = execp =
e2aed73b 159 (struct exec *) ((char *)rawptr + sizeof (struct aoutdata));
4a81b561 160
c93595dd 161 bfd_aout_swap_exec_header_in (abfd, exec_bytes, execp);
4a81b561
DHW
162
163 /* Set the file flags */
164 abfd->flags = NO_FLAGS;
165 if (execp->a_drsize || execp->a_trsize)
166 abfd->flags |= HAS_RELOC;
167 if (execp->a_entry)
168 abfd->flags |= EXEC_P;
169 if (execp->a_syms)
170 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
171
c93595dd
SC
172 if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
173 if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
4a81b561 174
4a81b561
DHW
175 bfd_get_start_address (abfd) = execp->a_entry;
176
e2aed73b 177 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
fc723380
JG
178 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct nlist);
179
e2aed73b
JG
180 /* Set the default architecture and machine type. These can be
181 overridden in the callback routine. */
182 abfd->obj_arch = bfd_arch_unknown;
183 abfd->obj_machine = 0;
184
185 /* The default relocation entry size is that of traditional V7 Unix. */
186 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
4a81b561
DHW
187
188 /* create the sections. This is raunchy, but bfd_close wants to reclaim
189 them */
190 obj_textsec (abfd) = (asection *)NULL;
191 obj_datasec (abfd) = (asection *)NULL;
192 obj_bsssec (abfd) = (asection *)NULL;
4a81b561
DHW
193 (void)bfd_make_section(abfd, ".text");
194 (void)bfd_make_section(abfd, ".data");
195 (void)bfd_make_section(abfd, ".bss");
196
e2aed73b
JG
197 abfd->sections = obj_textsec (abfd);
198 obj_textsec (abfd)->next = obj_datasec (abfd);
199 obj_datasec (abfd)->next = obj_bsssec (abfd);
200
4a81b561
DHW
201 obj_datasec (abfd)->size = execp->a_data;
202 obj_bsssec (abfd)->size = execp->a_bss;
203 obj_textsec (abfd)->size = execp->a_text;
c93595dd 204
1a602d6e
SC
205 if (abfd->flags & D_PAGED) {
206 obj_textsec (abfd)->size -= EXEC_BYTES_SIZE;
207 }
208
209
c93595dd
SC
210 obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
211 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
212 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
213 obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
214 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
215 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
4a81b561
DHW
216 obj_bsssec (abfd)->flags = SEC_ALLOC;
217
e2aed73b
JG
218#ifdef THIS_IS_ONLY_DOCUMENTATION
219 /* Call back to the format-dependent code to fill in the rest of the
220 fields and do any further cleanup. Things that should be filled
221 in by the callback: */
222
223 struct exec *execp = exec_hdr (abfd);
224
225 /* The virtual memory addresses of the sections */
226 obj_datasec (abfd)->vma = N_DATADDR(*execp);
227 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
228 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
229
230 /* The file offsets of the sections */
231 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
232 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
233
234 /* The file offsets of the relocation info */
235 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
236 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
237
238 /* The file offsets of the string table and symbol table. */
239 obj_str_filepos (abfd) = N_STROFF (*execp);
240 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
241
242 /* This common code can't fill in those things because they depend
243 on either the start address of the text segment, the rounding
244 up of virtual addersses between segments, or the starting file
245 position of the text segment -- all of which varies among different
246 versions of a.out. */
247
248 /* Determine the architecture and machine type of the object file. */
249 switch (N_MACHTYPE (*exec_hdr (abfd))) {
250 default:
251 abfd->obj_arch = bfd_arch_obscure;
252 break;
253 }
254
255 /* Determine the size of a relocation entry */
256 switch (abfd->obj_arch) {
257 case bfd_arch_sparc:
258 case bfd_arch_a29k:
259 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
260 default:
261 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
262 }
263
264 return abfd->xvec;
265
266 /* The architecture is encoded in various ways in various a.out variants,
267 or is not encoded at all in some of them. The relocation size depends
268 on the architecture and the a.out variant. Finally, the return value
269 is the bfd_target vector in use. If an error occurs, return zero and
270 set bfd_error to the appropriate error code.
271
272 Formats such as b.out, which have additional fields in the a.out
273 header, should cope with them in this callback as well. */
274#endif /* DOCUMENTATION */
275
10be52bf 276
e2aed73b 277 return (*callback_to_real_object_p)(abfd);
4a81b561
DHW
278}
279
280
281boolean
e2aed73b 282aout_mkobject (abfd)
4a81b561
DHW
283 bfd *abfd;
284{
285 char *rawptr;
286
287 bfd_error = system_call_error;
288
289 /* Use an intermediate variable for clarity */
e2aed73b 290 rawptr = bfd_zalloc (abfd, sizeof (struct aoutdata) + sizeof (struct exec));
4a81b561
DHW
291
292 if (rawptr == NULL) {
293 bfd_error = no_memory;
294 return false;
295 }
296
e2aed73b
JG
297 set_tdata (abfd, (struct aoutdata *) rawptr);
298 exec_hdr (abfd) = (struct exec *) (rawptr + sizeof (struct aoutdata));
4a81b561
DHW
299
300 /* For simplicity's sake we just make all the sections right here. */
301
302 obj_textsec (abfd) = (asection *)NULL;
303 obj_datasec (abfd) = (asection *)NULL;
304 obj_bsssec (abfd) = (asection *)NULL;
305 bfd_make_section (abfd, ".text");
306 bfd_make_section (abfd, ".data");
307 bfd_make_section (abfd, ".bss");
308
309 return true;
310}
311
312/* Keep track of machine architecture and machine type for a.out's.
313 Return the machine_type for a particular arch&machine, or M_UNKNOWN
314 if that exact arch&machine can't be represented in a.out format.
315
316 If the architecture is understood, machine type 0 (default) should
317 always be understood. */
318
e2aed73b 319enum machine_type
4a81b561
DHW
320aout_machine_type (arch, machine)
321 enum bfd_architecture arch;
322 unsigned long machine;
323{
324 enum machine_type arch_flags;
325
326 arch_flags = M_UNKNOWN;
327
328 switch (arch) {
329 case bfd_arch_sparc:
9872a49c
SC
330 if (machine == 0) arch_flags = M_SPARC;
331 break;
4a81b561
DHW
332
333 case bfd_arch_m68k:
9872a49c
SC
334 switch (machine) {
335 case 0: arch_flags = M_68010; break;
336 case 68000: arch_flags = M_UNKNOWN; break;
337 case 68010: arch_flags = M_68010; break;
338 case 68020: arch_flags = M_68020; break;
339 default: arch_flags = M_UNKNOWN; break;
340 }
341 break;
4a81b561
DHW
342
343 case bfd_arch_i386:
9872a49c
SC
344 if (machine == 0) arch_flags = M_386;
345 break;
4a81b561
DHW
346
347 case bfd_arch_a29k:
9872a49c
SC
348 if (machine == 0) arch_flags = M_29K;
349 break;
4a81b561
DHW
350
351 default:
9872a49c
SC
352 arch_flags = M_UNKNOWN;
353 break;
4a81b561
DHW
354 }
355 return arch_flags;
356}
357
358boolean
e2aed73b 359aout_set_arch_mach (abfd, arch, machine)
4a81b561
DHW
360 bfd *abfd;
361 enum bfd_architecture arch;
362 unsigned long machine;
363{
364 abfd->obj_arch = arch;
365 abfd->obj_machine = machine;
366 if (arch != bfd_arch_unknown &&
367 aout_machine_type (arch, machine) == M_UNKNOWN)
368 return false; /* We can't represent this type */
369 return true; /* We're easy ... */
370}
fc723380 371\f
e2aed73b 372/* exec and core file sections */
4a81b561
DHW
373
374boolean
e2aed73b 375aout_new_section_hook (abfd, newsect)
4a81b561
DHW
376 bfd *abfd;
377 asection *newsect;
378{
379 /* align to double at least */
380 newsect->alignment_power = 3;
381
382 if (bfd_get_format (abfd) == bfd_object) {
383 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
384 obj_textsec(abfd)= newsect;
385 return true;
386 }
387
388 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
389 obj_datasec(abfd) = newsect;
390 return true;
391 }
392
393 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
394 obj_bsssec(abfd) = newsect;
395 return true;
396 }
397 }
398
4a81b561
DHW
399 /* We allow more than three sections internally */
400 return true;
401}
402
403boolean
e2aed73b 404aout_set_section_contents (abfd, section, location, offset, count)
4a81b561
DHW
405 bfd *abfd;
406 sec_ptr section;
e2aed73b 407 PTR location;
4a81b561
DHW
408 file_ptr offset;
409 int count;
410{
411 if (abfd->output_has_begun == false)
4432f8ad 412 { /* set by bfd.c handler */
fc723380 413 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
4432f8ad
SC
414 {
415 bfd_error = invalid_operation;
416 return false;
417 }
4a81b561 418
41489b9a
SC
419 obj_textsec(abfd)->filepos = sizeof(struct exec);
420 obj_textsec(abfd)->size = align_power(obj_textsec(abfd)->size,
421 obj_textsec(abfd)->alignment_power);
1a602d6e 422 obj_datasec(abfd)->filepos = obj_textsec (abfd)->size + EXEC_BYTES_SIZE;
41489b9a
SC
423 obj_datasec(abfd)->size = align_power(obj_datasec(abfd)->size,
424 obj_datasec(abfd)->alignment_power);
425
1a602d6e 426
4432f8ad 427 }
4a81b561 428 /* regardless, once we know what we're doing, we might as well get going */
1a602d6e
SC
429 if (section != obj_bsssec(abfd))
430 {
431 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
4a81b561 432
1a602d6e
SC
433 if (count) {
434 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
435 true : false;
436 }
437 return false;
438 }
4432f8ad 439 return true;
4a81b561 440}
4a81b561
DHW
441\f
442/* Classify stabs symbols */
443
4a81b561
DHW
444#define sym_in_text_section(sym) \
445 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
446
447#define sym_in_data_section(sym) \
448 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
449
450#define sym_in_bss_section(sym) \
451 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
452
453/* Symbol is undefined if type is N_UNDF|N_EXT and if it has
454 zero in the "value" field. Nonzeroes there are fortrancommon
455 symbols. */
456#define sym_is_undefined(sym) \
457 ((sym)->n_type == (N_UNDF | N_EXT) && (sym)->n_value == 0)
458
459/* Symbol is a global definition if N_EXT is on and if it has
460 a nonzero type field. */
461#define sym_is_global_defn(sym) \
462 (((sym)->n_type & N_EXT) && (sym)->n_type & N_TYPE)
463
464/* Symbol is debugger info if any bits outside N_TYPE or N_EXT
465 are on. */
466#define sym_is_debugger_info(sym) \
467 ((sym)->n_type & ~(N_EXT | N_TYPE))
468
469#define sym_is_fortrancommon(sym) \
470 (((sym)->n_type == (N_EXT)) && (sym)->n_value != 0)
471
472/* Symbol is absolute if it has N_ABS set */
473#define sym_is_absolute(sym) \
474 (((sym)->n_type & N_TYPE)== N_ABS)
475
476
477#define sym_is_indirect(sym) \
478 (((sym)->n_type & N_ABS)== N_ABS)
479
480/* Only in their own functions for ease of debugging; when sym flags have
481 stabilised these should be inlined into their (single) caller */
482
483static void
484translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd)
485 struct nlist *sym_pointer;
486 aout_symbol_type *cache_ptr;
487 bfd *abfd;
488{
489 switch (cache_ptr->type & N_TYPE) {
490 case N_SETA:
491 case N_SETT:
492 case N_SETD:
493 case N_SETB:
494 {
495 asection *section = bfd_make_section(abfd,
496 cache_ptr->symbol.name);
9872a49c 497 arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
4a81b561
DHW
498
499 switch ( (cache_ptr->type & N_TYPE) ) {
500 case N_SETA:
501 reloc->relent.section = (asection *)NULL;
502 cache_ptr->symbol.section = (asection *)NULL;
503 break;
504 case N_SETT:
505 reloc->relent.section = (asection *)obj_textsec(abfd);
506 cache_ptr->symbol.value -= reloc->relent.section->vma;
507 break;
508 case N_SETD:
509 reloc->relent.section = (asection *)obj_datasec(abfd);
510 cache_ptr->symbol.value -= reloc->relent.section->vma;
511 break;
512 case N_SETB:
513 reloc->relent.section = (asection *)obj_bsssec(abfd);
514 cache_ptr->symbol.value -= reloc->relent.section->vma;
515 break;
516 }
517 cache_ptr->symbol.section = reloc->relent.section;
518 reloc->relent.addend = cache_ptr->symbol.value ;
fc723380
JG
519
520 /* We modify the symbol to belong to a section depending upon the
4a81b561
DHW
521 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
522 really care, and add to the size of the section to contain a
523 pointer to the symbol. Build a reloc entry to relocate to this
fc723380 524 symbol attached to this section. */
4a81b561
DHW
525
526 section->flags = SEC_CONSTRUCTOR;
527 section->reloc_count++;
528 section->alignment_power = 2;
529 reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
530 reloc->next = section->constructor_chain;
531 section->constructor_chain = reloc;
532 reloc->relent.address = section->size;
533 section->size += sizeof(int *);
534
c93595dd 535 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
4a81b561
DHW
536 cache_ptr->symbol.flags |= BSF_DEBUGGING ;
537 }
538 break;
539 default:
540
541 if (sym_is_debugger_info (sym_pointer)) {
542 cache_ptr->symbol.flags = BSF_DEBUGGING ;
543 /* Work out the section correct for this symbol */
544 switch (sym_pointer->n_type & N_TYPE)
545 {
546 case N_TEXT:
547 case N_FN:
548 cache_ptr->symbol.section = obj_textsec (abfd);
549 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
550 break;
551 case N_DATA:
552 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
553 cache_ptr->symbol.section = obj_datasec (abfd);
554 break;
555 case N_BSS :
556 cache_ptr->symbol.section = obj_bsssec (abfd);
557 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
558 break;
559 case N_ABS:
560 default:
561 cache_ptr->symbol.section = 0;
562 break;
563 }
564 }
565 else {
566 if (sym_is_fortrancommon (sym_pointer))
567 {
568 cache_ptr->symbol.flags = BSF_FORT_COMM;
569 cache_ptr->symbol.section = (asection *)NULL;
570 }
571 else {
572 if (sym_is_undefined (sym_pointer)) {
573 cache_ptr->symbol.flags = BSF_UNDEFINED;
574 }
575 else if (sym_is_global_defn (sym_pointer)) {
576 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
577 }
578
579 else if (sym_is_absolute (sym_pointer)) {
580 cache_ptr->symbol.flags = BSF_ABSOLUTE;
581 }
582 else {
583 cache_ptr->symbol.flags = BSF_LOCAL;
584 }
585
586 /* In a.out, the value of a symbol is always relative to the
587 * start of the file, if this is a data symbol we'll subtract
588 * the size of the text section to get the section relative
589 * value. If this is a bss symbol (which would be strange)
590 * we'll subtract the size of the previous two sections
591 * to find the section relative address.
592 */
593
594 if (sym_in_text_section (sym_pointer)) {
595 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
596 cache_ptr->symbol.section = obj_textsec (abfd);
597 }
598 else if (sym_in_data_section (sym_pointer)){
599 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
600 cache_ptr->symbol.section = obj_datasec (abfd);
601 }
602 else if (sym_in_bss_section(sym_pointer)) {
603 cache_ptr->symbol.section = obj_bsssec (abfd);
604 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
605 }
606 else {
607 cache_ptr->symbol.section = (asection *)NULL;
608 cache_ptr->symbol.flags |= BSF_ABSOLUTE;
609 }
610 }
611 }
612 }
613}
c93595dd 614
4a81b561
DHW
615void
616translate_to_native_sym_flags (sym_pointer, cache_ptr_g, abfd)
617 struct nlist *sym_pointer;
4432f8ad 618 PTR cache_ptr_g;
4a81b561
DHW
619 bfd *abfd;
620{
621 asymbol *cache_ptr = (asymbol *)cache_ptr_g;
622
fc723380 623 /* FIXME check for writing bss */
4a81b561
DHW
624 if (bfd_get_section(cache_ptr)) {
625 if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
626 sym_pointer->n_type |= N_BSS;
627 }
628 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
629 sym_pointer->n_type |= N_DATA;
630 }
631 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
632 sym_pointer->n_type |= N_TEXT;
633 }
634 else {
fc723380
JG
635 bfd_error_vector.nonrepresentable_section(abfd,
636 bfd_get_output_section(cache_ptr)->name);
4a81b561
DHW
637 }
638 /* Turn the symbol from section relative to absolute again */
639 sym_pointer->n_value +=
640 cache_ptr->section->output_section->vma
641 + cache_ptr->section->output_offset ;
642 }
643 else {
644 sym_pointer->n_type |= N_ABS;
645 }
646
647 if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
648 sym_pointer->n_type = (N_UNDF | N_EXT);
649 return;
650 }
651
652 if (cache_ptr->flags & BSF_ABSOLUTE) {
653 sym_pointer->n_type |= N_ABS;
654 }
655
656 if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
657 sym_pointer->n_type |= N_EXT;
658 }
659 if (cache_ptr->flags & BSF_DEBUGGING) {
660 sym_pointer->n_type = ((aout_symbol_type *)cache_ptr)->type;
661 }
4a81b561
DHW
662}
663\f
664/* Native-level interface to symbols. */
665
666/* We read the symbols into a buffer, which is discarded when this
667 function exits. We read the strings into a buffer large enough to
668 hold them all plus all the cached symbol entries. */
669
670asymbol *
e2aed73b 671aout_make_empty_symbol (abfd)
4a81b561
DHW
672bfd *abfd;
673{
674 aout_symbol_type *new =
9872a49c 675 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
4a81b561
DHW
676 new->symbol.the_bfd = abfd;
677
678 return &new->symbol;
679}
680
681boolean
e2aed73b 682DEFUN(aout_slurp_symbol_table, (abfd),
aa802a32 683 bfd *abfd)
4a81b561 684{
4a81b561
DHW
685 size_t symbol_size;
686 size_t string_size;
fc723380 687 unsigned char string_chars[LONG_SIZE];
4a81b561
DHW
688 struct nlist *syms;
689 char *strings;
690 aout_symbol_type *cached;
691
692 /* If there's no work to be done, don't do any */
693 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
694 symbol_size = exec_hdr(abfd)->a_syms;
695 if (symbol_size == 0) {
696 bfd_error = no_symbols;
697 return false;
698 }
699
700 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
fc723380 701 if (bfd_read ((PTR)string_chars, LONG_SIZE, 1, abfd) != LONG_SIZE)
4a81b561 702 return false;
fc723380 703 string_size = bfd_h_getlong (abfd, string_chars);
4a81b561 704
9872a49c 705 strings = bfd_alloc(abfd, string_size + 1);
d6a554ae 706 cached = (aout_symbol_type *)
fc723380
JG
707 bfd_zalloc(abfd, bfd_get_symcount (abfd) * sizeof(aout_symbol_type));
708 /* Alloc this last, so we can free it if obstack is in use. */
d6a554ae 709 syms = (struct nlist *) bfd_alloc(abfd, symbol_size);
4a81b561
DHW
710
711 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
9846338e 712 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
4a81b561 713 bailout:
fc723380
JG
714 if (syms) bfd_release (abfd, syms);
715 if (cached) bfd_release (abfd, cached);
716 if (strings)bfd_release (abfd, strings);
4a81b561
DHW
717 return false;
718 }
719
720 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
9846338e 721 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
4a81b561
DHW
722 goto bailout;
723 }
724
725 /* OK, now walk the new symtable, cacheing symbol properties */
9872a49c
SC
726 {
727 register struct nlist *sym_pointer;
fc723380 728 register struct nlist *sym_end = syms + bfd_get_symcount (abfd);
9872a49c 729 register aout_symbol_type *cache_ptr = cached;
4a81b561 730
4a81b561
DHW
731 /* run through the table and byte swap if needed */
732 for (sym_pointer = syms; sym_pointer < sym_end; sym_pointer++) {
733 sym_pointer->n_un.n_strx =
8e3c8f47 734 bfd_h_getlong (abfd, &sym_pointer->n_un.n_strx);
4a81b561 735 sym_pointer->n_desc =
8e3c8f47 736 bfd_h_getshort (abfd, &sym_pointer->n_desc);
4a81b561 737 sym_pointer->n_value =
8e3c8f47 738 bfd_h_getlong (abfd, &sym_pointer->n_value);
4a81b561 739 sym_pointer->n_other = (char)
8e3c8f47 740 bfd_h_getchar(abfd, &sym_pointer->n_other);
4a81b561 741 sym_pointer->n_type = (char)
8e3c8f47 742 bfd_h_getchar(abfd, &sym_pointer->n_type);
4a81b561 743 }
726cc6ef 744
9872a49c
SC
745 /* Run through table and copy values */
746 for (sym_pointer = syms, cache_ptr = cached;
747 sym_pointer < sym_end; sym_pointer++, cache_ptr++)
748 {
749 cache_ptr->symbol.the_bfd = abfd;
750 if (sym_pointer->n_un.n_strx)
751 cache_ptr->symbol.name = sym_pointer->n_un.n_strx + strings;
752 else
753 cache_ptr->symbol.name = (char *)NULL;
754 cache_ptr->symbol.value = sym_pointer->n_value;
755 cache_ptr->desc = sym_pointer->n_desc;
756 cache_ptr->other = sym_pointer->n_other;
757 cache_ptr->type = sym_pointer->n_type;
758 cache_ptr->symbol.udata = 0;
759 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
4a81b561 760
9872a49c
SC
761 }
762 }
4a81b561
DHW
763
764 obj_aout_symbols (abfd) = cached;
9872a49c 765 bfd_release (abfd, (PTR)syms);
4a81b561
DHW
766
767 return true;
768}
769
aa802a32 770
4a81b561 771void
e2aed73b 772DEFUN(aout_write_syms,(abfd),
aa802a32 773 bfd *abfd)
4a81b561
DHW
774{
775 unsigned int count ;
776 asymbol **generic = bfd_get_outsymbols (abfd);
777
778 unsigned int stindex = sizeof(stindex); /* initial string length */
779
780 for (count = 0; count < bfd_get_symcount (abfd); count++) {
781 asymbol *g = generic[count];
782 struct nlist nsp;
783
784 if (g->name) {
785 unsigned int length = strlen(g->name) +1;
786 bfd_h_putlong (abfd, stindex, (unsigned char *)&nsp.n_un.n_strx);
787 stindex += length;
788 }
789 else {
790 bfd_h_putlong (abfd, 0, (unsigned char *)&nsp.n_un.n_strx);
791 }
792
793 if (g->the_bfd->xvec->flavour == abfd->xvec->flavour)
794 {
795 nsp.n_desc = aout_symbol( g)->desc;
796 nsp.n_other = aout_symbol(g)->other;
797 nsp.n_type = aout_symbol(g)->type;
798 }
799 else
800 {
801 nsp.n_desc = 0;
802 nsp.n_other = 0;
803 nsp.n_type = 0;
804 }
805
806
807 nsp.n_value = g->value;
4432f8ad 808 translate_to_native_sym_flags (&nsp, (PTR)g, abfd);
4a81b561
DHW
809
810
811 bfd_h_putshort (abfd, nsp.n_desc, (unsigned char *)&nsp.n_desc);
812 bfd_h_putlong (abfd, nsp.n_value, (unsigned char *)&nsp.n_value);
9846338e 813 bfd_write((PTR)&nsp,1, sizeof(nsp), abfd);
4a81b561
DHW
814 }
815
816
817 /* Now output the strings. Be sure to put string length into correct
818 * byte ordering before writing it.
819 */
820 bfd_h_putlong (abfd, stindex, (unsigned char *)&stindex);
821
9846338e 822 bfd_write((PTR)&stindex, 1, sizeof(stindex), abfd);
4a81b561
DHW
823
824 generic = bfd_get_outsymbols(abfd);
825 for (count = 0; count < bfd_get_symcount(abfd); count++)
826 {
827 asymbol *g = *(generic++);
828
fc723380 829 if (g->name)
4a81b561
DHW
830 {
831 size_t length = strlen(g->name)+1;
9846338e 832 bfd_write((PTR)g->name, 1, length, abfd);
4a81b561
DHW
833 }
834 if ((g->flags & BSF_FAKE)==0) {
835 g->name = itos(count); /* smash the generic symbol */
836 }
837 }
838}
839
aa802a32 840
4a81b561 841void
e2aed73b 842DEFUN(aout_reclaim_symbol_table,(abfd),
aa802a32 843 bfd *abfd)
4a81b561 844{
4a81b561 845
4a81b561
DHW
846}
847\f
848unsigned int
e2aed73b 849aout_get_symtab_upper_bound (abfd)
4a81b561
DHW
850 bfd *abfd;
851{
e2aed73b 852 if (!aout_slurp_symbol_table (abfd)) return 0;
4a81b561
DHW
853
854 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
855}
856
857unsigned int
e2aed73b 858aout_get_symtab (abfd, location)
4a81b561
DHW
859 bfd *abfd;
860 asymbol **location;
861{
862 unsigned int counter = 0;
863 aout_symbol_type *symbase;
864
e2aed73b 865 if (!aout_slurp_symbol_table (abfd)) return 0;
4a81b561
DHW
866
867 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
868 *(location++) = (asymbol *)( symbase++);
869 *location++ =0;
870 return bfd_get_symcount(abfd);
871}
872
4a81b561 873\f
c93595dd
SC
874/* Standard reloc stuff */
875/* Output standard relocation information to a file in target byte order. */
876
877void
fc723380 878swap_std_reloc_out (abfd, g, natptr)
c93595dd 879 bfd *abfd;
fc723380 880 arelent *g; /* Generic relocation struct */
c93595dd 881 struct reloc_std_bytes *natptr;
c93595dd
SC
882{
883 int r_index;
884 int r_extern;
885 unsigned int r_length;
886 int r_pcrel;
887 int r_baserel, r_jmptable, r_relative;
888 unsigned int r_addend;
c93595dd 889
fc723380 890 bfd_h_putlong (abfd, g->address, natptr->r_address);
c93595dd 891
b6316534 892 r_length = g->howto->size ; /* Size as a power of two */
fc723380
JG
893 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
894 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
895 r_baserel = 0;
896 r_jmptable = 0;
897 r_relative = 0;
4a81b561 898
fc723380 899 r_addend = g->addend; /* Start here, see how it goes */
c93595dd 900
e2aed73b 901 /* name was clobbered by aout_write_syms to be symbol index */
c93595dd 902
fc723380
JG
903 if (g->sym_ptr_ptr != NULL)
904 {
905 if ((*(g->sym_ptr_ptr))->section) {
906 /* put the section offset into the addend for output */
907 r_addend += (*(g->sym_ptr_ptr))->section->vma;
c93595dd
SC
908 }
909
fc723380
JG
910 r_index = stoi((*(g->sym_ptr_ptr))->name);
911 r_extern = 1;
912 }
913 else {
914 r_extern = 0;
915 if (g->section == NULL) {
d0ec7a8e
SC
916 /* It is possible to have a reloc with nothing, we generate an
917 abs + 0 */
918 r_addend = 0;
fc723380
JG
919 r_index = N_ABS | N_EXT;
920 }
921 else if(g->section->output_section == obj_textsec(abfd)) {
922 r_index = N_TEXT | N_EXT;
923 r_addend += g->section->output_section->vma;
924 }
925 else if (g->section->output_section == obj_datasec(abfd)) {
926 r_index = N_DATA | N_EXT;
927 r_addend += g->section->output_section->vma;
928 }
929 else if (g->section->output_section == obj_bsssec(abfd)) {
930 r_index = N_BSS | N_EXT ;
931 r_addend += g->section->output_section->vma;
c93595dd 932 }
fc723380
JG
933 else {
934 BFD_ASSERT(0);
935 }
936 }
937
938 /* now the fun stuff */
939 if (abfd->xvec->header_byteorder_big_p != false) {
940 natptr->r_index[0] = r_index >> 16;
941 natptr->r_index[1] = r_index >> 8;
942 natptr->r_index[2] = r_index;
943 natptr->r_bits[0] =
944 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
945 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
946 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
947 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
948 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
949 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
950 } else {
951 natptr->r_index[2] = r_index >> 16;
952 natptr->r_index[1] = r_index >> 8;
953 natptr->r_index[0] = r_index;
954 natptr->r_bits[0] =
955 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
956 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
957 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
958 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
959 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
960 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
961 }
c93595dd
SC
962}
963
964
965/* Extended stuff */
966/* Output extended relocation information to a file in target byte order. */
967
968void
fc723380 969swap_ext_reloc_out (abfd, g, natptr)
c93595dd 970 bfd *abfd;
fc723380 971 arelent *g; /* Generic relocation struct */
c93595dd 972 register struct reloc_ext_bytes *natptr;
c93595dd 973{
c93595dd
SC
974 int r_index;
975 int r_extern;
976 unsigned int r_type;
977 unsigned int r_addend;
c93595dd 978
fc723380 979 bfd_h_putlong (abfd, g->address, natptr->r_address);
c93595dd 980
fc723380
JG
981 /* Find a type in the output format which matches the input howto -
982 at the moment we assume input format == output format FIXME!! */
983 r_type = (enum reloc_type) g->howto->type;
c93595dd 984
fc723380 985 r_addend = g->addend; /* Start here, see how it goes */
c93595dd 986
e2aed73b 987 /* name was clobbered by aout_write_syms to be symbol index*/
c93595dd 988
fc723380
JG
989 if (g->sym_ptr_ptr != NULL)
990 {
991 if ((*(g->sym_ptr_ptr))->section) {
992 /* put the section offset into the addend for output */
993 r_addend += (*(g->sym_ptr_ptr))->section->vma;
c93595dd 994 }
c93595dd 995
fc723380
JG
996 r_index = stoi((*(g->sym_ptr_ptr))->name);
997 r_extern = 1;
c93595dd 998 }
fc723380
JG
999 else {
1000 r_extern = 0;
1001 if (g->section == NULL) {
1002 BFD_ASSERT(0);
1003 r_index = N_ABS | N_EXT;
1004 }
1005 else if(g->section->output_section == obj_textsec(abfd)) {
1006 r_index = N_TEXT | N_EXT;
1007 r_addend += g->section->output_section->vma;
1008 }
1009 else if (g->section->output_section == obj_datasec(abfd)) {
1010 r_index = N_DATA | N_EXT;
1011 r_addend += g->section->output_section->vma;
1012 }
1013 else if (g->section->output_section == obj_bsssec(abfd)) {
1014 r_index = N_BSS | N_EXT ;
1015 r_addend += g->section->output_section->vma;
1016 }
1017 else {
1018 BFD_ASSERT(0);
1019 }
1020 }
c93595dd 1021
fc723380
JG
1022 /* now the fun stuff */
1023 if (abfd->xvec->header_byteorder_big_p != false) {
1024 natptr->r_index[0] = r_index >> 16;
1025 natptr->r_index[1] = r_index >> 8;
1026 natptr->r_index[2] = r_index;
1027 natptr->r_bits[0] =
1028 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
10be52bf 1029 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
fc723380
JG
1030 } else {
1031 natptr->r_index[2] = r_index >> 16;
1032 natptr->r_index[1] = r_index >> 8;
1033 natptr->r_index[0] = r_index;
1034 natptr->r_bits[0] =
1035 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
10be52bf 1036 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
c93595dd 1037 }
fc723380
JG
1038
1039 bfd_h_putlong (abfd, r_addend, natptr->r_addend);
c93595dd 1040}
fc723380 1041
c93595dd
SC
1042#define MOVE_ADDRESS(ad) \
1043 if (r_extern) { \
1044 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1045 cache_ptr->section = (asection *)NULL; \
1046 cache_ptr->addend = ad; \
1047 } else { \
1048 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1049 switch (r_index) { \
1050 case N_TEXT: \
1051 case N_TEXT | N_EXT: \
1052 cache_ptr->section = obj_textsec(abfd); \
1053 cache_ptr->addend = ad - su->textsec->vma; \
1054 break; \
1055 case N_DATA: \
1056 case N_DATA | N_EXT: \
1057 cache_ptr->section = obj_datasec(abfd); \
1058 cache_ptr->addend = ad - su->datasec->vma; \
1059 break; \
1060 case N_BSS: \
1061 case N_BSS | N_EXT: \
1062 cache_ptr->section = obj_bsssec(abfd); \
1063 cache_ptr->addend = ad - su->bsssec->vma; \
1064 break; \
1065 case N_ABS: \
1066 case N_ABS | N_EXT: \
fc723380
JG
1067 cache_ptr->section = NULL; /* No section */ \
1068 cache_ptr->addend = ad; /* FIXME, is this right? */ \
c93595dd
SC
1069 BFD_ASSERT(1); \
1070 break; \
1071 default: \
fc723380
JG
1072 cache_ptr->section = NULL; /* No section */ \
1073 cache_ptr->addend = ad; /* FIXME, is this right? */ \
c93595dd
SC
1074 BFD_ASSERT(1); \
1075 break; \
1076 } \
1077 } \
1078
1079void
1080swap_ext_reloc_in (abfd, bytes, cache_ptr, symbols)
1081 bfd *abfd;
1082 struct reloc_ext_bytes *bytes;
1083 arelent *cache_ptr;
1084 asymbol **symbols;
1085{
1086 int r_index;
1087 int r_extern;
1088 unsigned int r_type;
e2aed73b 1089 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
c93595dd
SC
1090
1091 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1092
1093 /* now the fun stuff */
1094 if (abfd->xvec->header_byteorder_big_p != false) {
1095 r_index = (bytes->r_index[0] << 16)
1096 | (bytes->r_index[1] << 8)
1097 | bytes->r_index[2];
1098 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_BIG));
1099 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_BIG)
1100 >> RELOC_EXT_BITS_TYPE_SH_BIG;
1101 } else {
1102 r_index = (bytes->r_index[2] << 16)
1103 | (bytes->r_index[1] << 8)
1104 | bytes->r_index[0];
1105 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1106 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1107 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1108 }
1109
1110 cache_ptr->howto = howto_table_ext + r_type;
1111 MOVE_ADDRESS(bfd_h_getlong(abfd,bytes->r_addend));
c93595dd
SC
1112}
1113
1114void
1115swap_std_reloc_in (abfd, bytes, cache_ptr, symbols)
1116 bfd *abfd;
fc723380 1117 struct reloc_std_bytes *bytes;
c93595dd
SC
1118 arelent *cache_ptr;
1119 asymbol **symbols;
1120{
1121 int r_index;
1122 int r_extern;
1123 unsigned int r_length;
1124 int r_pcrel;
1125 int r_baserel, r_jmptable, r_relative;
e2aed73b 1126 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
fc723380 1127
c93595dd
SC
1128 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1129
1130 /* now the fun stuff */
1131 if (abfd->xvec->header_byteorder_big_p != false) {
1132 r_index = (bytes->r_index[0] << 16)
1133 | (bytes->r_index[1] << 8)
1134 | bytes->r_index[2];
1135 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_BIG));
1136 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_BIG));
1137 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_BIG));
1138 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1139 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_BIG));
1140 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_BIG)
fc723380 1141 >> RELOC_STD_BITS_LENGTH_SH_BIG;
c93595dd
SC
1142 } else {
1143 r_index = (bytes->r_index[2] << 16)
1144 | (bytes->r_index[1] << 8)
1145 | bytes->r_index[0];
1146 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1147 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_LITTLE));
1148 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1149 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1150 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1151 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_LITTLE)
fc723380 1152 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
c93595dd
SC
1153 }
1154
1155 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
1156 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1157
1158 MOVE_ADDRESS(0);
1159}
1160
1161/* Reloc hackery */
4a81b561
DHW
1162
1163boolean
e2aed73b 1164aout_slurp_reloc_table (abfd, asect, symbols)
4a81b561
DHW
1165 bfd *abfd;
1166 sec_ptr asect;
1167 asymbol **symbols;
1168{
1169 unsigned int count;
1170 size_t reloc_size;
9846338e 1171 PTR relocs;
4a81b561 1172 arelent *reloc_cache;
c93595dd 1173 size_t each_size;
4a81b561
DHW
1174
1175 if (asect->relocation) return true;
1176
1177 if (asect->flags & SEC_CONSTRUCTOR) return true;
1178
1179 if (asect == obj_datasec (abfd)) {
1180 reloc_size = exec_hdr(abfd)->a_drsize;
1181 goto doit;
1182 }
1183
1184 if (asect == obj_textsec (abfd)) {
1185 reloc_size = exec_hdr(abfd)->a_trsize;
1186 goto doit;
1187 }
1188
1189 bfd_error = invalid_operation;
1190 return false;
1191
1192 doit:
1193 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
e2aed73b 1194 each_size = obj_reloc_entry_size (abfd);
c93595dd
SC
1195
1196 count = reloc_size / each_size;
4a81b561 1197
9872a49c
SC
1198
1199 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1200 (arelent)));
fc723380
JG
1201 if (!reloc_cache) {
1202nomem:
1203 bfd_error = no_memory;
1204 return false;
1205 }
1206
9872a49c 1207 relocs = bfd_alloc (abfd, reloc_size);
fc723380
JG
1208 if (!relocs) {
1209 bfd_release (abfd, reloc_cache);
1210 goto nomem;
1211 }
4a81b561 1212
fc723380
JG
1213 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1214 bfd_release (abfd, relocs);
1215 bfd_release (abfd, reloc_cache);
4a81b561 1216 bfd_error = system_call_error;
4a81b561
DHW
1217 return false;
1218 }
1219
fc723380
JG
1220 if (each_size == RELOC_EXT_SIZE) {
1221 register struct reloc_ext_bytes *rptr = (struct reloc_ext_bytes *) relocs;
1222 unsigned int counter = 0;
1223 arelent *cache_ptr = reloc_cache;
c93595dd 1224
fc723380
JG
1225 for (; counter < count; counter++, rptr++, cache_ptr++) {
1226 swap_ext_reloc_in(abfd, rptr, cache_ptr, symbols);
c93595dd 1227 }
fc723380 1228 } else {
9846338e 1229 register struct reloc_std_bytes *rptr = (struct reloc_std_bytes *) relocs;
4a81b561
DHW
1230 unsigned int counter = 0;
1231 arelent *cache_ptr = reloc_cache;
1232
1233 for (; counter < count; counter++, rptr++, cache_ptr++) {
c93595dd 1234 swap_std_reloc_in(abfd, rptr, cache_ptr, symbols);
4a81b561 1235 }
4a81b561 1236
c93595dd 1237 }
fc723380
JG
1238
1239 bfd_release (abfd,relocs);
4a81b561
DHW
1240 asect->relocation = reloc_cache;
1241 asect->reloc_count = count;
1242 return true;
1243}
1244
c93595dd
SC
1245
1246
1247/* Write out a relocation section into an object file. */
1248
e2aed73b
JG
1249boolean
1250aout_squirt_out_relocs (abfd, section)
4a81b561
DHW
1251 bfd *abfd;
1252 asection *section;
1253{
1254 arelent **generic;
fc723380 1255 unsigned char *native, *natptr;
c93595dd 1256 size_t each_size;
4a81b561
DHW
1257
1258 unsigned int count = section->reloc_count;
c93595dd 1259 size_t natsize;
4a81b561
DHW
1260
1261 if (count == 0) return true;
c93595dd 1262
e2aed73b 1263 each_size = obj_reloc_entry_size (abfd);
c93595dd 1264 natsize = each_size * count;
9872a49c 1265 native = (unsigned char *) bfd_zalloc (abfd, natsize);
4a81b561
DHW
1266 if (!native) {
1267 bfd_error = no_memory;
1268 return false;
1269 }
1270
c93595dd 1271 generic = section->orelocation;
4a81b561 1272
c93595dd
SC
1273 if (each_size == RELOC_EXT_SIZE)
1274 {
fc723380
JG
1275 for (natptr = native;
1276 count != 0;
1277 --count, natptr += each_size, ++generic)
b6316534 1278 swap_ext_reloc_out (abfd, *generic, (struct reloc_ext_bytes *)natptr);
c93595dd
SC
1279 }
1280 else
1281 {
fc723380
JG
1282 for (natptr = native;
1283 count != 0;
1284 --count, natptr += each_size, ++generic)
b6316534 1285 swap_std_reloc_out(abfd, *generic, (struct reloc_std_bytes *)natptr);
4a81b561
DHW
1286 }
1287
9846338e 1288 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
9872a49c 1289 bfd_release(abfd, native);
4a81b561
DHW
1290 return false;
1291 }
9872a49c 1292 bfd_release (abfd, native);
4a81b561
DHW
1293
1294 return true;
1295}
1296
1297/* This is stupid. This function should be a boolean predicate */
1298unsigned int
e2aed73b 1299aout_canonicalize_reloc (abfd, section, relptr, symbols)
4a81b561
DHW
1300 bfd *abfd;
1301 sec_ptr section;
1302 arelent **relptr;
1303 asymbol **symbols;
1304{
1305 arelent *tblptr = section->relocation;
1306 unsigned int count;
1307
e2aed73b 1308 if (!(tblptr || aout_slurp_reloc_table (abfd, section, symbols)))
4a81b561
DHW
1309 return 0;
1310
1311 if (section->flags & SEC_CONSTRUCTOR) {
1312 arelent_chain *chain = section->constructor_chain;
1313 for (count = 0; count < section->reloc_count; count ++) {
1314 *relptr ++ = &chain->relent;
1315 chain = chain->next;
1316 }
1317 }
1318 else {
1319 tblptr = section->relocation;
1320 if (!tblptr) return 0;
1321
1322 for (count = 0; count++ < section->reloc_count;)
1323 {
1324 *relptr++ = tblptr++;
1325 }
1326 }
1327 *relptr = 0;
1328
1329 return section->reloc_count;
1330}
1331
1332unsigned int
e2aed73b 1333aout_get_reloc_upper_bound (abfd, asect)
4a81b561
DHW
1334 bfd *abfd;
1335 sec_ptr asect;
1336{
1337 if (bfd_get_format (abfd) != bfd_object) {
1338 bfd_error = invalid_operation;
1339 return 0;
1340 }
1341 if (asect->flags & SEC_CONSTRUCTOR) {
1342 return (sizeof (arelent *) * (asect->reloc_count+1));
1343 }
1344
c93595dd 1345
4a81b561
DHW
1346 if (asect == obj_datasec (abfd))
1347 return (sizeof (arelent *) *
e2aed73b 1348 ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
4a81b561
DHW
1349 +1));
1350
1351 if (asect == obj_textsec (abfd))
1352 return (sizeof (arelent *) *
e2aed73b 1353 ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
4a81b561
DHW
1354 +1));
1355
1356 bfd_error = invalid_operation;
1357 return 0;
1358}
1359
1360void
e2aed73b 1361aout_reclaim_reloc (ignore_abfd, ignore)
4a81b561 1362 bfd *ignore_abfd;
b1847ba9 1363 sec_ptr ignore;
4a81b561 1364{
9872a49c 1365
4a81b561
DHW
1366}
1367\f
1368
1369alent *
e2aed73b 1370aout_get_lineno(ignore_abfd, ignore_symbol)
4a81b561 1371bfd *ignore_abfd;
e2aed73b 1372asymbol *ignore_symbol;
4a81b561
DHW
1373{
1374return (alent *)NULL;
1375}
1376
1377void
e2aed73b 1378aout_print_symbol(ignore_abfd, afile, symbol, how)
4a81b561 1379bfd *ignore_abfd;
e2aed73b 1380PTR afile;
4a81b561
DHW
1381asymbol *symbol;
1382bfd_print_symbol_enum_type how;
1383{
e2aed73b
JG
1384 FILE *file = (FILE *)afile;
1385
4a81b561
DHW
1386 switch (how) {
1387 case bfd_print_symbol_name_enum:
1388 fprintf(file,"%s", symbol->name);
1389 break;
1390 case bfd_print_symbol_type_enum:
1391 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
fc723380 1392 (unsigned)(aout_symbol(symbol)->other & 0xff),
4a81b561
DHW
1393 (unsigned)(aout_symbol(symbol)->type));
1394 break;
1395 case bfd_print_symbol_all_enum:
1396 {
9846338e 1397 CONST char *section_name = symbol->section == (asection *)NULL ?
4a81b561
DHW
1398 "*abs" : symbol->section->name;
1399
9846338e 1400 bfd_print_symbol_vandf((PTR)file,symbol);
4a81b561
DHW
1401
1402 fprintf(file," %-5s %04x %02x %02x %s",
1403 section_name,
1404 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
fc723380 1405 (unsigned)(aout_symbol(symbol)->other & 0xff),
4a81b561
DHW
1406 (unsigned)(aout_symbol(symbol)->type & 0xff),
1407 symbol->name);
1408 }
1409 break;
1410 }
1411}
4a81b561
DHW
1412
1413/*
1414 provided a bfd, a section and an offset into the section, calculate
1415 and return the name of the source file and the line nearest to the
1416 wanted location.
1417*/
1418
1419boolean
e2aed73b 1420DEFUN(aout_find_nearest_line,(abfd,
aa802a32
SC
1421 section,
1422 symbols,
1423 offset,
1424 filename_ptr,
1425 functionname_ptr,
1426 line_ptr),
1427 bfd *abfd AND
1428 asection *section AND
1429 asymbol **symbols AND
1430 bfd_vma offset AND
9846338e
SC
1431 CONST char **filename_ptr AND
1432 CONST char **functionname_ptr AND
aa802a32 1433 unsigned int *line_ptr)
4a81b561
DHW
1434{
1435 /* Run down the file looking for the filename, function and linenumber */
1436 asymbol **p;
1437 static char buffer[100];
1438 bfd_vma high_line_vma = ~0;
1439 bfd_vma low_func_vma = 0;
1440 asymbol *func = 0;
1441 *filename_ptr = abfd->filename;
1442 *functionname_ptr = 0;
1443 *line_ptr = 0;
1444 if (symbols != (asymbol **)NULL) {
1445 for (p = symbols; *p; p++) {
1446 aout_symbol_type *q = (aout_symbol_type *)(*p);
1447 switch (q->type){
1448 case N_SO:
1449 *filename_ptr = q->symbol.name;
1450 if (obj_textsec(abfd) != section) {
1451 return true;
1452 }
1453 break;
1454 case N_SLINE:
1455
1456 case N_DSLINE:
1457 case N_BSLINE:
1458 /* We'll keep this if it resolves nearer than the one we have already */
1459 if (q->symbol.value >= offset &&
1460 q->symbol.value < high_line_vma) {
1461 *line_ptr = q->desc;
1462 high_line_vma = q->symbol.value;
1463 }
1464 break;
1465 case N_FUN:
1466 {
1467 /* We'll keep this if it is nearer than the one we have already */
1468 if (q->symbol.value >= low_func_vma &&
1469 q->symbol.value <= offset) {
1470 low_func_vma = q->symbol.value;
1471 func = (asymbol *)q;
1472 }
1473 if (*line_ptr && func) {
9846338e 1474 CONST char *function = func->name;
4a81b561
DHW
1475 char *p;
1476 strncpy(buffer, function, sizeof(buffer)-1);
1477 buffer[sizeof(buffer)-1] = 0;
1478 /* Have to remove : stuff */
1479 p = strchr(buffer,':');
1480 if (p != NULL) {*p = NULL; }
1481 *functionname_ptr = buffer;
1482 return true;
1483
1484 }
1485 }
1486 break;
1487 }
1488 }
1489 }
1490
1491 return true;
1492
1493}
1494
e2aed73b
JG
1495int
1496DEFUN(aout_sizeof_headers,(ignore_abfd),
b1847ba9 1497 bfd *ignore_abfd)
39a2ce33 1498{
b1847ba9 1499 return 0; /* FIXME, this is the wrong value! */
39a2ce33 1500}
This page took 0.092371 seconds and 4 git commands to generate.