Tweak previous change (only assume malformed_archive if errno == 0).
[deliverable/binutils-gdb.git] / bfd / aout.c
1 /* BFD semi-generic back-end for a.out binaries */
2
3 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
4
5 This file is part of BFD, the Binary File Diddler.
6
7 BFD is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 1, or (at your option)
10 any later version.
11
12 BFD is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with BFD; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21
22 #include <ansidecl.h>
23 #include <sysdep.h>
24 #include "bfd.h"
25 #include "libbfd.h"
26
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
32 void (*bfd_error_trap)();
33
34 /*SUPPRESS558*/
35 /*SUPPRESS529*/
36
37 #define CTOR_TABLE_RELOC_IDX 2
38 static reloc_howto_type howto_table_ext[] =
39 {
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),
67 };
68
69 /* Convert standard reloc records to "arelent" format (incl byte swap). */
70
71 static reloc_howto_type howto_table_std[] = {
72 /* type rs size bsz pcrel bitpos abs ovrf sf name part_inpl readmask setmask pcdone */
73 HOWTO( 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff,0x000000ff, false),
74 HOWTO( 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff,0x0000ffff, false),
75 HOWTO( 2, 0, 2, 32, false, 0, true, true,0,"32", true, 0xffffffff,0xffffffff, false),
76 HOWTO( 3, 0, 3, 64, false, 0, true, true,0,"64", true, 0xdeaddead,0xdeaddead, false),
77 HOWTO( 4, 0, 0, 8, true, 0, false, true,0,"DISP8", true, 0x000000ff,0x000000ff, false),
78 HOWTO( 5, 0, 1, 16, true, 0, false, true,0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
79 HOWTO( 6, 0, 2, 32, true, 0, false, true,0,"DISP32", true, 0xffffffff,0xffffffff, false),
80 HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedface,0xfeedface, false),
81 };
82
83
84 bfd_error_vector_type bfd_error_vector;
85
86 void
87 DEFUN(bfd_aout_swap_exec_header_in,(abfd, raw_bytes, execp),
88 bfd *abfd AND
89 unsigned char *raw_bytes AND
90 struct exec *execp)
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
105 void
106 DEFUN(bfd_aout_swap_exec_header_out,(abfd, execp, raw_bytes),
107 bfd *abfd AND
108 struct exec *execp AND
109 unsigned char *raw_bytes)
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
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
129 bfd_target *
130 some_aout_object_p (abfd, callback_to_real_object_p)
131 bfd *abfd;
132 bfd_target *(*callback_to_real_object_p) ();
133 {
134 unsigned char exec_bytes[EXEC_BYTES_SIZE]; /* Raw bytes of exec hdr */
135 struct exec *execp;
136 PTR rawptr;
137
138 if (bfd_seek (abfd, 0L, false) < 0) {
139 bfd_error = system_call_error;
140 return 0;
141 }
142
143 if (bfd_read ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
144 != EXEC_BYTES_SIZE) {
145 bfd_error = wrong_format;
146 return 0;
147 }
148
149 /* Use an intermediate variable for clarity */
150 rawptr = (PTR) bfd_zalloc (abfd, sizeof (struct aoutdata) + sizeof (struct exec));
151
152 if (rawptr == NULL) {
153 bfd_error = no_memory;
154 return 0;
155 }
156
157 set_tdata (abfd, ((struct aoutdata *) rawptr));
158 exec_hdr (abfd) = execp =
159 (struct exec *) ((char *)rawptr + sizeof (struct aoutdata));
160
161 bfd_aout_swap_exec_header_in (abfd, exec_bytes, execp);
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
172 if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
173 if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
174
175 bfd_get_start_address (abfd) = execp->a_entry;
176
177 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
178 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct nlist);
179
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;
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;
193 (void)bfd_make_section(abfd, ".text");
194 (void)bfd_make_section(abfd, ".data");
195 (void)bfd_make_section(abfd, ".bss");
196
197 abfd->sections = obj_textsec (abfd);
198 obj_textsec (abfd)->next = obj_datasec (abfd);
199 obj_datasec (abfd)->next = obj_bsssec (abfd);
200
201 obj_datasec (abfd)->size = execp->a_data;
202 obj_bsssec (abfd)->size = execp->a_bss;
203 obj_textsec (abfd)->size = execp->a_text;
204
205 if (abfd->flags & D_PAGED) {
206 obj_textsec (abfd)->size -= EXEC_BYTES_SIZE;
207 }
208
209
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));
216 obj_bsssec (abfd)->flags = SEC_ALLOC;
217
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
276
277 return (*callback_to_real_object_p)(abfd);
278 }
279
280
281 boolean
282 aout_mkobject (abfd)
283 bfd *abfd;
284 {
285 char *rawptr;
286
287 bfd_error = system_call_error;
288
289 /* Use an intermediate variable for clarity */
290 rawptr = bfd_zalloc (abfd, sizeof (struct aoutdata) + sizeof (struct exec));
291
292 if (rawptr == NULL) {
293 bfd_error = no_memory;
294 return false;
295 }
296
297 set_tdata (abfd, (struct aoutdata *) rawptr);
298 exec_hdr (abfd) = (struct exec *) (rawptr + sizeof (struct aoutdata));
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
319 enum machine_type
320 aout_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:
330 if (machine == 0) arch_flags = M_SPARC;
331 break;
332
333 case bfd_arch_m68k:
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;
342
343 case bfd_arch_i386:
344 if (machine == 0) arch_flags = M_386;
345 break;
346
347 case bfd_arch_a29k:
348 if (machine == 0) arch_flags = M_29K;
349 break;
350
351 default:
352 arch_flags = M_UNKNOWN;
353 break;
354 }
355 return arch_flags;
356 }
357
358 boolean
359 aout_set_arch_mach (abfd, arch, machine)
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 }
371 \f
372 /* exec and core file sections */
373
374 boolean
375 aout_new_section_hook (abfd, newsect)
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
399 /* We allow more than three sections internally */
400 return true;
401 }
402
403 boolean
404 aout_set_section_contents (abfd, section, location, offset, count)
405 bfd *abfd;
406 sec_ptr section;
407 PTR location;
408 file_ptr offset;
409 int count;
410 {
411 if (abfd->output_has_begun == false)
412 { /* set by bfd.c handler */
413 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
414 {
415 bfd_error = invalid_operation;
416 return false;
417 }
418
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);
422 obj_datasec(abfd)->filepos = obj_textsec (abfd)->size + EXEC_BYTES_SIZE;
423 obj_datasec(abfd)->size = align_power(obj_datasec(abfd)->size,
424 obj_datasec(abfd)->alignment_power);
425
426
427 }
428 /* regardless, once we know what we're doing, we might as well get going */
429 if (section != obj_bsssec(abfd))
430 {
431 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
432
433 if (count) {
434 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
435 true : false;
436 }
437 return false;
438 }
439 return true;
440 }
441 \f
442 /* Classify stabs symbols */
443
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
483 static void
484 translate_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);
497 arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
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 ;
519
520 /* We modify the symbol to belong to a section depending upon the
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
524 symbol attached to this section. */
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
535 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
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 }
614
615 void
616 translate_to_native_sym_flags (sym_pointer, cache_ptr_g, abfd)
617 struct nlist *sym_pointer;
618 PTR cache_ptr_g;
619 bfd *abfd;
620 {
621 asymbol *cache_ptr = (asymbol *)cache_ptr_g;
622
623 /* FIXME check for writing bss */
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 {
635 bfd_error_vector.nonrepresentable_section(abfd,
636 bfd_get_output_section(cache_ptr)->name);
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 }
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
670 asymbol *
671 aout_make_empty_symbol (abfd)
672 bfd *abfd;
673 {
674 aout_symbol_type *new =
675 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
676 new->symbol.the_bfd = abfd;
677
678 return &new->symbol;
679 }
680
681 boolean
682 DEFUN(aout_slurp_symbol_table, (abfd),
683 bfd *abfd)
684 {
685 size_t symbol_size;
686 size_t string_size;
687 unsigned char string_chars[LONG_SIZE];
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);
701 if (bfd_read ((PTR)string_chars, LONG_SIZE, 1, abfd) != LONG_SIZE)
702 return false;
703 string_size = bfd_h_getlong (abfd, string_chars);
704
705 strings = bfd_alloc(abfd, string_size + 1);
706 cached = (aout_symbol_type *)
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. */
709 syms = (struct nlist *) bfd_alloc(abfd, symbol_size);
710
711 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
712 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
713 bailout:
714 if (syms) bfd_release (abfd, syms);
715 if (cached) bfd_release (abfd, cached);
716 if (strings)bfd_release (abfd, strings);
717 return false;
718 }
719
720 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
721 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
722 goto bailout;
723 }
724
725 /* OK, now walk the new symtable, cacheing symbol properties */
726 {
727 register struct nlist *sym_pointer;
728 register struct nlist *sym_end = syms + bfd_get_symcount (abfd);
729 register aout_symbol_type *cache_ptr = cached;
730
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 =
734 bfd_h_getlong (abfd, &sym_pointer->n_un.n_strx);
735 sym_pointer->n_desc =
736 bfd_h_getshort (abfd, &sym_pointer->n_desc);
737 sym_pointer->n_value =
738 bfd_h_getlong (abfd, &sym_pointer->n_value);
739 sym_pointer->n_other = (char)
740 bfd_h_getchar(abfd, &sym_pointer->n_other);
741 sym_pointer->n_type = (char)
742 bfd_h_getchar(abfd, &sym_pointer->n_type);
743 }
744
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);
760
761 }
762 }
763
764 obj_aout_symbols (abfd) = cached;
765 bfd_release (abfd, (PTR)syms);
766
767 return true;
768 }
769
770
771 void
772 DEFUN(aout_write_syms,(abfd),
773 bfd *abfd)
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;
808 translate_to_native_sym_flags (&nsp, (PTR)g, abfd);
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);
813 bfd_write((PTR)&nsp,1, sizeof(nsp), abfd);
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
822 bfd_write((PTR)&stindex, 1, sizeof(stindex), abfd);
823
824 generic = bfd_get_outsymbols(abfd);
825 for (count = 0; count < bfd_get_symcount(abfd); count++)
826 {
827 asymbol *g = *(generic++);
828
829 if (g->name)
830 {
831 size_t length = strlen(g->name)+1;
832 bfd_write((PTR)g->name, 1, length, abfd);
833 }
834 if ((g->flags & BSF_FAKE)==0) {
835 g->name = itos(count); /* smash the generic symbol */
836 }
837 }
838 }
839
840
841 void
842 DEFUN(aout_reclaim_symbol_table,(abfd),
843 bfd *abfd)
844 {
845
846 }
847 \f
848 unsigned int
849 aout_get_symtab_upper_bound (abfd)
850 bfd *abfd;
851 {
852 if (!aout_slurp_symbol_table (abfd)) return 0;
853
854 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
855 }
856
857 unsigned int
858 aout_get_symtab (abfd, location)
859 bfd *abfd;
860 asymbol **location;
861 {
862 unsigned int counter = 0;
863 aout_symbol_type *symbase;
864
865 if (!aout_slurp_symbol_table (abfd)) return 0;
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
873 \f
874 /* Standard reloc stuff */
875 /* Output standard relocation information to a file in target byte order. */
876
877 void
878 swap_std_reloc_out (abfd, g, natptr)
879 bfd *abfd;
880 arelent *g; /* Generic relocation struct */
881 struct reloc_std_bytes *natptr;
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;
889
890 bfd_h_putlong (abfd, g->address, natptr->r_address);
891
892 r_length = g->howto->size ; /* Size as a power of two */
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;
898
899 r_addend = g->addend; /* Start here, see how it goes */
900
901 /* name was clobbered by aout_write_syms to be symbol index */
902
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;
908 }
909
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) {
916 /* It is possible to have a reloc with nothing, we generate an
917 abs + 0 */
918 r_addend = 0;
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;
932 }
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 }
962 }
963
964
965 /* Extended stuff */
966 /* Output extended relocation information to a file in target byte order. */
967
968 void
969 swap_ext_reloc_out (abfd, g, natptr)
970 bfd *abfd;
971 arelent *g; /* Generic relocation struct */
972 register struct reloc_ext_bytes *natptr;
973 {
974 int r_index;
975 int r_extern;
976 unsigned int r_type;
977 unsigned int r_addend;
978
979 bfd_h_putlong (abfd, g->address, natptr->r_address);
980
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;
984
985 r_addend = g->addend; /* Start here, see how it goes */
986
987 /* name was clobbered by aout_write_syms to be symbol index*/
988
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;
994 }
995
996 r_index = stoi((*(g->sym_ptr_ptr))->name);
997 r_extern = 1;
998 }
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 }
1021
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)
1029 | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
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)
1036 | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1037 }
1038
1039 bfd_h_putlong (abfd, r_addend, natptr->r_addend);
1040 }
1041
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: \
1067 cache_ptr->section = NULL; /* No section */ \
1068 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1069 BFD_ASSERT(1); \
1070 break; \
1071 default: \
1072 cache_ptr->section = NULL; /* No section */ \
1073 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1074 BFD_ASSERT(1); \
1075 break; \
1076 } \
1077 } \
1078
1079 void
1080 swap_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;
1089 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
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));
1112 }
1113
1114 void
1115 swap_std_reloc_in (abfd, bytes, cache_ptr, symbols)
1116 bfd *abfd;
1117 struct reloc_std_bytes *bytes;
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;
1126 struct aoutdata *su = (struct aoutdata *)(abfd->tdata);
1127
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)
1141 >> RELOC_STD_BITS_LENGTH_SH_BIG;
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)
1152 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
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 */
1162
1163 boolean
1164 aout_slurp_reloc_table (abfd, asect, symbols)
1165 bfd *abfd;
1166 sec_ptr asect;
1167 asymbol **symbols;
1168 {
1169 unsigned int count;
1170 size_t reloc_size;
1171 PTR relocs;
1172 arelent *reloc_cache;
1173 size_t each_size;
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);
1194 each_size = obj_reloc_entry_size (abfd);
1195
1196 count = reloc_size / each_size;
1197
1198
1199 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1200 (arelent)));
1201 if (!reloc_cache) {
1202 nomem:
1203 bfd_error = no_memory;
1204 return false;
1205 }
1206
1207 relocs = bfd_alloc (abfd, reloc_size);
1208 if (!relocs) {
1209 bfd_release (abfd, reloc_cache);
1210 goto nomem;
1211 }
1212
1213 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1214 bfd_release (abfd, relocs);
1215 bfd_release (abfd, reloc_cache);
1216 bfd_error = system_call_error;
1217 return false;
1218 }
1219
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;
1224
1225 for (; counter < count; counter++, rptr++, cache_ptr++) {
1226 swap_ext_reloc_in(abfd, rptr, cache_ptr, symbols);
1227 }
1228 } else {
1229 register struct reloc_std_bytes *rptr = (struct reloc_std_bytes *) relocs;
1230 unsigned int counter = 0;
1231 arelent *cache_ptr = reloc_cache;
1232
1233 for (; counter < count; counter++, rptr++, cache_ptr++) {
1234 swap_std_reloc_in(abfd, rptr, cache_ptr, symbols);
1235 }
1236
1237 }
1238
1239 bfd_release (abfd,relocs);
1240 asect->relocation = reloc_cache;
1241 asect->reloc_count = count;
1242 return true;
1243 }
1244
1245
1246
1247 /* Write out a relocation section into an object file. */
1248
1249 boolean
1250 aout_squirt_out_relocs (abfd, section)
1251 bfd *abfd;
1252 asection *section;
1253 {
1254 arelent **generic;
1255 unsigned char *native, *natptr;
1256 size_t each_size;
1257
1258 unsigned int count = section->reloc_count;
1259 size_t natsize;
1260
1261 if (count == 0) return true;
1262
1263 each_size = obj_reloc_entry_size (abfd);
1264 natsize = each_size * count;
1265 native = (unsigned char *) bfd_zalloc (abfd, natsize);
1266 if (!native) {
1267 bfd_error = no_memory;
1268 return false;
1269 }
1270
1271 generic = section->orelocation;
1272
1273 if (each_size == RELOC_EXT_SIZE)
1274 {
1275 for (natptr = native;
1276 count != 0;
1277 --count, natptr += each_size, ++generic)
1278 swap_ext_reloc_out (abfd, *generic, (struct reloc_ext_bytes *)natptr);
1279 }
1280 else
1281 {
1282 for (natptr = native;
1283 count != 0;
1284 --count, natptr += each_size, ++generic)
1285 swap_std_reloc_out(abfd, *generic, (struct reloc_std_bytes *)natptr);
1286 }
1287
1288 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1289 bfd_release(abfd, native);
1290 return false;
1291 }
1292 bfd_release (abfd, native);
1293
1294 return true;
1295 }
1296
1297 /* This is stupid. This function should be a boolean predicate */
1298 unsigned int
1299 aout_canonicalize_reloc (abfd, section, relptr, symbols)
1300 bfd *abfd;
1301 sec_ptr section;
1302 arelent **relptr;
1303 asymbol **symbols;
1304 {
1305 arelent *tblptr = section->relocation;
1306 unsigned int count;
1307
1308 if (!(tblptr || aout_slurp_reloc_table (abfd, section, symbols)))
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
1332 unsigned int
1333 aout_get_reloc_upper_bound (abfd, asect)
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
1345
1346 if (asect == obj_datasec (abfd))
1347 return (sizeof (arelent *) *
1348 ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
1349 +1));
1350
1351 if (asect == obj_textsec (abfd))
1352 return (sizeof (arelent *) *
1353 ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
1354 +1));
1355
1356 bfd_error = invalid_operation;
1357 return 0;
1358 }
1359
1360 void
1361 aout_reclaim_reloc (ignore_abfd, ignore)
1362 bfd *ignore_abfd;
1363 sec_ptr ignore;
1364 {
1365
1366 }
1367 \f
1368
1369 alent *
1370 aout_get_lineno(ignore_abfd, ignore_symbol)
1371 bfd *ignore_abfd;
1372 asymbol *ignore_symbol;
1373 {
1374 return (alent *)NULL;
1375 }
1376
1377 void
1378 aout_print_symbol(ignore_abfd, afile, symbol, how)
1379 bfd *ignore_abfd;
1380 PTR afile;
1381 asymbol *symbol;
1382 bfd_print_symbol_enum_type how;
1383 {
1384 FILE *file = (FILE *)afile;
1385
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),
1392 (unsigned)(aout_symbol(symbol)->other & 0xff),
1393 (unsigned)(aout_symbol(symbol)->type));
1394 break;
1395 case bfd_print_symbol_all_enum:
1396 {
1397 CONST char *section_name = symbol->section == (asection *)NULL ?
1398 "*abs" : symbol->section->name;
1399
1400 bfd_print_symbol_vandf((PTR)file,symbol);
1401
1402 fprintf(file," %-5s %04x %02x %02x %s",
1403 section_name,
1404 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1405 (unsigned)(aout_symbol(symbol)->other & 0xff),
1406 (unsigned)(aout_symbol(symbol)->type & 0xff),
1407 symbol->name);
1408 }
1409 break;
1410 }
1411 }
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
1419 boolean
1420 DEFUN(aout_find_nearest_line,(abfd,
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
1431 CONST char **filename_ptr AND
1432 CONST char **functionname_ptr AND
1433 unsigned int *line_ptr)
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) {
1474 CONST char *function = func->name;
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
1495 int
1496 DEFUN(aout_sizeof_headers,(ignore_abfd),
1497 bfd *ignore_abfd)
1498 {
1499 return 0; /* FIXME, this is the wrong value! */
1500 }
This page took 0.061011 seconds and 4 git commands to generate.