elf32-cr16.c revision 1.3 1 1.1 christos /* BFD back-end for National Semiconductor's CR16 ELF
2 1.3 christos Copyright (C) 2007-2015 Free Software Foundation, Inc.
3 1.1 christos Written by M R Swami Reddy.
4 1.1 christos
5 1.1 christos This file is part of BFD, the Binary File Descriptor library.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program; if not, write to the Free Software Foundation,
19 1.1 christos Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
20 1.1 christos
21 1.1 christos #include "sysdep.h"
22 1.1 christos #include "bfd.h"
23 1.1 christos #include "bfdlink.h"
24 1.1 christos #include "libbfd.h"
25 1.1 christos #include "libiberty.h"
26 1.1 christos #include "elf-bfd.h"
27 1.1 christos #include "elf/cr16.h"
28 1.1 christos
29 1.1 christos /* The cr16 linker needs to keep track of the number of relocs that
30 1.1 christos it decides to copy in check_relocs for each symbol. This is so
31 1.1 christos that it can discard PC relative relocs if it doesn't need them when
32 1.1 christos linking with -Bsymbolic. We store the information in a field
33 1.1 christos extending the regular ELF linker hash table. */
34 1.1 christos
35 1.1 christos struct elf32_cr16_link_hash_entry
36 1.1 christos {
37 1.1 christos /* The basic elf link hash table entry. */
38 1.1 christos struct elf_link_hash_entry root;
39 1.1 christos
40 1.1 christos /* For function symbols, the number of times this function is
41 1.1 christos called directly (ie by name). */
42 1.1 christos unsigned int direct_calls;
43 1.1 christos
44 1.1 christos /* For function symbols, the size of this function's stack
45 1.1 christos (if <= 255 bytes). We stuff this into "call" instructions
46 1.1 christos to this target when it's valid and profitable to do so.
47 1.1 christos
48 1.1 christos This does not include stack allocated by movm! */
49 1.1 christos unsigned char stack_size;
50 1.1 christos
51 1.1 christos /* For function symbols, arguments (if any) for movm instruction
52 1.1 christos in the prologue. We stuff this value into "call" instructions
53 1.1 christos to the target when it's valid and profitable to do so. */
54 1.1 christos unsigned char movm_args;
55 1.1 christos
56 1.1 christos /* For function symbols, the amount of stack space that would be allocated
57 1.1 christos by the movm instruction. This is redundant with movm_args, but we
58 1.1 christos add it to the hash table to avoid computing it over and over. */
59 1.1 christos unsigned char movm_stack_size;
60 1.1 christos
61 1.1 christos /* Used to mark functions which have had redundant parts of their
62 1.1 christos prologue deleted. */
63 1.1 christos #define CR16_DELETED_PROLOGUE_BYTES 0x1
64 1.1 christos unsigned char flags;
65 1.1 christos
66 1.1 christos /* Calculated value. */
67 1.1 christos bfd_vma value;
68 1.1 christos };
69 1.1 christos
70 1.1 christos /* cr16_reloc_map array maps BFD relocation enum into a CRGAS relocation type. */
71 1.1 christos
72 1.1 christos struct cr16_reloc_map
73 1.1 christos {
74 1.1 christos bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum. */
75 1.1 christos unsigned short cr16_reloc_type; /* CR16 relocation type. */
76 1.1 christos };
77 1.1 christos
78 1.1 christos static const struct cr16_reloc_map cr16_reloc_map[R_CR16_MAX] =
79 1.1 christos {
80 1.1 christos {BFD_RELOC_NONE, R_CR16_NONE},
81 1.1 christos {BFD_RELOC_CR16_NUM8, R_CR16_NUM8},
82 1.1 christos {BFD_RELOC_CR16_NUM16, R_CR16_NUM16},
83 1.1 christos {BFD_RELOC_CR16_NUM32, R_CR16_NUM32},
84 1.1 christos {BFD_RELOC_CR16_NUM32a, R_CR16_NUM32a},
85 1.1 christos {BFD_RELOC_CR16_REGREL4, R_CR16_REGREL4},
86 1.1 christos {BFD_RELOC_CR16_REGREL4a, R_CR16_REGREL4a},
87 1.1 christos {BFD_RELOC_CR16_REGREL14, R_CR16_REGREL14},
88 1.1 christos {BFD_RELOC_CR16_REGREL14a, R_CR16_REGREL14a},
89 1.1 christos {BFD_RELOC_CR16_REGREL16, R_CR16_REGREL16},
90 1.1 christos {BFD_RELOC_CR16_REGREL20, R_CR16_REGREL20},
91 1.1 christos {BFD_RELOC_CR16_REGREL20a, R_CR16_REGREL20a},
92 1.1 christos {BFD_RELOC_CR16_ABS20, R_CR16_ABS20},
93 1.1 christos {BFD_RELOC_CR16_ABS24, R_CR16_ABS24},
94 1.1 christos {BFD_RELOC_CR16_IMM4, R_CR16_IMM4},
95 1.1 christos {BFD_RELOC_CR16_IMM8, R_CR16_IMM8},
96 1.1 christos {BFD_RELOC_CR16_IMM16, R_CR16_IMM16},
97 1.1 christos {BFD_RELOC_CR16_IMM20, R_CR16_IMM20},
98 1.1 christos {BFD_RELOC_CR16_IMM24, R_CR16_IMM24},
99 1.1 christos {BFD_RELOC_CR16_IMM32, R_CR16_IMM32},
100 1.1 christos {BFD_RELOC_CR16_IMM32a, R_CR16_IMM32a},
101 1.1 christos {BFD_RELOC_CR16_DISP4, R_CR16_DISP4},
102 1.1 christos {BFD_RELOC_CR16_DISP8, R_CR16_DISP8},
103 1.1 christos {BFD_RELOC_CR16_DISP16, R_CR16_DISP16},
104 1.1 christos {BFD_RELOC_CR16_DISP24, R_CR16_DISP24},
105 1.1 christos {BFD_RELOC_CR16_DISP24a, R_CR16_DISP24a},
106 1.1 christos {BFD_RELOC_CR16_SWITCH8, R_CR16_SWITCH8},
107 1.1 christos {BFD_RELOC_CR16_SWITCH16, R_CR16_SWITCH16},
108 1.1 christos {BFD_RELOC_CR16_SWITCH32, R_CR16_SWITCH32},
109 1.1 christos {BFD_RELOC_CR16_GOT_REGREL20, R_CR16_GOT_REGREL20},
110 1.1 christos {BFD_RELOC_CR16_GOTC_REGREL20, R_CR16_GOTC_REGREL20},
111 1.1 christos {BFD_RELOC_CR16_GLOB_DAT, R_CR16_GLOB_DAT}
112 1.1 christos };
113 1.1 christos
114 1.1 christos static reloc_howto_type cr16_elf_howto_table[] =
115 1.1 christos {
116 1.1 christos HOWTO (R_CR16_NONE, /* type */
117 1.1 christos 0, /* rightshift */
118 1.3 christos 3, /* size */
119 1.3 christos 0, /* bitsize */
120 1.1 christos FALSE, /* pc_relative */
121 1.1 christos 0, /* bitpos */
122 1.1 christos complain_overflow_dont, /* complain_on_overflow */
123 1.1 christos bfd_elf_generic_reloc, /* special_function */
124 1.1 christos "R_CR16_NONE", /* name */
125 1.1 christos FALSE, /* partial_inplace */
126 1.1 christos 0, /* src_mask */
127 1.1 christos 0, /* dst_mask */
128 1.1 christos FALSE), /* pcrel_offset */
129 1.1 christos
130 1.1 christos HOWTO (R_CR16_NUM8, /* type */
131 1.1 christos 0, /* rightshift */
132 1.1 christos 0, /* size */
133 1.1 christos 8, /* bitsize */
134 1.1 christos FALSE, /* pc_relative */
135 1.1 christos 0, /* bitpos */
136 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
137 1.1 christos bfd_elf_generic_reloc, /* special_function */
138 1.1 christos "R_CR16_NUM8", /* name */
139 1.1 christos FALSE, /* partial_inplace */
140 1.1 christos 0x0, /* src_mask */
141 1.1 christos 0xff, /* dst_mask */
142 1.1 christos FALSE), /* pcrel_offset */
143 1.1 christos
144 1.1 christos HOWTO (R_CR16_NUM16, /* type */
145 1.1 christos 0, /* rightshift */
146 1.1 christos 1, /* size */
147 1.1 christos 16, /* bitsize */
148 1.1 christos FALSE, /* pc_relative */
149 1.1 christos 0, /* bitpos */
150 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
151 1.1 christos bfd_elf_generic_reloc, /* special_function */
152 1.1 christos "R_CR16_NUM16", /* name */
153 1.1 christos FALSE, /* partial_inplace */
154 1.1 christos 0x0, /* src_mask */
155 1.1 christos 0xffff, /* dst_mask */
156 1.1 christos FALSE), /* pcrel_offset */
157 1.1 christos
158 1.1 christos HOWTO (R_CR16_NUM32, /* type */
159 1.1 christos 0, /* rightshift */
160 1.1 christos 2, /* size */
161 1.1 christos 32, /* bitsize */
162 1.1 christos FALSE, /* pc_relative */
163 1.1 christos 0, /* bitpos */
164 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
165 1.1 christos bfd_elf_generic_reloc, /* special_function */
166 1.1 christos "R_CR16_NUM32", /* name */
167 1.1 christos FALSE, /* partial_inplace */
168 1.1 christos 0x0, /* src_mask */
169 1.1 christos 0xffffffff, /* dst_mask */
170 1.1 christos FALSE), /* pcrel_offset */
171 1.1 christos
172 1.1 christos HOWTO (R_CR16_NUM32a, /* type */
173 1.1 christos 1, /* rightshift */
174 1.1 christos 2, /* size */
175 1.1 christos 32, /* bitsize */
176 1.1 christos FALSE, /* pc_relative */
177 1.1 christos 0, /* bitpos */
178 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
179 1.1 christos bfd_elf_generic_reloc, /* special_function */
180 1.1 christos "R_CR16_NUM32a", /* name */
181 1.1 christos FALSE, /* partial_inplace */
182 1.1 christos 0x0, /* src_mask */
183 1.1 christos 0xffffffff, /* dst_mask */
184 1.1 christos FALSE), /* pcrel_offset */
185 1.1 christos
186 1.1 christos HOWTO (R_CR16_REGREL4, /* type */
187 1.1 christos 0, /* rightshift */
188 1.1 christos 0, /* size */
189 1.1 christos 4, /* bitsize */
190 1.1 christos FALSE, /* pc_relative */
191 1.1 christos 0, /* bitpos */
192 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
193 1.1 christos bfd_elf_generic_reloc, /* special_function */
194 1.1 christos "R_CR16_REGREL4", /* name */
195 1.1 christos FALSE, /* partial_inplace */
196 1.1 christos 0x0, /* src_mask */
197 1.1 christos 0xf, /* dst_mask */
198 1.1 christos FALSE), /* pcrel_offset */
199 1.1 christos
200 1.1 christos HOWTO (R_CR16_REGREL4a, /* type */
201 1.1 christos 0, /* rightshift */
202 1.1 christos 0, /* size */
203 1.1 christos 4, /* bitsize */
204 1.1 christos FALSE, /* pc_relative */
205 1.1 christos 0, /* bitpos */
206 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
207 1.1 christos bfd_elf_generic_reloc, /* special_function */
208 1.1 christos "R_CR16_REGREL4a", /* name */
209 1.1 christos FALSE, /* partial_inplace */
210 1.1 christos 0x0, /* src_mask */
211 1.1 christos 0xf, /* dst_mask */
212 1.1 christos FALSE), /* pcrel_offset */
213 1.1 christos
214 1.1 christos HOWTO (R_CR16_REGREL14, /* type */
215 1.1 christos 0, /* rightshift */
216 1.1 christos 1, /* size */
217 1.1 christos 14, /* bitsize */
218 1.1 christos FALSE, /* pc_relative */
219 1.1 christos 0, /* bitpos */
220 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
221 1.1 christos bfd_elf_generic_reloc, /* special_function */
222 1.1 christos "R_CR16_REGREL14", /* name */
223 1.1 christos FALSE, /* partial_inplace */
224 1.1 christos 0x0, /* src_mask */
225 1.1 christos 0x3fff, /* dst_mask */
226 1.1 christos FALSE), /* pcrel_offset */
227 1.1 christos
228 1.1 christos HOWTO (R_CR16_REGREL14a, /* type */
229 1.1 christos 0, /* rightshift */
230 1.1 christos 1, /* size */
231 1.1 christos 14, /* bitsize */
232 1.1 christos FALSE, /* pc_relative */
233 1.1 christos 0, /* bitpos */
234 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
235 1.1 christos bfd_elf_generic_reloc, /* special_function */
236 1.1 christos "R_CR16_REGREL14a", /* name */
237 1.1 christos FALSE, /* partial_inplace */
238 1.1 christos 0x0, /* src_mask */
239 1.1 christos 0x3fff, /* dst_mask */
240 1.1 christos FALSE), /* pcrel_offset */
241 1.1 christos
242 1.1 christos HOWTO (R_CR16_REGREL16, /* type */
243 1.1 christos 0, /* rightshift */
244 1.1 christos 1, /* size */
245 1.1 christos 16, /* bitsize */
246 1.1 christos FALSE, /* pc_relative */
247 1.1 christos 0, /* bitpos */
248 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
249 1.1 christos bfd_elf_generic_reloc, /* special_function */
250 1.1 christos "R_CR16_REGREL16", /* name */
251 1.1 christos FALSE, /* partial_inplace */
252 1.1 christos 0x0, /* src_mask */
253 1.1 christos 0xffff, /* dst_mask */
254 1.1 christos FALSE), /* pcrel_offset */
255 1.1 christos
256 1.1 christos HOWTO (R_CR16_REGREL20, /* type */
257 1.1 christos 0, /* rightshift */
258 1.1 christos 2, /* size */
259 1.1 christos 20, /* bitsize */
260 1.1 christos FALSE, /* pc_relative */
261 1.1 christos 0, /* bitpos */
262 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
263 1.1 christos bfd_elf_generic_reloc, /* special_function */
264 1.1 christos "R_CR16_REGREL20", /* name */
265 1.1 christos FALSE, /* partial_inplace */
266 1.1 christos 0x0, /* src_mask */
267 1.1 christos 0xfffff, /* dst_mask */
268 1.1 christos FALSE), /* pcrel_offset */
269 1.1 christos
270 1.1 christos HOWTO (R_CR16_REGREL20a, /* type */
271 1.1 christos 0, /* rightshift */
272 1.1 christos 2, /* size */
273 1.1 christos 20, /* bitsize */
274 1.1 christos FALSE, /* pc_relative */
275 1.1 christos 0, /* bitpos */
276 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
277 1.1 christos bfd_elf_generic_reloc, /* special_function */
278 1.1 christos "R_CR16_REGREL20a", /* name */
279 1.1 christos FALSE, /* partial_inplace */
280 1.1 christos 0x0, /* src_mask */
281 1.1 christos 0xfffff, /* dst_mask */
282 1.1 christos FALSE), /* pcrel_offset */
283 1.1 christos
284 1.1 christos HOWTO (R_CR16_ABS20, /* type */
285 1.1 christos 0, /* rightshift */
286 1.1 christos 2, /* size */
287 1.1 christos 20, /* bitsize */
288 1.1 christos FALSE, /* pc_relative */
289 1.1 christos 0, /* bitpos */
290 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
291 1.1 christos bfd_elf_generic_reloc, /* special_function */
292 1.1 christos "R_CR16_ABS20", /* name */
293 1.1 christos FALSE, /* partial_inplace */
294 1.1 christos 0x0, /* src_mask */
295 1.1 christos 0xfffff, /* dst_mask */
296 1.1 christos FALSE), /* pcrel_offset */
297 1.1 christos
298 1.1 christos HOWTO (R_CR16_ABS24, /* type */
299 1.1 christos 0, /* rightshift */
300 1.1 christos 2, /* size */
301 1.1 christos 24, /* bitsize */
302 1.1 christos FALSE, /* pc_relative */
303 1.1 christos 0, /* bitpos */
304 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
305 1.1 christos bfd_elf_generic_reloc, /* special_function */
306 1.1 christos "R_CR16_ABS24", /* name */
307 1.1 christos FALSE, /* partial_inplace */
308 1.1 christos 0x0, /* src_mask */
309 1.1 christos 0xffffff, /* dst_mask */
310 1.1 christos FALSE), /* pcrel_offset */
311 1.1 christos
312 1.1 christos HOWTO (R_CR16_IMM4, /* type */
313 1.1 christos 0, /* rightshift */
314 1.1 christos 0, /* size */
315 1.1 christos 4, /* bitsize */
316 1.1 christos FALSE, /* pc_relative */
317 1.1 christos 0, /* bitpos */
318 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
319 1.1 christos bfd_elf_generic_reloc, /* special_function */
320 1.1 christos "R_CR16_IMM4", /* name */
321 1.1 christos FALSE, /* partial_inplace */
322 1.1 christos 0x0, /* src_mask */
323 1.1 christos 0xf, /* dst_mask */
324 1.1 christos FALSE), /* pcrel_offset */
325 1.1 christos
326 1.1 christos HOWTO (R_CR16_IMM8, /* type */
327 1.1 christos 0, /* rightshift */
328 1.1 christos 0, /* size */
329 1.1 christos 8, /* bitsize */
330 1.1 christos FALSE, /* pc_relative */
331 1.1 christos 0, /* bitpos */
332 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
333 1.1 christos bfd_elf_generic_reloc, /* special_function */
334 1.1 christos "R_CR16_IMM8", /* name */
335 1.1 christos FALSE, /* partial_inplace */
336 1.1 christos 0x0, /* src_mask */
337 1.1 christos 0xff, /* dst_mask */
338 1.1 christos FALSE), /* pcrel_offset */
339 1.1 christos
340 1.1 christos HOWTO (R_CR16_IMM16, /* type */
341 1.1 christos 0, /* rightshift */
342 1.1 christos 1, /* size */
343 1.1 christos 16, /* bitsize */
344 1.1 christos FALSE, /* pc_relative */
345 1.1 christos 0, /* bitpos */
346 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
347 1.1 christos bfd_elf_generic_reloc, /* special_function */
348 1.1 christos "R_CR16_IMM16", /* name */
349 1.1 christos FALSE, /* partial_inplace */
350 1.1 christos 0x0, /* src_mask */
351 1.1 christos 0xffff, /* dst_mask */
352 1.1 christos FALSE), /* pcrel_offset */
353 1.1 christos
354 1.1 christos HOWTO (R_CR16_IMM20, /* type */
355 1.1 christos 0, /* rightshift */
356 1.1 christos 2, /* size */
357 1.1 christos 20, /* bitsize */
358 1.1 christos FALSE, /* pc_relative */
359 1.1 christos 0, /* bitpos */
360 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
361 1.1 christos bfd_elf_generic_reloc, /* special_function */
362 1.1 christos "R_CR16_IMM20", /* name */
363 1.1 christos FALSE, /* partial_inplace */
364 1.1 christos 0x0, /* src_mask */
365 1.1 christos 0xfffff, /* dst_mask */
366 1.1 christos FALSE), /* pcrel_offset */
367 1.1 christos
368 1.1 christos HOWTO (R_CR16_IMM24, /* type */
369 1.1 christos 0, /* rightshift */
370 1.1 christos 2, /* size */
371 1.1 christos 24, /* bitsize */
372 1.1 christos FALSE, /* pc_relative */
373 1.1 christos 0, /* bitpos */
374 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
375 1.1 christos bfd_elf_generic_reloc, /* special_function */
376 1.1 christos "R_CR16_IMM24", /* name */
377 1.1 christos FALSE, /* partial_inplace */
378 1.1 christos 0x0, /* src_mask */
379 1.1 christos 0xffffff, /* dst_mask */
380 1.1 christos FALSE), /* pcrel_offset */
381 1.1 christos
382 1.1 christos HOWTO (R_CR16_IMM32, /* type */
383 1.1 christos 0, /* rightshift */
384 1.1 christos 2, /* size */
385 1.1 christos 32, /* bitsize */
386 1.1 christos FALSE, /* pc_relative */
387 1.1 christos 0, /* bitpos */
388 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
389 1.1 christos bfd_elf_generic_reloc, /* special_function */
390 1.1 christos "R_CR16_IMM32", /* name */
391 1.1 christos FALSE, /* partial_inplace */
392 1.1 christos 0x0, /* src_mask */
393 1.1 christos 0xffffffff, /* dst_mask */
394 1.1 christos FALSE), /* pcrel_offset */
395 1.1 christos
396 1.1 christos HOWTO (R_CR16_IMM32a, /* type */
397 1.1 christos 1, /* rightshift */
398 1.1 christos 2, /* size */
399 1.1 christos 32, /* bitsize */
400 1.1 christos FALSE, /* pc_relative */
401 1.1 christos 0, /* bitpos */
402 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
403 1.1 christos bfd_elf_generic_reloc, /* special_function */
404 1.1 christos "R_CR16_IMM32a", /* name */
405 1.1 christos FALSE, /* partial_inplace */
406 1.1 christos 0x0, /* src_mask */
407 1.1 christos 0xffffffff, /* dst_mask */
408 1.1 christos FALSE), /* pcrel_offset */
409 1.1 christos
410 1.1 christos HOWTO (R_CR16_DISP4, /* type */
411 1.1 christos 1, /* rightshift */
412 1.1 christos 0, /* size (0 = byte, 1 = short, 2 = long) */
413 1.1 christos 4, /* bitsize */
414 1.1 christos TRUE, /* pc_relative */
415 1.1 christos 0, /* bitpos */
416 1.1 christos complain_overflow_unsigned, /* complain_on_overflow */
417 1.1 christos bfd_elf_generic_reloc, /* special_function */
418 1.1 christos "R_CR16_DISP4", /* name */
419 1.1 christos FALSE, /* partial_inplace */
420 1.1 christos 0x0, /* src_mask */
421 1.1 christos 0xf, /* dst_mask */
422 1.1 christos FALSE), /* pcrel_offset */
423 1.1 christos
424 1.1 christos HOWTO (R_CR16_DISP8, /* type */
425 1.1 christos 1, /* rightshift */
426 1.1 christos 0, /* size (0 = byte, 1 = short, 2 = long) */
427 1.1 christos 8, /* bitsize */
428 1.1 christos TRUE, /* pc_relative */
429 1.1 christos 0, /* bitpos */
430 1.1 christos complain_overflow_unsigned, /* complain_on_overflow */
431 1.1 christos bfd_elf_generic_reloc, /* special_function */
432 1.1 christos "R_CR16_DISP8", /* name */
433 1.1 christos FALSE, /* partial_inplace */
434 1.1 christos 0x0, /* src_mask */
435 1.1 christos 0x1ff, /* dst_mask */
436 1.1 christos FALSE), /* pcrel_offset */
437 1.1 christos
438 1.1 christos HOWTO (R_CR16_DISP16, /* type */
439 1.1 christos 0, /* rightshift REVIITS: To sync with WinIDEA*/
440 1.1 christos 1, /* size (0 = byte, 1 = short, 2 = long) */
441 1.1 christos 16, /* bitsize */
442 1.1 christos TRUE, /* pc_relative */
443 1.1 christos 0, /* bitpos */
444 1.1 christos complain_overflow_unsigned, /* complain_on_overflow */
445 1.1 christos bfd_elf_generic_reloc, /* special_function */
446 1.1 christos "R_CR16_DISP16", /* name */
447 1.1 christos FALSE, /* partial_inplace */
448 1.1 christos 0x0, /* src_mask */
449 1.1 christos 0x1ffff, /* dst_mask */
450 1.1 christos FALSE), /* pcrel_offset */
451 1.1 christos /* REVISIT: DISP24 should be left-shift by 2 as per ISA doc
452 1.1 christos but its not done, to sync with WinIDEA and CR16 4.1 tools */
453 1.1 christos HOWTO (R_CR16_DISP24, /* type */
454 1.1 christos 0, /* rightshift */
455 1.1 christos 2, /* size (0 = byte, 1 = short, 2 = long) */
456 1.1 christos 24, /* bitsize */
457 1.1 christos TRUE, /* pc_relative */
458 1.1 christos 0, /* bitpos */
459 1.1 christos complain_overflow_unsigned, /* complain_on_overflow */
460 1.1 christos bfd_elf_generic_reloc, /* special_function */
461 1.1 christos "R_CR16_DISP24", /* name */
462 1.1 christos FALSE, /* partial_inplace */
463 1.1 christos 0x0, /* src_mask */
464 1.1 christos 0x1ffffff, /* dst_mask */
465 1.1 christos FALSE), /* pcrel_offset */
466 1.1 christos
467 1.1 christos HOWTO (R_CR16_DISP24a, /* type */
468 1.1 christos 0, /* rightshift */
469 1.1 christos 2, /* size (0 = byte, 1 = short, 2 = long) */
470 1.1 christos 24, /* bitsize */
471 1.1 christos TRUE, /* pc_relative */
472 1.1 christos 0, /* bitpos */
473 1.1 christos complain_overflow_unsigned, /* complain_on_overflow */
474 1.1 christos bfd_elf_generic_reloc, /* special_function */
475 1.1 christos "R_CR16_DISP24a", /* name */
476 1.1 christos FALSE, /* partial_inplace */
477 1.1 christos 0x0, /* src_mask */
478 1.1 christos 0xffffff, /* dst_mask */
479 1.1 christos FALSE), /* pcrel_offset */
480 1.1 christos
481 1.1 christos /* An 8 bit switch table entry. This is generated for an expression
482 1.1 christos such as ``.byte L1 - L2''. The offset holds the difference
483 1.1 christos between the reloc address and L2. */
484 1.1 christos HOWTO (R_CR16_SWITCH8, /* type */
485 1.1 christos 0, /* rightshift */
486 1.1 christos 0, /* size (0 = byte, 1 = short, 2 = long) */
487 1.1 christos 8, /* bitsize */
488 1.1 christos FALSE, /* pc_relative */
489 1.1 christos 0, /* bitpos */
490 1.1 christos complain_overflow_unsigned, /* complain_on_overflow */
491 1.1 christos bfd_elf_generic_reloc, /* special_function */
492 1.1 christos "R_CR16_SWITCH8", /* name */
493 1.1 christos FALSE, /* partial_inplace */
494 1.1 christos 0x0, /* src_mask */
495 1.1 christos 0xff, /* dst_mask */
496 1.1 christos TRUE), /* pcrel_offset */
497 1.1 christos
498 1.1 christos /* A 16 bit switch table entry. This is generated for an expression
499 1.1 christos such as ``.word L1 - L2''. The offset holds the difference
500 1.1 christos between the reloc address and L2. */
501 1.1 christos HOWTO (R_CR16_SWITCH16, /* type */
502 1.1 christos 0, /* rightshift */
503 1.1 christos 1, /* size (0 = byte, 1 = short, 2 = long) */
504 1.1 christos 16, /* bitsize */
505 1.1 christos FALSE, /* pc_relative */
506 1.1 christos 0, /* bitpos */
507 1.1 christos complain_overflow_unsigned, /* complain_on_overflow */
508 1.1 christos bfd_elf_generic_reloc, /* special_function */
509 1.1 christos "R_CR16_SWITCH16", /* name */
510 1.1 christos FALSE, /* partial_inplace */
511 1.1 christos 0x0, /* src_mask */
512 1.1 christos 0xffff, /* dst_mask */
513 1.1 christos TRUE), /* pcrel_offset */
514 1.1 christos
515 1.1 christos /* A 32 bit switch table entry. This is generated for an expression
516 1.1 christos such as ``.long L1 - L2''. The offset holds the difference
517 1.1 christos between the reloc address and L2. */
518 1.1 christos HOWTO (R_CR16_SWITCH32, /* type */
519 1.1 christos 0, /* rightshift */
520 1.1 christos 2, /* size (0 = byte, 1 = short, 2 = long) */
521 1.1 christos 32, /* bitsize */
522 1.1 christos FALSE, /* pc_relative */
523 1.1 christos 0, /* bitpos */
524 1.1 christos complain_overflow_unsigned, /* complain_on_overflow */
525 1.1 christos bfd_elf_generic_reloc, /* special_function */
526 1.1 christos "R_CR16_SWITCH32", /* name */
527 1.1 christos FALSE, /* partial_inplace */
528 1.1 christos 0x0, /* src_mask */
529 1.1 christos 0xffffffff, /* dst_mask */
530 1.1 christos TRUE), /* pcrel_offset */
531 1.1 christos
532 1.1 christos HOWTO (R_CR16_GOT_REGREL20, /* type */
533 1.1 christos 0, /* rightshift */
534 1.1 christos 2, /* size */
535 1.1 christos 20, /* bitsize */
536 1.1 christos FALSE, /* pc_relative */
537 1.1 christos 0, /* bitpos */
538 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
539 1.1 christos bfd_elf_generic_reloc, /* special_function */
540 1.1 christos "R_CR16_GOT_REGREL20", /* name */
541 1.1 christos TRUE, /* partial_inplace */
542 1.1 christos 0x0, /* src_mask */
543 1.1 christos 0xfffff, /* dst_mask */
544 1.1 christos FALSE), /* pcrel_offset */
545 1.1 christos
546 1.1 christos HOWTO (R_CR16_GOTC_REGREL20, /* type */
547 1.1 christos 0, /* rightshift */
548 1.1 christos 2, /* size */
549 1.1 christos 20, /* bitsize */
550 1.1 christos FALSE, /* pc_relative */
551 1.1 christos 0, /* bitpos */
552 1.1 christos complain_overflow_bitfield,/* complain_on_overflow */
553 1.1 christos bfd_elf_generic_reloc, /* special_function */
554 1.1 christos "R_CR16_GOTC_REGREL20", /* name */
555 1.1 christos TRUE, /* partial_inplace */
556 1.1 christos 0x0, /* src_mask */
557 1.1 christos 0xfffff, /* dst_mask */
558 1.1 christos FALSE), /* pcrel_offset */
559 1.1 christos
560 1.1 christos HOWTO (R_CR16_GLOB_DAT, /* type */
561 1.1 christos 0, /* rightshift */
562 1.1 christos 2, /* size (0 = byte, 1 = short, 2 = long) */
563 1.1 christos 32, /* bitsize */
564 1.1 christos FALSE, /* pc_relative */
565 1.1 christos 0, /* bitpos */
566 1.1 christos complain_overflow_unsigned, /* complain_on_overflow */
567 1.1 christos bfd_elf_generic_reloc, /* special_function */
568 1.1 christos "R_CR16_GLOB_DAT", /* name */
569 1.1 christos FALSE, /* partial_inplace */
570 1.1 christos 0x0, /* src_mask */
571 1.1 christos 0xffffffff, /* dst_mask */
572 1.1 christos TRUE) /* pcrel_offset */
573 1.1 christos };
574 1.1 christos
575 1.1 christos
576 1.1 christos /* Create the GOT section. */
577 1.1 christos
578 1.1 christos static bfd_boolean
579 1.1 christos _bfd_cr16_elf_create_got_section (bfd * abfd, struct bfd_link_info * info)
580 1.1 christos {
581 1.1 christos flagword flags;
582 1.1 christos asection * s;
583 1.1 christos struct elf_link_hash_entry * h;
584 1.1 christos const struct elf_backend_data * bed = get_elf_backend_data (abfd);
585 1.1 christos int ptralign;
586 1.1 christos
587 1.1 christos /* This function may be called more than once. */
588 1.1 christos if (bfd_get_linker_section (abfd, ".got") != NULL)
589 1.1 christos return TRUE;
590 1.1 christos
591 1.1 christos switch (bed->s->arch_size)
592 1.1 christos {
593 1.1 christos case 16:
594 1.1 christos ptralign = 1;
595 1.1 christos break;
596 1.1 christos
597 1.1 christos case 32:
598 1.1 christos ptralign = 2;
599 1.1 christos break;
600 1.1 christos
601 1.1 christos default:
602 1.1 christos bfd_set_error (bfd_error_bad_value);
603 1.1 christos return FALSE;
604 1.1 christos }
605 1.1 christos
606 1.1 christos flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
607 1.1 christos | SEC_LINKER_CREATED);
608 1.1 christos
609 1.1 christos s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
610 1.1 christos if (s == NULL
611 1.1 christos || ! bfd_set_section_alignment (abfd, s, ptralign))
612 1.1 christos return FALSE;
613 1.1 christos
614 1.1 christos if (bed->want_got_plt)
615 1.1 christos {
616 1.1 christos s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
617 1.1 christos if (s == NULL
618 1.1 christos || ! bfd_set_section_alignment (abfd, s, ptralign))
619 1.1 christos return FALSE;
620 1.1 christos }
621 1.1 christos
622 1.1 christos /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
623 1.1 christos (or .got.plt) section. We don't do this in the linker script
624 1.1 christos because we don't want to define the symbol if we are not creating
625 1.1 christos a global offset table. */
626 1.1 christos h = _bfd_elf_define_linkage_sym (abfd, info, s, "_GLOBAL_OFFSET_TABLE_");
627 1.1 christos elf_hash_table (info)->hgot = h;
628 1.1 christos if (h == NULL)
629 1.1 christos return FALSE;
630 1.1 christos
631 1.1 christos /* The first bit of the global offset table is the header. */
632 1.1 christos s->size += bed->got_header_size;
633 1.1 christos
634 1.1 christos return TRUE;
635 1.1 christos }
636 1.1 christos
637 1.1 christos
638 1.1 christos /* Retrieve a howto ptr using a BFD reloc_code. */
639 1.1 christos
640 1.1 christos static reloc_howto_type *
641 1.1 christos elf_cr16_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
642 1.1 christos bfd_reloc_code_real_type code)
643 1.1 christos {
644 1.1 christos unsigned int i;
645 1.1 christos
646 1.1 christos for (i = 0; i < R_CR16_MAX; i++)
647 1.1 christos if (code == cr16_reloc_map[i].bfd_reloc_enum)
648 1.1 christos return &cr16_elf_howto_table[cr16_reloc_map[i].cr16_reloc_type];
649 1.1 christos
650 1.1 christos _bfd_error_handler ("Unsupported CR16 relocation type: 0x%x\n", code);
651 1.1 christos return NULL;
652 1.1 christos }
653 1.1 christos
654 1.1 christos static reloc_howto_type *
655 1.1 christos elf_cr16_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
656 1.1 christos const char *r_name)
657 1.1 christos {
658 1.1 christos unsigned int i;
659 1.1 christos
660 1.1 christos for (i = 0; ARRAY_SIZE (cr16_elf_howto_table); i++)
661 1.1 christos if (cr16_elf_howto_table[i].name != NULL
662 1.1 christos && strcasecmp (cr16_elf_howto_table[i].name, r_name) == 0)
663 1.1 christos return cr16_elf_howto_table + i;
664 1.1 christos
665 1.1 christos return NULL;
666 1.1 christos }
667 1.1 christos
668 1.1 christos /* Retrieve a howto ptr using an internal relocation entry. */
669 1.1 christos
670 1.1 christos static void
671 1.1 christos elf_cr16_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
672 1.1 christos Elf_Internal_Rela *dst)
673 1.1 christos {
674 1.1 christos unsigned int r_type = ELF32_R_TYPE (dst->r_info);
675 1.1 christos
676 1.3 christos if (r_type >= R_CR16_MAX)
677 1.3 christos {
678 1.3 christos (*_bfd_error_handler) (_("%B: unrecognised CR16 reloc number: %d"),
679 1.3 christos abfd, r_type);
680 1.3 christos bfd_set_error (bfd_error_bad_value);
681 1.3 christos r_type = R_CR16_NONE;
682 1.3 christos }
683 1.1 christos cache_ptr->howto = cr16_elf_howto_table + r_type;
684 1.1 christos }
685 1.1 christos
686 1.1 christos /* Look through the relocs for a section during the first phase.
687 1.1 christos Since we don't do .gots or .plts, we just need to consider the
688 1.1 christos virtual table relocs for gc. */
689 1.1 christos
690 1.1 christos static bfd_boolean
691 1.1 christos cr16_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
692 1.1 christos const Elf_Internal_Rela *relocs)
693 1.1 christos {
694 1.1 christos Elf_Internal_Shdr *symtab_hdr;
695 1.1 christos Elf_Internal_Sym * isymbuf = NULL;
696 1.1 christos struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
697 1.1 christos const Elf_Internal_Rela *rel;
698 1.1 christos const Elf_Internal_Rela *rel_end;
699 1.1 christos bfd * dynobj;
700 1.1 christos bfd_vma * local_got_offsets;
701 1.1 christos asection * sgot;
702 1.1 christos asection * srelgot;
703 1.1 christos
704 1.1 christos sgot = NULL;
705 1.1 christos srelgot = NULL;
706 1.1 christos bfd_boolean result = FALSE;
707 1.1 christos
708 1.3 christos if (bfd_link_relocatable (info))
709 1.1 christos return TRUE;
710 1.1 christos
711 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
712 1.1 christos sym_hashes = elf_sym_hashes (abfd);
713 1.1 christos sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
714 1.1 christos if (!elf_bad_symtab (abfd))
715 1.1 christos sym_hashes_end -= symtab_hdr->sh_info;
716 1.1 christos
717 1.1 christos dynobj = elf_hash_table (info)->dynobj;
718 1.1 christos local_got_offsets = elf_local_got_offsets (abfd);
719 1.1 christos rel_end = relocs + sec->reloc_count;
720 1.1 christos for (rel = relocs; rel < rel_end; rel++)
721 1.1 christos {
722 1.1 christos struct elf_link_hash_entry *h;
723 1.1 christos unsigned long r_symndx;
724 1.1 christos
725 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info);
726 1.1 christos if (r_symndx < symtab_hdr->sh_info)
727 1.1 christos h = NULL;
728 1.1 christos else
729 1.1 christos {
730 1.1 christos h = sym_hashes[r_symndx - symtab_hdr->sh_info];
731 1.1 christos while (h->root.type == bfd_link_hash_indirect
732 1.1 christos || h->root.type == bfd_link_hash_warning)
733 1.1 christos h = (struct elf_link_hash_entry *) h->root.u.i.link;
734 1.3 christos
735 1.3 christos /* PR15323, ref flags aren't set for references in the same
736 1.3 christos object. */
737 1.3 christos h->root.non_ir_ref = 1;
738 1.1 christos }
739 1.1 christos
740 1.1 christos /* Some relocs require a global offset table. */
741 1.1 christos if (dynobj == NULL)
742 1.1 christos {
743 1.1 christos switch (ELF32_R_TYPE (rel->r_info))
744 1.1 christos {
745 1.1 christos case R_CR16_GOT_REGREL20:
746 1.1 christos case R_CR16_GOTC_REGREL20:
747 1.1 christos elf_hash_table (info)->dynobj = dynobj = abfd;
748 1.1 christos if (! _bfd_cr16_elf_create_got_section (dynobj, info))
749 1.1 christos goto fail;
750 1.1 christos break;
751 1.1 christos
752 1.1 christos default:
753 1.1 christos break;
754 1.1 christos }
755 1.1 christos }
756 1.1 christos
757 1.1 christos switch (ELF32_R_TYPE (rel->r_info))
758 1.1 christos {
759 1.1 christos case R_CR16_GOT_REGREL20:
760 1.1 christos case R_CR16_GOTC_REGREL20:
761 1.1 christos /* This symbol requires a global offset table entry. */
762 1.1 christos
763 1.1 christos if (sgot == NULL)
764 1.1 christos {
765 1.1 christos sgot = bfd_get_linker_section (dynobj, ".got");
766 1.1 christos BFD_ASSERT (sgot != NULL);
767 1.1 christos }
768 1.1 christos
769 1.1 christos if (srelgot == NULL
770 1.3 christos && (h != NULL || bfd_link_executable (info)))
771 1.1 christos {
772 1.1 christos srelgot = bfd_get_linker_section (dynobj, ".rela.got");
773 1.1 christos if (srelgot == NULL)
774 1.3 christos {
775 1.1 christos flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
776 1.1 christos | SEC_IN_MEMORY | SEC_LINKER_CREATED
777 1.1 christos | SEC_READONLY);
778 1.1 christos srelgot = bfd_make_section_anyway_with_flags (dynobj,
779 1.1 christos ".rela.got",
780 1.1 christos flags);
781 1.1 christos if (srelgot == NULL
782 1.1 christos || ! bfd_set_section_alignment (dynobj, srelgot, 2))
783 1.1 christos goto fail;
784 1.1 christos }
785 1.1 christos }
786 1.1 christos
787 1.1 christos if (h != NULL)
788 1.1 christos {
789 1.1 christos if (h->got.offset != (bfd_vma) -1)
790 1.1 christos /* We have already allocated space in the .got. */
791 1.1 christos break;
792 1.1 christos
793 1.1 christos h->got.offset = sgot->size;
794 1.1 christos
795 1.1 christos /* Make sure this symbol is output as a dynamic symbol. */
796 1.1 christos if (h->dynindx == -1)
797 1.1 christos {
798 1.1 christos if (! bfd_elf_link_record_dynamic_symbol (info, h))
799 1.1 christos goto fail;
800 1.1 christos }
801 1.1 christos
802 1.1 christos srelgot->size += sizeof (Elf32_External_Rela);
803 1.1 christos }
804 1.1 christos else
805 1.1 christos {
806 1.1 christos /* This is a global offset table entry for a local
807 1.1 christos symbol. */
808 1.1 christos if (local_got_offsets == NULL)
809 1.1 christos {
810 1.1 christos size_t size;
811 1.1 christos unsigned int i;
812 1.1 christos
813 1.1 christos size = symtab_hdr->sh_info * sizeof (bfd_vma);
814 1.1 christos local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
815 1.1 christos
816 1.1 christos if (local_got_offsets == NULL)
817 1.1 christos goto fail;
818 1.1 christos
819 1.1 christos elf_local_got_offsets (abfd) = local_got_offsets;
820 1.1 christos
821 1.1 christos for (i = 0; i < symtab_hdr->sh_info; i++)
822 1.1 christos local_got_offsets[i] = (bfd_vma) -1;
823 1.1 christos }
824 1.1 christos
825 1.1 christos if (local_got_offsets[r_symndx] != (bfd_vma) -1)
826 1.1 christos /* We have already allocated space in the .got. */
827 1.1 christos break;
828 1.1 christos
829 1.1 christos local_got_offsets[r_symndx] = sgot->size;
830 1.1 christos
831 1.3 christos if (bfd_link_executable (info))
832 1.1 christos /* If we are generating a shared object, we need to
833 1.1 christos output a R_CR16_RELATIVE reloc so that the dynamic
834 1.1 christos linker can adjust this GOT entry. */
835 1.1 christos srelgot->size += sizeof (Elf32_External_Rela);
836 1.1 christos }
837 1.1 christos
838 1.1 christos sgot->size += 4;
839 1.1 christos break;
840 1.1 christos
841 1.1 christos }
842 1.1 christos }
843 1.1 christos
844 1.1 christos result = TRUE;
845 1.1 christos fail:
846 1.1 christos if (isymbuf != NULL)
847 1.1 christos free (isymbuf);
848 1.1 christos
849 1.1 christos return result;
850 1.1 christos }
851 1.1 christos
852 1.1 christos /* Perform a relocation as part of a final link. */
853 1.1 christos
854 1.1 christos static bfd_reloc_status_type
855 1.1 christos cr16_elf_final_link_relocate (reloc_howto_type *howto,
856 1.1 christos bfd *input_bfd,
857 1.1 christos bfd *output_bfd ATTRIBUTE_UNUSED,
858 1.1 christos asection *input_section,
859 1.1 christos bfd_byte *contents,
860 1.1 christos bfd_vma offset,
861 1.1 christos bfd_vma Rvalue,
862 1.1 christos bfd_vma addend,
863 1.1 christos struct elf_link_hash_entry * h,
864 1.1 christos unsigned long symndx ATTRIBUTE_UNUSED,
865 1.1 christos struct bfd_link_info *info ATTRIBUTE_UNUSED,
866 1.1 christos asection *sec ATTRIBUTE_UNUSED,
867 1.1 christos int is_local ATTRIBUTE_UNUSED)
868 1.1 christos {
869 1.1 christos unsigned short r_type = howto->type;
870 1.1 christos bfd_byte *hit_data = contents + offset;
871 1.1 christos bfd_vma reloc_bits, check, Rvalue1;
872 1.1 christos bfd * dynobj;
873 1.1 christos
874 1.1 christos dynobj = elf_hash_table (info)->dynobj;
875 1.1 christos
876 1.1 christos switch (r_type)
877 1.1 christos {
878 1.1 christos case R_CR16_IMM4:
879 1.1 christos case R_CR16_IMM20:
880 1.1 christos case R_CR16_ABS20:
881 1.1 christos break;
882 1.1 christos
883 1.1 christos case R_CR16_IMM8:
884 1.1 christos case R_CR16_IMM16:
885 1.1 christos case R_CR16_IMM32:
886 1.1 christos case R_CR16_IMM32a:
887 1.1 christos case R_CR16_REGREL4:
888 1.1 christos case R_CR16_REGREL4a:
889 1.1 christos case R_CR16_REGREL14:
890 1.1 christos case R_CR16_REGREL14a:
891 1.1 christos case R_CR16_REGREL16:
892 1.1 christos case R_CR16_REGREL20:
893 1.1 christos case R_CR16_REGREL20a:
894 1.1 christos case R_CR16_GOT_REGREL20:
895 1.1 christos case R_CR16_GOTC_REGREL20:
896 1.1 christos case R_CR16_ABS24:
897 1.1 christos case R_CR16_DISP16:
898 1.1 christos case R_CR16_DISP24:
899 1.1 christos /* 'hit_data' is relative to the start of the instruction, not the
900 1.1 christos relocation offset. Advance it to account for the exact offset. */
901 1.1 christos hit_data += 2;
902 1.1 christos break;
903 1.1 christos
904 1.1 christos case R_CR16_NONE:
905 1.1 christos return bfd_reloc_ok;
906 1.1 christos break;
907 1.1 christos
908 1.1 christos case R_CR16_DISP4:
909 1.1 christos if (is_local)
910 1.1 christos Rvalue += -1;
911 1.1 christos break;
912 1.1 christos
913 1.1 christos case R_CR16_DISP8:
914 1.1 christos case R_CR16_DISP24a:
915 1.1 christos if (is_local)
916 1.1 christos Rvalue -= -1;
917 1.1 christos break;
918 1.1 christos
919 1.1 christos case R_CR16_SWITCH8:
920 1.1 christos case R_CR16_SWITCH16:
921 1.1 christos case R_CR16_SWITCH32:
922 1.1 christos /* We only care about the addend, where the difference between
923 1.1 christos expressions is kept. */
924 1.1 christos Rvalue = 0;
925 1.3 christos
926 1.1 christos default:
927 1.1 christos break;
928 1.1 christos }
929 1.1 christos
930 1.1 christos if (howto->pc_relative)
931 1.1 christos {
932 1.1 christos /* Subtract the address of the section containing the location. */
933 1.1 christos Rvalue -= (input_section->output_section->vma
934 1.1 christos + input_section->output_offset);
935 1.1 christos /* Subtract the position of the location within the section. */
936 1.1 christos Rvalue -= offset;
937 1.1 christos }
938 1.1 christos
939 1.1 christos /* Add in supplied addend. */
940 1.1 christos Rvalue += addend;
941 1.1 christos
942 1.1 christos /* Complain if the bitfield overflows, whether it is considered
943 1.1 christos as signed or unsigned. */
944 1.1 christos check = Rvalue >> howto->rightshift;
945 1.1 christos
946 1.1 christos /* Assumes two's complement. This expression avoids
947 1.1 christos overflow if howto->bitsize is the number of bits in
948 1.1 christos bfd_vma. */
949 1.1 christos reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
950 1.1 christos
951 1.1 christos /* For GOT and GOTC relocs no boundary checks applied. */
952 1.1 christos if (!((r_type == R_CR16_GOT_REGREL20)
953 1.1 christos || (r_type == R_CR16_GOTC_REGREL20)))
954 1.1 christos {
955 1.1 christos if (((bfd_vma) check & ~reloc_bits) != 0
956 1.1 christos && (((bfd_vma) check & ~reloc_bits)
957 1.1 christos != (-(bfd_vma) 1 & ~reloc_bits)))
958 1.1 christos {
959 1.1 christos /* The above right shift is incorrect for a signed
960 1.1 christos value. See if turning on the upper bits fixes the
961 1.1 christos overflow. */
962 1.1 christos if (howto->rightshift && (bfd_signed_vma) Rvalue < 0)
963 1.1 christos {
964 1.1 christos check |= ((bfd_vma) - 1
965 1.1 christos & ~((bfd_vma) - 1
966 1.1 christos >> howto->rightshift));
967 1.1 christos
968 1.1 christos if (((bfd_vma) check & ~reloc_bits)
969 1.1 christos != (-(bfd_vma) 1 & ~reloc_bits))
970 1.1 christos return bfd_reloc_overflow;
971 1.1 christos }
972 1.1 christos else
973 1.1 christos return bfd_reloc_overflow;
974 1.1 christos }
975 1.1 christos
976 1.1 christos /* Drop unwanted bits from the value we are relocating to. */
977 1.1 christos Rvalue >>= (bfd_vma) howto->rightshift;
978 1.1 christos
979 1.1 christos /* Apply dst_mask to select only relocatable part of the insn. */
980 1.1 christos Rvalue &= howto->dst_mask;
981 1.1 christos }
982 1.1 christos
983 1.1 christos switch (howto->size)
984 1.1 christos {
985 1.1 christos case 0:
986 1.1 christos if (r_type == R_CR16_DISP8)
987 1.1 christos {
988 1.1 christos Rvalue1 = bfd_get_16 (input_bfd, hit_data);
989 1.1 christos Rvalue = ((Rvalue1 & 0xf000) | ((Rvalue << 4) & 0xf00)
990 1.1 christos | (Rvalue1 & 0x00f0) | (Rvalue & 0xf));
991 1.1 christos bfd_put_16 (input_bfd, Rvalue, hit_data);
992 1.1 christos }
993 1.1 christos else if (r_type == R_CR16_IMM4)
994 1.1 christos {
995 1.1 christos Rvalue1 = bfd_get_16 (input_bfd, hit_data);
996 1.1 christos Rvalue = (((Rvalue1 & 0xff) << 8) | ((Rvalue << 4) & 0xf0)
997 1.1 christos | ((Rvalue1 & 0x0f00) >> 8));
998 1.1 christos bfd_put_16 (input_bfd, Rvalue, hit_data);
999 1.1 christos }
1000 1.1 christos else if (r_type == R_CR16_DISP4)
1001 1.1 christos {
1002 1.1 christos Rvalue1 = bfd_get_16 (input_bfd, hit_data);
1003 1.1 christos Rvalue = (Rvalue1 | ((Rvalue & 0xf) << 4));
1004 1.1 christos bfd_put_16 (input_bfd, Rvalue, hit_data);
1005 1.1 christos }
1006 1.1 christos else
1007 1.1 christos {
1008 1.1 christos bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
1009 1.1 christos }
1010 1.1 christos break;
1011 1.1 christos
1012 1.1 christos case 1:
1013 1.1 christos if (r_type == R_CR16_DISP16)
1014 1.1 christos {
1015 1.1 christos Rvalue |= (bfd_get_16 (input_bfd, hit_data));
1016 1.1 christos Rvalue = ((Rvalue & 0xfffe) | ((Rvalue >> 16) & 0x1));
1017 1.1 christos }
1018 1.1 christos if (r_type == R_CR16_IMM16)
1019 1.1 christos {
1020 1.1 christos Rvalue1 = bfd_get_16 (input_bfd, hit_data);
1021 1.1 christos
1022 1.1 christos /* Add or subtract the offset value. */
1023 1.1 christos if (Rvalue1 & 0x8000)
1024 1.1 christos Rvalue -= (~Rvalue1 + 1) & 0xffff;
1025 1.1 christos else
1026 1.1 christos Rvalue += Rvalue1;
1027 1.1 christos
1028 1.1 christos /* Check for range. */
1029 1.1 christos if ((long) Rvalue > 0xffff || (long) Rvalue < 0x0)
1030 1.1 christos return bfd_reloc_overflow;
1031 1.1 christos }
1032 1.1 christos
1033 1.1 christos bfd_put_16 (input_bfd, Rvalue, hit_data);
1034 1.1 christos break;
1035 1.1 christos
1036 1.1 christos case 2:
1037 1.1 christos if ((r_type == R_CR16_ABS20) || (r_type == R_CR16_IMM20))
1038 1.1 christos {
1039 1.1 christos Rvalue1 = (bfd_get_16 (input_bfd, hit_data + 2)
1040 1.1 christos | (((bfd_get_16 (input_bfd, hit_data) & 0xf) <<16)));
1041 1.1 christos
1042 1.1 christos /* Add or subtract the offset value. */
1043 1.1 christos if (Rvalue1 & 0x80000)
1044 1.1 christos Rvalue -= (~Rvalue1 + 1) & 0xfffff;
1045 1.1 christos else
1046 1.1 christos Rvalue += Rvalue1;
1047 1.1 christos
1048 1.1 christos /* Check for range. */
1049 1.1 christos if ((long) Rvalue > 0xfffff || (long) Rvalue < 0x0)
1050 1.1 christos return bfd_reloc_overflow;
1051 1.1 christos
1052 1.1 christos bfd_put_16 (input_bfd, ((bfd_get_16 (input_bfd, hit_data) & 0xfff0)
1053 1.1 christos | ((Rvalue >> 16) & 0xf)), hit_data);
1054 1.1 christos bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
1055 1.1 christos }
1056 1.3 christos else if (r_type == R_CR16_GOT_REGREL20)
1057 1.1 christos {
1058 1.1 christos asection * sgot = bfd_get_linker_section (dynobj, ".got");
1059 1.1 christos
1060 1.1 christos if (h != NULL)
1061 1.1 christos {
1062 1.1 christos bfd_vma off;
1063 1.1 christos
1064 1.1 christos off = h->got.offset;
1065 1.1 christos BFD_ASSERT (off != (bfd_vma) -1);
1066 1.1 christos
1067 1.1 christos if (! elf_hash_table (info)->dynamic_sections_created
1068 1.1 christos || SYMBOL_REFERENCES_LOCAL (info, h))
1069 1.1 christos /* This is actually a static link, or it is a
1070 1.1 christos -Bsymbolic link and the symbol is defined
1071 1.1 christos locally, or the symbol was forced to be local
1072 1.1 christos because of a version file. We must initialize
1073 1.3 christos this entry in the global offset table.
1074 1.1 christos When doing a dynamic link, we create a .rela.got
1075 1.1 christos relocation entry to initialize the value. This
1076 1.1 christos is done in the finish_dynamic_symbol routine. */
1077 1.1 christos bfd_put_32 (output_bfd, Rvalue, sgot->contents + off);
1078 1.1 christos
1079 1.1 christos Rvalue = sgot->output_offset + off;
1080 1.1 christos }
1081 1.1 christos else
1082 1.1 christos {
1083 1.1 christos bfd_vma off;
1084 1.1 christos
1085 1.1 christos off = elf_local_got_offsets (input_bfd)[symndx];
1086 1.1 christos bfd_put_32 (output_bfd,Rvalue, sgot->contents + off);
1087 1.1 christos
1088 1.1 christos Rvalue = sgot->output_offset + off;
1089 1.1 christos }
1090 1.1 christos
1091 1.1 christos Rvalue += addend;
1092 1.1 christos
1093 1.3 christos /* REVISIT: if ((long) Rvalue > 0xffffff ||
1094 1.1 christos (long) Rvalue < -0x800000). */
1095 1.1 christos if ((long) Rvalue > 0xffffff || (long) Rvalue < 0)
1096 1.1 christos return bfd_reloc_overflow;
1097 1.1 christos
1098 1.1 christos
1099 1.1 christos bfd_put_16 (input_bfd, (bfd_get_16 (input_bfd, hit_data))
1100 1.1 christos | (((Rvalue >> 16) & 0xf) << 8), hit_data);
1101 1.1 christos bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
1102 1.1 christos
1103 1.1 christos }
1104 1.1 christos else if (r_type == R_CR16_GOTC_REGREL20)
1105 1.1 christos {
1106 1.1 christos asection * sgot;
1107 1.1 christos sgot = bfd_get_linker_section (dynobj, ".got");
1108 1.1 christos
1109 1.1 christos if (h != NULL)
1110 1.1 christos {
1111 1.1 christos bfd_vma off;
1112 1.1 christos
1113 1.1 christos off = h->got.offset;
1114 1.1 christos BFD_ASSERT (off != (bfd_vma) -1);
1115 1.1 christos
1116 1.1 christos Rvalue >>=1; /* For code symbols. */
1117 1.1 christos
1118 1.1 christos if (! elf_hash_table (info)->dynamic_sections_created
1119 1.1 christos || SYMBOL_REFERENCES_LOCAL (info, h))
1120 1.1 christos /* This is actually a static link, or it is a
1121 1.1 christos -Bsymbolic link and the symbol is defined
1122 1.1 christos locally, or the symbol was forced to be local
1123 1.1 christos because of a version file. We must initialize
1124 1.3 christos this entry in the global offset table.
1125 1.1 christos When doing a dynamic link, we create a .rela.got
1126 1.1 christos relocation entry to initialize the value. This
1127 1.1 christos is done in the finish_dynamic_symbol routine. */
1128 1.1 christos bfd_put_32 (output_bfd, Rvalue, sgot->contents + off);
1129 1.1 christos
1130 1.1 christos Rvalue = sgot->output_offset + off;
1131 1.1 christos }
1132 1.1 christos else
1133 1.1 christos {
1134 1.1 christos bfd_vma off;
1135 1.1 christos
1136 1.1 christos off = elf_local_got_offsets (input_bfd)[symndx];
1137 1.1 christos Rvalue >>= 1;
1138 1.1 christos bfd_put_32 (output_bfd,Rvalue, sgot->contents + off);
1139 1.1 christos Rvalue = sgot->output_offset + off;
1140 1.1 christos }
1141 1.1 christos
1142 1.1 christos Rvalue += addend;
1143 1.1 christos
1144 1.1 christos /* Check if any value in DISP. */
1145 1.1 christos Rvalue1 =((bfd_get_32 (input_bfd, hit_data) >>16)
1146 1.1 christos | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16));
1147 1.1 christos
1148 1.1 christos /* Add or subtract the offset value. */
1149 1.1 christos if (Rvalue1 & 0x80000)
1150 1.1 christos Rvalue -= (~Rvalue1 + 1) & 0xfffff;
1151 1.1 christos else
1152 1.1 christos Rvalue += Rvalue1;
1153 1.1 christos
1154 1.1 christos /* Check for range. */
1155 1.3 christos /* REVISIT: if ((long) Rvalue > 0xffffff
1156 1.1 christos || (long) Rvalue < -0x800000). */
1157 1.1 christos if ((long) Rvalue > 0xffffff || (long) Rvalue < 0)
1158 1.1 christos return bfd_reloc_overflow;
1159 1.1 christos
1160 1.1 christos bfd_put_16 (input_bfd, (bfd_get_16 (input_bfd, hit_data))
1161 1.1 christos | (((Rvalue >> 16) & 0xf) << 8), hit_data);
1162 1.1 christos bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
1163 1.1 christos }
1164 1.1 christos else
1165 1.1 christos {
1166 1.1 christos if (r_type == R_CR16_ABS24)
1167 1.1 christos {
1168 1.1 christos Rvalue1 = ((bfd_get_32 (input_bfd, hit_data) >> 16)
1169 1.1 christos | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16)
1170 1.1 christos | (((bfd_get_32 (input_bfd, hit_data) & 0xf) <<20)));
1171 1.1 christos
1172 1.1 christos /* Add or subtract the offset value. */
1173 1.1 christos if (Rvalue1 & 0x800000)
1174 1.1 christos Rvalue -= (~Rvalue1 + 1) & 0xffffff;
1175 1.1 christos else
1176 1.1 christos Rvalue += Rvalue1;
1177 1.1 christos
1178 1.1 christos /* Check for Range. */
1179 1.1 christos if ((long) Rvalue > 0xffffff || (long) Rvalue < 0x0)
1180 1.1 christos return bfd_reloc_overflow;
1181 1.1 christos
1182 1.1 christos Rvalue = ((((Rvalue >> 20) & 0xf) | (((Rvalue >> 16) & 0xf)<<8)
1183 1.1 christos | (bfd_get_32 (input_bfd, hit_data) & 0xf0f0))
1184 1.1 christos | ((Rvalue & 0xffff) << 16));
1185 1.1 christos }
1186 1.1 christos else if (r_type == R_CR16_DISP24)
1187 1.1 christos {
1188 1.1 christos Rvalue = ((((Rvalue >> 20)& 0xf) | (((Rvalue >>16) & 0xf)<<8)
1189 1.1 christos | (bfd_get_16 (input_bfd, hit_data)))
1190 1.1 christos | (((Rvalue & 0xfffe) | ((Rvalue >> 24) & 0x1)) << 16));
1191 1.1 christos }
1192 1.1 christos else if ((r_type == R_CR16_IMM32) || (r_type == R_CR16_IMM32a))
1193 1.1 christos {
1194 1.1 christos Rvalue1 =((((bfd_get_32 (input_bfd, hit_data)) >> 16) &0xffff)
1195 1.1 christos | (((bfd_get_32 (input_bfd, hit_data)) &0xffff)) << 16);
1196 1.1 christos
1197 1.1 christos /* Add or subtract the offset value. */
1198 1.1 christos if (Rvalue1 & 0x80000000)
1199 1.1 christos Rvalue -= (~Rvalue1 + 1) & 0xffffffff;
1200 1.1 christos else
1201 1.1 christos Rvalue += Rvalue1;
1202 1.1 christos
1203 1.1 christos /* Check for range. */
1204 1.1 christos if (Rvalue > 0xffffffff || (long) Rvalue < 0x0)
1205 1.1 christos return bfd_reloc_overflow;
1206 1.1 christos
1207 1.1 christos Rvalue = (((Rvalue >> 16)& 0xffff) | (Rvalue & 0xffff) << 16);
1208 1.1 christos }
1209 1.1 christos else if (r_type == R_CR16_DISP24a)
1210 1.1 christos {
1211 1.1 christos Rvalue = (((Rvalue & 0xfffffe) | (Rvalue >> 23)));
1212 1.1 christos Rvalue = ((Rvalue >> 16) & 0xff) | ((Rvalue & 0xffff) << 16)
1213 1.1 christos | (bfd_get_32 (input_bfd, hit_data));
1214 1.1 christos }
1215 1.1 christos else if ((r_type == R_CR16_REGREL20)
1216 1.1 christos || (r_type == R_CR16_REGREL20a))
1217 1.1 christos {
1218 1.1 christos Rvalue1 = ((bfd_get_32 (input_bfd, hit_data) >> 16)
1219 1.1 christos | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16));
1220 1.1 christos /* Add or subtract the offset value. */
1221 1.1 christos if (Rvalue1 & 0x80000)
1222 1.1 christos Rvalue -= (~Rvalue1 + 1) & 0xfffff;
1223 1.1 christos else
1224 1.1 christos Rvalue += Rvalue1;
1225 1.1 christos
1226 1.1 christos /* Check for range. */
1227 1.1 christos if ((long) Rvalue > 0xfffff || (long) Rvalue < 0x0)
1228 1.1 christos return bfd_reloc_overflow;
1229 1.1 christos
1230 1.1 christos Rvalue = (((((Rvalue >> 20)& 0xf) | (((Rvalue >>16) & 0xf)<<8)
1231 1.1 christos | ((Rvalue & 0xffff) << 16)))
1232 1.1 christos | (bfd_get_32 (input_bfd, hit_data) & 0xf0ff));
1233 1.1 christos
1234 1.1 christos }
1235 1.1 christos else if (r_type == R_CR16_NUM32)
1236 1.1 christos {
1237 1.3 christos Rvalue1 = (bfd_get_32 (input_bfd, hit_data));
1238 1.1 christos
1239 1.1 christos /* Add or subtract the offset value */
1240 1.1 christos if (Rvalue1 & 0x80000000)
1241 1.1 christos Rvalue -= (~Rvalue1 + 1) & 0xffffffff;
1242 1.1 christos else
1243 1.1 christos Rvalue += Rvalue1;
1244 1.1 christos
1245 1.1 christos /* Check for Ranga */
1246 1.1 christos if (Rvalue > 0xffffffff)
1247 1.1 christos return bfd_reloc_overflow;
1248 1.1 christos }
1249 1.1 christos
1250 1.1 christos bfd_put_32 (input_bfd, Rvalue, hit_data);
1251 1.1 christos }
1252 1.1 christos break;
1253 1.1 christos
1254 1.1 christos default:
1255 1.1 christos return bfd_reloc_notsupported;
1256 1.1 christos }
1257 1.1 christos
1258 1.1 christos return bfd_reloc_ok;
1259 1.1 christos }
1260 1.1 christos
1261 1.1 christos /* Delete some bytes from a section while relaxing. */
1262 1.1 christos
1263 1.1 christos static bfd_boolean
1264 1.1 christos elf32_cr16_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
1265 1.1 christos asection *sec, bfd_vma addr, int count)
1266 1.1 christos {
1267 1.1 christos Elf_Internal_Shdr *symtab_hdr;
1268 1.1 christos unsigned int sec_shndx;
1269 1.1 christos bfd_byte *contents;
1270 1.1 christos Elf_Internal_Rela *irel, *irelend;
1271 1.1 christos bfd_vma toaddr;
1272 1.1 christos Elf_Internal_Sym *isym;
1273 1.1 christos Elf_Internal_Sym *isymend;
1274 1.1 christos struct elf_link_hash_entry **sym_hashes;
1275 1.1 christos struct elf_link_hash_entry **end_hashes;
1276 1.1 christos struct elf_link_hash_entry **start_hashes;
1277 1.1 christos unsigned int symcount;
1278 1.1 christos
1279 1.1 christos sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1280 1.1 christos
1281 1.1 christos contents = elf_section_data (sec)->this_hdr.contents;
1282 1.1 christos
1283 1.1 christos toaddr = sec->size;
1284 1.1 christos
1285 1.1 christos irel = elf_section_data (sec)->relocs;
1286 1.1 christos irelend = irel + sec->reloc_count;
1287 1.1 christos
1288 1.1 christos /* Actually delete the bytes. */
1289 1.1 christos memmove (contents + addr, contents + addr + count,
1290 1.1 christos (size_t) (toaddr - addr - count));
1291 1.1 christos sec->size -= count;
1292 1.1 christos
1293 1.1 christos /* Adjust all the relocs. */
1294 1.1 christos for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1295 1.1 christos /* Get the new reloc address. */
1296 1.1 christos if ((irel->r_offset > addr && irel->r_offset < toaddr))
1297 1.1 christos irel->r_offset -= count;
1298 1.1 christos
1299 1.1 christos /* Adjust the local symbols defined in this section. */
1300 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1301 1.1 christos isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1302 1.1 christos for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
1303 1.1 christos {
1304 1.1 christos if (isym->st_shndx == sec_shndx
1305 1.1 christos && isym->st_value > addr
1306 1.1 christos && isym->st_value < toaddr)
1307 1.1 christos {
1308 1.1 christos /* Adjust the addend of SWITCH relocations in this section,
1309 1.1 christos which reference this local symbol. */
1310 1.1 christos #if 0
1311 1.1 christos for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1312 1.1 christos {
1313 1.1 christos unsigned long r_symndx;
1314 1.1 christos Elf_Internal_Sym *rsym;
1315 1.1 christos bfd_vma addsym, subsym;
1316 1.1 christos
1317 1.1 christos /* Skip if not a SWITCH relocation. */
1318 1.1 christos if (ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH8
1319 1.1 christos && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH16
1320 1.1 christos && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH32)
1321 1.1 christos continue;
1322 1.3 christos
1323 1.1 christos r_symndx = ELF32_R_SYM (irel->r_info);
1324 1.1 christos rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
1325 1.1 christos
1326 1.1 christos /* Skip if not the local adjusted symbol. */
1327 1.1 christos if (rsym != isym)
1328 1.1 christos continue;
1329 1.1 christos
1330 1.1 christos addsym = isym->st_value;
1331 1.1 christos subsym = addsym - irel->r_addend;
1332 1.1 christos
1333 1.1 christos /* Fix the addend only when -->> (addsym > addr >= subsym). */
1334 1.1 christos if (subsym <= addr)
1335 1.1 christos irel->r_addend -= count;
1336 1.1 christos else
1337 1.1 christos continue;
1338 1.1 christos }
1339 1.1 christos #endif
1340 1.1 christos
1341 1.1 christos isym->st_value -= count;
1342 1.1 christos }
1343 1.1 christos }
1344 1.1 christos
1345 1.1 christos /* Now adjust the global symbols defined in this section. */
1346 1.1 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1347 1.1 christos - symtab_hdr->sh_info);
1348 1.1 christos sym_hashes = start_hashes = elf_sym_hashes (abfd);
1349 1.1 christos end_hashes = sym_hashes + symcount;
1350 1.1 christos
1351 1.1 christos for (; sym_hashes < end_hashes; sym_hashes++)
1352 1.1 christos {
1353 1.1 christos struct elf_link_hash_entry *sym_hash = *sym_hashes;
1354 1.1 christos
1355 1.1 christos /* The '--wrap SYMBOL' option is causing a pain when the object file,
1356 1.1 christos containing the definition of __wrap_SYMBOL, includes a direct
1357 1.1 christos call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
1358 1.1 christos the same symbol (which is __wrap_SYMBOL), but still exist as two
1359 1.1 christos different symbols in 'sym_hashes', we don't want to adjust
1360 1.1 christos the global symbol __wrap_SYMBOL twice.
1361 1.1 christos This check is only relevant when symbols are being wrapped. */
1362 1.1 christos if (link_info->wrap_hash != NULL)
1363 1.1 christos {
1364 1.1 christos struct elf_link_hash_entry **cur_sym_hashes;
1365 1.1 christos
1366 1.1 christos /* Loop only over the symbols whom been already checked. */
1367 1.1 christos for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
1368 1.1 christos cur_sym_hashes++)
1369 1.1 christos /* If the current symbol is identical to 'sym_hash', that means
1370 1.1 christos the symbol was already adjusted (or at least checked). */
1371 1.1 christos if (*cur_sym_hashes == sym_hash)
1372 1.1 christos break;
1373 1.1 christos
1374 1.1 christos /* Don't adjust the symbol again. */
1375 1.1 christos if (cur_sym_hashes < sym_hashes)
1376 1.1 christos continue;
1377 1.1 christos }
1378 1.1 christos
1379 1.1 christos if ((sym_hash->root.type == bfd_link_hash_defined
1380 1.1 christos || sym_hash->root.type == bfd_link_hash_defweak)
1381 1.1 christos && sym_hash->root.u.def.section == sec
1382 1.1 christos && sym_hash->root.u.def.value > addr
1383 1.1 christos && sym_hash->root.u.def.value < toaddr)
1384 1.1 christos sym_hash->root.u.def.value -= count;
1385 1.1 christos }
1386 1.1 christos
1387 1.1 christos return TRUE;
1388 1.1 christos }
1389 1.1 christos
1390 1.1 christos /* Relocate a CR16 ELF section. */
1391 1.1 christos
1392 1.1 christos static bfd_boolean
1393 1.1 christos elf32_cr16_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
1394 1.1 christos bfd *input_bfd, asection *input_section,
1395 1.1 christos bfd_byte *contents, Elf_Internal_Rela *relocs,
1396 1.1 christos Elf_Internal_Sym *local_syms,
1397 1.1 christos asection **local_sections)
1398 1.1 christos {
1399 1.1 christos Elf_Internal_Shdr *symtab_hdr;
1400 1.1 christos struct elf_link_hash_entry **sym_hashes;
1401 1.1 christos Elf_Internal_Rela *rel, *relend;
1402 1.1 christos
1403 1.1 christos symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1404 1.1 christos sym_hashes = elf_sym_hashes (input_bfd);
1405 1.1 christos
1406 1.1 christos rel = relocs;
1407 1.1 christos relend = relocs + input_section->reloc_count;
1408 1.1 christos for (; rel < relend; rel++)
1409 1.1 christos {
1410 1.1 christos int r_type;
1411 1.1 christos reloc_howto_type *howto;
1412 1.1 christos unsigned long r_symndx;
1413 1.1 christos Elf_Internal_Sym *sym;
1414 1.1 christos asection *sec;
1415 1.1 christos struct elf_link_hash_entry *h;
1416 1.1 christos bfd_vma relocation;
1417 1.1 christos bfd_reloc_status_type r;
1418 1.1 christos
1419 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info);
1420 1.1 christos r_type = ELF32_R_TYPE (rel->r_info);
1421 1.1 christos howto = cr16_elf_howto_table + (r_type);
1422 1.1 christos
1423 1.1 christos h = NULL;
1424 1.1 christos sym = NULL;
1425 1.1 christos sec = NULL;
1426 1.1 christos if (r_symndx < symtab_hdr->sh_info)
1427 1.1 christos {
1428 1.1 christos sym = local_syms + r_symndx;
1429 1.1 christos sec = local_sections[r_symndx];
1430 1.1 christos relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1431 1.1 christos }
1432 1.1 christos else
1433 1.1 christos {
1434 1.3 christos bfd_boolean unresolved_reloc, warned, ignored;
1435 1.1 christos
1436 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1437 1.1 christos r_symndx, symtab_hdr, sym_hashes,
1438 1.1 christos h, sec, relocation,
1439 1.3 christos unresolved_reloc, warned, ignored);
1440 1.1 christos }
1441 1.1 christos
1442 1.1 christos if (sec != NULL && discarded_section (sec))
1443 1.1 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
1444 1.1 christos rel, 1, relend, howto, 0, contents);
1445 1.1 christos
1446 1.3 christos if (bfd_link_relocatable (info))
1447 1.1 christos continue;
1448 1.1 christos
1449 1.1 christos r = cr16_elf_final_link_relocate (howto, input_bfd, output_bfd,
1450 1.1 christos input_section,
1451 1.1 christos contents, rel->r_offset,
1452 1.1 christos relocation, rel->r_addend,
1453 1.1 christos (struct elf_link_hash_entry *) h,
1454 1.1 christos r_symndx,
1455 1.1 christos info, sec, h == NULL);
1456 1.1 christos
1457 1.1 christos if (r != bfd_reloc_ok)
1458 1.1 christos {
1459 1.1 christos const char *name;
1460 1.1 christos const char *msg = NULL;
1461 1.1 christos
1462 1.1 christos if (h != NULL)
1463 1.1 christos name = h->root.root.string;
1464 1.1 christos else
1465 1.1 christos {
1466 1.1 christos name = (bfd_elf_string_from_elf_section
1467 1.1 christos (input_bfd, symtab_hdr->sh_link, sym->st_name));
1468 1.1 christos if (name == NULL || *name == '\0')
1469 1.1 christos name = bfd_section_name (input_bfd, sec);
1470 1.1 christos }
1471 1.1 christos
1472 1.1 christos switch (r)
1473 1.1 christos {
1474 1.1 christos case bfd_reloc_overflow:
1475 1.1 christos if (!((*info->callbacks->reloc_overflow)
1476 1.1 christos (info, (h ? &h->root : NULL), name, howto->name,
1477 1.1 christos (bfd_vma) 0, input_bfd, input_section,
1478 1.1 christos rel->r_offset)))
1479 1.1 christos return FALSE;
1480 1.1 christos break;
1481 1.1 christos
1482 1.1 christos case bfd_reloc_undefined:
1483 1.1 christos if (!((*info->callbacks->undefined_symbol)
1484 1.1 christos (info, name, input_bfd, input_section,
1485 1.1 christos rel->r_offset, TRUE)))
1486 1.1 christos return FALSE;
1487 1.1 christos break;
1488 1.1 christos
1489 1.1 christos case bfd_reloc_outofrange:
1490 1.1 christos msg = _("internal error: out of range error");
1491 1.1 christos goto common_error;
1492 1.1 christos
1493 1.1 christos case bfd_reloc_notsupported:
1494 1.1 christos msg = _("internal error: unsupported relocation error");
1495 1.1 christos goto common_error;
1496 1.1 christos
1497 1.1 christos case bfd_reloc_dangerous:
1498 1.1 christos msg = _("internal error: dangerous error");
1499 1.1 christos goto common_error;
1500 1.1 christos
1501 1.1 christos default:
1502 1.1 christos msg = _("internal error: unknown error");
1503 1.1 christos /* Fall through. */
1504 1.1 christos
1505 1.1 christos common_error:
1506 1.1 christos if (!((*info->callbacks->warning)
1507 1.1 christos (info, msg, name, input_bfd, input_section,
1508 1.1 christos rel->r_offset)))
1509 1.1 christos return FALSE;
1510 1.1 christos break;
1511 1.1 christos }
1512 1.1 christos }
1513 1.1 christos }
1514 1.1 christos
1515 1.1 christos return TRUE;
1516 1.1 christos }
1517 1.1 christos
1518 1.1 christos /* This is a version of bfd_generic_get_relocated_section_contents
1519 1.1 christos which uses elf32_cr16_relocate_section. */
1520 1.1 christos
1521 1.1 christos static bfd_byte *
1522 1.1 christos elf32_cr16_get_relocated_section_contents (bfd *output_bfd,
1523 1.1 christos struct bfd_link_info *link_info,
1524 1.1 christos struct bfd_link_order *link_order,
1525 1.1 christos bfd_byte *data,
1526 1.1 christos bfd_boolean relocatable,
1527 1.1 christos asymbol **symbols)
1528 1.1 christos {
1529 1.1 christos Elf_Internal_Shdr *symtab_hdr;
1530 1.1 christos asection *input_section = link_order->u.indirect.section;
1531 1.1 christos bfd *input_bfd = input_section->owner;
1532 1.1 christos asection **sections = NULL;
1533 1.1 christos Elf_Internal_Rela *internal_relocs = NULL;
1534 1.1 christos Elf_Internal_Sym *isymbuf = NULL;
1535 1.1 christos
1536 1.1 christos /* We only need to handle the case of relaxing, or of having a
1537 1.1 christos particular set of section contents, specially. */
1538 1.1 christos if (relocatable
1539 1.1 christos || elf_section_data (input_section)->this_hdr.contents == NULL)
1540 1.1 christos return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1541 1.1 christos link_order, data,
1542 1.1 christos relocatable,
1543 1.1 christos symbols);
1544 1.1 christos
1545 1.1 christos symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1546 1.1 christos
1547 1.1 christos memcpy (data, elf_section_data (input_section)->this_hdr.contents,
1548 1.1 christos (size_t) input_section->size);
1549 1.1 christos
1550 1.1 christos if ((input_section->flags & SEC_RELOC) != 0
1551 1.1 christos && input_section->reloc_count > 0)
1552 1.1 christos {
1553 1.1 christos Elf_Internal_Sym *isym;
1554 1.1 christos Elf_Internal_Sym *isymend;
1555 1.1 christos asection **secpp;
1556 1.1 christos bfd_size_type amt;
1557 1.1 christos
1558 1.1 christos internal_relocs = _bfd_elf_link_read_relocs (input_bfd, input_section,
1559 1.1 christos NULL, NULL, FALSE);
1560 1.1 christos if (internal_relocs == NULL)
1561 1.1 christos goto error_return;
1562 1.1 christos
1563 1.1 christos if (symtab_hdr->sh_info != 0)
1564 1.1 christos {
1565 1.1 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1566 1.1 christos if (isymbuf == NULL)
1567 1.1 christos isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1568 1.1 christos symtab_hdr->sh_info, 0,
1569 1.1 christos NULL, NULL, NULL);
1570 1.1 christos if (isymbuf == NULL)
1571 1.1 christos goto error_return;
1572 1.1 christos }
1573 1.1 christos
1574 1.1 christos amt = symtab_hdr->sh_info;
1575 1.1 christos amt *= sizeof (asection *);
1576 1.1 christos sections = bfd_malloc (amt);
1577 1.1 christos if (sections == NULL && amt != 0)
1578 1.1 christos goto error_return;
1579 1.1 christos
1580 1.1 christos isymend = isymbuf + symtab_hdr->sh_info;
1581 1.1 christos for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
1582 1.1 christos {
1583 1.1 christos asection *isec;
1584 1.1 christos
1585 1.1 christos if (isym->st_shndx == SHN_UNDEF)
1586 1.1 christos isec = bfd_und_section_ptr;
1587 1.1 christos else if (isym->st_shndx == SHN_ABS)
1588 1.1 christos isec = bfd_abs_section_ptr;
1589 1.1 christos else if (isym->st_shndx == SHN_COMMON)
1590 1.1 christos isec = bfd_com_section_ptr;
1591 1.1 christos else
1592 1.1 christos isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
1593 1.1 christos
1594 1.1 christos *secpp = isec;
1595 1.1 christos }
1596 1.1 christos
1597 1.1 christos if (! elf32_cr16_relocate_section (output_bfd, link_info, input_bfd,
1598 1.1 christos input_section, data, internal_relocs,
1599 1.1 christos isymbuf, sections))
1600 1.1 christos goto error_return;
1601 1.1 christos
1602 1.1 christos if (sections != NULL)
1603 1.1 christos free (sections);
1604 1.1 christos if (isymbuf != NULL
1605 1.1 christos && symtab_hdr->contents != (unsigned char *) isymbuf)
1606 1.1 christos free (isymbuf);
1607 1.1 christos if (elf_section_data (input_section)->relocs != internal_relocs)
1608 1.1 christos free (internal_relocs);
1609 1.1 christos }
1610 1.1 christos
1611 1.1 christos return data;
1612 1.1 christos
1613 1.1 christos error_return:
1614 1.1 christos if (sections != NULL)
1615 1.1 christos free (sections);
1616 1.1 christos if (isymbuf != NULL
1617 1.1 christos && symtab_hdr->contents != (unsigned char *) isymbuf)
1618 1.1 christos free (isymbuf);
1619 1.1 christos if (internal_relocs != NULL
1620 1.1 christos && elf_section_data (input_section)->relocs != internal_relocs)
1621 1.1 christos free (internal_relocs);
1622 1.1 christos return NULL;
1623 1.1 christos }
1624 1.1 christos
1625 1.1 christos /* Assorted hash table functions. */
1626 1.1 christos
1627 1.1 christos /* Initialize an entry in the link hash table. */
1628 1.1 christos
1629 1.1 christos /* Create an entry in an CR16 ELF linker hash table. */
1630 1.1 christos
1631 1.1 christos static struct bfd_hash_entry *
1632 1.1 christos elf32_cr16_link_hash_newfunc (struct bfd_hash_entry *entry,
1633 1.1 christos struct bfd_hash_table *table,
1634 1.1 christos const char *string)
1635 1.1 christos {
1636 1.1 christos struct elf32_cr16_link_hash_entry *ret =
1637 1.1 christos (struct elf32_cr16_link_hash_entry *) entry;
1638 1.1 christos
1639 1.1 christos /* Allocate the structure if it has not already been allocated by a
1640 1.1 christos subclass. */
1641 1.1 christos if (ret == (struct elf32_cr16_link_hash_entry *) NULL)
1642 1.1 christos ret = ((struct elf32_cr16_link_hash_entry *)
1643 1.1 christos bfd_hash_allocate (table,
1644 1.1 christos sizeof (struct elf32_cr16_link_hash_entry)));
1645 1.1 christos if (ret == (struct elf32_cr16_link_hash_entry *) NULL)
1646 1.1 christos return (struct bfd_hash_entry *) ret;
1647 1.1 christos
1648 1.1 christos /* Call the allocation method of the superclass. */
1649 1.1 christos ret = ((struct elf32_cr16_link_hash_entry *)
1650 1.1 christos _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1651 1.1 christos table, string));
1652 1.1 christos if (ret != (struct elf32_cr16_link_hash_entry *) NULL)
1653 1.1 christos {
1654 1.1 christos ret->direct_calls = 0;
1655 1.1 christos ret->stack_size = 0;
1656 1.1 christos ret->movm_args = 0;
1657 1.1 christos ret->movm_stack_size = 0;
1658 1.1 christos ret->flags = 0;
1659 1.1 christos ret->value = 0;
1660 1.1 christos }
1661 1.1 christos
1662 1.1 christos return (struct bfd_hash_entry *) ret;
1663 1.1 christos }
1664 1.1 christos
1665 1.1 christos /* Create an cr16 ELF linker hash table. */
1666 1.1 christos
1667 1.1 christos static struct bfd_link_hash_table *
1668 1.1 christos elf32_cr16_link_hash_table_create (bfd *abfd)
1669 1.1 christos {
1670 1.1 christos struct elf_link_hash_table *ret;
1671 1.1 christos bfd_size_type amt = sizeof (struct elf_link_hash_table);
1672 1.1 christos
1673 1.3 christos ret = (struct elf_link_hash_table *) bfd_zmalloc (amt);
1674 1.1 christos if (ret == (struct elf_link_hash_table *) NULL)
1675 1.1 christos return NULL;
1676 1.1 christos
1677 1.1 christos if (!_bfd_elf_link_hash_table_init (ret, abfd,
1678 1.1 christos elf32_cr16_link_hash_newfunc,
1679 1.1 christos sizeof (struct elf32_cr16_link_hash_entry),
1680 1.1 christos GENERIC_ELF_DATA))
1681 1.1 christos {
1682 1.1 christos free (ret);
1683 1.1 christos return NULL;
1684 1.1 christos }
1685 1.1 christos
1686 1.1 christos return &ret->root;
1687 1.1 christos }
1688 1.1 christos
1689 1.1 christos static unsigned long
1690 1.1 christos elf_cr16_mach (flagword flags)
1691 1.1 christos {
1692 1.1 christos switch (flags)
1693 1.1 christos {
1694 1.1 christos case EM_CR16:
1695 1.1 christos default:
1696 1.1 christos return bfd_mach_cr16;
1697 1.1 christos }
1698 1.1 christos }
1699 1.1 christos
1700 1.1 christos /* The final processing done just before writing out a CR16 ELF object
1701 1.1 christos file. This gets the CR16 architecture right based on the machine
1702 1.1 christos number. */
1703 1.1 christos
1704 1.1 christos static void
1705 1.1 christos _bfd_cr16_elf_final_write_processing (bfd *abfd,
1706 1.1 christos bfd_boolean linker ATTRIBUTE_UNUSED)
1707 1.1 christos {
1708 1.1 christos unsigned long val;
1709 1.1 christos switch (bfd_get_mach (abfd))
1710 1.1 christos {
1711 1.1 christos default:
1712 1.1 christos case bfd_mach_cr16:
1713 1.1 christos val = EM_CR16;
1714 1.1 christos break;
1715 1.1 christos }
1716 1.1 christos
1717 1.1 christos
1718 1.1 christos elf_elfheader (abfd)->e_flags |= val;
1719 1.1 christos }
1720 1.1 christos
1721 1.1 christos
1722 1.1 christos static bfd_boolean
1723 1.1 christos _bfd_cr16_elf_object_p (bfd *abfd)
1724 1.1 christos {
1725 1.1 christos bfd_default_set_arch_mach (abfd, bfd_arch_cr16,
1726 1.1 christos elf_cr16_mach (elf_elfheader (abfd)->e_flags));
1727 1.1 christos return TRUE;
1728 1.1 christos }
1729 1.1 christos
1730 1.1 christos /* Merge backend specific data from an object file to the output
1731 1.1 christos object file when linking. */
1732 1.1 christos
1733 1.1 christos static bfd_boolean
1734 1.1 christos _bfd_cr16_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
1735 1.1 christos {
1736 1.1 christos if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1737 1.1 christos || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1738 1.1 christos return TRUE;
1739 1.1 christos
1740 1.1 christos if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1741 1.1 christos && bfd_get_mach (obfd) < bfd_get_mach (ibfd))
1742 1.1 christos {
1743 1.1 christos if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
1744 1.1 christos bfd_get_mach (ibfd)))
1745 1.1 christos return FALSE;
1746 1.1 christos }
1747 1.1 christos
1748 1.1 christos return TRUE;
1749 1.1 christos }
1750 1.1 christos
1751 1.1 christos
1752 1.1 christos /* This function handles relaxing for the CR16.
1753 1.1 christos
1754 1.1 christos There's quite a few relaxing opportunites available on the CR16:
1755 1.1 christos
1756 1.1 christos * bcond:24 -> bcond:16 1 byte
1757 1.1 christos * bcond:16 -> bcond:8 1 byte
1758 1.1 christos * arithmetic imm32 -> arithmetic imm20 12 bits
1759 1.1 christos * arithmetic imm20/imm16 -> arithmetic imm4 12/16 bits
1760 1.1 christos
1761 1.1 christos Symbol- and reloc-reading infrastructure copied from elf-m10200.c. */
1762 1.1 christos
1763 1.1 christos static bfd_boolean
1764 1.1 christos elf32_cr16_relax_section (bfd *abfd, asection *sec,
1765 1.1 christos struct bfd_link_info *link_info, bfd_boolean *again)
1766 1.1 christos {
1767 1.1 christos Elf_Internal_Shdr *symtab_hdr;
1768 1.1 christos Elf_Internal_Rela *internal_relocs;
1769 1.1 christos Elf_Internal_Rela *irel, *irelend;
1770 1.1 christos bfd_byte *contents = NULL;
1771 1.1 christos Elf_Internal_Sym *isymbuf = NULL;
1772 1.1 christos
1773 1.1 christos /* Assume nothing changes. */
1774 1.1 christos *again = FALSE;
1775 1.1 christos
1776 1.1 christos /* We don't have to do anything for a relocatable link, if
1777 1.1 christos this section does not have relocs, or if this is not a
1778 1.1 christos code section. */
1779 1.3 christos if (bfd_link_relocatable (link_info)
1780 1.1 christos || (sec->flags & SEC_RELOC) == 0
1781 1.1 christos || sec->reloc_count == 0
1782 1.1 christos || (sec->flags & SEC_CODE) == 0)
1783 1.1 christos return TRUE;
1784 1.1 christos
1785 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1786 1.1 christos
1787 1.1 christos /* Get a copy of the native relocations. */
1788 1.1 christos internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
1789 1.1 christos link_info->keep_memory);
1790 1.1 christos if (internal_relocs == NULL)
1791 1.1 christos goto error_return;
1792 1.1 christos
1793 1.1 christos /* Walk through them looking for relaxing opportunities. */
1794 1.1 christos irelend = internal_relocs + sec->reloc_count;
1795 1.1 christos for (irel = internal_relocs; irel < irelend; irel++)
1796 1.1 christos {
1797 1.1 christos bfd_vma symval;
1798 1.1 christos
1799 1.1 christos /* If this isn't something that can be relaxed, then ignore
1800 1.1 christos this reloc. */
1801 1.1 christos if (ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP16
1802 1.1 christos && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP24
1803 1.1 christos && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM32
1804 1.1 christos && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM20
1805 1.1 christos && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM16)
1806 1.1 christos continue;
1807 1.1 christos
1808 1.1 christos /* Get the section contents if we haven't done so already. */
1809 1.1 christos if (contents == NULL)
1810 1.1 christos {
1811 1.1 christos /* Get cached copy if it exists. */
1812 1.1 christos if (elf_section_data (sec)->this_hdr.contents != NULL)
1813 1.1 christos contents = elf_section_data (sec)->this_hdr.contents;
1814 1.1 christos /* Go get them off disk. */
1815 1.1 christos else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1816 1.1 christos goto error_return;
1817 1.1 christos }
1818 1.1 christos
1819 1.1 christos /* Read this BFD's local symbols if we haven't done so already. */
1820 1.1 christos if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1821 1.1 christos {
1822 1.1 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1823 1.1 christos if (isymbuf == NULL)
1824 1.1 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1825 1.1 christos symtab_hdr->sh_info, 0,
1826 1.1 christos NULL, NULL, NULL);
1827 1.1 christos if (isymbuf == NULL)
1828 1.1 christos goto error_return;
1829 1.1 christos }
1830 1.1 christos
1831 1.1 christos /* Get the value of the symbol referred to by the reloc. */
1832 1.1 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1833 1.1 christos {
1834 1.1 christos /* A local symbol. */
1835 1.1 christos Elf_Internal_Sym *isym;
1836 1.1 christos asection *sym_sec;
1837 1.1 christos
1838 1.1 christos isym = isymbuf + ELF32_R_SYM (irel->r_info);
1839 1.1 christos if (isym->st_shndx == SHN_UNDEF)
1840 1.1 christos sym_sec = bfd_und_section_ptr;
1841 1.1 christos else if (isym->st_shndx == SHN_ABS)
1842 1.1 christos sym_sec = bfd_abs_section_ptr;
1843 1.1 christos else if (isym->st_shndx == SHN_COMMON)
1844 1.1 christos sym_sec = bfd_com_section_ptr;
1845 1.1 christos else
1846 1.1 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1847 1.1 christos symval = (isym->st_value
1848 1.1 christos + sym_sec->output_section->vma
1849 1.1 christos + sym_sec->output_offset);
1850 1.1 christos }
1851 1.1 christos else
1852 1.1 christos {
1853 1.1 christos unsigned long indx;
1854 1.1 christos struct elf_link_hash_entry *h;
1855 1.1 christos
1856 1.1 christos /* An external symbol. */
1857 1.1 christos indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1858 1.1 christos h = elf_sym_hashes (abfd)[indx];
1859 1.1 christos BFD_ASSERT (h != NULL);
1860 1.1 christos
1861 1.1 christos if (h->root.type != bfd_link_hash_defined
1862 1.1 christos && h->root.type != bfd_link_hash_defweak)
1863 1.1 christos /* This appears to be a reference to an undefined
1864 1.1 christos symbol. Just ignore it--it will be caught by the
1865 1.1 christos regular reloc processing. */
1866 1.1 christos continue;
1867 1.1 christos
1868 1.1 christos symval = (h->root.u.def.value
1869 1.1 christos + h->root.u.def.section->output_section->vma
1870 1.1 christos + h->root.u.def.section->output_offset);
1871 1.1 christos }
1872 1.1 christos
1873 1.1 christos /* For simplicity of coding, we are going to modify the section
1874 1.1 christos contents, the section relocs, and the BFD symbol table. We
1875 1.1 christos must tell the rest of the code not to free up this
1876 1.1 christos information. It would be possible to instead create a table
1877 1.1 christos of changes which have to be made, as is done in coff-mips.c;
1878 1.1 christos that would be more work, but would require less memory when
1879 1.1 christos the linker is run. */
1880 1.1 christos
1881 1.1 christos /* Try to turn a 24 branch/call into a 16bit relative
1882 1.1 christos branch/call. */
1883 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP24)
1884 1.1 christos {
1885 1.1 christos bfd_vma value = symval;
1886 1.1 christos
1887 1.1 christos /* Deal with pc-relative gunk. */
1888 1.1 christos value -= (sec->output_section->vma + sec->output_offset);
1889 1.1 christos value -= irel->r_offset;
1890 1.1 christos value += irel->r_addend;
1891 1.1 christos
1892 1.1 christos /* See if the value will fit in 16 bits, note the high value is
1893 1.1 christos 0xfffe + 2 as the target will be two bytes closer if we are
1894 1.1 christos able to relax. */
1895 1.1 christos if ((long) value < 0x10000 && (long) value > -0x10002)
1896 1.1 christos {
1897 1.1 christos unsigned int code;
1898 1.1 christos
1899 1.1 christos /* Get the opcode. */
1900 1.1 christos code = (unsigned int) bfd_get_32 (abfd, contents + irel->r_offset);
1901 1.1 christos
1902 1.1 christos /* Verify it's a 'bcond' and fix the opcode. */
1903 1.1 christos if ((code & 0xffff) == 0x0010)
1904 1.1 christos bfd_put_16 (abfd, 0x1800 | ((0xf & (code >> 20)) << 4), contents + irel->r_offset);
1905 1.1 christos else
1906 1.1 christos continue;
1907 1.1 christos
1908 1.1 christos /* Note that we've changed the relocs, section contents, etc. */
1909 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
1910 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
1911 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
1912 1.1 christos
1913 1.1 christos /* Fix the relocation's type. */
1914 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1915 1.1 christos R_CR16_DISP16);
1916 1.1 christos
1917 1.1 christos /* Delete two bytes of data. */
1918 1.1 christos if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
1919 1.1 christos irel->r_offset + 2, 2))
1920 1.1 christos goto error_return;
1921 1.1 christos
1922 1.1 christos /* That will change things, so, we should relax again.
1923 1.1 christos Note that this is not required, and it may be slow. */
1924 1.1 christos *again = TRUE;
1925 1.1 christos }
1926 1.1 christos }
1927 1.1 christos
1928 1.1 christos /* Try to turn a 16bit pc-relative branch into an
1929 1.1 christos 8bit pc-relative branch. */
1930 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP16)
1931 1.1 christos {
1932 1.1 christos bfd_vma value = symval;
1933 1.1 christos
1934 1.1 christos /* Deal with pc-relative gunk. */
1935 1.1 christos value -= (sec->output_section->vma + sec->output_offset);
1936 1.1 christos value -= irel->r_offset;
1937 1.1 christos value += irel->r_addend;
1938 1.1 christos
1939 1.1 christos /* See if the value will fit in 8 bits, note the high value is
1940 1.1 christos 0xfc + 2 as the target will be two bytes closer if we are
1941 1.1 christos able to relax. */
1942 1.1 christos /*if ((long) value < 0x1fa && (long) value > -0x100) REVISIT:range */
1943 1.1 christos if ((long) value < 0xfa && (long) value > -0x100)
1944 1.1 christos {
1945 1.1 christos unsigned short code;
1946 1.1 christos
1947 1.1 christos /* Get the opcode. */
1948 1.1 christos code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1949 1.1 christos
1950 1.1 christos /* Verify it's a 'bcond' and fix the opcode. */
1951 1.1 christos if ((code & 0xff0f) == 0x1800)
1952 1.1 christos bfd_put_16 (abfd, (code & 0xf0f0), contents + irel->r_offset);
1953 1.1 christos else
1954 1.1 christos continue;
1955 1.1 christos
1956 1.1 christos /* Note that we've changed the relocs, section contents, etc. */
1957 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
1958 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
1959 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
1960 1.1 christos
1961 1.1 christos /* Fix the relocation's type. */
1962 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1963 1.1 christos R_CR16_DISP8);
1964 1.1 christos
1965 1.1 christos /* Delete two bytes of data. */
1966 1.1 christos if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
1967 1.1 christos irel->r_offset + 2, 2))
1968 1.1 christos goto error_return;
1969 1.1 christos
1970 1.1 christos /* That will change things, so, we should relax again.
1971 1.1 christos Note that this is not required, and it may be slow. */
1972 1.1 christos *again = TRUE;
1973 1.1 christos }
1974 1.1 christos }
1975 1.1 christos
1976 1.1 christos /* Try to turn a 32-bit IMM address into a 20/16-bit IMM address */
1977 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM32)
1978 1.1 christos {
1979 1.1 christos bfd_vma value = symval;
1980 1.1 christos unsigned short is_add_mov = 0;
1981 1.1 christos bfd_vma value1 = 0;
1982 1.3 christos
1983 1.1 christos /* Get the existing value from the mcode */
1984 1.1 christos value1 = ((bfd_get_32 (abfd, contents + irel->r_offset + 2) >> 16)
1985 1.1 christos |(((bfd_get_32 (abfd, contents + irel->r_offset + 2) & 0xffff) << 16)));
1986 1.1 christos
1987 1.1 christos /* See if the value will fit in 20 bits. */
1988 1.1 christos if ((long) (value + value1) < 0xfffff && (long) (value + value1) > 0)
1989 1.1 christos {
1990 1.1 christos unsigned short code;
1991 1.1 christos
1992 1.1 christos /* Get the opcode. */
1993 1.1 christos code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1994 1.1 christos
1995 1.1 christos /* Verify it's a 'arithmetic ADDD or MOVD instruction'.
1996 1.1 christos For ADDD and MOVD only, convert to IMM32 -> IMM20. */
1997 1.3 christos
1998 1.1 christos if (((code & 0xfff0) == 0x0070) || ((code & 0xfff0) == 0x0020))
1999 1.1 christos is_add_mov = 1;
2000 1.1 christos
2001 1.1 christos if (is_add_mov)
2002 1.1 christos {
2003 1.1 christos /* Note that we've changed the relocs, section contents,
2004 1.1 christos etc. */
2005 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
2006 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
2007 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
2008 1.1 christos
2009 1.1 christos /* Fix the opcode. */
2010 1.1 christos if ((code & 0xfff0) == 0x0070) /* For movd. */
2011 1.1 christos bfd_put_8 (abfd, 0x05, contents + irel->r_offset + 1);
2012 1.1 christos else /* code == 0x0020 for addd. */
2013 1.1 christos bfd_put_8 (abfd, 0x04, contents + irel->r_offset + 1);
2014 1.1 christos
2015 1.1 christos bfd_put_8 (abfd, (code & 0xf) << 4, contents + irel->r_offset);
2016 1.1 christos
2017 1.3 christos /* If existing value is nagavive adjust approriately
2018 1.1 christos place the 16-20bits (ie 4 bit) in new opcode,
2019 1.1 christos as the 0xffffxxxx, the higher 2 byte values removed. */
2020 1.1 christos if (value1 & 0x80000000)
2021 1.1 christos bfd_put_8 (abfd, (0x0f | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
2022 1.1 christos else
2023 1.1 christos bfd_put_8 (abfd, (((value1 >> 16)&0xf) | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
2024 1.1 christos
2025 1.1 christos /* Fix the relocation's type. */
2026 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2027 1.1 christos R_CR16_IMM20);
2028 1.1 christos
2029 1.1 christos /* Delete two bytes of data. */
2030 1.1 christos if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
2031 1.1 christos irel->r_offset + 2, 2))
2032 1.1 christos goto error_return;
2033 1.1 christos
2034 1.1 christos /* That will change things, so, we should relax again.
2035 1.1 christos Note that this is not required, and it may be slow. */
2036 1.1 christos *again = TRUE;
2037 1.1 christos }
2038 1.1 christos }
2039 1.1 christos
2040 1.1 christos /* See if the value will fit in 16 bits. */
2041 1.3 christos if ((!is_add_mov)
2042 1.1 christos && ((long)(value + value1) < 0x7fff && (long)(value + value1) > 0))
2043 1.1 christos {
2044 1.1 christos unsigned short code;
2045 1.1 christos
2046 1.1 christos /* Get the opcode. */
2047 1.1 christos code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
2048 1.1 christos
2049 1.1 christos /* Note that we've changed the relocs, section contents, etc. */
2050 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
2051 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
2052 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
2053 1.1 christos
2054 1.1 christos /* Fix the opcode. */
2055 1.1 christos if ((code & 0xf0) == 0x70) /* For movd. */
2056 1.1 christos bfd_put_8 (abfd, 0x54, contents + irel->r_offset + 1);
2057 1.1 christos else if ((code & 0xf0) == 0x20) /* For addd. */
2058 1.1 christos bfd_put_8 (abfd, 0x60, contents + irel->r_offset + 1);
2059 1.1 christos else if ((code & 0xf0) == 0x90) /* For cmpd. */
2060 1.1 christos bfd_put_8 (abfd, 0x56, contents + irel->r_offset + 1);
2061 1.1 christos else
2062 1.1 christos continue;
2063 1.1 christos
2064 1.1 christos bfd_put_8 (abfd, 0xb0 | (code & 0xf), contents + irel->r_offset);
2065 1.1 christos
2066 1.3 christos /* If existing value is nagavive adjust approriately
2067 1.1 christos place the 12-16bits (ie 4 bit) in new opcode,
2068 1.1 christos as the 0xfffffxxx, the higher 2 byte values removed. */
2069 1.1 christos if (value1 & 0x80000000)
2070 1.1 christos bfd_put_8 (abfd, (0x0f | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
2071 1.1 christos else
2072 1.1 christos bfd_put_16 (abfd, value1, contents + irel->r_offset + 2);
2073 1.1 christos
2074 1.1 christos
2075 1.1 christos /* Fix the relocation's type. */
2076 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2077 1.1 christos R_CR16_IMM16);
2078 1.1 christos
2079 1.1 christos /* Delete two bytes of data. */
2080 1.1 christos if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
2081 1.1 christos irel->r_offset + 2, 2))
2082 1.1 christos goto error_return;
2083 1.1 christos
2084 1.1 christos /* That will change things, so, we should relax again.
2085 1.1 christos Note that this is not required, and it may be slow. */
2086 1.1 christos *again = TRUE;
2087 1.1 christos }
2088 1.1 christos }
2089 1.1 christos
2090 1.1 christos #if 0
2091 1.1 christos /* Try to turn a 16bit immediate address into a 4bit
2092 1.1 christos immediate address. */
2093 1.3 christos if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
2094 1.1 christos || (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM16))
2095 1.1 christos {
2096 1.1 christos bfd_vma value = symval;
2097 1.1 christos bfd_vma value1 = 0;
2098 1.1 christos
2099 1.1 christos /* Get the existing value from the mcode */
2100 1.1 christos value1 = ((bfd_get_16 (abfd, contents + irel->r_offset + 2) & 0xffff));
2101 1.1 christos
2102 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
2103 1.1 christos {
2104 1.1 christos value1 |= ((bfd_get_16 (abfd, contents + irel->r_offset + 1) & 0xf000) << 0x4);
2105 1.1 christos }
2106 1.1 christos
2107 1.1 christos /* See if the value will fit in 4 bits. */
2108 1.1 christos if ((((long) (value + value1)) < 0xf)
2109 1.1 christos && (((long) (value + value1)) > 0))
2110 1.1 christos {
2111 1.1 christos unsigned short code;
2112 1.1 christos
2113 1.1 christos /* Get the opcode. */
2114 1.1 christos code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
2115 1.1 christos
2116 1.1 christos /* Note that we've changed the relocs, section contents, etc. */
2117 1.1 christos elf_section_data (sec)->relocs = internal_relocs;
2118 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
2119 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
2120 1.1 christos
2121 1.1 christos /* Fix the opcode. */
2122 1.1 christos if (((code & 0x0f00) == 0x0400) || ((code & 0x0f00) == 0x0500))
2123 1.1 christos {
2124 1.1 christos if ((code & 0x0f00) == 0x0400) /* For movd imm20. */
2125 1.1 christos bfd_put_8 (abfd, 0x60, contents + irel->r_offset);
2126 1.1 christos else /* For addd imm20. */
2127 1.1 christos bfd_put_8 (abfd, 0x54, contents + irel->r_offset);
2128 1.1 christos bfd_put_8 (abfd, (code & 0xf0) >> 4, contents + irel->r_offset + 1);
2129 1.1 christos }
2130 1.1 christos else
2131 1.1 christos {
2132 1.1 christos if ((code & 0xfff0) == 0x56b0) /* For cmpd imm16. */
2133 1.1 christos bfd_put_8 (abfd, 0x56, contents + irel->r_offset);
2134 1.1 christos else if ((code & 0xfff0) == 0x54b0) /* For movd imm16. */
2135 1.1 christos bfd_put_8 (abfd, 0x54, contents + irel->r_offset);
2136 1.1 christos else if ((code & 0xfff0) == 0x58b0) /* For movb imm16. */
2137 1.1 christos bfd_put_8 (abfd, 0x58, contents + irel->r_offset);
2138 1.1 christos else if ((code & 0xfff0) == 0x5Ab0) /* For movw imm16. */
2139 1.1 christos bfd_put_8 (abfd, 0x5A, contents + irel->r_offset);
2140 1.1 christos else if ((code & 0xfff0) == 0x60b0) /* For addd imm16. */
2141 1.1 christos bfd_put_8 (abfd, 0x60, contents + irel->r_offset);
2142 1.1 christos else if ((code & 0xfff0) == 0x30b0) /* For addb imm16. */
2143 1.1 christos bfd_put_8 (abfd, 0x30, contents + irel->r_offset);
2144 1.1 christos else if ((code & 0xfff0) == 0x2Cb0) /* For addub imm16. */
2145 1.1 christos bfd_put_8 (abfd, 0x2C, contents + irel->r_offset);
2146 1.1 christos else if ((code & 0xfff0) == 0x32b0) /* For adduw imm16. */
2147 1.1 christos bfd_put_8 (abfd, 0x32, contents + irel->r_offset);
2148 1.1 christos else if ((code & 0xfff0) == 0x38b0) /* For subb imm16. */
2149 1.1 christos bfd_put_8 (abfd, 0x38, contents + irel->r_offset);
2150 1.1 christos else if ((code & 0xfff0) == 0x3Cb0) /* For subcb imm16. */
2151 1.1 christos bfd_put_8 (abfd, 0x3C, contents + irel->r_offset);
2152 1.1 christos else if ((code & 0xfff0) == 0x3Fb0) /* For subcw imm16. */
2153 1.1 christos bfd_put_8 (abfd, 0x3F, contents + irel->r_offset);
2154 1.1 christos else if ((code & 0xfff0) == 0x3Ab0) /* For subw imm16. */
2155 1.1 christos bfd_put_8 (abfd, 0x3A, contents + irel->r_offset);
2156 1.1 christos else if ((code & 0xfff0) == 0x50b0) /* For cmpb imm16. */
2157 1.1 christos bfd_put_8 (abfd, 0x50, contents + irel->r_offset);
2158 1.1 christos else if ((code & 0xfff0) == 0x52b0) /* For cmpw imm16. */
2159 1.1 christos bfd_put_8 (abfd, 0x52, contents + irel->r_offset);
2160 1.1 christos else
2161 1.1 christos continue;
2162 1.1 christos
2163 1.1 christos bfd_put_8 (abfd, (code & 0xf), contents + irel->r_offset + 1);
2164 1.1 christos }
2165 1.1 christos
2166 1.1 christos /* Fix the relocation's type. */
2167 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2168 1.1 christos R_CR16_IMM4);
2169 1.1 christos
2170 1.1 christos /* Delete two bytes of data. */
2171 1.1 christos if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
2172 1.1 christos irel->r_offset + 2, 2))
2173 1.1 christos goto error_return;
2174 1.1 christos
2175 1.1 christos /* That will change things, so, we should relax again.
2176 1.1 christos Note that this is not required, and it may be slow. */
2177 1.1 christos *again = TRUE;
2178 1.1 christos }
2179 1.1 christos }
2180 1.1 christos #endif
2181 1.1 christos }
2182 1.1 christos
2183 1.1 christos if (isymbuf != NULL
2184 1.1 christos && symtab_hdr->contents != (unsigned char *) isymbuf)
2185 1.1 christos {
2186 1.1 christos if (! link_info->keep_memory)
2187 1.1 christos free (isymbuf);
2188 1.1 christos else
2189 1.1 christos /* Cache the symbols for elf_link_input_bfd. */
2190 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf;
2191 1.1 christos }
2192 1.1 christos
2193 1.1 christos if (contents != NULL
2194 1.1 christos && elf_section_data (sec)->this_hdr.contents != contents)
2195 1.1 christos {
2196 1.1 christos if (! link_info->keep_memory)
2197 1.1 christos free (contents);
2198 1.1 christos else
2199 1.1 christos /* Cache the section contents for elf_link_input_bfd. */
2200 1.1 christos elf_section_data (sec)->this_hdr.contents = contents;
2201 1.3 christos
2202 1.1 christos }
2203 1.1 christos
2204 1.1 christos if (internal_relocs != NULL
2205 1.1 christos && elf_section_data (sec)->relocs != internal_relocs)
2206 1.1 christos free (internal_relocs);
2207 1.1 christos
2208 1.1 christos return TRUE;
2209 1.1 christos
2210 1.1 christos error_return:
2211 1.1 christos if (isymbuf != NULL
2212 1.1 christos && symtab_hdr->contents != (unsigned char *) isymbuf)
2213 1.1 christos free (isymbuf);
2214 1.1 christos if (contents != NULL
2215 1.1 christos && elf_section_data (sec)->this_hdr.contents != contents)
2216 1.1 christos free (contents);
2217 1.1 christos if (internal_relocs != NULL
2218 1.1 christos && elf_section_data (sec)->relocs != internal_relocs)
2219 1.1 christos free (internal_relocs);
2220 1.1 christos
2221 1.1 christos return FALSE;
2222 1.1 christos }
2223 1.1 christos
2224 1.1 christos static asection *
2225 1.1 christos elf32_cr16_gc_mark_hook (asection *sec,
2226 1.1 christos struct bfd_link_info *info,
2227 1.1 christos Elf_Internal_Rela *rel,
2228 1.1 christos struct elf_link_hash_entry *h,
2229 1.1 christos Elf_Internal_Sym *sym)
2230 1.1 christos {
2231 1.1 christos return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2232 1.1 christos }
2233 1.1 christos
2234 1.1 christos /* Update the got entry reference counts for the section being removed. */
2235 1.1 christos
2236 1.1 christos static bfd_boolean
2237 1.1 christos elf32_cr16_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
2238 1.1 christos struct bfd_link_info *info ATTRIBUTE_UNUSED,
2239 1.1 christos asection *sec ATTRIBUTE_UNUSED,
2240 1.1 christos const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
2241 1.1 christos {
2242 1.1 christos /* We don't support garbage collection of GOT and PLT relocs yet. */
2243 1.1 christos return TRUE;
2244 1.1 christos }
2245 1.1 christos
2246 1.1 christos /* Create dynamic sections when linking against a dynamic object. */
2247 1.1 christos
2248 1.1 christos static bfd_boolean
2249 1.1 christos _bfd_cr16_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
2250 1.1 christos {
2251 1.1 christos flagword flags;
2252 1.1 christos asection * s;
2253 1.1 christos const struct elf_backend_data * bed = get_elf_backend_data (abfd);
2254 1.1 christos int ptralign = 0;
2255 1.1 christos
2256 1.1 christos switch (bed->s->arch_size)
2257 1.1 christos {
2258 1.1 christos case 16:
2259 1.1 christos ptralign = 1;
2260 1.1 christos break;
2261 1.1 christos
2262 1.1 christos case 32:
2263 1.1 christos ptralign = 2;
2264 1.1 christos break;
2265 1.1 christos
2266 1.1 christos default:
2267 1.1 christos bfd_set_error (bfd_error_bad_value);
2268 1.1 christos return FALSE;
2269 1.1 christos }
2270 1.1 christos
2271 1.1 christos /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
2272 1.1 christos .rel[a].bss sections. */
2273 1.1 christos
2274 1.1 christos flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
2275 1.1 christos | SEC_LINKER_CREATED);
2276 1.1 christos
2277 1.1 christos s = bfd_make_section_anyway_with_flags (abfd,
2278 1.1 christos (bed->default_use_rela_p
2279 1.1 christos ? ".rela.plt" : ".rel.plt"),
2280 1.1 christos flags | SEC_READONLY);
2281 1.1 christos if (s == NULL
2282 1.1 christos || ! bfd_set_section_alignment (abfd, s, ptralign))
2283 1.1 christos return FALSE;
2284 1.1 christos
2285 1.1 christos if (! _bfd_cr16_elf_create_got_section (abfd, info))
2286 1.1 christos return FALSE;
2287 1.1 christos
2288 1.1 christos if (bed->want_dynbss)
2289 1.1 christos {
2290 1.1 christos /* The .dynbss section is a place to put symbols which are defined
2291 1.1 christos by dynamic objects, are referenced by regular objects, and are
2292 1.1 christos not functions. We must allocate space for them in the process
2293 1.1 christos image and use a R_*_COPY reloc to tell the dynamic linker to
2294 1.1 christos initialize them at run time. The linker script puts the .dynbss
2295 1.1 christos section into the .bss section of the final image. */
2296 1.1 christos s = bfd_make_section_anyway_with_flags (abfd, ".dynbss",
2297 1.1 christos SEC_ALLOC | SEC_LINKER_CREATED);
2298 1.1 christos if (s == NULL)
2299 1.1 christos return FALSE;
2300 1.1 christos
2301 1.1 christos /* The .rel[a].bss section holds copy relocs. This section is not
2302 1.1 christos normally needed. We need to create it here, though, so that the
2303 1.1 christos linker will map it to an output section. We can't just create it
2304 1.1 christos only if we need it, because we will not know whether we need it
2305 1.1 christos until we have seen all the input files, and the first time the
2306 1.1 christos main linker code calls BFD after examining all the input files
2307 1.1 christos (size_dynamic_sections) the input sections have already been
2308 1.1 christos mapped to the output sections. If the section turns out not to
2309 1.1 christos be needed, we can discard it later. We will never need this
2310 1.1 christos section when generating a shared object, since they do not use
2311 1.1 christos copy relocs. */
2312 1.3 christos if (! bfd_link_executable (info))
2313 1.1 christos {
2314 1.1 christos s = bfd_make_section_anyway_with_flags (abfd,
2315 1.1 christos (bed->default_use_rela_p
2316 1.1 christos ? ".rela.bss" : ".rel.bss"),
2317 1.1 christos flags | SEC_READONLY);
2318 1.1 christos if (s == NULL
2319 1.1 christos || ! bfd_set_section_alignment (abfd, s, ptralign))
2320 1.1 christos return FALSE;
2321 1.1 christos }
2322 1.1 christos }
2323 1.1 christos
2324 1.1 christos return TRUE;
2325 1.1 christos }
2326 1.1 christos
2327 1.1 christos /* Adjust a symbol defined by a dynamic object and referenced by a
2329 1.1 christos regular object. The current definition is in some section of the
2330 1.1 christos dynamic object, but we're not including those sections. We have to
2331 1.1 christos change the definition to something the rest of the link can
2332 1.1 christos understand. */
2333 1.1 christos
2334 1.1 christos static bfd_boolean
2335 1.1 christos _bfd_cr16_elf_adjust_dynamic_symbol (struct bfd_link_info * info,
2336 1.1 christos struct elf_link_hash_entry * h)
2337 1.1 christos {
2338 1.1 christos bfd * dynobj;
2339 1.1 christos asection * s;
2340 1.1 christos
2341 1.1 christos dynobj = elf_hash_table (info)->dynobj;
2342 1.1 christos
2343 1.1 christos /* Make sure we know what is going on here. */
2344 1.1 christos BFD_ASSERT (dynobj != NULL
2345 1.1 christos && (h->needs_plt
2346 1.1 christos || h->u.weakdef != NULL
2347 1.1 christos || (h->def_dynamic
2348 1.1 christos && h->ref_regular
2349 1.1 christos && !h->def_regular)));
2350 1.1 christos
2351 1.1 christos /* If this is a function, put it in the procedure linkage table. We
2352 1.1 christos will fill in the contents of the procedure linkage table later,
2353 1.1 christos when we know the address of the .got section. */
2354 1.1 christos if (h->type == STT_FUNC
2355 1.1 christos || h->needs_plt)
2356 1.3 christos {
2357 1.1 christos if (! bfd_link_executable (info)
2358 1.1 christos && !h->def_dynamic
2359 1.1 christos && !h->ref_dynamic)
2360 1.1 christos {
2361 1.1 christos /* This case can occur if we saw a PLT reloc in an input
2362 1.1 christos file, but the symbol was never referred to by a dynamic
2363 1.1 christos object. In such a case, we don't actually need to build
2364 1.1 christos a procedure linkage table, and we can just do a REL32
2365 1.1 christos reloc instead. */
2366 1.1 christos BFD_ASSERT (h->needs_plt);
2367 1.1 christos return TRUE;
2368 1.1 christos }
2369 1.1 christos
2370 1.1 christos /* Make sure this symbol is output as a dynamic symbol. */
2371 1.1 christos if (h->dynindx == -1)
2372 1.1 christos {
2373 1.1 christos if (! bfd_elf_link_record_dynamic_symbol (info, h))
2374 1.1 christos return FALSE;
2375 1.1 christos }
2376 1.1 christos
2377 1.1 christos /* We also need to make an entry in the .got.plt section, which
2378 1.1 christos will be placed in the .got section by the linker script. */
2379 1.1 christos
2380 1.1 christos s = bfd_get_linker_section (dynobj, ".got.plt");
2381 1.1 christos BFD_ASSERT (s != NULL);
2382 1.1 christos s->size += 4;
2383 1.1 christos
2384 1.1 christos /* We also need to make an entry in the .rela.plt section. */
2385 1.1 christos
2386 1.1 christos s = bfd_get_linker_section (dynobj, ".rela.plt");
2387 1.1 christos BFD_ASSERT (s != NULL);
2388 1.1 christos s->size += sizeof (Elf32_External_Rela);
2389 1.1 christos
2390 1.1 christos return TRUE;
2391 1.1 christos }
2392 1.1 christos
2393 1.1 christos /* If this is a weak symbol, and there is a real definition, the
2394 1.1 christos processor independent code will have arranged for us to see the
2395 1.1 christos real definition first, and we can just use the same value. */
2396 1.1 christos if (h->u.weakdef != NULL)
2397 1.1 christos {
2398 1.1 christos BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2399 1.1 christos || h->u.weakdef->root.type == bfd_link_hash_defweak);
2400 1.1 christos h->root.u.def.section = h->u.weakdef->root.u.def.section;
2401 1.1 christos h->root.u.def.value = h->u.weakdef->root.u.def.value;
2402 1.1 christos return TRUE;
2403 1.1 christos }
2404 1.1 christos
2405 1.1 christos /* This is a reference to a symbol defined by a dynamic object which
2406 1.1 christos is not a function. */
2407 1.1 christos
2408 1.1 christos /* If we are creating a shared library, we must presume that the
2409 1.1 christos only references to the symbol are via the global offset table.
2410 1.1 christos For such cases we need not do anything here; the relocations will
2411 1.3 christos be handled correctly by relocate_section. */
2412 1.1 christos if (bfd_link_executable (info))
2413 1.1 christos return TRUE;
2414 1.1 christos
2415 1.1 christos /* If there are no references to this symbol that do not use the
2416 1.1 christos GOT, we don't need to generate a copy reloc. */
2417 1.1 christos if (!h->non_got_ref)
2418 1.1 christos return TRUE;
2419 1.1 christos
2420 1.1 christos /* We must allocate the symbol in our .dynbss section, which will
2421 1.1 christos become part of the .bss section of the executable. There will be
2422 1.1 christos an entry for this symbol in the .dynsym section. The dynamic
2423 1.1 christos object will contain position independent code, so all references
2424 1.1 christos from the dynamic object to this symbol will go through the global
2425 1.1 christos offset table. The dynamic linker will use the .dynsym entry to
2426 1.1 christos determine the address it must put in the global offset table, so
2427 1.1 christos both the dynamic object and the regular object will refer to the
2428 1.1 christos same memory location for the variable. */
2429 1.1 christos
2430 1.1 christos s = bfd_get_linker_section (dynobj, ".dynbss");
2431 1.1 christos BFD_ASSERT (s != NULL);
2432 1.1 christos
2433 1.1 christos /* We must generate a R_CR16_COPY reloc to tell the dynamic linker to
2434 1.1 christos copy the initial value out of the dynamic object and into the
2435 1.1 christos runtime process image. We need to remember the offset into the
2436 1.1 christos .rela.bss section we are going to use. */
2437 1.1 christos if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
2438 1.1 christos {
2439 1.1 christos asection * srel;
2440 1.1 christos
2441 1.1 christos srel = bfd_get_linker_section (dynobj, ".rela.bss");
2442 1.1 christos BFD_ASSERT (srel != NULL);
2443 1.1 christos srel->size += sizeof (Elf32_External_Rela);
2444 1.1 christos h->needs_copy = 1;
2445 1.1 christos }
2446 1.3 christos
2447 1.1 christos return _bfd_elf_adjust_dynamic_copy (info, h, s);
2448 1.1 christos }
2449 1.1 christos
2450 1.1 christos /* Set the sizes of the dynamic sections. */
2451 1.1 christos
2452 1.1 christos static bfd_boolean
2453 1.1 christos _bfd_cr16_elf_size_dynamic_sections (bfd * output_bfd,
2454 1.1 christos struct bfd_link_info * info)
2455 1.1 christos {
2456 1.1 christos bfd * dynobj;
2457 1.1 christos asection * s;
2458 1.1 christos bfd_boolean plt;
2459 1.1 christos bfd_boolean relocs;
2460 1.1 christos bfd_boolean reltext;
2461 1.1 christos
2462 1.1 christos dynobj = elf_hash_table (info)->dynobj;
2463 1.1 christos BFD_ASSERT (dynobj != NULL);
2464 1.1 christos
2465 1.1 christos if (elf_hash_table (info)->dynamic_sections_created)
2466 1.1 christos {
2467 1.3 christos /* Set the contents of the .interp section to the interpreter. */
2468 1.1 christos if (bfd_link_executable (info) && !info->nointerp)
2469 1.1 christos {
2470 1.1 christos #if 0
2471 1.1 christos s = bfd_get_linker_section (dynobj, ".interp");
2472 1.1 christos BFD_ASSERT (s != NULL);
2473 1.1 christos s->size = sizeof ELF_DYNAMIC_INTERPRETER;
2474 1.1 christos s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2475 1.1 christos #endif
2476 1.1 christos }
2477 1.1 christos }
2478 1.1 christos else
2479 1.1 christos {
2480 1.1 christos /* We may have created entries in the .rela.got section.
2481 1.1 christos However, if we are not creating the dynamic sections, we will
2482 1.1 christos not actually use these entries. Reset the size of .rela.got,
2483 1.1 christos which will cause it to get stripped from the output file
2484 1.1 christos below. */
2485 1.1 christos s = bfd_get_linker_section (dynobj, ".rela.got");
2486 1.1 christos if (s != NULL)
2487 1.1 christos s->size = 0;
2488 1.1 christos }
2489 1.1 christos
2490 1.1 christos /* The check_relocs and adjust_dynamic_symbol entry points have
2491 1.1 christos determined the sizes of the various dynamic sections. Allocate
2492 1.1 christos memory for them. */
2493 1.1 christos plt = FALSE;
2494 1.1 christos relocs = FALSE;
2495 1.1 christos reltext = FALSE;
2496 1.1 christos for (s = dynobj->sections; s != NULL; s = s->next)
2497 1.1 christos {
2498 1.1 christos const char * name;
2499 1.1 christos
2500 1.1 christos if ((s->flags & SEC_LINKER_CREATED) == 0)
2501 1.1 christos continue;
2502 1.1 christos
2503 1.1 christos /* It's OK to base decisions on the section name, because none
2504 1.1 christos of the dynobj section names depend upon the input files. */
2505 1.1 christos name = bfd_get_section_name (dynobj, s);
2506 1.1 christos
2507 1.1 christos if (strcmp (name, ".plt") == 0)
2508 1.1 christos {
2509 1.1 christos /* Remember whether there is a PLT. */
2510 1.1 christos plt = s->size != 0;
2511 1.1 christos }
2512 1.1 christos else if (CONST_STRNEQ (name, ".rela"))
2513 1.1 christos {
2514 1.1 christos if (s->size != 0)
2515 1.1 christos {
2516 1.1 christos asection * target;
2517 1.1 christos
2518 1.1 christos /* Remember whether there are any reloc sections other
2519 1.1 christos than .rela.plt. */
2520 1.1 christos if (strcmp (name, ".rela.plt") != 0)
2521 1.1 christos {
2522 1.1 christos const char * outname;
2523 1.1 christos
2524 1.1 christos relocs = TRUE;
2525 1.1 christos
2526 1.1 christos /* If this relocation section applies to a read only
2527 1.1 christos section, then we probably need a DT_TEXTREL
2528 1.1 christos entry. The entries in the .rela.plt section
2529 1.1 christos really apply to the .got section, which we
2530 1.1 christos created ourselves and so know is not readonly. */
2531 1.1 christos outname = bfd_get_section_name (output_bfd,
2532 1.1 christos s->output_section);
2533 1.1 christos target = bfd_get_section_by_name (output_bfd, outname + 5);
2534 1.1 christos if (target != NULL
2535 1.1 christos && (target->flags & SEC_READONLY) != 0
2536 1.1 christos && (target->flags & SEC_ALLOC) != 0)
2537 1.1 christos reltext = TRUE;
2538 1.1 christos }
2539 1.1 christos
2540 1.1 christos /* We use the reloc_count field as a counter if we need
2541 1.1 christos to copy relocs into the output file. */
2542 1.1 christos s->reloc_count = 0;
2543 1.1 christos }
2544 1.1 christos }
2545 1.1 christos else if (! CONST_STRNEQ (name, ".got")
2546 1.1 christos && strcmp (name, ".dynbss") != 0)
2547 1.1 christos /* It's not one of our sections, so don't allocate space. */
2548 1.1 christos continue;
2549 1.1 christos
2550 1.1 christos if (s->size == 0)
2551 1.1 christos {
2552 1.1 christos /* If we don't need this section, strip it from the
2553 1.1 christos output file. This is mostly to handle .rela.bss and
2554 1.1 christos .rela.plt. We must create both sections in
2555 1.1 christos create_dynamic_sections, because they must be created
2556 1.1 christos before the linker maps input sections to output
2557 1.1 christos sections. The linker does that before
2558 1.1 christos adjust_dynamic_symbol is called, and it is that
2559 1.1 christos function which decides whether anything needs to go
2560 1.1 christos into these sections. */
2561 1.1 christos s->flags |= SEC_EXCLUDE;
2562 1.1 christos continue;
2563 1.1 christos }
2564 1.1 christos
2565 1.1 christos if ((s->flags & SEC_HAS_CONTENTS) == 0)
2566 1.1 christos continue;
2567 1.1 christos
2568 1.1 christos /* Allocate memory for the section contents. We use bfd_zalloc
2569 1.1 christos here in case unused entries are not reclaimed before the
2570 1.1 christos section's contents are written out. This should not happen,
2571 1.1 christos but this way if it does, we get a R_CR16_NONE reloc
2572 1.1 christos instead of garbage. */
2573 1.1 christos s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2574 1.1 christos if (s->contents == NULL)
2575 1.1 christos return FALSE;
2576 1.1 christos }
2577 1.1 christos
2578 1.1 christos if (elf_hash_table (info)->dynamic_sections_created)
2579 1.1 christos {
2580 1.1 christos /* Add some entries to the .dynamic section. We fill in the
2581 1.1 christos values later, in _bfd_cr16_elf_finish_dynamic_sections,
2582 1.1 christos but we must add the entries now so that we get the correct
2583 1.1 christos size for the .dynamic section. The DT_DEBUG entry is filled
2584 1.3 christos in by the dynamic linker and used by the debugger. */
2585 1.1 christos if (! bfd_link_executable (info))
2586 1.1 christos {
2587 1.1 christos if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2588 1.1 christos return FALSE;
2589 1.1 christos }
2590 1.1 christos
2591 1.1 christos if (plt)
2592 1.1 christos {
2593 1.1 christos if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2594 1.1 christos || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2595 1.1 christos || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2596 1.1 christos || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
2597 1.1 christos return FALSE;
2598 1.1 christos }
2599 1.1 christos
2600 1.1 christos if (relocs)
2601 1.1 christos {
2602 1.1 christos if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2603 1.1 christos || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2604 1.1 christos || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
2605 1.1 christos sizeof (Elf32_External_Rela)))
2606 1.1 christos return FALSE;
2607 1.1 christos }
2608 1.1 christos
2609 1.1 christos if (reltext)
2610 1.1 christos {
2611 1.1 christos if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2612 1.1 christos return FALSE;
2613 1.1 christos }
2614 1.1 christos }
2615 1.1 christos
2616 1.1 christos return TRUE;
2617 1.1 christos }
2618 1.1 christos
2619 1.1 christos /* Finish up dynamic symbol handling. We set the contents of various
2620 1.1 christos dynamic sections here. */
2621 1.1 christos
2622 1.1 christos static bfd_boolean
2623 1.1 christos _bfd_cr16_elf_finish_dynamic_symbol (bfd * output_bfd,
2624 1.1 christos struct bfd_link_info * info,
2625 1.1 christos struct elf_link_hash_entry * h,
2626 1.1 christos Elf_Internal_Sym * sym)
2627 1.1 christos {
2628 1.1 christos bfd * dynobj;
2629 1.1 christos
2630 1.1 christos dynobj = elf_hash_table (info)->dynobj;
2631 1.1 christos
2632 1.1 christos if (h->got.offset != (bfd_vma) -1)
2633 1.1 christos {
2634 1.1 christos asection * sgot;
2635 1.1 christos asection * srel;
2636 1.1 christos Elf_Internal_Rela rel;
2637 1.1 christos
2638 1.1 christos /* This symbol has an entry in the global offset table. Set it up. */
2639 1.1 christos
2640 1.1 christos sgot = bfd_get_linker_section (dynobj, ".got");
2641 1.1 christos srel = bfd_get_linker_section (dynobj, ".rela.got");
2642 1.1 christos BFD_ASSERT (sgot != NULL && srel != NULL);
2643 1.1 christos
2644 1.1 christos rel.r_offset = (sgot->output_section->vma
2645 1.1 christos + sgot->output_offset
2646 1.1 christos + (h->got.offset & ~1));
2647 1.1 christos
2648 1.1 christos /* If this is a -Bsymbolic link, and the symbol is defined
2649 1.1 christos locally, we just want to emit a RELATIVE reloc. Likewise if
2650 1.1 christos the symbol was forced to be local because of a version file.
2651 1.1 christos The entry in the global offset table will already have been
2652 1.3 christos initialized in the relocate_section function. */
2653 1.1 christos if (bfd_link_executable (info)
2654 1.1 christos && (info->symbolic || h->dynindx == -1)
2655 1.1 christos && h->def_regular)
2656 1.1 christos {
2657 1.1 christos rel.r_info = ELF32_R_INFO (0, R_CR16_GOT_REGREL20);
2658 1.1 christos rel.r_addend = (h->root.u.def.value
2659 1.1 christos + h->root.u.def.section->output_section->vma
2660 1.1 christos + h->root.u.def.section->output_offset);
2661 1.1 christos }
2662 1.1 christos else
2663 1.1 christos {
2664 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
2665 1.1 christos rel.r_info = ELF32_R_INFO (h->dynindx, R_CR16_GOT_REGREL20);
2666 1.1 christos rel.r_addend = 0;
2667 1.1 christos }
2668 1.1 christos
2669 1.1 christos bfd_elf32_swap_reloca_out (output_bfd, &rel,
2670 1.1 christos (bfd_byte *) ((Elf32_External_Rela *) srel->contents
2671 1.1 christos + srel->reloc_count));
2672 1.1 christos ++ srel->reloc_count;
2673 1.1 christos }
2674 1.1 christos
2675 1.1 christos if (h->needs_copy)
2676 1.1 christos {
2677 1.1 christos asection * s;
2678 1.1 christos Elf_Internal_Rela rel;
2679 1.1 christos
2680 1.1 christos /* This symbol needs a copy reloc. Set it up. */
2681 1.1 christos BFD_ASSERT (h->dynindx != -1
2682 1.1 christos && (h->root.type == bfd_link_hash_defined
2683 1.1 christos || h->root.type == bfd_link_hash_defweak));
2684 1.1 christos
2685 1.1 christos s = bfd_get_linker_section (dynobj, ".rela.bss");
2686 1.1 christos BFD_ASSERT (s != NULL);
2687 1.1 christos
2688 1.1 christos rel.r_offset = (h->root.u.def.value
2689 1.1 christos + h->root.u.def.section->output_section->vma
2690 1.1 christos + h->root.u.def.section->output_offset);
2691 1.1 christos rel.r_info = ELF32_R_INFO (h->dynindx, R_CR16_GOT_REGREL20);
2692 1.1 christos rel.r_addend = 0;
2693 1.1 christos bfd_elf32_swap_reloca_out (output_bfd, &rel,
2694 1.1 christos (bfd_byte *) ((Elf32_External_Rela *) s->contents
2695 1.1 christos + s->reloc_count));
2696 1.1 christos ++ s->reloc_count;
2697 1.1 christos }
2698 1.1 christos
2699 1.3 christos /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
2700 1.1 christos if (h == elf_hash_table (info)->hdynamic
2701 1.1 christos || h == elf_hash_table (info)->hgot)
2702 1.1 christos sym->st_shndx = SHN_ABS;
2703 1.1 christos
2704 1.1 christos return TRUE;
2705 1.1 christos }
2706 1.1 christos
2707 1.1 christos /* Finish up the dynamic sections. */
2708 1.1 christos
2709 1.1 christos static bfd_boolean
2710 1.1 christos _bfd_cr16_elf_finish_dynamic_sections (bfd * output_bfd,
2711 1.1 christos struct bfd_link_info * info)
2712 1.1 christos {
2713 1.1 christos bfd * dynobj;
2714 1.1 christos asection * sgot;
2715 1.1 christos asection * sdyn;
2716 1.1 christos
2717 1.1 christos dynobj = elf_hash_table (info)->dynobj;
2718 1.1 christos
2719 1.1 christos sgot = bfd_get_linker_section (dynobj, ".got.plt");
2720 1.1 christos BFD_ASSERT (sgot != NULL);
2721 1.1 christos sdyn = bfd_get_linker_section (dynobj, ".dynamic");
2722 1.1 christos
2723 1.1 christos if (elf_hash_table (info)->dynamic_sections_created)
2724 1.1 christos {
2725 1.1 christos Elf32_External_Dyn * dyncon;
2726 1.1 christos Elf32_External_Dyn * dynconend;
2727 1.1 christos
2728 1.1 christos BFD_ASSERT (sdyn != NULL);
2729 1.1 christos
2730 1.1 christos dyncon = (Elf32_External_Dyn *) sdyn->contents;
2731 1.1 christos dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
2732 1.1 christos
2733 1.1 christos for (; dyncon < dynconend; dyncon++)
2734 1.1 christos {
2735 1.1 christos Elf_Internal_Dyn dyn;
2736 1.1 christos const char * name;
2737 1.1 christos asection * s;
2738 1.1 christos
2739 1.1 christos bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
2740 1.1 christos
2741 1.1 christos switch (dyn.d_tag)
2742 1.1 christos {
2743 1.1 christos default:
2744 1.1 christos break;
2745 1.1 christos
2746 1.1 christos case DT_PLTGOT:
2747 1.1 christos name = ".got";
2748 1.1 christos goto get_vma;
2749 1.1 christos
2750 1.1 christos case DT_JMPREL:
2751 1.1 christos name = ".rela.plt";
2752 1.1 christos get_vma:
2753 1.1 christos s = bfd_get_section_by_name (output_bfd, name);
2754 1.1 christos BFD_ASSERT (s != NULL);
2755 1.1 christos dyn.d_un.d_ptr = s->vma;
2756 1.1 christos bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
2757 1.1 christos break;
2758 1.1 christos
2759 1.1 christos case DT_PLTRELSZ:
2760 1.1 christos s = bfd_get_section_by_name (output_bfd, ".rela.plt");
2761 1.1 christos BFD_ASSERT (s != NULL);
2762 1.1 christos dyn.d_un.d_val = s->size;
2763 1.1 christos bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
2764 1.1 christos break;
2765 1.1 christos
2766 1.1 christos case DT_RELASZ:
2767 1.1 christos /* My reading of the SVR4 ABI indicates that the
2768 1.1 christos procedure linkage table relocs (DT_JMPREL) should be
2769 1.1 christos included in the overall relocs (DT_RELA). This is
2770 1.1 christos what Solaris does. However, UnixWare can not handle
2771 1.1 christos that case. Therefore, we override the DT_RELASZ entry
2772 1.1 christos here to make it not include the JMPREL relocs. Since
2773 1.1 christos the linker script arranges for .rela.plt to follow all
2774 1.1 christos other relocation sections, we don't have to worry
2775 1.1 christos about changing the DT_RELA entry. */
2776 1.1 christos s = bfd_get_section_by_name (output_bfd, ".rela.plt");
2777 1.1 christos if (s != NULL)
2778 1.1 christos dyn.d_un.d_val -= s->size;
2779 1.1 christos bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
2780 1.1 christos break;
2781 1.1 christos }
2782 1.1 christos }
2783 1.1 christos
2784 1.1 christos }
2785 1.1 christos
2786 1.1 christos /* Fill in the first three entries in the global offset table. */
2787 1.1 christos if (sgot->size > 0)
2788 1.1 christos {
2789 1.1 christos if (sdyn == NULL)
2790 1.1 christos bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
2791 1.1 christos else
2792 1.1 christos bfd_put_32 (output_bfd,
2793 1.1 christos sdyn->output_section->vma + sdyn->output_offset,
2794 1.1 christos sgot->contents);
2795 1.1 christos }
2796 1.1 christos
2797 1.1 christos elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
2798 1.1 christos
2799 1.1 christos return TRUE;
2800 1.1 christos }
2801 1.1 christos
2802 1.1 christos /* Given a .data.rel section and a .emreloc in-memory section, store
2803 1.1 christos relocation information into the .emreloc section which can be
2804 1.1 christos used at runtime to relocate the section. This is called by the
2805 1.1 christos linker when the --embedded-relocs switch is used. This is called
2806 1.1 christos after the add_symbols entry point has been called for all the
2807 1.1 christos objects, and before the final_link entry point is called. */
2808 1.1 christos
2809 1.1 christos bfd_boolean
2810 1.1 christos bfd_cr16_elf32_create_embedded_relocs (bfd *abfd,
2811 1.1 christos struct bfd_link_info *info,
2812 1.1 christos asection *datasec,
2813 1.1 christos asection *relsec,
2814 1.1 christos char **errmsg)
2815 1.1 christos {
2816 1.1 christos Elf_Internal_Shdr *symtab_hdr;
2817 1.1 christos Elf_Internal_Sym *isymbuf = NULL;
2818 1.1 christos Elf_Internal_Rela *internal_relocs = NULL;
2819 1.1 christos Elf_Internal_Rela *irel, *irelend;
2820 1.1 christos bfd_byte *p;
2821 1.1 christos bfd_size_type amt;
2822 1.3 christos
2823 1.1 christos BFD_ASSERT (! bfd_link_relocatable (info));
2824 1.1 christos
2825 1.1 christos *errmsg = NULL;
2826 1.1 christos
2827 1.1 christos if (datasec->reloc_count == 0)
2828 1.1 christos return TRUE;
2829 1.1 christos
2830 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2831 1.1 christos
2832 1.1 christos /* Get a copy of the native relocations. */
2833 1.1 christos internal_relocs = (_bfd_elf_link_read_relocs
2834 1.1 christos (abfd, datasec, NULL, NULL, info->keep_memory));
2835 1.1 christos if (internal_relocs == NULL)
2836 1.1 christos goto error_return;
2837 1.1 christos
2838 1.1 christos amt = (bfd_size_type) datasec->reloc_count * 8;
2839 1.1 christos relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
2840 1.1 christos if (relsec->contents == NULL)
2841 1.1 christos goto error_return;
2842 1.1 christos
2843 1.1 christos p = relsec->contents;
2844 1.1 christos
2845 1.1 christos irelend = internal_relocs + datasec->reloc_count;
2846 1.1 christos for (irel = internal_relocs; irel < irelend; irel++, p += 8)
2847 1.1 christos {
2848 1.1 christos asection *targetsec;
2849 1.1 christos
2850 1.1 christos /* We are going to write a four byte longword into the runtime
2851 1.1 christos reloc section. The longword will be the address in the data
2852 1.1 christos section which must be relocated. It is followed by the name
2853 1.1 christos of the target section NUL-padded or truncated to 8
2854 1.1 christos characters. */
2855 1.1 christos
2856 1.1 christos /* We can only relocate absolute longword relocs at run time. */
2857 1.1 christos if (!((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32a)
2858 1.1 christos || (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32)))
2859 1.1 christos {
2860 1.1 christos *errmsg = _("unsupported reloc type");
2861 1.1 christos bfd_set_error (bfd_error_bad_value);
2862 1.1 christos goto error_return;
2863 1.1 christos }
2864 1.1 christos
2865 1.1 christos /* Get the target section referred to by the reloc. */
2866 1.1 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2867 1.1 christos {
2868 1.1 christos /* A local symbol. */
2869 1.1 christos Elf_Internal_Sym *isym;
2870 1.1 christos
2871 1.1 christos /* Read this BFD's local symbols if we haven't done so already. */
2872 1.1 christos if (isymbuf == NULL)
2873 1.1 christos {
2874 1.1 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
2875 1.1 christos if (isymbuf == NULL)
2876 1.1 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
2877 1.1 christos symtab_hdr->sh_info, 0,
2878 1.1 christos NULL, NULL, NULL);
2879 1.1 christos if (isymbuf == NULL)
2880 1.1 christos goto error_return;
2881 1.1 christos }
2882 1.1 christos
2883 1.1 christos isym = isymbuf + ELF32_R_SYM (irel->r_info);
2884 1.1 christos targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
2885 1.1 christos }
2886 1.1 christos else
2887 1.1 christos {
2888 1.1 christos unsigned long indx;
2889 1.1 christos struct elf_link_hash_entry *h;
2890 1.1 christos
2891 1.1 christos /* An external symbol. */
2892 1.1 christos indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2893 1.1 christos h = elf_sym_hashes (abfd)[indx];
2894 1.1 christos BFD_ASSERT (h != NULL);
2895 1.1 christos if (h->root.type == bfd_link_hash_defined
2896 1.1 christos || h->root.type == bfd_link_hash_defweak)
2897 1.1 christos targetsec = h->root.u.def.section;
2898 1.1 christos else
2899 1.1 christos targetsec = NULL;
2900 1.1 christos }
2901 1.1 christos
2902 1.1 christos bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
2903 1.1 christos memset (p + 4, 0, 4);
2904 1.1 christos if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32a)
2905 1.1 christos && (targetsec != NULL) )
2906 1.1 christos strncpy ((char *) p + 4, targetsec->output_section->name, 4);
2907 1.1 christos }
2908 1.1 christos
2909 1.1 christos if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2910 1.1 christos free (isymbuf);
2911 1.1 christos if (internal_relocs != NULL
2912 1.1 christos && elf_section_data (datasec)->relocs != internal_relocs)
2913 1.1 christos free (internal_relocs);
2914 1.1 christos return TRUE;
2915 1.1 christos
2916 1.1 christos error_return:
2917 1.1 christos if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2918 1.1 christos free (isymbuf);
2919 1.1 christos if (internal_relocs != NULL
2920 1.1 christos && elf_section_data (datasec)->relocs != internal_relocs)
2921 1.1 christos free (internal_relocs);
2922 1.1 christos return FALSE;
2923 1.1 christos }
2924 1.1 christos
2925 1.1 christos
2926 1.1 christos /* Classify relocation types, such that combreloc can sort them
2927 1.1 christos properly. */
2928 1.1 christos
2929 1.3 christos static enum elf_reloc_type_class
2930 1.3 christos _bfd_cr16_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
2931 1.3 christos const asection *rel_sec ATTRIBUTE_UNUSED,
2932 1.1 christos const Elf_Internal_Rela *rela)
2933 1.1 christos {
2934 1.1 christos switch ((int) ELF32_R_TYPE (rela->r_info))
2935 1.1 christos {
2936 1.1 christos case R_CR16_GOT_REGREL20:
2937 1.1 christos case R_CR16_GOTC_REGREL20:
2938 1.1 christos return reloc_class_relative;
2939 1.1 christos default:
2940 1.1 christos return reloc_class_normal;
2941 1.1 christos }
2942 1.1 christos }
2943 1.1 christos
2944 1.3 christos /* Definitions for setting CR16 target vector. */
2945 1.1 christos #define TARGET_LITTLE_SYM cr16_elf32_vec
2946 1.1 christos #define TARGET_LITTLE_NAME "elf32-cr16"
2947 1.1 christos #define ELF_ARCH bfd_arch_cr16
2948 1.1 christos #define ELF_MACHINE_CODE EM_CR16
2949 1.1 christos #define ELF_MACHINE_ALT1 EM_CR16_OLD
2950 1.1 christos #define ELF_MAXPAGESIZE 0x1
2951 1.1 christos #define elf_symbol_leading_char '_'
2952 1.1 christos
2953 1.1 christos #define bfd_elf32_bfd_reloc_type_lookup elf_cr16_reloc_type_lookup
2954 1.1 christos #define bfd_elf32_bfd_reloc_name_lookup elf_cr16_reloc_name_lookup
2955 1.1 christos #define elf_info_to_howto elf_cr16_info_to_howto
2956 1.1 christos #define elf_info_to_howto_rel 0
2957 1.1 christos #define elf_backend_relocate_section elf32_cr16_relocate_section
2958 1.1 christos #define bfd_elf32_bfd_relax_section elf32_cr16_relax_section
2959 1.1 christos #define bfd_elf32_bfd_get_relocated_section_contents \
2960 1.1 christos elf32_cr16_get_relocated_section_contents
2961 1.1 christos #define elf_backend_gc_mark_hook elf32_cr16_gc_mark_hook
2962 1.1 christos #define elf_backend_gc_sweep_hook elf32_cr16_gc_sweep_hook
2963 1.1 christos #define elf_backend_can_gc_sections 1
2964 1.1 christos #define elf_backend_rela_normal 1
2965 1.1 christos #define elf_backend_check_relocs cr16_elf_check_relocs
2966 1.1 christos /* So we can set bits in e_flags. */
2967 1.1 christos #define elf_backend_final_write_processing \
2968 1.1 christos _bfd_cr16_elf_final_write_processing
2969 1.1 christos #define elf_backend_object_p _bfd_cr16_elf_object_p
2970 1.1 christos
2971 1.1 christos #define bfd_elf32_bfd_merge_private_bfd_data \
2972 1.1 christos _bfd_cr16_elf_merge_private_bfd_data
2973 1.1 christos
2974 1.1 christos
2975 1.1 christos #define bfd_elf32_bfd_link_hash_table_create \
2976 1.1 christos elf32_cr16_link_hash_table_create
2977 1.1 christos
2978 1.1 christos #define elf_backend_create_dynamic_sections \
2979 1.1 christos _bfd_cr16_elf_create_dynamic_sections
2980 1.1 christos #define elf_backend_adjust_dynamic_symbol \
2981 1.1 christos _bfd_cr16_elf_adjust_dynamic_symbol
2982 1.1 christos #define elf_backend_size_dynamic_sections \
2983 1.1 christos _bfd_cr16_elf_size_dynamic_sections
2984 1.1 christos #define elf_backend_omit_section_dynsym \
2985 1.1 christos ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
2986 1.1 christos #define elf_backend_finish_dynamic_symbol \
2987 1.1 christos _bfd_cr16_elf_finish_dynamic_symbol
2988 1.1 christos #define elf_backend_finish_dynamic_sections \
2989 1.1 christos _bfd_cr16_elf_finish_dynamic_sections
2990 1.1 christos
2991 1.1 christos #define elf_backend_reloc_type_class _bfd_cr16_elf_reloc_type_class
2992 1.1 christos
2993 1.1 christos
2994 1.1 christos #define elf_backend_want_got_plt 1
2995 1.1 christos #define elf_backend_plt_readonly 1
2996 1.1 christos #define elf_backend_want_plt_sym 0
2997 1.1 christos #define elf_backend_got_header_size 12
2998 1.1 christos
2999 #include "elf32-target.h"
3000