1 |
/* OR32-specific support for 32-bit ELF |
/* OR32-specific support for 32-bit ELF |
2 |
Copyright (C) 2002 Free Software Foundation, Inc. |
Copyright 2002, 2004 Free Software Foundation, Inc. |
3 |
Contributed by Ivan Guzvinec <ivang@opencores.org> |
Contributed by Ivan Guzvinec <ivang@opencores.org> |
4 |
|
|
5 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
25 |
#include "elf/or32.h" |
#include "elf/or32.h" |
26 |
#include "libiberty.h" |
#include "libiberty.h" |
27 |
|
|
28 |
static reloc_howto_type * bfd_elf32_bfd_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type)); |
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup |
29 |
static void or32_info_to_howto_rel PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *)); |
PARAMS ((bfd *, bfd_reloc_code_real_type)); |
30 |
static boolean or32_elf_object_p PARAMS ((bfd *)); |
static void or32_info_to_howto_rel |
31 |
static void or32_elf_final_write_processing PARAMS ((bfd *, boolean)); |
PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); |
32 |
static bfd_reloc_status_type or32_elf_32_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
static bfd_boolean or32_elf_object_p |
33 |
static bfd_reloc_status_type or32_elf_16_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
PARAMS ((bfd *)); |
34 |
static bfd_reloc_status_type or32_elf_8_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
static void or32_elf_final_write_processing |
35 |
static bfd_reloc_status_type or32_elf_const_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
PARAMS ((bfd *, bfd_boolean)); |
36 |
static bfd_reloc_status_type or32_elf_consth_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
static bfd_reloc_status_type or32_elf_32_reloc |
37 |
static bfd_reloc_status_type or32_elf_jumptarg_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
38 |
|
static bfd_reloc_status_type or32_elf_16_reloc |
39 |
|
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
40 |
|
static bfd_reloc_status_type or32_elf_8_reloc |
41 |
|
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
42 |
|
static bfd_reloc_status_type or32_elf_const_reloc |
43 |
|
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
44 |
|
static bfd_reloc_status_type or32_elf_consth_reloc |
45 |
|
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
46 |
|
static bfd_reloc_status_type or32_elf_jumptarg_reloc |
47 |
|
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
48 |
|
|
49 |
/* Try to minimize the amount of space occupied by relocation tables |
/* Try to minimize the amount of space occupied by relocation tables |
50 |
on the ROM (not that the ROM won't be swamped by other ELF overhead). */ |
on the ROM (not that the ROM won't be swamped by other ELF overhead). */ |
51 |
#define USE_REL |
#define USE_REL 1 |
52 |
|
|
53 |
static reloc_howto_type elf_or32_howto_table[] = |
static reloc_howto_type elf_or32_howto_table[] = |
54 |
{ |
{ |
57 |
0, /* rightshift */ |
0, /* rightshift */ |
58 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
59 |
32, /* bitsize */ |
32, /* bitsize */ |
60 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
61 |
0, /* bitpos */ |
0, /* bitpos */ |
62 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
63 |
bfd_elf_generic_reloc, /* special_function */ |
bfd_elf_generic_reloc, /* special_function */ |
64 |
"R_OR32_NONE", /* name */ |
"R_OR32_NONE", /* name */ |
65 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
66 |
0, /* src_mask */ |
0, /* src_mask */ |
67 |
0, /* dst_mask */ |
0, /* dst_mask */ |
68 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
69 |
|
|
70 |
/* A standard 32 bit relocation. */ |
/* A standard 32 bit relocation. */ |
71 |
HOWTO (R_OR32_32, /* type */ |
HOWTO (R_OR32_32, /* type */ |
72 |
0, /* rightshift */ |
0, /* rightshift */ |
73 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
74 |
32, /* bitsize */ |
32, /* bitsize */ |
75 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
76 |
0, /* bitpos */ |
0, /* bitpos */ |
77 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
78 |
or32_elf_32_reloc, /* special_function */ |
or32_elf_32_reloc, /* special_function */ |
79 |
"R_OR32_32", /* name */ |
"R_OR32_32", /* name */ |
80 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
81 |
0xffffffff, /* src_mask */ |
0xffffffff, /* src_mask */ |
82 |
0xffffffff, /* dst_mask */ |
0xffffffff, /* dst_mask */ |
83 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
84 |
|
|
85 |
/* A standard 16 bit relocation. */ |
/* A standard 16 bit relocation. */ |
86 |
HOWTO (R_OR32_16, /* type */ |
HOWTO (R_OR32_16, /* type */ |
87 |
0, /* rightshift */ |
0, /* rightshift */ |
88 |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
1, /* size (0 = byte, 1 = short, 2 = long) */ |
89 |
16, /* bitsize */ |
16, /* bitsize */ |
90 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
91 |
0, /* bitpos */ |
0, /* bitpos */ |
92 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
93 |
or32_elf_16_reloc, /* special_function */ |
or32_elf_16_reloc, /* special_function */ |
94 |
"R_OR32_16", /* name */ |
"R_OR32_16", /* name */ |
95 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
96 |
0x0000ffff, /* src_mask */ |
0x0000ffff, /* src_mask */ |
97 |
0x0000ffff, /* dst_mask */ |
0x0000ffff, /* dst_mask */ |
98 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
99 |
|
|
100 |
/* A standard 8 bit relocation. */ |
/* A standard 8 bit relocation. */ |
101 |
HOWTO (R_OR32_8, /* type */ |
HOWTO (R_OR32_8, /* type */ |
102 |
0, /* rightshift */ |
0, /* rightshift */ |
103 |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
0, /* size (0 = byte, 1 = short, 2 = long) */ |
104 |
8, /* bitsize */ |
8, /* bitsize */ |
105 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
106 |
0, /* bitpos */ |
0, /* bitpos */ |
107 |
complain_overflow_bitfield, /* complain_on_overflow */ |
complain_overflow_bitfield, /* complain_on_overflow */ |
108 |
or32_elf_8_reloc, /* special_function */ |
or32_elf_8_reloc, /* special_function */ |
109 |
"R_OR32_8", /* name */ |
"R_OR32_8", /* name */ |
110 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
111 |
0x000000ff, /* src_mask */ |
0x000000ff, /* src_mask */ |
112 |
0x000000ff, /* dst_mask */ |
0x000000ff, /* dst_mask */ |
113 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
114 |
|
|
115 |
/* A standard low 16 bit relocation. */ |
/* A standard low 16 bit relocation. */ |
116 |
HOWTO (R_OR32_CONST, /* type */ |
HOWTO (R_OR32_CONST, /* type */ |
117 |
0, /* rightshift */ |
0, /* rightshift */ |
118 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
119 |
16, /* bitsize */ |
16, /* bitsize */ |
120 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
121 |
0, /* bitpos */ |
0, /* bitpos */ |
122 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
123 |
or32_elf_const_reloc, /* special_function */ |
or32_elf_const_reloc, /* special_function */ |
124 |
"R_OR32_CONST", /* name */ |
"R_OR32_CONST", /* name */ |
125 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
126 |
0x0000ffff, /* src_mask */ |
0x0000ffff, /* src_mask */ |
127 |
0x0000ffff, /* dst_mask */ |
0x0000ffff, /* dst_mask */ |
128 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
129 |
|
|
130 |
/* A standard high 16 bit relocation. */ |
/* A standard high 16 bit relocation. */ |
131 |
HOWTO (R_OR32_CONSTH, /* type */ |
HOWTO (R_OR32_CONSTH, /* type */ |
132 |
16, /* rightshift */ |
16, /* rightshift */ |
133 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
134 |
16, /* bitsize */ |
16, /* bitsize */ |
135 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
136 |
0, /* bitpos */ |
0, /* bitpos */ |
137 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
138 |
or32_elf_consth_reloc, /* special_function */ |
or32_elf_consth_reloc, /* special_function */ |
139 |
"R_OR32_CONSTH", /* name */ |
"R_OR32_CONSTH", /* name */ |
140 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
141 |
0xffff0000, /* src_mask */ |
0xffff0000, /* src_mask */ |
142 |
0x0000ffff, /* dst_mask */ |
0x0000ffff, /* dst_mask */ |
143 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
144 |
|
|
145 |
/* A standard branch relocation. */ |
/* A standard branch relocation. */ |
146 |
HOWTO (R_OR32_JUMPTARG, /* type */ |
HOWTO (R_OR32_JUMPTARG, /* type */ |
147 |
2, /* rightshift */ |
2, /* rightshift */ |
148 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
149 |
28, /* bitsize */ |
28, /* bitsize */ |
150 |
true, /* pc_relative */ |
TRUE, /* pc_relative */ |
151 |
0, /* bitpos */ |
0, /* bitpos */ |
152 |
complain_overflow_signed, /* complain_on_overflow */ |
complain_overflow_signed, /* complain_on_overflow */ |
153 |
or32_elf_jumptarg_reloc,/* special_function */ |
or32_elf_jumptarg_reloc,/* special_function */ |
154 |
"R_OR32_JUMPTARG", /* name */ |
"R_OR32_JUMPTARG", /* name */ |
155 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
156 |
0, /* src_mask */ |
0, /* src_mask */ |
157 |
0x03ffffff, /* dst_mask */ |
0x03ffffff, /* dst_mask */ |
158 |
true), /* pcrel_offset */ |
TRUE), /* pcrel_offset */ |
159 |
|
|
160 |
/* GNU extension to record C++ vtable hierarchy. */ |
/* GNU extension to record C++ vtable hierarchy. */ |
161 |
HOWTO (R_OR32_GNU_VTINHERIT, /* type */ |
HOWTO (R_OR32_GNU_VTINHERIT, /* type */ |
162 |
0, /* rightshift */ |
0, /* rightshift */ |
163 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
164 |
0, /* bitsize */ |
0, /* bitsize */ |
165 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
166 |
0, /* bitpos */ |
0, /* bitpos */ |
167 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
168 |
NULL, /* special_function */ |
NULL, /* special_function */ |
169 |
"R_OR32_GNU_VTINHERIT", /* name */ |
"R_OR32_GNU_VTINHERIT", /* name */ |
170 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
171 |
0, /* src_mask */ |
0, /* src_mask */ |
172 |
0, /* dst_mask */ |
0, /* dst_mask */ |
173 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
174 |
|
|
175 |
/* GNU extension to record C++ vtable member usage. */ |
/* GNU extension to record C++ vtable member usage. */ |
176 |
HOWTO (R_OR32_GNU_VTENTRY, /* type */ |
HOWTO (R_OR32_GNU_VTENTRY, /* type */ |
177 |
0, /* rightshift */ |
0, /* rightshift */ |
178 |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
2, /* size (0 = byte, 1 = short, 2 = long) */ |
179 |
0, /* bitsize */ |
0, /* bitsize */ |
180 |
false, /* pc_relative */ |
FALSE, /* pc_relative */ |
181 |
0, /* bitpos */ |
0, /* bitpos */ |
182 |
complain_overflow_dont, /* complain_on_overflow */ |
complain_overflow_dont, /* complain_on_overflow */ |
183 |
_bfd_elf_rel_vtable_reloc_fn, /* special_function */ |
_bfd_elf_rel_vtable_reloc_fn, /* special_function */ |
184 |
"R_OR32_GNU_VTENTRY", /* name */ |
"R_OR32_GNU_VTENTRY", /* name */ |
185 |
false, /* partial_inplace */ |
FALSE, /* partial_inplace */ |
186 |
0, /* src_mask */ |
0, /* src_mask */ |
187 |
0, /* dst_mask */ |
0, /* dst_mask */ |
188 |
false), /* pcrel_offset */ |
FALSE), /* pcrel_offset */ |
189 |
}; |
}; |
190 |
|
|
191 |
/* Map BFD reloc types to OR32 ELF reloc types. */ |
/* Map BFD reloc types to OR32 ELF reloc types. */ |
231 |
or32_info_to_howto_rel (abfd, cache_ptr, dst) |
or32_info_to_howto_rel (abfd, cache_ptr, dst) |
232 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
233 |
arelent *cache_ptr; |
arelent *cache_ptr; |
234 |
Elf32_Internal_Rel *dst; |
Elf_Internal_Rela *dst; |
235 |
{ |
{ |
236 |
unsigned int r_type; |
unsigned int r_type; |
237 |
|
|
242 |
|
|
243 |
/* Set the right machine number for an OR32 ELF file. */ |
/* Set the right machine number for an OR32 ELF file. */ |
244 |
|
|
245 |
static boolean |
static bfd_boolean |
246 |
or32_elf_object_p (abfd) |
or32_elf_object_p (abfd) |
247 |
bfd *abfd; |
bfd *abfd; |
248 |
{ |
{ |
249 |
(void) bfd_default_set_arch_mach (abfd, bfd_arch_or32, 0); |
(void) bfd_default_set_arch_mach (abfd, bfd_arch_or32, 0); |
250 |
return true; |
return TRUE; |
251 |
} |
} |
252 |
|
|
253 |
/* The final processing done just before writing out an OR32 ELF object file. |
/* The final processing done just before writing out an OR32 ELF object file. |
256 |
static void |
static void |
257 |
or32_elf_final_write_processing (abfd, linker) |
or32_elf_final_write_processing (abfd, linker) |
258 |
bfd *abfd; |
bfd *abfd; |
259 |
boolean linker ATTRIBUTE_UNUSED; |
bfd_boolean linker ATTRIBUTE_UNUSED; |
260 |
{ |
{ |
261 |
int mach; |
int mach; |
262 |
unsigned long val; |
unsigned long val; |
417 |
relocation += symbol->section->output_offset; |
relocation += symbol->section->output_offset; |
418 |
relocation += reloc_entry->addend; |
relocation += reloc_entry->addend; |
419 |
|
|
420 |
if (reloc_entry->address > input_section->_cooked_size) |
if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) |
421 |
return bfd_reloc_outofrange; |
return bfd_reloc_outofrange; |
422 |
|
|
423 |
/* Save the information, and let LO16 do the actual relocation. */ |
/* Save the information, and let LO16 do the actual relocation. */ |