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