00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "bfd.h"
00029 #include "sysdep.h"
00030 #include "libbfd.h"
00031 #include "bfdlink.h"
00032 #include "coff/tic4x.h"
00033 #include "coff/internal.h"
00034 #include "libcoff.h"
00035
00036 #undef F_LSYMS
00037 #define F_LSYMS F_LSYMS_TICOFF
00038
00039 static bfd_boolean ticoff_bfd_is_local_label_name
00040 PARAMS ((bfd *, const char *));
00041 static bfd_reloc_status_type tic4x_relocation
00042 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char ** ));
00043 static reloc_howto_type *tic4x_coff_reloc_type_lookup
00044 PARAMS ((bfd *, bfd_reloc_code_real_type ));
00045 static void tic4x_lookup_howto
00046 PARAMS ((arelent *, struct internal_reloc * ));
00047 static reloc_howto_type *coff_tic4x_rtype_to_howto
00048 PARAMS ((bfd *, asection *, struct internal_reloc *, struct coff_link_hash_entry *, struct internal_syment *, bfd_vma * ));
00049 static void tic4x_reloc_processing
00050 PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection * ));
00051
00052
00053
00054
00055 static bfd_boolean
00056 ticoff_bfd_is_local_label_name (abfd, name)
00057 bfd *abfd ATTRIBUTE_UNUSED;
00058 const char *name;
00059 {
00060 if (TICOFF_LOCAL_LABEL_P(name))
00061 return TRUE;
00062 return FALSE;
00063 }
00064
00065 #define coff_bfd_is_local_label_name ticoff_bfd_is_local_label_name
00066
00067 #define RELOC_PROCESSING(RELENT,RELOC,SYMS,ABFD,SECT)\
00068 tic4x_reloc_processing (RELENT,RELOC,SYMS,ABFD,SECT)
00069
00070
00071
00072
00073
00074 #define BADMAG(x) COFF2_BADMAG(x)
00075
00076 #undef coff_rtype_to_howto
00077 #define coff_rtype_to_howto coff_tic4x_rtype_to_howto
00078
00079 #include "coffcode.h"
00080
00081 static bfd_reloc_status_type
00082 tic4x_relocation (abfd, reloc_entry, symbol, data, input_section,
00083 output_bfd, error_message)
00084 bfd *abfd ATTRIBUTE_UNUSED;
00085 arelent *reloc_entry;
00086 asymbol *symbol ATTRIBUTE_UNUSED;
00087 PTR data ATTRIBUTE_UNUSED;
00088 asection *input_section;
00089 bfd *output_bfd;
00090 char **error_message ATTRIBUTE_UNUSED;
00091 {
00092 if (output_bfd != (bfd *) NULL)
00093 {
00094
00095
00096
00097 reloc_entry->address += input_section->output_offset;
00098 return bfd_reloc_ok;
00099 }
00100 return bfd_reloc_continue;
00101 }
00102
00103 reloc_howto_type tic4x_howto_table[] =
00104 {
00105 HOWTO(R_RELWORD, 0, 2, 16, FALSE, 0, complain_overflow_signed, tic4x_relocation, "RELWORD", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
00106 HOWTO(R_REL24, 0, 2, 24, FALSE, 0, complain_overflow_bitfield, tic4x_relocation, "REL24", TRUE, 0x00ffffff, 0x00ffffff, FALSE),
00107 HOWTO(R_RELLONG, 0, 2, 32, FALSE, 0, complain_overflow_dont, tic4x_relocation, "RELLONG", TRUE, 0xffffffff, 0xffffffff, FALSE),
00108 HOWTO(R_PCRWORD, 0, 2, 16, TRUE, 0, complain_overflow_signed, tic4x_relocation, "PCRWORD", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
00109 HOWTO(R_PCR24, 0, 2, 24, TRUE, 0, complain_overflow_signed, tic4x_relocation, "PCR24", TRUE, 0x00ffffff, 0x00ffffff, FALSE),
00110 HOWTO(R_PARTLS16, 0, 2, 16, FALSE, 0, complain_overflow_dont, tic4x_relocation, "PARTLS16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
00111 HOWTO(R_PARTMS8, 16, 2, 16, FALSE, 0, complain_overflow_dont, tic4x_relocation, "PARTMS8", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
00112 HOWTO(R_RELWORD, 0, 2, 16, FALSE, 0, complain_overflow_signed, tic4x_relocation, "ARELWORD", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
00113 HOWTO(R_REL24, 0, 2, 24, FALSE, 0, complain_overflow_signed, tic4x_relocation, "AREL24", TRUE, 0x00ffffff, 0x00ffffff, FALSE),
00114 HOWTO(R_RELLONG, 0, 2, 32, FALSE, 0, complain_overflow_signed, tic4x_relocation, "ARELLONG", TRUE, 0xffffffff, 0xffffffff, FALSE),
00115 HOWTO(R_PCRWORD, 0, 2, 16, TRUE, 0, complain_overflow_signed, tic4x_relocation, "APCRWORD", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
00116 HOWTO(R_PCR24, 0, 2, 24, TRUE, 0, complain_overflow_signed, tic4x_relocation, "APCR24", TRUE, 0x00ffffff, 0x00ffffff, FALSE),
00117 HOWTO(R_PARTLS16, 0, 2, 16, FALSE, 0, complain_overflow_dont, tic4x_relocation, "APARTLS16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
00118 HOWTO(R_PARTMS8, 16, 2, 16, FALSE, 0, complain_overflow_dont, tic4x_relocation, "APARTMS8", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
00119 };
00120 #define HOWTO_SIZE (sizeof(tic4x_howto_table) / sizeof(tic4x_howto_table[0]))
00121
00122 #undef coff_bfd_reloc_type_lookup
00123 #define coff_bfd_reloc_type_lookup tic4x_coff_reloc_type_lookup
00124
00125
00126
00127
00128 static reloc_howto_type *
00129 tic4x_coff_reloc_type_lookup (abfd, code)
00130 bfd *abfd ATTRIBUTE_UNUSED;
00131 bfd_reloc_code_real_type code;
00132 {
00133 unsigned int type;
00134 unsigned int i;
00135
00136 switch (code)
00137 {
00138 case BFD_RELOC_32: type = R_RELLONG; break;
00139 case BFD_RELOC_24: type = R_REL24; break;
00140 case BFD_RELOC_16: type = R_RELWORD; break;
00141 case BFD_RELOC_24_PCREL: type = R_PCR24; break;
00142 case BFD_RELOC_16_PCREL: type = R_PCRWORD; break;
00143 case BFD_RELOC_HI16: type = R_PARTMS8; break;
00144 case BFD_RELOC_LO16: type = R_PARTLS16; break;
00145 default:
00146 return NULL;
00147 }
00148
00149 for (i = 0; i < HOWTO_SIZE; i++)
00150 {
00151 if (tic4x_howto_table[i].type == type)
00152 return tic4x_howto_table + i;
00153 }
00154 return NULL;
00155 }
00156
00157
00158
00159
00160
00161 static void
00162 tic4x_lookup_howto (internal, dst)
00163 arelent *internal;
00164 struct internal_reloc *dst;
00165 {
00166 unsigned int i;
00167 int bank = (dst->r_symndx == -1) ? HOWTO_BANK : 0;
00168
00169 for (i = 0; i < HOWTO_SIZE; i++)
00170 {
00171 if (tic4x_howto_table[i].type == dst->r_type)
00172 {
00173 internal->howto = tic4x_howto_table + i + bank;
00174 return;
00175 }
00176 }
00177
00178 (*_bfd_error_handler) (_("Unrecognized reloc type 0x%x"),
00179 (unsigned int) dst->r_type);
00180 abort();
00181 }
00182
00183 static reloc_howto_type *
00184 coff_tic4x_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
00185 bfd *abfd ATTRIBUTE_UNUSED;
00186 asection *sec;
00187 struct internal_reloc *rel;
00188 struct coff_link_hash_entry *h ATTRIBUTE_UNUSED;
00189 struct internal_syment *sym ATTRIBUTE_UNUSED;
00190 bfd_vma *addendp;
00191 {
00192 arelent genrel;
00193
00194 if (rel->r_symndx == -1 && addendp != NULL)
00195
00196
00197
00198 *addendp = (sec->output_section->vma + sec->output_offset) - sec->vma;
00199
00200 tic4x_lookup_howto (&genrel, rel);
00201
00202 return genrel.howto;
00203 }
00204
00205
00206 static void
00207 tic4x_reloc_processing (relent, reloc, symbols, abfd, section)
00208 arelent *relent;
00209 struct internal_reloc *reloc;
00210 asymbol **symbols;
00211 bfd *abfd;
00212 asection *section;
00213 {
00214 asymbol *ptr;
00215
00216 relent->address = reloc->r_vaddr;
00217
00218 if (reloc->r_symndx != -1)
00219 {
00220 if (reloc->r_symndx < 0 || reloc->r_symndx >= obj_conv_table_size (abfd))
00221 {
00222 (*_bfd_error_handler)
00223 (_("%s: warning: illegal symbol index %ld in relocs"),
00224 bfd_get_filename (abfd), reloc->r_symndx);
00225 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
00226 ptr = NULL;
00227 }
00228 else
00229 {
00230 relent->sym_ptr_ptr = (symbols
00231 + obj_convert (abfd)[reloc->r_symndx]);
00232 ptr = *(relent->sym_ptr_ptr);
00233 }
00234 }
00235 else
00236 {
00237 relent->sym_ptr_ptr = section->symbol_ptr_ptr;
00238 ptr = *(relent->sym_ptr_ptr);
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 CALC_ADDEND (abfd, ptr, *reloc, relent);
00250
00251 relent->address -= section->vma;
00252
00253
00254
00255 tic4x_lookup_howto (relent, reloc);
00256 }
00257
00258
00259
00260 CREATE_LITTLE_COFF_TARGET_VEC(tic4x_coff0_vec, "coff0-tic4x", HAS_LOAD_PAGE, 0, '_', NULL, (PTR)&ticoff0_swap_table);
00261
00262
00263 CREATE_BIGHDR_COFF_TARGET_VEC(tic4x_coff0_beh_vec, "coff0-beh-tic4x", HAS_LOAD_PAGE, 0, '_', &tic4x_coff0_vec, (PTR)&ticoff0_swap_table);
00264
00265
00266 CREATE_LITTLE_COFF_TARGET_VEC(tic4x_coff1_vec, "coff1-tic4x", HAS_LOAD_PAGE, 0, '_', &tic4x_coff0_beh_vec, (PTR)&ticoff1_swap_table);
00267
00268
00269 CREATE_BIGHDR_COFF_TARGET_VEC(tic4x_coff1_beh_vec, "coff1-beh-tic4x", HAS_LOAD_PAGE, 0, '_', &tic4x_coff1_vec, (PTR)&ticoff1_swap_table);
00270
00271
00272 CREATE_LITTLE_COFF_TARGET_VEC(tic4x_coff2_vec, "coff2-tic4x", HAS_LOAD_PAGE, 0, '_', &tic4x_coff1_beh_vec, COFF_SWAP_TABLE);
00273
00274
00275 CREATE_BIGHDR_COFF_TARGET_VEC(tic4x_coff2_beh_vec, "coff2-beh-tic4x", HAS_LOAD_PAGE, 0, '_', &tic4x_coff2_vec, COFF_SWAP_TABLE);