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