1 |
/* BFD back-end for Hitachi H8/300 COFF binaries. |
/* BFD back-end for Renesas H8/300 COFF 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 Steve Chamberlain, <sac@cygnus.com>. |
Written by Steve Chamberlain, <sac@cygnus.com>. |
6 |
|
|
7 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
8 |
|
|
9 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
10 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
11 |
the Free Software Foundation; either version 2 of the License, or |
the Free Software Foundation; either version 2 of the License, or |
12 |
(at your option) any later version. |
(at your option) any later version. |
13 |
|
|
14 |
This program is distributed in the hope that it will be useful, |
This program is distributed in the hope that it will be useful, |
15 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 |
GNU General Public License for more details. |
GNU General Public License for more details. |
18 |
|
|
19 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
20 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
21 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
22 |
|
|
23 |
#include "bfd.h" |
#include "bfd.h" |
24 |
#include "sysdep.h" |
#include "sysdep.h" |
28 |
#include "coff/h8300.h" |
#include "coff/h8300.h" |
29 |
#include "coff/internal.h" |
#include "coff/internal.h" |
30 |
#include "libcoff.h" |
#include "libcoff.h" |
31 |
|
#include "libiberty.h" |
32 |
|
|
33 |
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1) |
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1) |
34 |
|
|
61 |
|
|
62 |
static struct bfd_hash_entry * |
static struct bfd_hash_entry * |
63 |
funcvec_hash_newfunc |
funcvec_hash_newfunc |
64 |
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); |
(struct bfd_hash_entry *, struct bfd_hash_table *, const char *); |
65 |
|
|
66 |
static boolean |
static bfd_boolean |
67 |
funcvec_hash_table_init |
funcvec_hash_table_init |
68 |
PARAMS ((struct funcvec_hash_table *, bfd *, |
(struct funcvec_hash_table *, bfd *, |
69 |
struct bfd_hash_entry *(*) PARAMS ((struct bfd_hash_entry *, |
struct bfd_hash_entry *(*) (struct bfd_hash_entry *, |
70 |
struct bfd_hash_table *, |
struct bfd_hash_table *, |
71 |
const char *)))); |
const char *)); |
72 |
|
|
73 |
static bfd_reloc_status_type special PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
static bfd_reloc_status_type special |
74 |
static int select_reloc PARAMS ((reloc_howto_type *)); |
(bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **); |
75 |
static void rtype2howto PARAMS ((arelent *, struct internal_reloc *)); |
static int select_reloc |
76 |
static void reloc_processing PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *)); |
(reloc_howto_type *); |
77 |
static boolean h8300_symbol_address_p PARAMS ((bfd *, asection *, bfd_vma)); |
static void rtype2howto |
78 |
static int h8300_reloc16_estimate PARAMS ((bfd *, asection *, arelent *, unsigned int, struct bfd_link_info *)); |
(arelent *, struct internal_reloc *); |
79 |
static void h8300_reloc16_extra_cases PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *, bfd_byte *, unsigned int *, unsigned int *)); |
static void reloc_processing |
80 |
static boolean h8300_bfd_link_add_symbols PARAMS ((bfd *, struct bfd_link_info *)); |
(arelent *, struct internal_reloc *, asymbol **, bfd *, asection *); |
81 |
|
static bfd_boolean h8300_symbol_address_p |
82 |
|
(bfd *, asection *, bfd_vma); |
83 |
|
static int h8300_reloc16_estimate |
84 |
|
(bfd *, asection *, arelent *, unsigned int, |
85 |
|
struct bfd_link_info *); |
86 |
|
static void h8300_reloc16_extra_cases |
87 |
|
(bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *, |
88 |
|
bfd_byte *, unsigned int *, unsigned int *); |
89 |
|
static bfd_boolean h8300_bfd_link_add_symbols |
90 |
|
(bfd *, struct bfd_link_info *); |
91 |
|
|
92 |
/* To lookup a value in the function vector hash table. */ |
/* To lookup a value in the function vector hash table. */ |
93 |
#define funcvec_hash_lookup(table, string, create, copy) \ |
#define funcvec_hash_lookup(table, string, create, copy) \ |
98 |
the generic linker hash table, not the COFF backend linker hash |
the generic linker hash table, not the COFF backend linker hash |
99 |
table! We use this to attach additional data structures we |
table! We use this to attach additional data structures we |
100 |
need while linking on the h8300. */ |
need while linking on the h8300. */ |
101 |
struct h8300_coff_link_hash_table |
struct h8300_coff_link_hash_table { |
|
{ |
|
102 |
/* The main hash table. */ |
/* The main hash table. */ |
103 |
struct generic_link_hash_table root; |
struct generic_link_hash_table root; |
104 |
|
|
111 |
struct funcvec_hash_table *funcvec_hash_table; |
struct funcvec_hash_table *funcvec_hash_table; |
112 |
}; |
}; |
113 |
|
|
114 |
static struct bfd_link_hash_table *h8300_coff_link_hash_table_create |
static struct bfd_link_hash_table *h8300_coff_link_hash_table_create (bfd *); |
|
PARAMS ((bfd *)); |
|
115 |
|
|
116 |
/* Get the H8/300 COFF linker hash table from a link_info structure. */ |
/* Get the H8/300 COFF linker hash table from a link_info structure. */ |
117 |
|
|
122 |
a new entry is added to the funcvec hash table. */ |
a new entry is added to the funcvec hash table. */ |
123 |
|
|
124 |
static struct bfd_hash_entry * |
static struct bfd_hash_entry * |
125 |
funcvec_hash_newfunc (entry, gen_table, string) |
funcvec_hash_newfunc (struct bfd_hash_entry *entry, |
126 |
struct bfd_hash_entry *entry; |
struct bfd_hash_table *gen_table, |
127 |
struct bfd_hash_table *gen_table; |
const char *string) |
|
const char *string; |
|
128 |
{ |
{ |
129 |
struct funcvec_hash_entry *ret; |
struct funcvec_hash_entry *ret; |
130 |
struct funcvec_hash_table *table; |
struct funcvec_hash_table *table; |
136 |
subclass. */ |
subclass. */ |
137 |
if (ret == NULL) |
if (ret == NULL) |
138 |
ret = ((struct funcvec_hash_entry *) |
ret = ((struct funcvec_hash_entry *) |
139 |
bfd_hash_allocate (gen_table, |
bfd_hash_allocate (gen_table, |
140 |
sizeof (struct funcvec_hash_entry))); |
sizeof (struct funcvec_hash_entry))); |
141 |
if (ret == NULL) |
if (ret == NULL) |
142 |
return NULL; |
return NULL; |
143 |
|
|
144 |
/* Call the allocation method of the superclass. */ |
/* Call the allocation method of the superclass. */ |
145 |
ret = ((struct funcvec_hash_entry *) |
ret = ((struct funcvec_hash_entry *) |
146 |
bfd_hash_newfunc ((struct bfd_hash_entry *) ret, gen_table, string)); |
bfd_hash_newfunc ((struct bfd_hash_entry *) ret, gen_table, string)); |
147 |
|
|
148 |
if (ret == NULL) |
if (ret == NULL) |
149 |
return NULL; |
return NULL; |
154 |
/* Bump the offset at which we store entries in the function |
/* Bump the offset at which we store entries in the function |
155 |
vector. We'd like to bump up the size of the vectors section, |
vector. We'd like to bump up the size of the vectors section, |
156 |
but it's not easily available here. */ |
but it's not easily available here. */ |
157 |
if (bfd_get_mach (table->abfd) == bfd_mach_h8300) |
switch (bfd_get_mach (table->abfd)) |
158 |
table->offset += 2; |
{ |
159 |
else if (bfd_get_mach (table->abfd) == bfd_mach_h8300h |
case bfd_mach_h8300: |
160 |
|| bfd_get_mach (table->abfd) == bfd_mach_h8300s) |
case bfd_mach_h8300hn: |
161 |
table->offset += 4; |
case bfd_mach_h8300sn: |
162 |
else |
table->offset += 2; |
163 |
return NULL; |
break; |
164 |
|
case bfd_mach_h8300h: |
165 |
|
case bfd_mach_h8300s: |
166 |
|
table->offset += 4; |
167 |
|
break; |
168 |
|
default: |
169 |
|
return NULL; |
170 |
|
} |
171 |
|
|
172 |
/* Everything went OK. */ |
/* Everything went OK. */ |
173 |
return (struct bfd_hash_entry *) ret; |
return (struct bfd_hash_entry *) ret; |
175 |
|
|
176 |
/* Initialize the function vector hash table. */ |
/* Initialize the function vector hash table. */ |
177 |
|
|
178 |
static boolean |
static bfd_boolean |
179 |
funcvec_hash_table_init (table, abfd, newfunc) |
funcvec_hash_table_init (struct funcvec_hash_table *table, |
180 |
struct funcvec_hash_table *table; |
bfd *abfd, |
181 |
bfd *abfd; |
struct bfd_hash_entry *(*newfunc) |
182 |
struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, |
(struct bfd_hash_entry *, |
183 |
struct bfd_hash_table *, |
struct bfd_hash_table *, |
184 |
const char *)); |
const char *)) |
185 |
{ |
{ |
186 |
/* Initialize our local fields, then call the generic initialization |
/* Initialize our local fields, then call the generic initialization |
187 |
routine. */ |
routine. */ |
191 |
} |
} |
192 |
|
|
193 |
/* Create the derived linker hash table. We use a derived hash table |
/* Create the derived linker hash table. We use a derived hash table |
194 |
basically to hold "static" information during an h8/300 coff link |
basically to hold "static" information during an H8/300 coff link |
195 |
without using static variables. */ |
without using static variables. */ |
196 |
|
|
197 |
static struct bfd_link_hash_table * |
static struct bfd_link_hash_table * |
198 |
h8300_coff_link_hash_table_create (abfd) |
h8300_coff_link_hash_table_create (bfd *abfd) |
|
bfd *abfd; |
|
199 |
{ |
{ |
200 |
struct h8300_coff_link_hash_table *ret; |
struct h8300_coff_link_hash_table *ret; |
201 |
bfd_size_type amt = sizeof (struct h8300_coff_link_hash_table); |
bfd_size_type amt = sizeof (struct h8300_coff_link_hash_table); |
214 |
ret->vectors_sec = NULL; |
ret->vectors_sec = NULL; |
215 |
ret->funcvec_hash_table = NULL; |
ret->funcvec_hash_table = NULL; |
216 |
|
|
217 |
/* OK. Everything's intialized, return the base pointer. */ |
/* OK. Everything's initialized, return the base pointer. */ |
218 |
return &ret->root.root; |
return &ret->root.root; |
219 |
} |
} |
220 |
|
|
228 |
the addend until the final link. */ |
the addend until the final link. */ |
229 |
|
|
230 |
static bfd_reloc_status_type |
static bfd_reloc_status_type |
231 |
special (abfd, reloc_entry, symbol, data, input_section, output_bfd, |
special (bfd *abfd ATTRIBUTE_UNUSED, |
232 |
error_message) |
arelent *reloc_entry ATTRIBUTE_UNUSED, |
233 |
bfd *abfd ATTRIBUTE_UNUSED; |
asymbol *symbol ATTRIBUTE_UNUSED, |
234 |
arelent *reloc_entry ATTRIBUTE_UNUSED; |
PTR data ATTRIBUTE_UNUSED, |
235 |
asymbol *symbol ATTRIBUTE_UNUSED; |
asection *input_section ATTRIBUTE_UNUSED, |
236 |
PTR data ATTRIBUTE_UNUSED; |
bfd *output_bfd, |
237 |
asection *input_section ATTRIBUTE_UNUSED; |
char **error_message ATTRIBUTE_UNUSED) |
|
bfd *output_bfd; |
|
|
char **error_message ATTRIBUTE_UNUSED; |
|
238 |
{ |
{ |
239 |
if (output_bfd == (bfd *) NULL) |
if (output_bfd == (bfd *) NULL) |
240 |
return bfd_reloc_continue; |
return bfd_reloc_continue; |
244 |
return bfd_reloc_ok; |
return bfd_reloc_ok; |
245 |
} |
} |
246 |
|
|
247 |
static reloc_howto_type howto_table[] = |
static reloc_howto_type howto_table[] = { |
248 |
{ |
HOWTO (R_RELBYTE, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, special, "8", FALSE, 0x000000ff, 0x000000ff, FALSE), |
249 |
HOWTO (R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "8", false, 0x000000ff, 0x000000ff, false), |
HOWTO (R_RELWORD, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, special, "16", FALSE, 0x0000ffff, 0x0000ffff, FALSE), |
250 |
HOWTO (R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "16", false, 0x0000ffff, 0x0000ffff, false), |
HOWTO (R_RELLONG, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, special, "32", FALSE, 0xffffffff, 0xffffffff, FALSE), |
251 |
HOWTO (R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, special, "32", false, 0xffffffff, 0xffffffff, false), |
HOWTO (R_PCRBYTE, 0, 0, 8, TRUE, 0, complain_overflow_signed, special, "DISP8", FALSE, 0x000000ff, 0x000000ff, TRUE), |
252 |
HOWTO (R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, special, "DISP8", false, 0x000000ff, 0x000000ff, true), |
HOWTO (R_PCRWORD, 0, 1, 16, TRUE, 0, complain_overflow_signed, special, "DISP16", FALSE, 0x0000ffff, 0x0000ffff, TRUE), |
253 |
HOWTO (R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, special, "DISP16", false, 0x0000ffff, 0x0000ffff, true), |
HOWTO (R_PCRLONG, 0, 2, 32, TRUE, 0, complain_overflow_signed, special, "DISP32", FALSE, 0xffffffff, 0xffffffff, TRUE), |
254 |
HOWTO (R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, special, "DISP32", false, 0xffffffff, 0xffffffff, true), |
HOWTO (R_MOV16B1, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, special, "relaxable mov.b:16", FALSE, 0x0000ffff, 0x0000ffff, FALSE), |
255 |
HOWTO (R_MOV16B1, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "relaxable mov.b:16", false, 0x0000ffff, 0x0000ffff, false), |
HOWTO (R_MOV16B2, 0, 1, 8, FALSE, 0, complain_overflow_bitfield, special, "relaxed mov.b:16", FALSE, 0x000000ff, 0x000000ff, FALSE), |
256 |
HOWTO (R_MOV16B2, 0, 1, 8, false, 0, complain_overflow_bitfield, special, "relaxed mov.b:16", false, 0x000000ff, 0x000000ff, false), |
HOWTO (R_JMP1, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, special, "16/pcrel", FALSE, 0x0000ffff, 0x0000ffff, FALSE), |
257 |
HOWTO (R_JMP1, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "16/pcrel", false, 0x0000ffff, 0x0000ffff, false), |
HOWTO (R_JMP2, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, special, "pcrecl/16", FALSE, 0x000000ff, 0x000000ff, FALSE), |
258 |
HOWTO (R_JMP2, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "pcrecl/16", false, 0x000000ff, 0x000000ff, false), |
HOWTO (R_JMPL1, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, special, "24/pcrell", FALSE, 0x00ffffff, 0x00ffffff, FALSE), |
259 |
HOWTO (R_JMPL1, 0, 2, 32, false, 0, complain_overflow_bitfield, special, "24/pcrell", false, 0x00ffffff, 0x00ffffff, false), |
HOWTO (R_JMPL2, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, special, "pc8/24", FALSE, 0x000000ff, 0x000000ff, FALSE), |
260 |
HOWTO (R_JMPL2, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "pc8/24", false, 0x000000ff, 0x000000ff, false), |
HOWTO (R_MOV24B1, 0, 1, 32, FALSE, 0, complain_overflow_bitfield, special, "relaxable mov.b:24", FALSE, 0xffffffff, 0xffffffff, FALSE), |
261 |
HOWTO (R_MOV24B1, 0, 1, 32, false, 0, complain_overflow_bitfield, special, "relaxable mov.b:24", false, 0xffffffff, 0xffffffff, false), |
HOWTO (R_MOV24B2, 0, 1, 8, FALSE, 0, complain_overflow_bitfield, special, "relaxed mov.b:24", FALSE, 0x0000ffff, 0x0000ffff, FALSE), |
|
HOWTO (R_MOV24B2, 0, 1, 8, false, 0, complain_overflow_bitfield, special, "relaxed mov.b:24", false, 0x0000ffff, 0x0000ffff, false), |
|
262 |
|
|
263 |
/* An indirect reference to a function. This causes the function's address |
/* An indirect reference to a function. This causes the function's address |
264 |
to be added to the function vector in lo-mem and puts the address of |
to be added to the function vector in lo-mem and puts the address of |
265 |
the function vector's entry in the jsr instruction. */ |
the function vector's entry in the jsr instruction. */ |
266 |
HOWTO (R_MEM_INDIRECT, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "8/indirect", false, 0x000000ff, 0x000000ff, false), |
HOWTO (R_MEM_INDIRECT, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, special, "8/indirect", FALSE, 0x000000ff, 0x000000ff, FALSE), |
267 |
|
|
268 |
/* Internal reloc for relaxing. This is created when a 16bit pc-relative |
/* Internal reloc for relaxing. This is created when a 16-bit pc-relative |
269 |
branch is turned into an 8bit pc-relative branch. */ |
branch is turned into an 8-bit pc-relative branch. */ |
270 |
HOWTO (R_PCRWORD_B, 0, 0, 8, true, 0, complain_overflow_bitfield, special, "relaxed bCC:16", false, 0x000000ff, 0x000000ff, false), |
HOWTO (R_PCRWORD_B, 0, 0, 8, TRUE, 0, complain_overflow_bitfield, special, "relaxed bCC:16", FALSE, 0x000000ff, 0x000000ff, FALSE), |
271 |
|
|
272 |
HOWTO (R_MOVL1, 0, 2, 32, false, 0, complain_overflow_bitfield,special, "32/24 relaxable move", false, 0xffffffff, 0xffffffff, false), |
HOWTO (R_MOVL1, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,special, "32/24 relaxable move", FALSE, 0xffffffff, 0xffffffff, FALSE), |
273 |
|
|
274 |
HOWTO (R_MOVL2, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "32/24 relaxed move", false, 0x0000ffff, 0x0000ffff, false), |
HOWTO (R_MOVL2, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, special, "32/24 relaxed move", FALSE, 0x0000ffff, 0x0000ffff, FALSE), |
275 |
|
|
276 |
HOWTO (R_BCC_INV, 0, 0, 8, true, 0, complain_overflow_signed, special, "DISP8 inverted", false, 0x000000ff, 0x000000ff, true), |
HOWTO (R_BCC_INV, 0, 0, 8, TRUE, 0, complain_overflow_signed, special, "DISP8 inverted", FALSE, 0x000000ff, 0x000000ff, TRUE), |
277 |
|
|
278 |
HOWTO (R_JMP_DEL, 0, 0, 8, true, 0, complain_overflow_signed, special, "Deleted jump", false, 0x000000ff, 0x000000ff, true), |
HOWTO (R_JMP_DEL, 0, 0, 8, TRUE, 0, complain_overflow_signed, special, "Deleted jump", FALSE, 0x000000ff, 0x000000ff, TRUE), |
279 |
}; |
}; |
280 |
|
|
281 |
/* Turn a howto into a reloc number. */ |
/* Turn a howto into a reloc number. */ |
282 |
|
|
283 |
#define SELECT_RELOC(x,howto) \ |
#define SELECT_RELOC(x,howto) \ |
284 |
{ x.r_type = select_reloc(howto); } |
{ x.r_type = select_reloc (howto); } |
285 |
|
|
286 |
#define BADMAG(x) (H8300BADMAG(x) && H8300HBADMAG(x) && H8300SBADMAG(x)) |
#define BADMAG(x) (H8300BADMAG (x) && H8300HBADMAG (x) && H8300SBADMAG (x) \ |
287 |
#define H8300 1 /* Customize coffcode.h */ |
&& H8300HNBADMAG(x) && H8300SNBADMAG(x)) |
288 |
|
#define H8300 1 /* Customize coffcode.h */ |
289 |
#define __A_MAGIC_SET__ |
#define __A_MAGIC_SET__ |
290 |
|
|
291 |
/* Code to swap in the reloc. */ |
/* Code to swap in the reloc. */ |
296 |
dst->r_stuff[1] = 'C'; |
dst->r_stuff[1] = 'C'; |
297 |
|
|
298 |
static int |
static int |
299 |
select_reloc (howto) |
select_reloc (reloc_howto_type *howto) |
|
reloc_howto_type *howto; |
|
300 |
{ |
{ |
301 |
return howto->type; |
return howto->type; |
302 |
} |
} |
304 |
/* Code to turn a r_type into a howto ptr, uses the above howto table. */ |
/* Code to turn a r_type into a howto ptr, uses the above howto table. */ |
305 |
|
|
306 |
static void |
static void |
307 |
rtype2howto (internal, dst) |
rtype2howto (arelent *internal, struct internal_reloc *dst) |
|
arelent *internal; |
|
|
struct internal_reloc *dst; |
|
308 |
{ |
{ |
309 |
switch (dst->r_type) |
switch (dst->r_type) |
310 |
{ |
{ |
374 |
} |
} |
375 |
} |
} |
376 |
|
|
377 |
#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry) |
#define RTYPE2HOWTO(internal, relocentry) rtype2howto (internal, relocentry) |
378 |
|
|
379 |
/* Perform any necessary magic to the addend in a reloc entry. */ |
/* Perform any necessary magic to the addend in a reloc entry. */ |
380 |
|
|
381 |
#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \ |
#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \ |
382 |
cache_ptr->addend = ext_reloc.r_offset; |
cache_ptr->addend = ext_reloc.r_offset; |
383 |
|
|
384 |
#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ |
#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ |
385 |
reloc_processing(relent, reloc, symbols, abfd, section) |
reloc_processing (relent, reloc, symbols, abfd, section) |
386 |
|
|
387 |
static void |
static void |
388 |
reloc_processing (relent, reloc, symbols, abfd, section) |
reloc_processing (arelent *relent, struct internal_reloc *reloc, |
389 |
arelent *relent; |
asymbol **symbols, bfd *abfd, asection *section) |
|
struct internal_reloc *reloc; |
|
|
asymbol **symbols; |
|
|
bfd *abfd; |
|
|
asection *section; |
|
390 |
{ |
{ |
391 |
relent->address = reloc->r_vaddr; |
relent->address = reloc->r_vaddr; |
392 |
rtype2howto (relent, reloc); |
rtype2howto (relent, reloc); |
393 |
|
|
394 |
if (((int) reloc->r_symndx) > 0) |
if (((int) reloc->r_symndx) > 0) |
395 |
{ |
relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; |
|
relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; |
|
|
} |
|
396 |
else |
else |
397 |
{ |
relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; |
|
relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; |
|
|
} |
|
398 |
|
|
399 |
relent->addend = reloc->r_offset; |
relent->addend = reloc->r_offset; |
|
|
|
400 |
relent->address -= section->vma; |
relent->address -= section->vma; |
|
#if 0 |
|
|
relent->section = 0; |
|
|
#endif |
|
401 |
} |
} |
402 |
|
|
403 |
static boolean |
static bfd_boolean |
404 |
h8300_symbol_address_p (abfd, input_section, address) |
h8300_symbol_address_p (bfd *abfd, asection *input_section, bfd_vma address) |
|
bfd *abfd; |
|
|
asection *input_section; |
|
|
bfd_vma address; |
|
405 |
{ |
{ |
406 |
asymbol **s; |
asymbol **s; |
407 |
|
|
413 |
while (*s) |
while (*s) |
414 |
{ |
{ |
415 |
asymbol *p = *s; |
asymbol *p = *s; |
416 |
|
|
417 |
if (p->section == input_section |
if (p->section == input_section |
418 |
&& (input_section->output_section->vma |
&& (input_section->output_section->vma |
419 |
+ input_section->output_offset |
+ input_section->output_offset |
420 |
+ p->value) == address) |
+ p->value) == address) |
421 |
return true; |
return TRUE; |
422 |
s++; |
s++; |
423 |
} |
} |
424 |
return false; |
return FALSE; |
425 |
} |
} |
426 |
|
|
427 |
/* If RELOC represents a relaxable instruction/reloc, change it into |
/* If RELOC represents a relaxable instruction/reloc, change it into |
433 |
in the howto table. This needs to be fixed. */ |
in the howto table. This needs to be fixed. */ |
434 |
|
|
435 |
static int |
static int |
436 |
h8300_reloc16_estimate (abfd, input_section, reloc, shrink, link_info) |
h8300_reloc16_estimate (bfd *abfd, asection *input_section, arelent *reloc, |
437 |
bfd *abfd; |
unsigned int shrink, struct bfd_link_info *link_info) |
|
asection *input_section; |
|
|
arelent *reloc; |
|
|
unsigned int shrink; |
|
|
struct bfd_link_info *link_info; |
|
438 |
{ |
{ |
439 |
bfd_vma value; |
bfd_vma value; |
440 |
bfd_vma dot; |
bfd_vma dot; |
454 |
/* Only examine the relocs which might be relaxable. */ |
/* Only examine the relocs which might be relaxable. */ |
455 |
switch (reloc->howto->type) |
switch (reloc->howto->type) |
456 |
{ |
{ |
457 |
/* This is the 16/24 bit absolute branch which could become an 8 bit |
/* This is the 16-/24-bit absolute branch which could become an |
458 |
pc-relative branch. */ |
8-bit pc-relative branch. */ |
459 |
case R_JMP1: |
case R_JMP1: |
460 |
case R_JMPL1: |
case R_JMPL1: |
461 |
/* Get the address of the target of this branch. */ |
/* Get the address of the target of this branch. */ |
474 |
/* If the distance is within -128..+128 inclusive, then we can relax |
/* If the distance is within -128..+128 inclusive, then we can relax |
475 |
this jump. +128 is valid since the target will move two bytes |
this jump. +128 is valid since the target will move two bytes |
476 |
closer if we do relax this branch. */ |
closer if we do relax this branch. */ |
477 |
if ((int)gap >= -128 && (int)gap <= 128 ) |
if ((int) gap >= -128 && (int) gap <= 128) |
478 |
{ |
{ |
479 |
|
bfd_byte code; |
480 |
|
|
481 |
|
if (!bfd_get_section_contents (abfd, input_section, & code, |
482 |
|
reloc->address, 1)) |
483 |
|
break; |
484 |
|
code = bfd_get_8 (abfd, & code); |
485 |
|
|
486 |
/* It's possible we may be able to eliminate this branch entirely; |
/* It's possible we may be able to eliminate this branch entirely; |
487 |
if the previous instruction is a branch around this instruction, |
if the previous instruction is a branch around this instruction, |
488 |
and there's no label at this instruction, then we can reverse |
and there's no label at this instruction, then we can reverse |
494 |
lab1: lab1: |
lab1: lab1: |
495 |
|
|
496 |
This saves 4 bytes instead of two, and should be relatively |
This saves 4 bytes instead of two, and should be relatively |
497 |
common. */ |
common. |
498 |
|
|
499 |
if (gap <= 126 |
Only perform this optimisation for jumps (code 0x5a) not |
500 |
|
subroutine calls, as otherwise it could transform: |
501 |
|
|
502 |
|
mov.w r0,r0 |
503 |
|
beq .L1 |
504 |
|
jsr @_bar |
505 |
|
.L1: rts |
506 |
|
_bar: rts |
507 |
|
into: |
508 |
|
mov.w r0,r0 |
509 |
|
bne _bar |
510 |
|
rts |
511 |
|
_bar: rts |
512 |
|
|
513 |
|
which changes the call (jsr) into a branch (bne). */ |
514 |
|
if (code == 0x5a |
515 |
|
&& gap <= 126 |
516 |
&& last_reloc |
&& last_reloc |
517 |
&& last_reloc->howto->type == R_PCRBYTE) |
&& last_reloc->howto->type == R_PCRBYTE) |
518 |
{ |
{ |
543 |
} |
} |
544 |
break; |
break; |
545 |
|
|
546 |
/* This is the 16 bit pc-relative branch which could become an 8 bit |
/* This is the 16-bit pc-relative branch which could become an 8-bit |
547 |
pc-relative branch. */ |
pc-relative branch. */ |
548 |
case R_PCRWORD: |
case R_PCRWORD: |
549 |
/* Get the address of the target of this branch, add one to the value |
/* Get the address of the target of this branch, add one to the value |
550 |
because the addend field in PCrel jumps is off by -1. */ |
because the addend field in PCrel jumps is off by -1. */ |
551 |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section) + 1; |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section) + 1; |
552 |
|
|
553 |
/* Get the address of the next instruction if we were to relax. */ |
/* Get the address of the next instruction if we were to relax. */ |
560 |
/* If the distance is within -128..+128 inclusive, then we can relax |
/* If the distance is within -128..+128 inclusive, then we can relax |
561 |
this jump. +128 is valid since the target will move two bytes |
this jump. +128 is valid since the target will move two bytes |
562 |
closer if we do relax this branch. */ |
closer if we do relax this branch. */ |
563 |
if ((int)gap >= -128 && (int)gap <= 128 ) |
if ((int) gap >= -128 && (int) gap <= 128) |
564 |
{ |
{ |
565 |
/* Change the reloc type. */ |
/* Change the reloc type. */ |
566 |
reloc->howto = howto_table + 15; |
reloc->howto = howto_table + 15; |
571 |
} |
} |
572 |
break; |
break; |
573 |
|
|
574 |
/* This is a 16 bit absolute address in a mov.b insn, which can |
/* This is a 16-bit absolute address in a mov.b insn, which can |
575 |
become an 8 bit absolute address if it's in the right range. */ |
become an 8-bit absolute address if it's in the right range. */ |
576 |
case R_MOV16B1: |
case R_MOV16B1: |
577 |
/* Get the address of the data referenced by this mov.b insn. */ |
/* Get the address of the data referenced by this mov.b insn. */ |
578 |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
579 |
|
value = bfd_h8300_pad_address (abfd, value); |
580 |
|
|
581 |
/* The address is in 0xff00..0xffff inclusive on the h8300 or |
/* If the address is in the top 256 bytes of the address space |
582 |
0xffff00..0xffffff inclusive on the h8300h, then we can |
then we can relax this instruction. */ |
583 |
relax this mov.b */ |
if (value >= 0xffffff00u) |
|
if ((bfd_get_mach (abfd) == bfd_mach_h8300 |
|
|
&& value >= 0xff00 |
|
|
&& value <= 0xffff) |
|
|
|| ((bfd_get_mach (abfd) == bfd_mach_h8300h |
|
|
|| bfd_get_mach (abfd) == bfd_mach_h8300s) |
|
|
&& value >= 0xffff00 |
|
|
&& value <= 0xffffff)) |
|
584 |
{ |
{ |
585 |
/* Change the reloc type. */ |
/* Change the reloc type. */ |
586 |
reloc->howto = reloc->howto + 1; |
reloc->howto = reloc->howto + 1; |
591 |
} |
} |
592 |
break; |
break; |
593 |
|
|
594 |
/* Similarly for a 24 bit absolute address in a mov.b. Note that |
/* Similarly for a 24-bit absolute address in a mov.b. Note that |
595 |
if we can't relax this into an 8 bit absolute, we'll fall through |
if we can't relax this into an 8-bit absolute, we'll fall through |
596 |
and try to relax it into a 16bit absolute. */ |
and try to relax it into a 16-bit absolute. */ |
597 |
case R_MOV24B1: |
case R_MOV24B1: |
598 |
/* Get the address of the data referenced by this mov.b insn. */ |
/* Get the address of the data referenced by this mov.b insn. */ |
599 |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
600 |
|
value = bfd_h8300_pad_address (abfd, value); |
601 |
|
|
602 |
/* The address is in 0xffff00..0xffffff inclusive on the h8300h, |
if (value >= 0xffffff00u) |
|
then we can relax this mov.b */ |
|
|
if ((bfd_get_mach (abfd) == bfd_mach_h8300h |
|
|
|| bfd_get_mach (abfd) == bfd_mach_h8300s) |
|
|
&& value >= 0xffff00 |
|
|
&& value <= 0xffffff) |
|
603 |
{ |
{ |
604 |
/* Change the reloc type. */ |
/* Change the reloc type. */ |
605 |
reloc->howto = reloc->howto + 1; |
reloc->howto = reloc->howto + 1; |
612 |
break; |
break; |
613 |
} |
} |
614 |
|
|
615 |
/* FALLTHROUGH and try to turn the 32/24 bit reloc into a 16 bit |
/* FALLTHROUGH and try to turn the 24-/32-bit reloc into a 16-bit |
616 |
reloc. */ |
reloc. */ |
617 |
|
|
618 |
/* This is a 24/32 bit absolute address in a mov insn, which can |
/* This is a 24-/32-bit absolute address in a mov insn, which can |
619 |
become an 16 bit absolute address if it's in the right range. */ |
become an 16-bit absolute address if it's in the right range. */ |
620 |
case R_MOVL1: |
case R_MOVL1: |
621 |
/* Get the address of the data referenced by this mov insn. */ |
/* Get the address of the data referenced by this mov insn. */ |
622 |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
623 |
|
value = bfd_h8300_pad_address (abfd, value); |
624 |
|
|
625 |
/* If this address is in 0x0000..0x7fff inclusive or |
/* If the address is a sign-extended 16-bit value then we can |
626 |
0xff8000..0xffffff inclusive, then it can be relaxed. */ |
relax this instruction. */ |
627 |
if (value <= 0x7fff || value >= 0xff8000) |
if (value <= 0x7fff || value >= 0xffff8000u) |
628 |
{ |
{ |
629 |
/* Change the reloc type. */ |
/* Change the reloc type. */ |
630 |
reloc->howto = howto_table + 17; |
reloc->howto = howto_table + 17; |
651 |
FIXME: Not all relocations check for overflow! */ |
FIXME: Not all relocations check for overflow! */ |
652 |
|
|
653 |
static void |
static void |
654 |
h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, |
h8300_reloc16_extra_cases (bfd *abfd, struct bfd_link_info *link_info, |
655 |
dst_ptr) |
struct bfd_link_order *link_order, arelent *reloc, |
656 |
bfd *abfd; |
bfd_byte *data, unsigned int *src_ptr, |
657 |
struct bfd_link_info *link_info; |
unsigned int *dst_ptr) |
|
struct bfd_link_order *link_order; |
|
|
arelent *reloc; |
|
|
bfd_byte *data; |
|
|
unsigned int *src_ptr; |
|
|
unsigned int *dst_ptr; |
|
658 |
{ |
{ |
659 |
unsigned int src_address = *src_ptr; |
unsigned int src_address = *src_ptr; |
660 |
unsigned int dst_address = *dst_ptr; |
unsigned int dst_address = *dst_ptr; |
662 |
bfd_vma value; |
bfd_vma value; |
663 |
bfd_vma dot; |
bfd_vma dot; |
664 |
int gap, tmp; |
int gap, tmp; |
665 |
|
unsigned char temp_code; |
666 |
|
|
667 |
switch (reloc->howto->type) |
switch (reloc->howto->type) |
668 |
{ |
{ |
669 |
/* Generic 8bit pc-relative relocation. */ |
/* Generic 8-bit pc-relative relocation. */ |
670 |
case R_PCRBYTE: |
case R_PCRBYTE: |
671 |
/* Get the address of the target of this branch. */ |
/* Get the address of the target of this branch. */ |
672 |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
681 |
if (gap < -128 || gap > 126) |
if (gap < -128 || gap > 126) |
682 |
{ |
{ |
683 |
if (! ((*link_info->callbacks->reloc_overflow) |
if (! ((*link_info->callbacks->reloc_overflow) |
684 |
(link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), |
(link_info, NULL, |
685 |
|
bfd_asymbol_name (*reloc->sym_ptr_ptr), |
686 |
reloc->howto->name, reloc->addend, input_section->owner, |
reloc->howto->name, reloc->addend, input_section->owner, |
687 |
input_section, reloc->address))) |
input_section, reloc->address))) |
688 |
abort (); |
abort (); |
690 |
|
|
691 |
/* Everything looks OK. Apply the relocation and update the |
/* Everything looks OK. Apply the relocation and update the |
692 |
src/dst address appropriately. */ |
src/dst address appropriately. */ |
|
|
|
693 |
bfd_put_8 (abfd, gap, data + dst_address); |
bfd_put_8 (abfd, gap, data + dst_address); |
694 |
dst_address++; |
dst_address++; |
695 |
src_address++; |
src_address++; |
697 |
/* All done. */ |
/* All done. */ |
698 |
break; |
break; |
699 |
|
|
700 |
/* Generic 16bit pc-relative relocation. */ |
/* Generic 16-bit pc-relative relocation. */ |
701 |
case R_PCRWORD: |
case R_PCRWORD: |
702 |
/* Get the address of the target of this branch. */ |
/* Get the address of the target of this branch. */ |
703 |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
713 |
if (gap > 32766 || gap < -32768) |
if (gap > 32766 || gap < -32768) |
714 |
{ |
{ |
715 |
if (! ((*link_info->callbacks->reloc_overflow) |
if (! ((*link_info->callbacks->reloc_overflow) |
716 |
(link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), |
(link_info, NULL, |
717 |
|
bfd_asymbol_name (*reloc->sym_ptr_ptr), |
718 |
reloc->howto->name, reloc->addend, input_section->owner, |
reloc->howto->name, reloc->addend, input_section->owner, |
719 |
input_section, reloc->address))) |
input_section, reloc->address))) |
720 |
abort (); |
abort (); |
722 |
|
|
723 |
/* Everything looks OK. Apply the relocation and update the |
/* Everything looks OK. Apply the relocation and update the |
724 |
src/dst address appropriately. */ |
src/dst address appropriately. */ |
|
|
|
725 |
bfd_put_16 (abfd, (bfd_vma) gap, data + dst_address); |
bfd_put_16 (abfd, (bfd_vma) gap, data + dst_address); |
726 |
dst_address += 2; |
dst_address += 2; |
727 |
src_address += 2; |
src_address += 2; |
729 |
/* All done. */ |
/* All done. */ |
730 |
break; |
break; |
731 |
|
|
732 |
/* Generic 8bit absolute relocation. */ |
/* Generic 8-bit absolute relocation. */ |
733 |
case R_RELBYTE: |
case R_RELBYTE: |
734 |
/* Get the address of the object referenced by this insn. */ |
/* Get the address of the object referenced by this insn. */ |
735 |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
736 |
|
|
737 |
/* Sanity check. */ |
bfd_put_8 (abfd, value & 0xff, data + dst_address); |
738 |
if (value <= 0xff |
dst_address += 1; |
739 |
|| (value >= 0x0000ff00 && value <= 0x0000ffff) |
src_address += 1; |
|
|| (value >= 0x00ffff00 && value <= 0x00ffffff) |
|
|
|| (value >= 0xffffff00 && value <= 0xffffffff)) |
|
|
{ |
|
|
/* Everything looks OK. Apply the relocation and update the |
|
|
src/dst address appropriately. */ |
|
|
|
|
|
bfd_put_8 (abfd, value & 0xff, data + dst_address); |
|
|
dst_address += 1; |
|
|
src_address += 1; |
|
|
} |
|
|
else |
|
|
{ |
|
|
if (! ((*link_info->callbacks->reloc_overflow) |
|
|
(link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), |
|
|
reloc->howto->name, reloc->addend, input_section->owner, |
|
|
input_section, reloc->address))) |
|
|
abort (); |
|
|
} |
|
740 |
|
|
741 |
/* All done. */ |
/* All done. */ |
742 |
break; |
break; |
743 |
|
|
744 |
/* Various simple 16bit absolute relocations. */ |
/* Various simple 16-bit absolute relocations. */ |
745 |
case R_MOV16B1: |
case R_MOV16B1: |
746 |
case R_JMP1: |
case R_JMP1: |
747 |
case R_RELWORD: |
case R_RELWORD: |
751 |
src_address += 2; |
src_address += 2; |
752 |
break; |
break; |
753 |
|
|
754 |
/* Various simple 24/32bit absolute relocations. */ |
/* Various simple 24-/32-bit absolute relocations. */ |
755 |
case R_MOV24B1: |
case R_MOV24B1: |
756 |
case R_MOVL1: |
case R_MOVL1: |
757 |
case R_RELLONG: |
case R_RELLONG: |
762 |
src_address += 4; |
src_address += 4; |
763 |
break; |
break; |
764 |
|
|
765 |
/* Another 24/32bit absolute relocation. */ |
/* Another 24-/32-bit absolute relocation. */ |
766 |
case R_JMPL1: |
case R_JMPL1: |
767 |
/* Get the address of the target of this branch. */ |
/* Get the address of the target of this branch. */ |
768 |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
774 |
src_address += 4; |
src_address += 4; |
775 |
break; |
break; |
776 |
|
|
777 |
/* A 16bit abolute relocation that was formerlly a 24/32bit |
/* This is a 24-/32-bit absolute address in one of the following |
778 |
absolute relocation. */ |
instructions: |
779 |
|
|
780 |
|
"band", "bclr", "biand", "bild", "bior", "bist", "bixor", |
781 |
|
"bld", "bnot", "bor", "bset", "bst", "btst", "bxor", "ldc.w", |
782 |
|
"stc.w" and "mov.[bwl]" |
783 |
|
|
784 |
|
We may relax this into an 16-bit absolute address if it's in |
785 |
|
the right range. */ |
786 |
case R_MOVL2: |
case R_MOVL2: |
787 |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
788 |
|
value = bfd_h8300_pad_address (abfd, value); |
789 |
|
|
790 |
/* Sanity check. */ |
/* Sanity check. */ |
791 |
if (value <= 0x7fff || value >= 0xff8000) |
if (value <= 0x7fff || value >= 0xffff8000u) |
792 |
{ |
{ |
793 |
/* Insert the 16bit value into the proper location. */ |
/* Insert the 16-bit value into the proper location. */ |
794 |
bfd_put_16 (abfd, value, data + dst_address); |
bfd_put_16 (abfd, value, data + dst_address); |
795 |
|
|
796 |
/* Fix the opcode. For all the move insns, we simply |
/* Fix the opcode. For all the instructions that belong to |
797 |
need to turn off bit 0x20 in the previous byte. */ |
this relaxation, we simply need to turn off bit 0x20 in |
798 |
data[dst_address - 1] &= ~0x20; |
the previous byte. */ |
799 |
|
data[dst_address - 1] &= ~0x20; |
800 |
dst_address += 2; |
dst_address += 2; |
801 |
src_address += 4; |
src_address += 4; |
802 |
} |
} |
803 |
else |
else |
804 |
{ |
{ |
805 |
if (! ((*link_info->callbacks->reloc_overflow) |
if (! ((*link_info->callbacks->reloc_overflow) |
806 |
(link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), |
(link_info, NULL, |
807 |
|
bfd_asymbol_name (*reloc->sym_ptr_ptr), |
808 |
reloc->howto->name, reloc->addend, input_section->owner, |
reloc->howto->name, reloc->addend, input_section->owner, |
809 |
input_section, reloc->address))) |
input_section, reloc->address))) |
810 |
abort (); |
abort (); |
811 |
} |
} |
812 |
break; |
break; |
813 |
|
|
814 |
/* A 16bit absolute branch that is now an 8-bit pc-relative branch. */ |
/* A 16-bit absolute branch that is now an 8-bit pc-relative branch. */ |
815 |
case R_JMP2: |
case R_JMP2: |
816 |
/* Get the address of the target of this branch. */ |
/* Get the address of the target of this branch. */ |
817 |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
827 |
if (gap < -128 || gap > 126) |
if (gap < -128 || gap > 126) |
828 |
{ |
{ |
829 |
if (! ((*link_info->callbacks->reloc_overflow) |
if (! ((*link_info->callbacks->reloc_overflow) |
830 |
(link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), |
(link_info, NULL, |
831 |
|
bfd_asymbol_name (*reloc->sym_ptr_ptr), |
832 |
reloc->howto->name, reloc->addend, input_section->owner, |
reloc->howto->name, reloc->addend, input_section->owner, |
833 |
input_section, reloc->address))) |
input_section, reloc->address))) |
834 |
abort (); |
abort (); |
842 |
bfd_put_8 (abfd, 0x55, data + dst_address - 1); |
bfd_put_8 (abfd, 0x55, data + dst_address - 1); |
843 |
break; |
break; |
844 |
case 0x5a: |
case 0x5a: |
845 |
/* jmp ->bra */ |
/* jmp -> bra */ |
846 |
bfd_put_8 (abfd, 0x40, data + dst_address - 1); |
bfd_put_8 (abfd, 0x40, data + dst_address - 1); |
847 |
break; |
break; |
848 |
|
|
850 |
abort (); |
abort (); |
851 |
} |
} |
852 |
|
|
853 |
/* Write out the 8bit value. */ |
/* Write out the 8-bit value. */ |
854 |
bfd_put_8 (abfd, gap, data + dst_address); |
bfd_put_8 (abfd, gap, data + dst_address); |
855 |
|
|
856 |
dst_address += 1; |
dst_address += 1; |
858 |
|
|
859 |
break; |
break; |
860 |
|
|
861 |
/* A 16bit pc-relative branch that is now an 8-bit pc-relative branch. */ |
/* A 16-bit pc-relative branch that is now an 8-bit pc-relative branch. */ |
862 |
case R_PCRWORD_B: |
case R_PCRWORD_B: |
863 |
/* Get the address of the target of this branch. */ |
/* Get the address of the target of this branch. */ |
864 |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
874 |
if (gap < -128 || gap > 126) |
if (gap < -128 || gap > 126) |
875 |
{ |
{ |
876 |
if (! ((*link_info->callbacks->reloc_overflow) |
if (! ((*link_info->callbacks->reloc_overflow) |
877 |
(link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), |
(link_info, NULL, |
878 |
|
bfd_asymbol_name (*reloc->sym_ptr_ptr), |
879 |
reloc->howto->name, reloc->addend, input_section->owner, |
reloc->howto->name, reloc->addend, input_section->owner, |
880 |
input_section, reloc->address))) |
input_section, reloc->address))) |
881 |
abort (); |
abort (); |
886 |
{ |
{ |
887 |
case 0x58: |
case 0x58: |
888 |
/* bCC:16 -> bCC:8 */ |
/* bCC:16 -> bCC:8 */ |
889 |
/* Get the condition code from the original insn. */ |
/* Get the second byte of the original insn, which contains |
890 |
|
the condition code. */ |
891 |
tmp = data[dst_address - 1]; |
tmp = data[dst_address - 1]; |
892 |
|
|
893 |
|
/* Compute the fisrt byte of the relaxed instruction. The |
894 |
|
original sequence 0x58 0xX0 is relaxed to 0x4X, where X |
895 |
|
represents the condition code. */ |
896 |
tmp &= 0xf0; |
tmp &= 0xf0; |
897 |
tmp >>= 4; |
tmp >>= 4; |
|
|
|
|
/* Now or in the high nibble of the opcode. */ |
|
898 |
tmp |= 0x40; |
tmp |= 0x40; |
899 |
|
|
900 |
/* Write it. */ |
/* Write it. */ |
910 |
abort (); |
abort (); |
911 |
} |
} |
912 |
|
|
913 |
/* Output the target. */ |
/* Output the target. */ |
914 |
bfd_put_8 (abfd, gap, data + dst_address - 1); |
bfd_put_8 (abfd, gap, data + dst_address - 1); |
915 |
|
|
916 |
/* We don't advance dst_address -- the 8bit reloc is applied at |
/* We don't advance dst_address -- the 8-bit reloc is applied at |
917 |
dst_address - 1, so the next insn should begin at dst_address. */ |
dst_address - 1, so the next insn should begin at dst_address. */ |
918 |
src_address += 2; |
src_address += 2; |
919 |
|
|
920 |
break; |
break; |
921 |
|
|
922 |
/* Similarly for a 24bit absolute that is now 8 bits. */ |
/* Similarly for a 24-bit absolute that is now 8 bits. */ |
923 |
case R_JMPL2: |
case R_JMPL2: |
924 |
/* Get the address of the target of this branch. */ |
/* Get the address of the target of this branch. */ |
925 |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
952 |
|
|
953 |
break; |
break; |
954 |
|
|
955 |
/* A 16bit absolute mov.b that is now an 8bit absolute mov.b. */ |
/* This is a 16-bit absolute address in one of the following |
956 |
|
instructions: |
957 |
|
|
958 |
|
"band", "bclr", "biand", "bild", "bior", "bist", "bixor", |
959 |
|
"bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and |
960 |
|
"mov.b" |
961 |
|
|
962 |
|
We may relax this into an 8-bit absolute address if it's in |
963 |
|
the right range. */ |
964 |
case R_MOV16B2: |
case R_MOV16B2: |
965 |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
966 |
|
|
967 |
/* Sanity check. */ |
/* All instructions with R_H8_DIR16B2 start with 0x6a. */ |
968 |
if (data[dst_address - 2] != 0x6a) |
if (data[dst_address - 2] != 0x6a) |
969 |
abort (); |
abort (); |
970 |
|
|
971 |
|
temp_code = data[src_address - 1]; |
972 |
|
|
973 |
|
/* If this is a mov.b instruction, clear the lower nibble, which |
974 |
|
contains the source/destination register number. */ |
975 |
|
if ((temp_code & 0x10) != 0x10) |
976 |
|
temp_code &= 0xf0; |
977 |
|
|
978 |
/* Fix up the opcode. */ |
/* Fix up the opcode. */ |
979 |
switch (data[src_address - 1] & 0xf0) |
switch (temp_code) |
980 |
{ |
{ |
981 |
case 0x00: |
case 0x00: |
982 |
|
/* This is mov.b @aa:16,Rd. */ |
983 |
data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20; |
data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20; |
984 |
break; |
break; |
985 |
case 0x80: |
case 0x80: |
986 |
|
/* This is mov.b Rs,@aa:16. */ |
987 |
data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30; |
data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30; |
988 |
break; |
break; |
989 |
|
case 0x18: |
990 |
|
/* This is a bit-maniputation instruction that stores one |
991 |
|
bit into memory, one of "bclr", "bist", "bnot", "bset", |
992 |
|
and "bst". */ |
993 |
|
data[dst_address - 2] = 0x7f; |
994 |
|
break; |
995 |
|
case 0x10: |
996 |
|
/* This is a bit-maniputation instruction that loads one bit |
997 |
|
from memory, one of "band", "biand", "bild", "bior", |
998 |
|
"bixor", "bld", "bor", "btst", and "bxor". */ |
999 |
|
data[dst_address - 2] = 0x7e; |
1000 |
|
break; |
1001 |
default: |
default: |
1002 |
abort (); |
abort (); |
1003 |
} |
} |
1006 |
src_address += 2; |
src_address += 2; |
1007 |
break; |
break; |
1008 |
|
|
1009 |
/* Similarly for a 24bit mov.b */ |
/* This is a 24-bit absolute address in one of the following |
1010 |
|
instructions: |
1011 |
|
|
1012 |
|
"band", "bclr", "biand", "bild", "bior", "bist", "bixor", |
1013 |
|
"bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and |
1014 |
|
"mov.b" |
1015 |
|
|
1016 |
|
We may relax this into an 8-bit absolute address if it's in |
1017 |
|
the right range. */ |
1018 |
case R_MOV24B2: |
case R_MOV24B2: |
1019 |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section); |
1020 |
|
|
1021 |
/* Sanity check. */ |
/* All instructions with R_MOV24B2 start with 0x6a. */ |
1022 |
if (data[dst_address - 2] != 0x6a) |
if (data[dst_address - 2] != 0x6a) |
1023 |
abort (); |
abort (); |
1024 |
|
|
1025 |
|
temp_code = data[src_address - 1]; |
1026 |
|
|
1027 |
|
/* If this is a mov.b instruction, clear the lower nibble, which |
1028 |
|
contains the source/destination register number. */ |
1029 |
|
if ((temp_code & 0x30) != 0x30) |
1030 |
|
temp_code &= 0xf0; |
1031 |
|
|
1032 |
/* Fix up the opcode. */ |
/* Fix up the opcode. */ |
1033 |
switch (data[src_address - 1] & 0xf0) |
switch (temp_code) |
1034 |
{ |
{ |
1035 |
case 0x20: |
case 0x20: |
1036 |
|
/* This is mov.b @aa:24/32,Rd. */ |
1037 |
data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20; |
data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20; |
1038 |
break; |
break; |
1039 |
case 0xa0: |
case 0xa0: |
1040 |
|
/* This is mov.b Rs,@aa:24/32. */ |
1041 |
data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30; |
data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30; |
1042 |
break; |
break; |
1043 |
|
case 0x38: |
1044 |
|
/* This is a bit-maniputation instruction that stores one |
1045 |
|
bit into memory, one of "bclr", "bist", "bnot", "bset", |
1046 |
|
and "bst". */ |
1047 |
|
data[dst_address - 2] = 0x7f; |
1048 |
|
break; |
1049 |
|
case 0x30: |
1050 |
|
/* This is a bit-maniputation instruction that loads one bit |
1051 |
|
from memory, one of "band", "biand", "bild", "bior", |
1052 |
|
"bixor", "bld", "bor", "btst", and "bxor". */ |
1053 |
|
data[dst_address - 2] = 0x7e; |
1054 |
|
break; |
1055 |
default: |
default: |
1056 |
abort (); |
abort (); |
1057 |
} |
} |
1074 |
if (gap < -128 || gap > 126) |
if (gap < -128 || gap > 126) |
1075 |
{ |
{ |
1076 |
if (! ((*link_info->callbacks->reloc_overflow) |
if (! ((*link_info->callbacks->reloc_overflow) |
1077 |
(link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), |
(link_info, NULL, |
1078 |
|
bfd_asymbol_name (*reloc->sym_ptr_ptr), |
1079 |
reloc->howto->name, reloc->addend, input_section->owner, |
reloc->howto->name, reloc->addend, input_section->owner, |
1080 |
input_section, reloc->address))) |
input_section, reloc->address))) |
1081 |
abort (); |
abort (); |
1097 |
src_address += 4; |
src_address += 4; |
1098 |
break; |
break; |
1099 |
|
|
1100 |
/* An 8bit memory indirect instruction (jmp/jsr). |
/* An 8-bit memory indirect instruction (jmp/jsr). |
1101 |
|
|
1102 |
There's several things that need to be done to handle |
There's several things that need to be done to handle |
1103 |
this relocation. |
this relocation. |
1117 |
const char *name; |
const char *name; |
1118 |
struct funcvec_hash_table *ftab; |
struct funcvec_hash_table *ftab; |
1119 |
struct funcvec_hash_entry *h; |
struct funcvec_hash_entry *h; |
1120 |
asection *vectors_sec = h8300_coff_hash_table (link_info)->vectors_sec; |
struct h8300_coff_link_hash_table *htab; |
1121 |
|
asection *vectors_sec; |
1122 |
|
|
1123 |
|
if (link_info->hash->creator != abfd->xvec) |
1124 |
|
{ |
1125 |
|
(*_bfd_error_handler) |
1126 |
|
(_("cannot handle R_MEM_INDIRECT reloc when using %s output"), |
1127 |
|
link_info->hash->creator->name); |
1128 |
|
|
1129 |
|
/* What else can we do? This function doesn't allow return |
1130 |
|
of an error, and we don't want to call abort as that |
1131 |
|
indicates an internal error. */ |
1132 |
|
#ifndef EXIT_FAILURE |
1133 |
|
#define EXIT_FAILURE 1 |
1134 |
|
#endif |
1135 |
|
xexit (EXIT_FAILURE); |
1136 |
|
} |
1137 |
|
htab = h8300_coff_hash_table (link_info); |
1138 |
|
vectors_sec = htab->vectors_sec; |
1139 |
|
|
1140 |
/* First see if this is a reloc against the absolute symbol |
/* First see if this is a reloc against the absolute symbol |
1141 |
or against a symbol with a nonnegative value <= 0xff. */ |
or against a symbol with a nonnegative value <= 0xff. */ |
1157 |
else |
else |
1158 |
{ |
{ |
1159 |
if (! ((*link_info->callbacks->reloc_overflow) |
if (! ((*link_info->callbacks->reloc_overflow) |
1160 |
(link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), |
(link_info, NULL, |
1161 |
|
bfd_asymbol_name (*reloc->sym_ptr_ptr), |
1162 |
reloc->howto->name, reloc->addend, input_section->owner, |
reloc->howto->name, reloc->addend, input_section->owner, |
1163 |
input_section, reloc->address))) |
input_section, reloc->address))) |
1164 |
abort (); |
abort (); |
1175 |
name = symbol->name; |
name = symbol->name; |
1176 |
if (symbol->flags & BSF_LOCAL) |
if (symbol->flags & BSF_LOCAL) |
1177 |
{ |
{ |
1178 |
char *new_name = bfd_malloc ((bfd_size_type) strlen (name) + 9); |
char *new_name = bfd_malloc ((bfd_size_type) strlen (name) + 10); |
1179 |
|
|
1180 |
if (new_name == NULL) |
if (new_name == NULL) |
1181 |
abort (); |
abort (); |
1182 |
|
|
1183 |
strcpy (new_name, name); |
sprintf (new_name, "%s_%08x", name, symbol->section->id); |
|
sprintf (new_name + strlen (name), "_%08x", |
|
|
(int) symbol->section); |
|
1184 |
name = new_name; |
name = new_name; |
1185 |
} |
} |
1186 |
|
|
1187 |
ftab = h8300_coff_hash_table (link_info)->funcvec_hash_table; |
ftab = htab->funcvec_hash_table; |
1188 |
h = funcvec_hash_lookup (ftab, name, false, false); |
h = funcvec_hash_lookup (ftab, name, FALSE, FALSE); |
1189 |
|
|
1190 |
/* This shouldn't ever happen. If it does that means we've got |
/* This shouldn't ever happen. If it does that means we've got |
1191 |
data corruption of some kind. Aborting seems like a reasonable |
data corruption of some kind. Aborting seems like a reasonable |
1192 |
think to do here. */ |
thing to do here. */ |
1193 |
if (h == NULL || vectors_sec == NULL) |
if (h == NULL || vectors_sec == NULL) |
1194 |
abort (); |
abort (); |
1195 |
|
|
1203 |
src_address++; |
src_address++; |
1204 |
|
|
1205 |
/* Now create an entry in the function vector itself. */ |
/* Now create an entry in the function vector itself. */ |
1206 |
if (bfd_get_mach (input_section->owner) == bfd_mach_h8300) |
switch (bfd_get_mach (input_section->owner)) |
1207 |
bfd_put_16 (abfd, |
{ |
1208 |
bfd_coff_reloc16_get_value (reloc, |
case bfd_mach_h8300: |
1209 |
link_info, |
case bfd_mach_h8300hn: |
1210 |
input_section), |
case bfd_mach_h8300sn: |
1211 |
vectors_sec->contents + h->offset); |
bfd_put_16 (abfd, |
1212 |
else if (bfd_get_mach (input_section->owner) == bfd_mach_h8300h |
bfd_coff_reloc16_get_value (reloc, |
1213 |
|| bfd_get_mach (input_section->owner) == bfd_mach_h8300s) |
link_info, |
1214 |
bfd_put_32 (abfd, |
input_section), |
1215 |
bfd_coff_reloc16_get_value (reloc, |
vectors_sec->contents + h->offset); |
1216 |
link_info, |
break; |
1217 |
input_section), |
case bfd_mach_h8300h: |
1218 |
vectors_sec->contents + h->offset); |
case bfd_mach_h8300s: |
1219 |
else |
bfd_put_32 (abfd, |
1220 |
abort (); |
bfd_coff_reloc16_get_value (reloc, |
1221 |
|
link_info, |
1222 |
|
input_section), |
1223 |
|
vectors_sec->contents + h->offset); |
1224 |
|
break; |
1225 |
|
default: |
1226 |
|
abort (); |
1227 |
|
} |
1228 |
|
|
1229 |
/* Gross. We've already written the contents of the vector section |
/* Gross. We've already written the contents of the vector section |
1230 |
before we get here... So we write it again with the new data. */ |
before we get here... So we write it again with the new data. */ |
1232 |
vectors_sec->output_section, |
vectors_sec->output_section, |
1233 |
vectors_sec->contents, |
vectors_sec->contents, |
1234 |
(file_ptr) vectors_sec->output_offset, |
(file_ptr) vectors_sec->output_offset, |
1235 |
vectors_sec->_raw_size); |
vectors_sec->size); |
1236 |
break; |
break; |
1237 |
} |
} |
1238 |
|
|
1257 |
from this BFD to the bfd linker hash table. It may add a few |
from this BFD to the bfd linker hash table. It may add a few |
1258 |
selected static symbols to the bfd linker hash table. */ |
selected static symbols to the bfd linker hash table. */ |
1259 |
|
|
1260 |
static boolean |
static bfd_boolean |
1261 |
h8300_bfd_link_add_symbols (abfd, info) |
h8300_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info) |
|
bfd *abfd; |
|
|
struct bfd_link_info *info; |
|
1262 |
{ |
{ |
1263 |
asection *sec; |
asection *sec; |
1264 |
struct funcvec_hash_table *funcvec_hash_table; |
struct funcvec_hash_table *funcvec_hash_table; |
1265 |
bfd_size_type amt; |
bfd_size_type amt; |
1266 |
|
struct h8300_coff_link_hash_table *htab; |
1267 |
|
|
1268 |
|
/* Add the symbols using the generic code. */ |
1269 |
|
_bfd_generic_link_add_symbols (abfd, info); |
1270 |
|
|
1271 |
|
if (info->hash->creator != abfd->xvec) |
1272 |
|
return TRUE; |
1273 |
|
|
1274 |
|
htab = h8300_coff_hash_table (info); |
1275 |
|
|
1276 |
/* If we haven't created a vectors section, do so now. */ |
/* If we haven't created a vectors section, do so now. */ |
1277 |
if (!h8300_coff_hash_table (info)->vectors_sec) |
if (!htab->vectors_sec) |
1278 |
{ |
{ |
1279 |
flagword flags; |
flagword flags; |
1280 |
|
|
1281 |
/* Make sure the appropriate flags are set, including SEC_IN_MEMORY. */ |
/* Make sure the appropriate flags are set, including SEC_IN_MEMORY. */ |
1282 |
flags = (SEC_ALLOC | SEC_LOAD |
flags = (SEC_ALLOC | SEC_LOAD |
1283 |
| SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY); |
| SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY); |
1284 |
h8300_coff_hash_table (info)->vectors_sec = bfd_make_section (abfd, |
htab->vectors_sec = bfd_make_section (abfd, ".vectors"); |
|
".vectors"); |
|
1285 |
|
|
1286 |
/* If the section wasn't created, or we couldn't set the flags, |
/* If the section wasn't created, or we couldn't set the flags, |
1287 |
quit quickly now, rather than dieing a painful death later. */ |
quit quickly now, rather than dying a painful death later. */ |
1288 |
if (! h8300_coff_hash_table (info)->vectors_sec |
if (!htab->vectors_sec |
1289 |
|| ! bfd_set_section_flags (abfd, |
|| !bfd_set_section_flags (abfd, htab->vectors_sec, flags)) |
1290 |
h8300_coff_hash_table(info)->vectors_sec, |
return FALSE; |
|
flags)) |
|
|
return false; |
|
1291 |
|
|
1292 |
/* Also create the vector hash table. */ |
/* Also create the vector hash table. */ |
1293 |
amt = sizeof (struct funcvec_hash_table); |
amt = sizeof (struct funcvec_hash_table); |
1294 |
funcvec_hash_table = (struct funcvec_hash_table *) bfd_alloc (abfd, amt); |
funcvec_hash_table = (struct funcvec_hash_table *) bfd_alloc (abfd, amt); |
1295 |
|
|
1296 |
if (!funcvec_hash_table) |
if (!funcvec_hash_table) |
1297 |
return false; |
return FALSE; |
1298 |
|
|
1299 |
/* And initialize the funcvec hash table. */ |
/* And initialize the funcvec hash table. */ |
1300 |
if (!funcvec_hash_table_init (funcvec_hash_table, abfd, |
if (!funcvec_hash_table_init (funcvec_hash_table, abfd, |
1301 |
funcvec_hash_newfunc)) |
funcvec_hash_newfunc)) |
1302 |
{ |
{ |
1303 |
bfd_release (abfd, funcvec_hash_table); |
bfd_release (abfd, funcvec_hash_table); |
1304 |
return false; |
return FALSE; |
1305 |
} |
} |
1306 |
|
|
1307 |
/* Store away a pointer to the funcvec hash table. */ |
/* Store away a pointer to the funcvec hash table. */ |
1308 |
h8300_coff_hash_table (info)->funcvec_hash_table = funcvec_hash_table; |
htab->funcvec_hash_table = funcvec_hash_table; |
1309 |
} |
} |
1310 |
|
|
1311 |
/* Load up the function vector hash table. */ |
/* Load up the function vector hash table. */ |
1312 |
funcvec_hash_table = h8300_coff_hash_table (info)->funcvec_hash_table; |
funcvec_hash_table = htab->funcvec_hash_table; |
|
|
|
|
/* Add the symbols using the generic code. */ |
|
|
_bfd_generic_link_add_symbols (abfd, info); |
|
1313 |
|
|
1314 |
/* Now scan the relocs for all the sections in this bfd; create |
/* Now scan the relocs for all the sections in this bfd; create |
1315 |
additional space in the .vectors section as needed. */ |
additional space in the .vectors section as needed. */ |
1326 |
|
|
1327 |
relocs = (arelent **) bfd_malloc ((bfd_size_type) reloc_size); |
relocs = (arelent **) bfd_malloc ((bfd_size_type) reloc_size); |
1328 |
if (!relocs) |
if (!relocs) |
1329 |
return false; |
return FALSE; |
1330 |
|
|
1331 |
/* The symbols should have been read in by _bfd_generic link_add_symbols |
/* The symbols should have been read in by _bfd_generic link_add_symbols |
1332 |
call abovec, so we can cheat and use the pointer to them that was |
call abovec, so we can cheat and use the pointer to them that was |
1363 |
{ |
{ |
1364 |
char *new_name; |
char *new_name; |
1365 |
|
|
1366 |
new_name = bfd_malloc ((bfd_size_type) strlen (name) + 9); |
new_name = bfd_malloc ((bfd_size_type) strlen (name) + 10); |
1367 |
if (new_name == NULL) |
if (new_name == NULL) |
1368 |
abort (); |
abort (); |
1369 |
|
|
1370 |
strcpy (new_name, name); |
sprintf (new_name, "%s_%08x", name, symbol->section->id); |
|
sprintf (new_name + strlen (name), "_%08x", |
|
|
(int) symbol->section); |
|
1371 |
name = new_name; |
name = new_name; |
1372 |
} |
} |
1373 |
|
|
1374 |
/* Look this symbol up in the function vector hash table. */ |
/* Look this symbol up in the function vector hash table. */ |
1375 |
ftab = h8300_coff_hash_table (info)->funcvec_hash_table; |
ftab = htab->funcvec_hash_table; |
1376 |
h = funcvec_hash_lookup (ftab, name, false, false); |
h = funcvec_hash_lookup (ftab, name, FALSE, FALSE); |
1377 |
|
|
1378 |
/* If this symbol isn't already in the hash table, add |
/* If this symbol isn't already in the hash table, add |
1379 |
it and bump up the size of the hash table. */ |
it and bump up the size of the hash table. */ |
1380 |
if (h == NULL) |
if (h == NULL) |
1381 |
{ |
{ |
1382 |
h = funcvec_hash_lookup (ftab, name, true, true); |
h = funcvec_hash_lookup (ftab, name, TRUE, TRUE); |
1383 |
if (h == NULL) |
if (h == NULL) |
1384 |
{ |
{ |
1385 |
free (relocs); |
free (relocs); |
1386 |
return false; |
return FALSE; |
1387 |
} |
} |
1388 |
|
|
1389 |
/* Bump the size of the vectors section. Each vector |
/* Bump the size of the vectors section. Each vector |
1390 |
takes 2 bytes on the h8300 and 4 bytes on the h8300h. */ |
takes 2 bytes on the h8300 and 4 bytes on the h8300h. */ |
1391 |
if (bfd_get_mach (abfd) == bfd_mach_h8300) |
switch (bfd_get_mach (abfd)) |
1392 |
h8300_coff_hash_table (info)->vectors_sec->_raw_size += 2; |
{ |
1393 |
else if (bfd_get_mach (abfd) == bfd_mach_h8300h |
case bfd_mach_h8300: |
1394 |
|| bfd_get_mach (abfd) == bfd_mach_h8300s) |
case bfd_mach_h8300hn: |
1395 |
h8300_coff_hash_table (info)->vectors_sec->_raw_size += 4; |
case bfd_mach_h8300sn: |
1396 |
|
htab->vectors_sec->size += 2; |
1397 |
|
break; |
1398 |
|
case bfd_mach_h8300h: |
1399 |
|
case bfd_mach_h8300s: |
1400 |
|
htab->vectors_sec->size += 4; |
1401 |
|
break; |
1402 |
|
default: |
1403 |
|
abort (); |
1404 |
|
} |
1405 |
} |
} |
1406 |
} |
} |
1407 |
} |
} |
1412 |
|
|
1413 |
/* Now actually allocate some space for the function vector. It's |
/* Now actually allocate some space for the function vector. It's |
1414 |
wasteful to do this more than once, but this is easier. */ |
wasteful to do this more than once, but this is easier. */ |
1415 |
sec = h8300_coff_hash_table (info)->vectors_sec; |
sec = htab->vectors_sec; |
1416 |
if (sec->_raw_size != 0) |
if (sec->size != 0) |
1417 |
{ |
{ |
1418 |
/* Free the old contents. */ |
/* Free the old contents. */ |
1419 |
if (sec->contents) |
if (sec->contents) |
1420 |
free (sec->contents); |
free (sec->contents); |
1421 |
|
|
1422 |
/* Allocate new contents. */ |
/* Allocate new contents. */ |
1423 |
sec->contents = bfd_malloc (sec->_raw_size); |
sec->contents = bfd_malloc (sec->size); |
1424 |
} |
} |
1425 |
|
|
1426 |
return true; |
return TRUE; |
1427 |
} |
} |
1428 |
|
|
1429 |
#define coff_reloc16_extra_cases h8300_reloc16_extra_cases |
#define coff_reloc16_extra_cases h8300_reloc16_extra_cases |
1440 |
bfd_coff_reloc16_get_relocated_section_contents |
bfd_coff_reloc16_get_relocated_section_contents |
1441 |
#define coff_bfd_relax_section bfd_coff_reloc16_relax_section |
#define coff_bfd_relax_section bfd_coff_reloc16_relax_section |
1442 |
|
|
1443 |
CREATE_BIG_COFF_TARGET_VEC (h8300coff_vec, "coff-h8300", BFD_IS_RELAXABLE, 0, '_', NULL) |
CREATE_BIG_COFF_TARGET_VEC (h8300coff_vec, "coff-h8300", BFD_IS_RELAXABLE, 0, '_', NULL, COFF_SWAP_TABLE) |