1 |
/* BFD back-end for TMS320C54X coff binaries. |
/* BFD back-end for TMS320C54X coff binaries. |
2 |
Copyright 1999, 2000, 2001 Free Software Foundation, Inc. |
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 |
3 |
|
Free Software Foundation, Inc. |
4 |
Contributed by Timothy Wall (twall@cygnus.com) |
Contributed by Timothy Wall (twall@cygnus.com) |
5 |
|
|
6 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
31 |
#undef F_LSYMS |
#undef F_LSYMS |
32 |
#define F_LSYMS F_LSYMS_TICOFF |
#define F_LSYMS F_LSYMS_TICOFF |
33 |
|
|
34 |
static void tic54x_reloc_processing PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *)); |
static void tic54x_reloc_processing |
35 |
static bfd_reloc_status_type tic54x_relocation PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *)); |
36 |
static boolean tic54x_set_section_contents PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type)); |
static bfd_reloc_status_type tic54x_relocation |
37 |
static reloc_howto_type * coff_tic54x_rtype_to_howto PARAMS ((bfd *, asection *, struct internal_reloc *, struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *)); |
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
38 |
static bfd_vma tic54x_getl32 PARAMS ((const bfd_byte *)); |
static bfd_boolean tic54x_set_section_contents |
39 |
static void tic54x_putl32 PARAMS ((bfd_vma, bfd_byte *)); |
PARAMS ((bfd *, sec_ptr, const PTR, file_ptr, bfd_size_type)); |
40 |
static bfd_signed_vma tic54x_getl_signed_32 PARAMS ((const bfd_byte *)); |
static reloc_howto_type *coff_tic54x_rtype_to_howto |
41 |
static boolean tic54x_set_arch_mach PARAMS ((bfd *, enum bfd_architecture, unsigned long)); |
PARAMS ((bfd *, asection *, struct internal_reloc *, struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *)); |
42 |
static reloc_howto_type * tic54x_coff_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type)); |
static bfd_boolean tic54x_set_arch_mach |
43 |
static void tic54x_lookup_howto PARAMS ((arelent *, struct internal_reloc *)); |
PARAMS ((bfd *, enum bfd_architecture, unsigned long)); |
44 |
static boolean ticoff0_bad_format_hook PARAMS ((bfd *, PTR)); |
static reloc_howto_type * tic54x_coff_reloc_type_lookup |
45 |
static boolean ticoff1_bad_format_hook PARAMS ((bfd *, PTR)); |
PARAMS ((bfd *, bfd_reloc_code_real_type)); |
46 |
static boolean ticoff_bfd_is_local_label_name PARAMS ((bfd *, const char *)); |
static void tic54x_lookup_howto |
47 |
|
PARAMS ((arelent *, struct internal_reloc *)); |
48 |
|
static bfd_boolean ticoff_bfd_is_local_label_name |
49 |
|
PARAMS ((bfd *, const char *)); |
50 |
|
|
51 |
/* 32-bit operations |
/* 32-bit operations |
52 |
The octet order is screwy. words are LSB first (LS octet, actually), but |
The octet order is screwy. words are LSB first (LS octet, actually), but |
56 |
Don't bother with 64-bits, as there aren't any. */ |
Don't bother with 64-bits, as there aren't any. */ |
57 |
|
|
58 |
static bfd_vma |
static bfd_vma |
59 |
tic54x_getl32 (addr) |
tic54x_getl32 (const void *p) |
|
const bfd_byte *addr; |
|
60 |
{ |
{ |
61 |
|
const bfd_byte *addr = p; |
62 |
unsigned long v; |
unsigned long v; |
63 |
|
|
64 |
v = (unsigned long) addr[2]; |
v = (unsigned long) addr[2]; |
65 |
v |= (unsigned long) addr[3] << 8; |
v |= (unsigned long) addr[3] << 8; |
66 |
v |= (unsigned long) addr[0] << 16; |
v |= (unsigned long) addr[0] << 16; |
67 |
v |= (unsigned long) addr[1] << 24; |
v |= (unsigned long) addr[1] << 24; |
68 |
return (bfd_vma) v; |
return v; |
69 |
} |
} |
70 |
|
|
71 |
static void |
static void |
72 |
tic54x_putl32 (data, addr) |
tic54x_putl32 (bfd_vma data, void *p) |
73 |
bfd_vma data; |
{ |
74 |
bfd_byte *addr; |
bfd_byte *addr = p; |
75 |
{ |
addr[2] = data & 0xff; |
76 |
addr[2] = (bfd_byte)data; |
addr[3] = (data >> 8) & 0xff; |
77 |
addr[3] = (bfd_byte) (data >> 8); |
addr[0] = (data >> 16) & 0xff; |
78 |
addr[0] = (bfd_byte) (data >> 16); |
addr[1] = (data >> 24) & 0xff; |
|
addr[1] = (bfd_byte) (data >> 24); |
|
79 |
} |
} |
80 |
|
|
81 |
bfd_signed_vma |
static bfd_signed_vma |
82 |
tic54x_getl_signed_32 (addr) |
tic54x_getl_signed_32 (const void *p) |
|
register const bfd_byte *addr; |
|
83 |
{ |
{ |
84 |
|
const bfd_byte *addr = p; |
85 |
unsigned long v; |
unsigned long v; |
86 |
|
|
87 |
v = (unsigned long) addr[2]; |
v = (unsigned long) addr[2]; |
128 |
/* Set the architecture appropriately. Allow unkown architectures |
/* Set the architecture appropriately. Allow unkown architectures |
129 |
(e.g. binary). */ |
(e.g. binary). */ |
130 |
|
|
131 |
static boolean |
static bfd_boolean |
132 |
tic54x_set_arch_mach (abfd, arch, machine) |
tic54x_set_arch_mach (abfd, arch, machine) |
133 |
bfd *abfd; |
bfd *abfd; |
134 |
enum bfd_architecture arch; |
enum bfd_architecture arch; |
138 |
arch = bfd_arch_tic54x; |
arch = bfd_arch_tic54x; |
139 |
|
|
140 |
else if (arch != bfd_arch_tic54x) |
else if (arch != bfd_arch_tic54x) |
141 |
return false; |
return FALSE; |
142 |
|
|
143 |
return bfd_default_set_arch_mach (abfd, arch, machine); |
return bfd_default_set_arch_mach (abfd, arch, machine); |
144 |
} |
} |
173 |
|
|
174 |
/* NORMAL BANK */ |
/* NORMAL BANK */ |
175 |
/* 16-bit direct reference to symbol's address. */ |
/* 16-bit direct reference to symbol's address. */ |
176 |
HOWTO (R_RELWORD,0,1,16,false,0,complain_overflow_dont, |
HOWTO (R_RELWORD,0,1,16,FALSE,0,complain_overflow_dont, |
177 |
tic54x_relocation,"REL16",false,0xFFFF,0xFFFF,false), |
tic54x_relocation,"REL16",FALSE,0xFFFF,0xFFFF,FALSE), |
178 |
|
|
179 |
/* 7 LSBs of an address */ |
/* 7 LSBs of an address */ |
180 |
HOWTO (R_PARTLS7,0,1,7,false,0,complain_overflow_dont, |
HOWTO (R_PARTLS7,0,1,7,FALSE,0,complain_overflow_dont, |
181 |
tic54x_relocation,"LS7",false,0x007F,0x007F,false), |
tic54x_relocation,"LS7",FALSE,0x007F,0x007F,FALSE), |
182 |
|
|
183 |
/* 9 MSBs of an address */ |
/* 9 MSBs of an address */ |
184 |
/* TI assembler doesn't shift its encoding, and is thus incompatible */ |
/* TI assembler doesn't shift its encoding, and is thus incompatible */ |
185 |
HOWTO (R_PARTMS9,7,1,9,false,0,complain_overflow_dont, |
HOWTO (R_PARTMS9,7,1,9,FALSE,0,complain_overflow_dont, |
186 |
tic54x_relocation,"MS9",false,0x01FF,0x01FF,false), |
tic54x_relocation,"MS9",FALSE,0x01FF,0x01FF,FALSE), |
187 |
|
|
188 |
/* 23-bit relocation */ |
/* 23-bit relocation */ |
189 |
HOWTO (R_EXTWORD,0,2,23,false,0,complain_overflow_dont, |
HOWTO (R_EXTWORD,0,2,23,FALSE,0,complain_overflow_dont, |
190 |
tic54x_relocation,"RELEXT",false,0x7FFFFF,0x7FFFFF,false), |
tic54x_relocation,"RELEXT",FALSE,0x7FFFFF,0x7FFFFF,FALSE), |
191 |
|
|
192 |
/* 16 bits of 23-bit extended address */ |
/* 16 bits of 23-bit extended address */ |
193 |
HOWTO (R_EXTWORD16,0,1,16,false,0,complain_overflow_dont, |
HOWTO (R_EXTWORD16,0,1,16,FALSE,0,complain_overflow_dont, |
194 |
tic54x_relocation,"RELEXT16",false,0x7FFFFF,0x7FFFFF,false), |
tic54x_relocation,"RELEXT16",FALSE,0x7FFFFF,0x7FFFFF,FALSE), |
195 |
|
|
196 |
/* upper 7 bits of 23-bit extended address */ |
/* upper 7 bits of 23-bit extended address */ |
197 |
HOWTO (R_EXTWORDMS7,16,1,7,false,0,complain_overflow_dont, |
HOWTO (R_EXTWORDMS7,16,1,7,FALSE,0,complain_overflow_dont, |
198 |
tic54x_relocation,"RELEXTMS7",false,0x7F,0x7F,false), |
tic54x_relocation,"RELEXTMS7",FALSE,0x7F,0x7F,FALSE), |
199 |
|
|
200 |
/* ABSOLUTE BANK */ |
/* ABSOLUTE BANK */ |
201 |
/* 16-bit direct reference to symbol's address, absolute */ |
/* 16-bit direct reference to symbol's address, absolute */ |
202 |
HOWTO (R_RELWORD,0,1,16,false,0,complain_overflow_dont, |
HOWTO (R_RELWORD,0,1,16,FALSE,0,complain_overflow_dont, |
203 |
tic54x_relocation,"AREL16",false,0xFFFF,0xFFFF,false), |
tic54x_relocation,"AREL16",FALSE,0xFFFF,0xFFFF,FALSE), |
204 |
|
|
205 |
/* 7 LSBs of an address, absolute */ |
/* 7 LSBs of an address, absolute */ |
206 |
HOWTO (R_PARTLS7,0,1,7,false,0,complain_overflow_dont, |
HOWTO (R_PARTLS7,0,1,7,FALSE,0,complain_overflow_dont, |
207 |
tic54x_relocation,"ALS7",false,0x007F,0x007F,false), |
tic54x_relocation,"ALS7",FALSE,0x007F,0x007F,FALSE), |
208 |
|
|
209 |
/* 9 MSBs of an address, absolute */ |
/* 9 MSBs of an address, absolute */ |
210 |
/* TI assembler doesn't shift its encoding, and is thus incompatible */ |
/* TI assembler doesn't shift its encoding, and is thus incompatible */ |
211 |
HOWTO (R_PARTMS9,7,1,9,false,0,complain_overflow_dont, |
HOWTO (R_PARTMS9,7,1,9,FALSE,0,complain_overflow_dont, |
212 |
tic54x_relocation,"AMS9",false,0x01FF,0x01FF,false), |
tic54x_relocation,"AMS9",FALSE,0x01FF,0x01FF,FALSE), |
213 |
|
|
214 |
/* 23-bit direct reference, absolute */ |
/* 23-bit direct reference, absolute */ |
215 |
HOWTO (R_EXTWORD,0,2,23,false,0,complain_overflow_dont, |
HOWTO (R_EXTWORD,0,2,23,FALSE,0,complain_overflow_dont, |
216 |
tic54x_relocation,"ARELEXT",false,0x7FFFFF,0x7FFFFF,false), |
tic54x_relocation,"ARELEXT",FALSE,0x7FFFFF,0x7FFFFF,FALSE), |
217 |
|
|
218 |
/* 16 bits of 23-bit extended address, absolute */ |
/* 16 bits of 23-bit extended address, absolute */ |
219 |
HOWTO (R_EXTWORD16,0,1,16,false,0,complain_overflow_dont, |
HOWTO (R_EXTWORD16,0,1,16,FALSE,0,complain_overflow_dont, |
220 |
tic54x_relocation,"ARELEXT16",false,0x7FFFFF,0x7FFFFF,false), |
tic54x_relocation,"ARELEXT16",FALSE,0x7FFFFF,0x7FFFFF,FALSE), |
221 |
|
|
222 |
/* upper 7 bits of 23-bit extended address, absolute */ |
/* upper 7 bits of 23-bit extended address, absolute */ |
223 |
HOWTO (R_EXTWORDMS7,16,1,7,false,0,complain_overflow_dont, |
HOWTO (R_EXTWORDMS7,16,1,7,FALSE,0,complain_overflow_dont, |
224 |
tic54x_relocation,"ARELEXTMS7",false,0x7F,0x7F,false), |
tic54x_relocation,"ARELEXTMS7",FALSE,0x7F,0x7F,FALSE), |
225 |
|
|
226 |
/* 32-bit relocation exclusively for stabs */ |
/* 32-bit relocation exclusively for stabs */ |
227 |
HOWTO (R_RELLONG,0,2,32,false,0,complain_overflow_dont, |
HOWTO (R_RELLONG,0,2,32,FALSE,0,complain_overflow_dont, |
228 |
tic54x_relocation,"STAB",false,0xFFFFFFFF,0xFFFFFFFF,false), |
tic54x_relocation,"STAB",FALSE,0xFFFFFFFF,0xFFFFFFFF,FALSE), |
229 |
}; |
}; |
230 |
|
|
231 |
#define coff_bfd_reloc_type_lookup tic54x_coff_reloc_type_lookup |
#define coff_bfd_reloc_type_lookup tic54x_coff_reloc_type_lookup |
313 |
return genrel.howto; |
return genrel.howto; |
314 |
} |
} |
315 |
|
|
|
static boolean |
|
|
ticoff0_bad_format_hook (abfd, filehdr) |
|
|
bfd * abfd ATTRIBUTE_UNUSED; |
|
|
PTR filehdr; |
|
|
{ |
|
|
struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; |
|
|
|
|
|
if (COFF0_BADMAG (*internal_f)) |
|
|
return false; |
|
|
|
|
|
return true; |
|
|
} |
|
|
|
|
|
static boolean |
|
|
ticoff1_bad_format_hook (abfd, filehdr) |
|
|
bfd * abfd ATTRIBUTE_UNUSED; |
|
|
PTR filehdr; |
|
|
{ |
|
|
struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; |
|
|
|
|
|
if (COFF1_BADMAG (*internal_f)) |
|
|
return false; |
|
|
|
|
|
return true; |
|
|
} |
|
|
|
|
316 |
/* Replace the stock _bfd_coff_is_local_label_name to recognize TI COFF local |
/* Replace the stock _bfd_coff_is_local_label_name to recognize TI COFF local |
317 |
labels. */ |
labels. */ |
318 |
|
|
319 |
static boolean |
static bfd_boolean |
320 |
ticoff_bfd_is_local_label_name (abfd, name) |
ticoff_bfd_is_local_label_name (abfd, name) |
321 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
322 |
const char *name; |
const char *name; |
323 |
{ |
{ |
324 |
if (TICOFF_LOCAL_LABEL_P(name)) |
if (TICOFF_LOCAL_LABEL_P(name)) |
325 |
return true; |
return TRUE; |
326 |
return false; |
return FALSE; |
327 |
} |
} |
328 |
|
|
329 |
#define coff_bfd_is_local_label_name ticoff_bfd_is_local_label_name |
#define coff_bfd_is_local_label_name ticoff_bfd_is_local_label_name |
330 |
|
|
331 |
|
/* Clear the r_reserved field in relocs. */ |
332 |
|
#define SWAP_OUT_RELOC_EXTRA(abfd,src,dst) \ |
333 |
|
do \ |
334 |
|
{ \ |
335 |
|
dst->r_reserved[0] = 0; \ |
336 |
|
dst->r_reserved[1] = 0; \ |
337 |
|
} \ |
338 |
|
while (0) |
339 |
|
|
340 |
/* Customize coffcode.h; the default coff_ functions are set up to use COFF2; |
/* Customize coffcode.h; the default coff_ functions are set up to use COFF2; |
341 |
coff_bad_format_hook uses BADMAG, so set that for COFF2. The COFF1 |
coff_bad_format_hook uses BADMAG, so set that for COFF2. The COFF1 |
342 |
and COFF0 vectors use custom _bad_format_hook procs instead of setting |
and COFF0 vectors use custom _bad_format_hook procs instead of setting |
344 |
#define BADMAG(x) COFF2_BADMAG(x) |
#define BADMAG(x) COFF2_BADMAG(x) |
345 |
#include "coffcode.h" |
#include "coffcode.h" |
346 |
|
|
347 |
static boolean |
static bfd_boolean |
348 |
tic54x_set_section_contents (abfd, section, location, offset, bytes_to_do) |
tic54x_set_section_contents (abfd, section, location, offset, bytes_to_do) |
349 |
bfd *abfd; |
bfd *abfd; |
350 |
sec_ptr section; |
sec_ptr section; |
351 |
PTR location; |
const PTR location; |
352 |
file_ptr offset; |
file_ptr offset; |
353 |
bfd_size_type bytes_to_do; |
bfd_size_type bytes_to_do; |
354 |
{ |
{ |
373 |
if (reloc->r_symndx < 0 || reloc->r_symndx >= obj_conv_table_size (abfd)) |
if (reloc->r_symndx < 0 || reloc->r_symndx >= obj_conv_table_size (abfd)) |
374 |
{ |
{ |
375 |
(*_bfd_error_handler) |
(*_bfd_error_handler) |
376 |
(_("%s: warning: illegal symbol index %ld in relocs"), |
(_("%B: warning: illegal symbol index %ld in relocs"), |
377 |
bfd_archive_filename (abfd), reloc->r_symndx); |
abfd, reloc->r_symndx); |
378 |
relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; |
relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; |
379 |
ptr = NULL; |
ptr = NULL; |
380 |
} |
} |
408 |
tic54x_lookup_howto (relent, reloc); |
tic54x_lookup_howto (relent, reloc); |
409 |
} |
} |
410 |
|
|
|
/* COFF0 differs in file/section header size and relocation entry size. */ |
|
|
static const bfd_coff_backend_data ticoff0_swap_table = |
|
|
{ |
|
|
coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in, |
|
|
coff_SWAP_aux_out, coff_SWAP_sym_out, |
|
|
coff_SWAP_lineno_out, coff_SWAP_reloc_out, |
|
|
coff_SWAP_filehdr_out, coff_SWAP_aouthdr_out, |
|
|
coff_SWAP_scnhdr_out, |
|
|
FILHSZ_V0, AOUTSZ, SCNHSZ_V01, SYMESZ, AUXESZ, RELSZ_V0, LINESZ, FILNMLEN, |
|
|
#ifdef COFF_LONG_FILENAMES |
|
|
true, |
|
|
#else |
|
|
false, |
|
|
#endif |
|
|
#ifdef COFF_LONG_SECTION_NAMES |
|
|
true, |
|
|
#else |
|
|
false, |
|
|
#endif |
|
|
#ifdef COFF_FORCE_SYMBOLS_IN_STRINGS |
|
|
true, |
|
|
#else |
|
|
false, |
|
|
#endif |
|
|
#ifdef COFF_DEBUG_STRING_WIDE_PREFIX |
|
|
4, |
|
|
#else |
|
|
2, |
|
|
#endif |
|
|
COFF_DEFAULT_SECTION_ALIGNMENT_POWER, |
|
|
coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in, |
|
|
coff_SWAP_reloc_in, ticoff0_bad_format_hook, coff_set_arch_mach_hook, |
|
|
coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook, |
|
|
coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook, |
|
|
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate, |
|
|
coff_classify_symbol, coff_compute_section_file_positions, |
|
|
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto, |
|
|
coff_adjust_symndx, coff_link_add_one_symbol, |
|
|
coff_link_output_has_begun, coff_final_link_postscript |
|
|
}; |
|
|
|
|
|
/* COFF1 differs in section header size. */ |
|
|
static const bfd_coff_backend_data ticoff1_swap_table = |
|
|
{ |
|
|
coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in, |
|
|
coff_SWAP_aux_out, coff_SWAP_sym_out, |
|
|
coff_SWAP_lineno_out, coff_SWAP_reloc_out, |
|
|
coff_SWAP_filehdr_out, coff_SWAP_aouthdr_out, |
|
|
coff_SWAP_scnhdr_out, |
|
|
FILHSZ, AOUTSZ, SCNHSZ_V01, SYMESZ, AUXESZ, RELSZ, LINESZ, FILNMLEN, |
|
|
#ifdef COFF_LONG_FILENAMES |
|
|
true, |
|
|
#else |
|
|
false, |
|
|
#endif |
|
|
#ifdef COFF_LONG_SECTION_NAMES |
|
|
true, |
|
|
#else |
|
|
false, |
|
|
#endif |
|
|
COFF_DEFAULT_SECTION_ALIGNMENT_POWER, |
|
|
#ifdef COFF_FORCE_SYMBOLS_IN_STRINGS |
|
|
true, |
|
|
#else |
|
|
false, |
|
|
#endif |
|
|
#ifdef COFF_DEBUG_STRING_WIDE_PREFIX |
|
|
4, |
|
|
#else |
|
|
2, |
|
|
#endif |
|
|
coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in, |
|
|
coff_SWAP_reloc_in, ticoff1_bad_format_hook, coff_set_arch_mach_hook, |
|
|
coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook, |
|
|
coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook, |
|
|
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate, |
|
|
coff_classify_symbol, coff_compute_section_file_positions, |
|
|
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto, |
|
|
coff_adjust_symndx, coff_link_add_one_symbol, |
|
|
coff_link_output_has_begun, coff_final_link_postscript |
|
|
}; |
|
|
|
|
411 |
/* TI COFF v0, DOS tools (little-endian headers). */ |
/* TI COFF v0, DOS tools (little-endian headers). */ |
412 |
const bfd_target tic54x_coff0_vec = |
const bfd_target tic54x_coff0_vec = |
413 |
{ |
{ |