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