1 /* BFD back-end for TMS320C30 coff binaries. 2 Copyright 1998, 1999, 2000, 2001, 2002, 2005, 2007, 2008, 2011, 2012 3 Free Software Foundation, Inc. 4 Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au) 5 6 This file is part of BFD, the Binary File Descriptor library. 7 8 This program 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 3 of the License, or 11 (at your option) any later version. 12 13 This program 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 this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 21 02110-1301, USA. */ 22 23 #include "sysdep.h" 24 #include "bfd.h" 25 #include "libbfd.h" 26 #include "bfdlink.h" 27 #include "coff/tic30.h" 28 #include "coff/internal.h" 29 #include "libcoff.h" 30 31 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1) 32 33 reloc_howto_type tic30_coff_howto_table[] = 34 { 35 HOWTO (R_TIC30_ABS16, 2, 1, 16, FALSE, 0, 0, NULL, 36 "16", FALSE, 0x0000FFFF, 0x0000FFFF, FALSE), 37 HOWTO (R_TIC30_ABS24, 2, 2, 24, FALSE, 8, complain_overflow_bitfield, NULL, 38 "24", FALSE, 0xFFFFFF00, 0xFFFFFF00, FALSE), 39 HOWTO (R_TIC30_LDP, 18, 0, 24, FALSE, 0, complain_overflow_bitfield, NULL, 40 "LDP", FALSE, 0x00FF0000, 0x000000FF, FALSE), 41 HOWTO (R_TIC30_ABS32, 2, 2, 32, FALSE, 0, complain_overflow_bitfield, NULL, 42 "32", FALSE, 0xFFFFFFFF, 0xFFFFFFFF, FALSE), 43 HOWTO (R_TIC30_PC16, 2, 1, 16, TRUE, 0, complain_overflow_signed, NULL, 44 "PCREL", FALSE, 0x0000FFFF, 0x0000FFFF, FALSE), 45 EMPTY_HOWTO (-1) 46 }; 47 48 #ifndef coff_bfd_reloc_type_lookup 49 #define coff_bfd_reloc_type_lookup tic30_coff_reloc_type_lookup 50 #define coff_bfd_reloc_name_lookup tic30_coff_reloc_name_lookup 51 52 /* For the case statement use the code values used in tc_gen_reloc to 53 map to the howto table entries that match those in both the aout 54 and coff implementations. */ 55 56 static reloc_howto_type * 57 tic30_coff_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 58 bfd_reloc_code_real_type code) 59 { 60 switch (code) 61 { 62 case BFD_RELOC_8: 63 case BFD_RELOC_TIC30_LDP: 64 return &tic30_coff_howto_table[2]; 65 case BFD_RELOC_16: 66 return &tic30_coff_howto_table[0]; 67 case BFD_RELOC_24: 68 return &tic30_coff_howto_table[1]; 69 case BFD_RELOC_16_PCREL: 70 return &tic30_coff_howto_table[4]; 71 case BFD_RELOC_32: 72 return &tic30_coff_howto_table[3]; 73 default: 74 return (reloc_howto_type *) NULL; 75 } 76 } 77 78 static reloc_howto_type * 79 tic30_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 80 const char *r_name) 81 { 82 unsigned int i; 83 84 for (i = 0; 85 i < (sizeof (tic30_coff_howto_table) 86 / sizeof (tic30_coff_howto_table[0])); 87 i++) 88 if (tic30_coff_howto_table[i].name != NULL 89 && strcasecmp (tic30_coff_howto_table[i].name, r_name) == 0) 90 return &tic30_coff_howto_table[i]; 91 92 return NULL; 93 } 94 95 #endif 96 97 /* Turn a howto into a reloc number. */ 98 99 static int 100 coff_tic30_select_reloc (reloc_howto_type *howto) 101 { 102 return howto->type; 103 } 104 105 #define SELECT_RELOC(x,howto) x.r_type = coff_tic30_select_reloc(howto) 106 107 #define BADMAG(x) TIC30BADMAG(x) 108 #define TIC30 1 /* Customize coffcode.h */ 109 #define __A_MAGIC_SET__ 110 111 /* Code to swap in the reloc */ 112 #define SWAP_IN_RELOC_OFFSET H_GET_32 113 #define SWAP_OUT_RELOC_OFFSET H_PUT_32 114 #define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) dst->r_stuff[0] = 'S'; \ 115 dst->r_stuff[1] = 'C'; 116 117 /* Code to turn a r_type into a howto ptr, uses the above howto table. */ 118 119 static void 120 rtype2howto (arelent *internal, struct internal_reloc *dst) 121 { 122 switch (dst->r_type) 123 { 124 case R_TIC30_ABS16: 125 internal->howto = &tic30_coff_howto_table[0]; 126 break; 127 case R_TIC30_ABS24: 128 internal->howto = &tic30_coff_howto_table[1]; 129 break; 130 case R_TIC30_ABS32: 131 internal->howto = &tic30_coff_howto_table[3]; 132 break; 133 case R_TIC30_LDP: 134 internal->howto = &tic30_coff_howto_table[2]; 135 break; 136 case R_TIC30_PC16: 137 internal->howto = &tic30_coff_howto_table[4]; 138 break; 139 default: 140 abort (); 141 break; 142 } 143 } 144 145 #define RTYPE2HOWTO(internal, relocentry) rtype2howto (internal, relocentry) 146 147 /* Perform any necessary magic to the addend in a reloc entry */ 148 149 #define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \ 150 cache_ptr->addend = ext_reloc.r_offset; 151 152 #define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ 153 reloc_processing(relent, reloc, symbols, abfd, section) 154 155 static void 156 reloc_processing (arelent *relent, 157 struct internal_reloc *reloc, 158 asymbol **symbols, 159 bfd *abfd, 160 asection *section) 161 { 162 relent->address = reloc->r_vaddr; 163 rtype2howto (relent, reloc); 164 165 if (reloc->r_symndx > 0) 166 relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; 167 else 168 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; 169 170 relent->addend = reloc->r_offset; 171 relent->address -= section->vma; 172 } 173 174 #ifndef bfd_pe_print_pdata 175 #define bfd_pe_print_pdata NULL 176 #endif 177 178 #include "coffcode.h" 179 180 const bfd_target tic30_coff_vec = 181 { 182 "coff-tic30", /* name */ 183 bfd_target_coff_flavour, 184 BFD_ENDIAN_BIG, /* data byte order is big */ 185 BFD_ENDIAN_LITTLE, /* header byte order is little */ 186 187 (HAS_RELOC | EXEC_P | /* object flags */ 188 HAS_LINENO | HAS_DEBUG | 189 HAS_SYMS | HAS_LOCALS | WP_TEXT), 190 191 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ 192 '_', /* leading symbol underscore */ 193 '/', /* ar_pad_char */ 194 15, /* ar_max_namelen */ 195 0, /* match priority. */ 196 bfd_getb64, bfd_getb_signed_64, bfd_putb64, 197 bfd_getb32, bfd_getb_signed_32, bfd_putb32, 198 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ 199 bfd_getl64, bfd_getl_signed_64, bfd_putl64, 200 bfd_getl32, bfd_getl_signed_32, bfd_putl32, 201 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ 202 203 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ 204 bfd_generic_archive_p, _bfd_dummy_target}, 205 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ 206 bfd_false}, 207 {bfd_false, coff_write_object_contents, /* bfd_write_contents */ 208 _bfd_write_archive_contents, bfd_false}, 209 210 BFD_JUMP_TABLE_GENERIC (coff), 211 BFD_JUMP_TABLE_COPY (coff), 212 BFD_JUMP_TABLE_CORE (_bfd_nocore), 213 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), 214 BFD_JUMP_TABLE_SYMBOLS (coff), 215 BFD_JUMP_TABLE_RELOCS (coff), 216 BFD_JUMP_TABLE_WRITE (coff), 217 BFD_JUMP_TABLE_LINK (coff), 218 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 219 220 NULL, 221 222 COFF_SWAP_TABLE 223 }; 224