1 |
/* BFD back-end for Intel 960 b.out binaries. |
/* BFD back-end for Intel 960 b.out binaries. |
2 |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, |
3 |
2000, 2001, 2002 |
2000, 2001, 2002, 2003, 2004, 2005 |
4 |
Free Software Foundation, Inc. |
Free Software Foundation, Inc. |
5 |
Written by Cygnus Support. |
Written by Cygnus Support. |
6 |
|
|
30 |
#include "aout/stab_gnu.h" |
#include "aout/stab_gnu.h" |
31 |
#include "libaout.h" /* BFD a.out internal data structures. */ |
#include "libaout.h" /* BFD a.out internal data structures. */ |
32 |
|
|
33 |
static int aligncode PARAMS ((bfd *abfd, asection *input_section, arelent *r, unsigned int shrink)); |
static int aligncode |
34 |
static void perform_slip PARAMS ((bfd *abfd, unsigned int slip, asection *input_section, bfd_vma value)); |
PARAMS ((bfd *abfd, asection *input_section, arelent *r, |
35 |
static boolean b_out_squirt_out_relocs PARAMS ((bfd *abfd, asection *section)); |
unsigned int shrink)); |
36 |
static const bfd_target * b_out_callback PARAMS ((bfd *)); |
static void perform_slip |
37 |
static bfd_reloc_status_type calljx_callback PARAMS ((bfd *, struct bfd_link_info *, arelent *, PTR src, PTR dst, asection *)); |
PARAMS ((bfd *abfd, unsigned int slip, asection *input_section, |
38 |
static bfd_reloc_status_type callj_callback PARAMS ((bfd *, struct bfd_link_info *, arelent *, PTR data, unsigned int srcidx, unsigned int dstidx, asection *, boolean)); |
bfd_vma value)); |
39 |
static bfd_vma get_value PARAMS ((arelent *, struct bfd_link_info *, asection *)); |
static bfd_boolean b_out_squirt_out_relocs |
40 |
static int abs32code PARAMS ((bfd *, asection *, arelent *, unsigned int, struct bfd_link_info *)); |
PARAMS ((bfd *abfd, asection *section)); |
41 |
static boolean b_out_bfd_relax_section PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *)); |
static const bfd_target *b_out_callback |
42 |
static bfd_byte * b_out_bfd_get_relocated_section_contents PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *, boolean, asymbol **)); |
PARAMS ((bfd *)); |
43 |
static int b_out_sizeof_headers PARAMS ((bfd *, boolean)); |
static bfd_reloc_status_type calljx_callback |
44 |
static boolean b_out_set_arch_mach PARAMS ((bfd *, enum bfd_architecture, unsigned long)); |
PARAMS ((bfd *, struct bfd_link_info *, arelent *, PTR src, PTR dst, |
45 |
static boolean b_out_set_section_contents PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); |
asection *)); |
46 |
static long b_out_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); |
static bfd_reloc_status_type callj_callback |
47 |
static long b_out_canonicalize_reloc PARAMS ((bfd *, sec_ptr, arelent **, asymbol **)); |
PARAMS ((bfd *, struct bfd_link_info *, arelent *, PTR data, |
48 |
static boolean b_out_slurp_reloc_table PARAMS ((bfd *, sec_ptr, asymbol **)); |
unsigned int srcidx, unsigned int dstidx, asection *, bfd_boolean)); |
49 |
static reloc_howto_type * b_out_bfd_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type)); |
static bfd_vma get_value |
50 |
static boolean b_out_write_object_contents PARAMS ((bfd *)); |
PARAMS ((arelent *, struct bfd_link_info *, asection *)); |
51 |
static int b_out_symbol_cmp PARAMS ((const void *, const void *)); |
static int abs32code |
52 |
static boolean b_out_mkobject PARAMS ((bfd *)); |
PARAMS ((bfd *, asection *, arelent *, unsigned int, |
53 |
static const bfd_target * b_out_object_p PARAMS ((bfd *)); |
struct bfd_link_info *)); |
54 |
|
static bfd_boolean b_out_bfd_relax_section |
55 |
void bout_swap_exec_header_in PARAMS ((bfd *, struct external_exec *, struct internal_exec *)); |
PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *)); |
56 |
void bout_swap_exec_header_out PARAMS ((bfd *, struct internal_exec *, struct external_exec *)); |
static bfd_byte *b_out_bfd_get_relocated_section_contents |
57 |
|
PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *, |
58 |
|
bfd_boolean, asymbol **)); |
59 |
|
static int b_out_sizeof_headers |
60 |
|
PARAMS ((bfd *, bfd_boolean)); |
61 |
|
static bfd_boolean b_out_set_arch_mach |
62 |
|
PARAMS ((bfd *, enum bfd_architecture, unsigned long)); |
63 |
|
static bfd_boolean b_out_set_section_contents |
64 |
|
PARAMS ((bfd *, asection *, const PTR, file_ptr, bfd_size_type)); |
65 |
|
static long b_out_get_reloc_upper_bound |
66 |
|
PARAMS ((bfd *, sec_ptr)); |
67 |
|
static long b_out_canonicalize_reloc |
68 |
|
PARAMS ((bfd *, sec_ptr, arelent **, asymbol **)); |
69 |
|
static bfd_boolean b_out_slurp_reloc_table |
70 |
|
PARAMS ((bfd *, sec_ptr, asymbol **)); |
71 |
|
static reloc_howto_type *b_out_bfd_reloc_type_lookup |
72 |
|
PARAMS ((bfd *, bfd_reloc_code_real_type)); |
73 |
|
static bfd_boolean b_out_write_object_contents |
74 |
|
PARAMS ((bfd *)); |
75 |
|
static int b_out_symbol_cmp |
76 |
|
PARAMS ((const void *, const void *)); |
77 |
|
static bfd_boolean b_out_mkobject |
78 |
|
PARAMS ((bfd *)); |
79 |
|
static const bfd_target *b_out_object_p |
80 |
|
PARAMS ((bfd *)); |
81 |
|
|
82 |
|
void bout_swap_exec_header_in |
83 |
|
PARAMS ((bfd *, struct external_exec *, struct internal_exec *)); |
84 |
|
void bout_swap_exec_header_out |
85 |
|
PARAMS ((bfd *, struct internal_exec *, struct external_exec *)); |
86 |
|
|
87 |
/* Swaps the information in an executable header taken from a raw byte |
/* Swaps the information in an executable header taken from a raw byte |
88 |
stream memory image, into the internal exec_header structure. */ |
stream memory image, into the internal exec_header structure. */ |
200 |
obj_datasec (abfd)->lma = obj_datasec (abfd)->vma; |
obj_datasec (abfd)->lma = obj_datasec (abfd)->vma; |
201 |
|
|
202 |
/* And reload the sizes, since the aout module zaps them. */ |
/* And reload the sizes, since the aout module zaps them. */ |
203 |
obj_textsec (abfd)->_raw_size = execp->a_text; |
obj_textsec (abfd)->size = execp->a_text; |
204 |
|
|
205 |
bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section */ |
bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section */ |
206 |
obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign); |
obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign); |
230 |
struct internal_exec e; |
struct internal_exec e; |
231 |
}; |
}; |
232 |
|
|
233 |
static boolean |
static bfd_boolean |
234 |
b_out_mkobject (abfd) |
b_out_mkobject (abfd) |
235 |
bfd *abfd; |
bfd *abfd; |
236 |
{ |
{ |
239 |
|
|
240 |
rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, amt); |
rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, amt); |
241 |
if (rawptr == NULL) |
if (rawptr == NULL) |
242 |
return false; |
return FALSE; |
243 |
|
|
244 |
abfd->tdata.bout_data = rawptr; |
abfd->tdata.bout_data = rawptr; |
245 |
exec_hdr (abfd) = &rawptr->e; |
exec_hdr (abfd) = &rawptr->e; |
248 |
obj_datasec (abfd) = (asection *) NULL; |
obj_datasec (abfd) = (asection *) NULL; |
249 |
obj_bsssec (abfd) = (asection *) NULL; |
obj_bsssec (abfd) = (asection *) NULL; |
250 |
|
|
251 |
return true; |
return TRUE; |
252 |
} |
} |
253 |
|
|
254 |
static int |
static int |
282 |
return 0; |
return 0; |
283 |
} |
} |
284 |
|
|
285 |
static boolean |
static bfd_boolean |
286 |
b_out_write_object_contents (abfd) |
b_out_write_object_contents (abfd) |
287 |
bfd *abfd; |
bfd *abfd; |
288 |
{ |
{ |
290 |
bfd_size_type amt; |
bfd_size_type amt; |
291 |
|
|
292 |
if (! aout_32_make_sections (abfd)) |
if (! aout_32_make_sections (abfd)) |
293 |
return false; |
return FALSE; |
294 |
|
|
295 |
exec_hdr (abfd)->a_info = BMAGIC; |
exec_hdr (abfd)->a_info = BMAGIC; |
296 |
|
|
297 |
exec_hdr (abfd)->a_text = obj_textsec (abfd)->_raw_size; |
exec_hdr (abfd)->a_text = obj_textsec (abfd)->size; |
298 |
exec_hdr (abfd)->a_data = obj_datasec (abfd)->_raw_size; |
exec_hdr (abfd)->a_data = obj_datasec (abfd)->size; |
299 |
exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->_raw_size; |
exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->size; |
300 |
exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist); |
exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * 12; |
301 |
exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd); |
exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd); |
302 |
exec_hdr (abfd)->a_trsize = ((obj_textsec (abfd)->reloc_count) * |
exec_hdr (abfd)->a_trsize = (obj_textsec (abfd)->reloc_count) * 8; |
303 |
sizeof (struct relocation_info)); |
exec_hdr (abfd)->a_drsize = (obj_datasec (abfd)->reloc_count) * 8; |
|
exec_hdr (abfd)->a_drsize = ((obj_datasec (abfd)->reloc_count) * |
|
|
sizeof (struct relocation_info)); |
|
304 |
|
|
305 |
exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power; |
exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power; |
306 |
exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power; |
exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power; |
314 |
amt = EXEC_BYTES_SIZE; |
amt = EXEC_BYTES_SIZE; |
315 |
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 |
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 |
316 |
|| bfd_bwrite ((PTR) &swapped_hdr, amt, abfd) != amt) |
|| bfd_bwrite ((PTR) &swapped_hdr, amt, abfd) != amt) |
317 |
return false; |
return FALSE; |
318 |
|
|
319 |
/* Now write out reloc info, followed by syms and strings */ |
/* Now write out reloc info, followed by syms and strings */ |
320 |
if (bfd_get_symcount (abfd) != 0) |
if (bfd_get_symcount (abfd) != 0) |
346 |
/* Back to your regularly scheduled program. */ |
/* Back to your regularly scheduled program. */ |
347 |
if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*exec_hdr(abfd))), SEEK_SET) |
if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*exec_hdr(abfd))), SEEK_SET) |
348 |
!= 0) |
!= 0) |
349 |
return false; |
return FALSE; |
350 |
|
|
351 |
if (! aout_32_write_syms (abfd)) |
if (! aout_32_write_syms (abfd)) |
352 |
return false; |
return FALSE; |
353 |
|
|
354 |
if (bfd_seek (abfd, (file_ptr) (N_TROFF(*exec_hdr(abfd))), SEEK_SET) |
if (bfd_seek (abfd, (file_ptr) (N_TROFF(*exec_hdr(abfd))), SEEK_SET) |
355 |
!= 0) |
!= 0) |
356 |
return false; |
return FALSE; |
357 |
|
|
358 |
if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) return false; |
if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) |
359 |
|
return FALSE; |
360 |
if (bfd_seek (abfd, (file_ptr) (N_DROFF(*exec_hdr(abfd))), SEEK_SET) |
if (bfd_seek (abfd, (file_ptr) (N_DROFF(*exec_hdr(abfd))), SEEK_SET) |
361 |
!= 0) |
!= 0) |
362 |
return false; |
return FALSE; |
363 |
|
|
364 |
if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) return false; |
if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) |
365 |
|
return FALSE; |
366 |
} |
} |
367 |
return true; |
return TRUE; |
368 |
} |
} |
369 |
|
|
370 |
/* Some reloc hackery. */ |
/* Some reloc hackery. */ |
429 |
unsigned int srcidx; |
unsigned int srcidx; |
430 |
unsigned int dstidx; |
unsigned int dstidx; |
431 |
asection *input_section; |
asection *input_section; |
432 |
boolean shrinking; |
bfd_boolean shrinking; |
433 |
{ |
{ |
434 |
int word = bfd_get_32 (abfd, (bfd_byte *) data + srcidx); |
int word = bfd_get_32 (abfd, (bfd_byte *) data + srcidx); |
435 |
asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr); |
asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr); |
496 |
#define ALIGNER 10 |
#define ALIGNER 10 |
497 |
#define ALIGNDONE 11 |
#define ALIGNDONE 11 |
498 |
static reloc_howto_type howto_reloc_callj = |
static reloc_howto_type howto_reloc_callj = |
499 |
HOWTO(CALLJ, 0, 2, 24, true, 0, complain_overflow_signed, 0,"callj", true, 0x00ffffff, 0x00ffffff,false); |
HOWTO(CALLJ, 0, 2, 24, TRUE, 0, complain_overflow_signed, 0,"callj", TRUE, 0x00ffffff, 0x00ffffff,FALSE); |
500 |
static reloc_howto_type howto_reloc_abs32 = |
static reloc_howto_type howto_reloc_abs32 = |
501 |
HOWTO(ABS32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"abs32", true, 0xffffffff,0xffffffff,false); |
HOWTO(ABS32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,0,"abs32", TRUE, 0xffffffff,0xffffffff,FALSE); |
502 |
static reloc_howto_type howto_reloc_pcrel24 = |
static reloc_howto_type howto_reloc_pcrel24 = |
503 |
HOWTO(PCREL24, 0, 2, 24, true, 0, complain_overflow_signed,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false); |
HOWTO(PCREL24, 0, 2, 24, TRUE, 0, complain_overflow_signed,0,"pcrel24", TRUE, 0x00ffffff,0x00ffffff,FALSE); |
504 |
|
|
505 |
static reloc_howto_type howto_reloc_pcrel13 = |
static reloc_howto_type howto_reloc_pcrel13 = |
506 |
HOWTO(PCREL13, 0, 2, 13, true, 0, complain_overflow_signed,0,"pcrel13", true, 0x00001fff,0x00001fff,false); |
HOWTO(PCREL13, 0, 2, 13, TRUE, 0, complain_overflow_signed,0,"pcrel13", TRUE, 0x00001fff,0x00001fff,FALSE); |
507 |
|
|
508 |
static reloc_howto_type howto_reloc_abs32codeshrunk = |
static reloc_howto_type howto_reloc_abs32codeshrunk = |
509 |
HOWTO(ABS32CODE_SHRUNK, 0, 2, 24, true, 0, complain_overflow_signed, 0,"callx->callj", true, 0x00ffffff, 0x00ffffff,false); |
HOWTO(ABS32CODE_SHRUNK, 0, 2, 24, TRUE, 0, complain_overflow_signed, 0,"callx->callj", TRUE, 0x00ffffff, 0x00ffffff,FALSE); |
510 |
|
|
511 |
static reloc_howto_type howto_reloc_abs32code = |
static reloc_howto_type howto_reloc_abs32code = |
512 |
HOWTO(ABS32CODE, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"callx", true, 0xffffffff,0xffffffff,false); |
HOWTO(ABS32CODE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,0,"callx", TRUE, 0xffffffff,0xffffffff,FALSE); |
513 |
|
|
514 |
static reloc_howto_type howto_align_table[] = { |
static reloc_howto_type howto_align_table[] = { |
515 |
HOWTO (ALIGNER, 0, 0x1, 0, false, 0, complain_overflow_dont, 0, "align16", false, 0, 0, false), |
HOWTO (ALIGNER, 0, 0x1, 0, FALSE, 0, complain_overflow_dont, 0, "align16", FALSE, 0, 0, FALSE), |
516 |
HOWTO (ALIGNER, 0, 0x3, 0, false, 0, complain_overflow_dont, 0, "align32", false, 0, 0, false), |
HOWTO (ALIGNER, 0, 0x3, 0, FALSE, 0, complain_overflow_dont, 0, "align32", FALSE, 0, 0, FALSE), |
517 |
HOWTO (ALIGNER, 0, 0x7, 0, false, 0, complain_overflow_dont, 0, "align64", false, 0, 0, false), |
HOWTO (ALIGNER, 0, 0x7, 0, FALSE, 0, complain_overflow_dont, 0, "align64", FALSE, 0, 0, FALSE), |
518 |
HOWTO (ALIGNER, 0, 0xf, 0, false, 0, complain_overflow_dont, 0, "align128", false, 0, 0, false), |
HOWTO (ALIGNER, 0, 0xf, 0, FALSE, 0, complain_overflow_dont, 0, "align128", FALSE, 0, 0, FALSE), |
519 |
}; |
}; |
520 |
|
|
521 |
static reloc_howto_type howto_done_align_table[] = { |
static reloc_howto_type howto_done_align_table[] = { |
522 |
HOWTO (ALIGNDONE, 0x1, 0x1, 0, false, 0, complain_overflow_dont, 0, "donealign16", false, 0, 0, false), |
HOWTO (ALIGNDONE, 0x1, 0x1, 0, FALSE, 0, complain_overflow_dont, 0, "donealign16", FALSE, 0, 0, FALSE), |
523 |
HOWTO (ALIGNDONE, 0x3, 0x3, 0, false, 0, complain_overflow_dont, 0, "donealign32", false, 0, 0, false), |
HOWTO (ALIGNDONE, 0x3, 0x3, 0, FALSE, 0, complain_overflow_dont, 0, "donealign32", FALSE, 0, 0, FALSE), |
524 |
HOWTO (ALIGNDONE, 0x7, 0x7, 0, false, 0, complain_overflow_dont, 0, "donealign64", false, 0, 0, false), |
HOWTO (ALIGNDONE, 0x7, 0x7, 0, FALSE, 0, complain_overflow_dont, 0, "donealign64", FALSE, 0, 0, FALSE), |
525 |
HOWTO (ALIGNDONE, 0xf, 0xf, 0, false, 0, complain_overflow_dont, 0, "donealign128", false, 0, 0, false), |
HOWTO (ALIGNDONE, 0xf, 0xf, 0, FALSE, 0, complain_overflow_dont, 0, "donealign128", FALSE, 0, 0, FALSE), |
526 |
}; |
}; |
527 |
|
|
528 |
static reloc_howto_type * |
static reloc_howto_type * |
546 |
|
|
547 |
/* Allocate enough room for all the reloc entries, plus pointers to them all. */ |
/* Allocate enough room for all the reloc entries, plus pointers to them all. */ |
548 |
|
|
549 |
static boolean |
static bfd_boolean |
550 |
b_out_slurp_reloc_table (abfd, asect, symbols) |
b_out_slurp_reloc_table (abfd, asect, symbols) |
551 |
bfd *abfd; |
bfd *abfd; |
552 |
sec_ptr asect; |
sec_ptr asect; |
565 |
arelent *reloc_cache; |
arelent *reloc_cache; |
566 |
|
|
567 |
if (asect->relocation) |
if (asect->relocation) |
568 |
return true; |
return TRUE; |
569 |
|
|
570 |
if (!aout_32_slurp_symbol_table (abfd)) |
if (!aout_32_slurp_symbol_table (abfd)) |
571 |
return false; |
return FALSE; |
572 |
|
|
573 |
if (asect == obj_datasec (abfd)) |
if (asect == obj_datasec (abfd)) |
574 |
{ |
{ |
589 |
} |
} |
590 |
|
|
591 |
bfd_set_error (bfd_error_invalid_operation); |
bfd_set_error (bfd_error_invalid_operation); |
592 |
return false; |
return FALSE; |
593 |
|
|
594 |
doit: |
doit: |
595 |
if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0) |
if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0) |
596 |
return false; |
return FALSE; |
597 |
count = reloc_size / sizeof (struct relocation_info); |
count = reloc_size / sizeof (struct relocation_info); |
598 |
|
|
599 |
relocs = (struct relocation_info *) bfd_malloc (reloc_size); |
relocs = (struct relocation_info *) bfd_malloc (reloc_size); |
600 |
if (!relocs && reloc_size != 0) |
if (!relocs && reloc_size != 0) |
601 |
return false; |
return FALSE; |
602 |
|
|
603 |
amt = ((bfd_size_type) count + 1) * sizeof (arelent); |
amt = ((bfd_size_type) count + 1) * sizeof (arelent); |
604 |
reloc_cache = (arelent *) bfd_malloc (amt); |
reloc_cache = (arelent *) bfd_malloc (amt); |
606 |
{ |
{ |
607 |
if (relocs != NULL) |
if (relocs != NULL) |
608 |
free (relocs); |
free (relocs); |
609 |
return false; |
return FALSE; |
610 |
} |
} |
611 |
|
|
612 |
if (bfd_bread ((PTR) relocs, reloc_size, abfd) != reloc_size) |
if (bfd_bread ((PTR) relocs, reloc_size, abfd) != reloc_size) |
614 |
free (reloc_cache); |
free (reloc_cache); |
615 |
if (relocs != NULL) |
if (relocs != NULL) |
616 |
free (relocs); |
free (relocs); |
617 |
return false; |
return FALSE; |
618 |
} |
} |
619 |
|
|
620 |
if (bfd_header_big_endian (abfd)) |
if (bfd_header_big_endian (abfd)) |
769 |
asect->relocation = reloc_cache; |
asect->relocation = reloc_cache; |
770 |
asect->reloc_count = count; |
asect->reloc_count = count; |
771 |
|
|
772 |
return true; |
return TRUE; |
773 |
} |
} |
774 |
|
|
775 |
static boolean |
static bfd_boolean |
776 |
b_out_squirt_out_relocs (abfd, section) |
b_out_squirt_out_relocs (abfd, section) |
777 |
bfd *abfd; |
bfd *abfd; |
778 |
asection *section; |
asection *section; |
788 |
int extern_mask, pcrel_mask, len_2, callj_mask; |
int extern_mask, pcrel_mask, len_2, callj_mask; |
789 |
|
|
790 |
if (count == 0) |
if (count == 0) |
791 |
return true; |
return TRUE; |
792 |
|
|
793 |
generic = section->orelocation; |
generic = section->orelocation; |
794 |
natsize = (bfd_size_type) count * sizeof (struct relocation_info); |
natsize = (bfd_size_type) count * sizeof (struct relocation_info); |
795 |
native = ((struct relocation_info *) bfd_malloc (natsize)); |
native = ((struct relocation_info *) bfd_malloc (natsize)); |
796 |
if (!native && natsize != 0) |
if (!native && natsize != 0) |
797 |
return false; |
return FALSE; |
798 |
|
|
799 |
if (bfd_header_big_endian (abfd)) |
if (bfd_header_big_endian (abfd)) |
800 |
{ |
{ |
899 |
if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize) |
if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize) |
900 |
{ |
{ |
901 |
free ((PTR)native); |
free ((PTR)native); |
902 |
return false; |
return FALSE; |
903 |
} |
} |
904 |
|
|
905 |
free ((PTR)native); |
free ((PTR)native); |
906 |
|
|
907 |
return true; |
return TRUE; |
908 |
} |
} |
909 |
|
|
910 |
/* This is stupid. This function should be a boolean predicate. */ |
/* This is stupid. This function should be a boolean predicate. */ |
977 |
} |
} |
978 |
|
|
979 |
|
|
980 |
static boolean |
static bfd_boolean |
981 |
b_out_set_section_contents (abfd, section, location, offset, count) |
b_out_set_section_contents (abfd, section, location, offset, count) |
982 |
bfd *abfd; |
bfd *abfd; |
983 |
asection *section; |
asection *section; |
984 |
PTR location; |
const PTR location; |
985 |
file_ptr offset; |
file_ptr offset; |
986 |
bfd_size_type count; |
bfd_size_type count; |
987 |
{ |
{ |
989 |
{ |
{ |
990 |
/* Set by bfd.c handler. */ |
/* Set by bfd.c handler. */ |
991 |
if (! aout_32_make_sections (abfd)) |
if (! aout_32_make_sections (abfd)) |
992 |
return false; |
return FALSE; |
993 |
|
|
994 |
obj_textsec (abfd)->filepos = sizeof (struct internal_exec); |
obj_textsec (abfd)->filepos = sizeof (struct external_exec); |
995 |
obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos |
obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos |
996 |
+ obj_textsec (abfd)->_raw_size; |
+ obj_textsec (abfd)->size; |
997 |
} |
} |
998 |
|
|
999 |
/* Regardless, once we know what we're doing, we might as well get going. */ |
/* Regardless, once we know what we're doing, we might as well get going. */ |
1000 |
if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0) |
if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0) |
1001 |
return false; |
return FALSE; |
1002 |
|
|
1003 |
if (count == 0) |
if (count == 0) |
1004 |
return true; |
return TRUE; |
1005 |
|
|
1006 |
return bfd_bwrite ((PTR) location, count, abfd) == count; |
return bfd_bwrite ((PTR) location, count, abfd) == count; |
1007 |
} |
} |
1008 |
|
|
1009 |
static boolean |
static bfd_boolean |
1010 |
b_out_set_arch_mach (abfd, arch, machine) |
b_out_set_arch_mach (abfd, arch, machine) |
1011 |
bfd *abfd; |
bfd *abfd; |
1012 |
enum bfd_architecture arch; |
enum bfd_architecture arch; |
1015 |
bfd_default_set_arch_mach(abfd, arch, machine); |
bfd_default_set_arch_mach(abfd, arch, machine); |
1016 |
|
|
1017 |
if (arch == bfd_arch_unknown) /* Unknown machine arch is OK. */ |
if (arch == bfd_arch_unknown) /* Unknown machine arch is OK. */ |
1018 |
return true; |
return TRUE; |
1019 |
|
|
1020 |
if (arch == bfd_arch_i960) /* i960 default is OK. */ |
if (arch == bfd_arch_i960) /* i960 default is OK. */ |
1021 |
switch (machine) |
switch (machine) |
1029 |
case bfd_mach_i960_jx: |
case bfd_mach_i960_jx: |
1030 |
case bfd_mach_i960_hx: |
case bfd_mach_i960_hx: |
1031 |
case 0: |
case 0: |
1032 |
return true; |
return TRUE; |
1033 |
default: |
default: |
1034 |
return false; |
return FALSE; |
1035 |
} |
} |
1036 |
|
|
1037 |
return false; |
return FALSE; |
1038 |
} |
} |
1039 |
|
|
1040 |
static int |
static int |
1041 |
b_out_sizeof_headers (ignore_abfd, ignore) |
b_out_sizeof_headers (ignore_abfd, ignore) |
1042 |
bfd *ignore_abfd ATTRIBUTE_UNUSED; |
bfd *ignore_abfd ATTRIBUTE_UNUSED; |
1043 |
boolean ignore ATTRIBUTE_UNUSED; |
bfd_boolean ignore ATTRIBUTE_UNUSED; |
1044 |
{ |
{ |
1045 |
return sizeof (struct internal_exec); |
return sizeof (struct external_exec); |
1046 |
} |
} |
1047 |
|
|
1048 |
|
|
1069 |
generic symbols. */ |
generic symbols. */ |
1070 |
h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info, |
h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info, |
1071 |
bfd_asymbol_name (symbol), |
bfd_asymbol_name (symbol), |
1072 |
false, false, true); |
FALSE, FALSE, TRUE); |
1073 |
if (h != (struct bfd_link_hash_entry *) NULL |
if (h != (struct bfd_link_hash_entry *) NULL |
1074 |
&& (h->type == bfd_link_hash_defined |
&& (h->type == bfd_link_hash_defined |
1075 |
|| h->type == bfd_link_hash_defweak)) |
|| h->type == bfd_link_hash_defweak)) |
1082 |
if (! ((*link_info->callbacks->undefined_symbol) |
if (! ((*link_info->callbacks->undefined_symbol) |
1083 |
(link_info, bfd_asymbol_name (symbol), |
(link_info, bfd_asymbol_name (symbol), |
1084 |
input_section->owner, input_section, reloc->address, |
input_section->owner, input_section, reloc->address, |
1085 |
true))) |
TRUE))) |
1086 |
abort (); |
abort (); |
1087 |
value = 0; |
value = 0; |
1088 |
} |
} |
1221 |
return shrink; |
return shrink; |
1222 |
} |
} |
1223 |
|
|
1224 |
static boolean |
static bfd_boolean |
1225 |
b_out_bfd_relax_section (abfd, i, link_info, again) |
b_out_bfd_relax_section (abfd, i, link_info, again) |
1226 |
bfd *abfd; |
bfd *abfd; |
1227 |
asection *i; |
asection *i; |
1228 |
struct bfd_link_info *link_info; |
struct bfd_link_info *link_info; |
1229 |
boolean *again; |
bfd_boolean *again; |
1230 |
{ |
{ |
1231 |
/* Get enough memory to hold the stuff. */ |
/* Get enough memory to hold the stuff. */ |
1232 |
bfd *input_bfd = i->owner; |
bfd *input_bfd = i->owner; |
1237 |
input_section); |
input_section); |
1238 |
|
|
1239 |
if (reloc_size < 0) |
if (reloc_size < 0) |
1240 |
return false; |
return FALSE; |
1241 |
|
|
1242 |
/* We only run this relaxation once. It might work to run it |
/* We only run this relaxation once. It might work to run it |
1243 |
multiple times, but it hasn't been tested. */ |
multiple times, but it hasn't been tested. */ |
1244 |
*again = false; |
*again = FALSE; |
1245 |
|
|
1246 |
if (reloc_size) |
if (reloc_size) |
1247 |
{ |
{ |
1283 |
} |
} |
1284 |
} |
} |
1285 |
} |
} |
1286 |
input_section->_cooked_size = input_section->_raw_size - shrink; |
input_section->size -= shrink; |
1287 |
|
|
1288 |
if (reloc_vector != NULL) |
if (reloc_vector != NULL) |
1289 |
free (reloc_vector); |
free (reloc_vector); |
1290 |
return true; |
return TRUE; |
1291 |
error_return: |
error_return: |
1292 |
if (reloc_vector != NULL) |
if (reloc_vector != NULL) |
1293 |
free (reloc_vector); |
free (reloc_vector); |
1294 |
return false; |
return FALSE; |
1295 |
} |
} |
1296 |
|
|
1297 |
static bfd_byte * |
static bfd_byte * |
1298 |
b_out_bfd_get_relocated_section_contents (output_bfd, link_info, link_order, |
b_out_bfd_get_relocated_section_contents (output_bfd, link_info, link_order, |
1299 |
data, relocateable, symbols) |
data, relocatable, symbols) |
1300 |
bfd *output_bfd; |
bfd *output_bfd; |
1301 |
struct bfd_link_info *link_info; |
struct bfd_link_info *link_info; |
1302 |
struct bfd_link_order *link_order; |
struct bfd_link_order *link_order; |
1303 |
bfd_byte *data; |
bfd_byte *data; |
1304 |
boolean relocateable; |
bfd_boolean relocatable; |
1305 |
asymbol **symbols; |
asymbol **symbols; |
1306 |
{ |
{ |
1307 |
/* Get enough memory to hold the stuff. */ |
/* Get enough memory to hold the stuff. */ |
1315 |
if (reloc_size < 0) |
if (reloc_size < 0) |
1316 |
goto error_return; |
goto error_return; |
1317 |
|
|
1318 |
/* If producing relocateable output, don't bother to relax. */ |
/* If producing relocatable output, don't bother to relax. */ |
1319 |
if (relocateable) |
if (relocatable) |
1320 |
return bfd_generic_get_relocated_section_contents (output_bfd, link_info, |
return bfd_generic_get_relocated_section_contents (output_bfd, link_info, |
1321 |
link_order, |
link_order, |
1322 |
data, relocateable, |
data, relocatable, |
1323 |
symbols); |
symbols); |
1324 |
|
|
1325 |
reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size); |
reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size); |
1326 |
if (reloc_vector == NULL && reloc_size != 0) |
if (reloc_vector == NULL && reloc_size != 0) |
1327 |
goto error_return; |
goto error_return; |
1328 |
|
|
|
input_section->reloc_done = 1; |
|
|
|
|
1329 |
/* Read in the section. */ |
/* Read in the section. */ |
1330 |
BFD_ASSERT (true == bfd_get_section_contents (input_bfd, |
BFD_ASSERT (bfd_get_section_contents (input_bfd, |
1331 |
input_section, |
input_section, |
1332 |
data, |
data, |
1333 |
(bfd_vma) 0, |
(bfd_vma) 0, |
1334 |
input_section->_raw_size)); |
input_section->size)); |
1335 |
|
|
1336 |
reloc_count = bfd_canonicalize_reloc (input_bfd, |
reloc_count = bfd_canonicalize_reloc (input_bfd, |
1337 |
input_section, |
input_section, |
1393 |
case CALLJ: |
case CALLJ: |
1394 |
callj_callback (input_bfd, link_info, reloc, data, |
callj_callback (input_bfd, link_info, reloc, data, |
1395 |
src_address, dst_address, input_section, |
src_address, dst_address, input_section, |
1396 |
false); |
FALSE); |
1397 |
src_address += 4; |
src_address += 4; |
1398 |
dst_address += 4; |
dst_address += 4; |
1399 |
break; |
break; |
1400 |
case ALIGNDONE: |
case ALIGNDONE: |
1401 |
BFD_ASSERT (reloc->addend >= src_address); |
BFD_ASSERT (reloc->addend >= src_address); |
1402 |
BFD_ASSERT ((bfd_vma) reloc->addend |
BFD_ASSERT ((bfd_vma) reloc->addend |
1403 |
<= input_section->_raw_size); |
<= input_section->size); |
1404 |
src_address = reloc->addend; |
src_address = reloc->addend; |
1405 |
dst_address = ((dst_address + reloc->howto->size) |
dst_address = ((dst_address + reloc->howto->size) |
1406 |
& ~reloc->howto->size); |
& ~reloc->howto->size); |
1410 |
callj will reach, so do the right thing. */ |
callj will reach, so do the right thing. */ |
1411 |
callj_callback (input_bfd, link_info, reloc, data, |
callj_callback (input_bfd, link_info, reloc, data, |
1412 |
src_address + 4, dst_address, input_section, |
src_address + 4, dst_address, input_section, |
1413 |
true); |
TRUE); |
1414 |
dst_address += 4; |
dst_address += 4; |
1415 |
src_address += 8; |
src_address += 8; |
1416 |
break; |
break; |
1483 |
#define b_out_bfd_link_split_section _bfd_generic_link_split_section |
#define b_out_bfd_link_split_section _bfd_generic_link_split_section |
1484 |
#define b_out_bfd_gc_sections bfd_generic_gc_sections |
#define b_out_bfd_gc_sections bfd_generic_gc_sections |
1485 |
#define b_out_bfd_merge_sections bfd_generic_merge_sections |
#define b_out_bfd_merge_sections bfd_generic_merge_sections |
1486 |
|
#define b_out_bfd_is_group_section bfd_generic_is_group_section |
1487 |
#define b_out_bfd_discard_group bfd_generic_discard_group |
#define b_out_bfd_discard_group bfd_generic_discard_group |
1488 |
|
#define b_out_section_already_linked \ |
1489 |
|
_bfd_generic_section_already_linked |
1490 |
|
|
1491 |
#define aout_32_get_section_contents_in_window \ |
#define aout_32_get_section_contents_in_window \ |
1492 |
_bfd_generic_get_section_contents_in_window |
_bfd_generic_get_section_contents_in_window |