OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [elf32-v850.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* V850-specific support for 32-bit ELF
2
   Copyright 1996, 1997, 1998, 1999, 2000, 2001
3
   Free Software Foundation, Inc.
4
 
5
This file is part of BFD, the Binary File Descriptor library.
6
 
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
/* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char
22
   dependencies.  As is the gas & simulator code or the v850.  */
23
 
24
#include "bfd.h"
25
#include "sysdep.h"
26
#include "bfdlink.h"
27
#include "libbfd.h"
28
#include "elf-bfd.h"
29
#include "elf/v850.h"
30
 
31
/* sign-extend a 24-bit number */
32
#define SEXT24(x)       ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
33
 
34
static reloc_howto_type *v850_elf_reloc_type_lookup
35
  PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
36
static void v850_elf_info_to_howto_rel
37
  PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
38
static void v850_elf_info_to_howto_rela
39
  PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
40
static bfd_reloc_status_type v850_elf_reloc
41
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
42
static boolean v850_elf_is_local_label_name
43
  PARAMS ((bfd *, const char *));
44
static boolean v850_elf_relocate_section
45
  PARAMS((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
46
          Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
47
static bfd_reloc_status_type v850_elf_perform_relocation
48
  PARAMS ((bfd *, int, bfd_vma, bfd_byte *));
49
static boolean v850_elf_check_relocs
50
  PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
51
static void remember_hi16s_reloc
52
  PARAMS ((bfd *, bfd_vma, bfd_byte *));
53
static bfd_byte * find_remembered_hi16s_reloc
54
  PARAMS ((bfd_vma, boolean *));
55
static bfd_reloc_status_type v850_elf_final_link_relocate
56
  PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *, bfd_vma,
57
           bfd_vma, bfd_vma, struct bfd_link_info *, asection *, int));
58
static boolean v850_elf_object_p
59
  PARAMS ((bfd *));
60
static boolean v850_elf_fake_sections
61
  PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *));
62
static void v850_elf_final_write_processing
63
  PARAMS ((bfd *, boolean));
64
static boolean v850_elf_set_private_flags
65
  PARAMS ((bfd *, flagword));
66
static boolean v850_elf_copy_private_bfd_data
67
  PARAMS ((bfd *, bfd *));
68
static boolean v850_elf_merge_private_bfd_data
69
  PARAMS ((bfd *, bfd *));
70
static boolean v850_elf_print_private_bfd_data
71
  PARAMS ((bfd *, PTR));
72
static boolean v850_elf_section_from_bfd_section
73
  PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *, int *));
74
static void v850_elf_symbol_processing
75
  PARAMS ((bfd *, asymbol *));
76
static boolean v850_elf_add_symbol_hook
77
  PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
78
           const char **, flagword *, asection **, bfd_vma *));
79
static boolean v850_elf_link_output_symbol_hook
80
  PARAMS ((bfd *, struct bfd_link_info *, const char *,
81
           Elf_Internal_Sym *, asection *));
82
static boolean v850_elf_section_from_shdr
83
  PARAMS ((bfd *, Elf_Internal_Shdr *, char *));
84
 
85
/* Note: It is REQUIRED that the 'type' value of each entry in this array
86
   match the index of the entry in the array.  */
87
static reloc_howto_type v850_elf_howto_table[] =
88
{
89
  /* This reloc does nothing.  */
90
  HOWTO (R_V850_NONE,                   /* type */
91
         0,                              /* rightshift */
92
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
93
         32,                            /* bitsize */
94
         false,                         /* pc_relative */
95
         0,                              /* bitpos */
96
         complain_overflow_bitfield,    /* complain_on_overflow */
97
         bfd_elf_generic_reloc,         /* special_function */
98
         "R_V850_NONE",                 /* name */
99
         false,                         /* partial_inplace */
100
         0,                              /* src_mask */
101
         0,                              /* dst_mask */
102
         false),                        /* pcrel_offset */
103
 
104
  /* A PC relative 9 bit branch.  */
105
  HOWTO (R_V850_9_PCREL,                /* type */
106
         2,                             /* rightshift */
107
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
108
         26,                            /* bitsize */
109
         true,                          /* pc_relative */
110
         0,                              /* bitpos */
111
         complain_overflow_bitfield,    /* complain_on_overflow */
112
         v850_elf_reloc,                /* special_function */
113
         "R_V850_9_PCREL",              /* name */
114
         false,                         /* partial_inplace */
115
         0x00ffffff,                    /* src_mask */
116
         0x00ffffff,                    /* dst_mask */
117
         true),                         /* pcrel_offset */
118
 
119
  /* A PC relative 22 bit branch.  */
120
  HOWTO (R_V850_22_PCREL,               /* type */
121
         2,                             /* rightshift */
122
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
123
         22,                            /* bitsize */
124
         true,                          /* pc_relative */
125
         7,                             /* bitpos */
126
         complain_overflow_signed,      /* complain_on_overflow */
127
         v850_elf_reloc,                /* special_function */
128
         "R_V850_22_PCREL",             /* name */
129
         false,                         /* partial_inplace */
130
         0x07ffff80,                    /* src_mask */
131
         0x07ffff80,                    /* dst_mask */
132
         true),                         /* pcrel_offset */
133
 
134
  /* High 16 bits of symbol value.  */
135
  HOWTO (R_V850_HI16_S,                 /* type */
136
         0,                              /* rightshift */
137
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
138
         16,                            /* bitsize */
139
         false,                         /* pc_relative */
140
         0,                              /* bitpos */
141
         complain_overflow_dont,        /* complain_on_overflow */
142
         v850_elf_reloc,                /* special_function */
143
         "R_V850_HI16_S",               /* name */
144
         false,                         /* partial_inplace */
145
         0xffff,                        /* src_mask */
146
         0xffff,                        /* dst_mask */
147
         false),                        /* pcrel_offset */
148
 
149
  /* High 16 bits of symbol value.  */
150
  HOWTO (R_V850_HI16,                   /* type */
151
         0,                              /* rightshift */
152
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
153
         16,                            /* bitsize */
154
         false,                         /* pc_relative */
155
         0,                              /* bitpos */
156
         complain_overflow_dont,        /* complain_on_overflow */
157
         v850_elf_reloc,                /* special_function */
158
         "R_V850_HI16",                 /* name */
159
         false,                         /* partial_inplace */
160
         0xffff,                        /* src_mask */
161
         0xffff,                        /* dst_mask */
162
         false),                        /* pcrel_offset */
163
 
164
  /* Low 16 bits of symbol value.  */
165
  HOWTO (R_V850_LO16,                   /* type */
166
         0,                              /* rightshift */
167
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
168
         16,                            /* bitsize */
169
         false,                         /* pc_relative */
170
         0,                              /* bitpos */
171
         complain_overflow_dont,        /* complain_on_overflow */
172
         v850_elf_reloc,                /* special_function */
173
         "R_V850_LO16",                 /* name */
174
         false,                         /* partial_inplace */
175
         0xffff,                        /* src_mask */
176
         0xffff,                        /* dst_mask */
177
         false),                        /* pcrel_offset */
178
 
179
  /* Simple 32bit reloc.  */
180
  HOWTO (R_V850_32,                     /* type */
181
         0,                              /* rightshift */
182
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
183
         32,                            /* bitsize */
184
         false,                         /* pc_relative */
185
         0,                              /* bitpos */
186
         complain_overflow_dont,        /* complain_on_overflow */
187
         v850_elf_reloc,                /* special_function */
188
         "R_V850_32",                   /* name */
189
         false,                         /* partial_inplace */
190
         0xffffffff,                    /* src_mask */
191
         0xffffffff,                    /* dst_mask */
192
         false),                        /* pcrel_offset */
193
 
194
  /* Simple 16bit reloc.  */
195
  HOWTO (R_V850_16,                     /* type */
196
         0,                              /* rightshift */
197
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
198
         16,                            /* bitsize */
199
         false,                         /* pc_relative */
200
         0,                              /* bitpos */
201
         complain_overflow_dont,        /* complain_on_overflow */
202
         bfd_elf_generic_reloc,         /* special_function */
203
         "R_V850_16",                   /* name */
204
         false,                         /* partial_inplace */
205
         0xffff,                        /* src_mask */
206
         0xffff,                        /* dst_mask */
207
         false),                        /* pcrel_offset */
208
 
209
  /* Simple 8bit reloc.  */
210
  HOWTO (R_V850_8,                      /* type */
211
         0,                              /* rightshift */
212
         0,                              /* size (0 = byte, 1 = short, 2 = long) */
213
         8,                             /* bitsize */
214
         false,                         /* pc_relative */
215
         0,                              /* bitpos */
216
         complain_overflow_dont,        /* complain_on_overflow */
217
         bfd_elf_generic_reloc,         /* special_function */
218
         "R_V850_8",                    /* name */
219
         false,                         /* partial_inplace */
220
         0xff,                          /* src_mask */
221
         0xff,                          /* dst_mask */
222
         false),                        /* pcrel_offset */
223
 
224
  /* 16 bit offset from the short data area pointer.  */
225
  HOWTO (R_V850_SDA_16_16_OFFSET,       /* type */
226
         0,                              /* rightshift */
227
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
228
         16,                            /* bitsize */
229
         false,                         /* pc_relative */
230
         0,                              /* bitpos */
231
         complain_overflow_dont,        /* complain_on_overflow */
232
         v850_elf_reloc,                /* special_function */
233
         "R_V850_SDA_16_16_OFFSET",     /* name */
234
         false,                         /* partial_inplace */
235
         0xffff,                        /* src_mask */
236
         0xffff,                        /* dst_mask */
237
         false),                        /* pcrel_offset */
238
 
239
  /* 15 bit offset from the short data area pointer.  */
240
  HOWTO (R_V850_SDA_15_16_OFFSET,       /* type */
241
         1,                             /* rightshift */
242
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
243
         16,                            /* bitsize */
244
         false,                         /* pc_relative */
245
         1,                             /* bitpos */
246
         complain_overflow_dont,        /* complain_on_overflow */
247
         v850_elf_reloc,                /* special_function */
248
         "R_V850_SDA_15_16_OFFSET",     /* name */
249
         false,                         /* partial_inplace */
250
         0xfffe,                        /* src_mask */
251
         0xfffe,                        /* dst_mask */
252
         false),                        /* pcrel_offset */
253
 
254
  /* 16 bit offset from the zero data area pointer.  */
255
  HOWTO (R_V850_ZDA_16_16_OFFSET,       /* type */
256
         0,                              /* rightshift */
257
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
258
         16,                            /* bitsize */
259
         false,                         /* pc_relative */
260
         0,                              /* bitpos */
261
         complain_overflow_dont,        /* complain_on_overflow */
262
         v850_elf_reloc,                /* special_function */
263
         "R_V850_ZDA_16_16_OFFSET",     /* name */
264
         false,                         /* partial_inplace */
265
         0xffff,                        /* src_mask */
266
         0xffff,                        /* dst_mask */
267
         false),                        /* pcrel_offset */
268
 
269
  /* 15 bit offset from the zero data area pointer.  */
270
  HOWTO (R_V850_ZDA_15_16_OFFSET,       /* type */
271
         1,                             /* rightshift */
272
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
273
         16,                            /* bitsize */
274
         false,                         /* pc_relative */
275
         1,                             /* bitpos */
276
         complain_overflow_dont,        /* complain_on_overflow */
277
         v850_elf_reloc,                /* special_function */
278
         "R_V850_ZDA_15_16_OFFSET",     /* name */
279
         false,                         /* partial_inplace */
280
         0xfffe,                        /* src_mask */
281
         0xfffe,                        /* dst_mask */
282
         false),                        /* pcrel_offset */
283
 
284
  /* 6 bit offset from the tiny data area pointer.  */
285
  HOWTO (R_V850_TDA_6_8_OFFSET,         /* type */
286
         2,                             /* rightshift */
287
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
288
         8,                             /* bitsize */
289
         false,                         /* pc_relative */
290
         1,                             /* bitpos */
291
         complain_overflow_dont,        /* complain_on_overflow */
292
         v850_elf_reloc,                /* special_function */
293
         "R_V850_TDA_6_8_OFFSET",       /* name */
294
         false,                         /* partial_inplace */
295
         0x7e,                          /* src_mask */
296
         0x7e,                          /* dst_mask */
297
         false),                        /* pcrel_offset */
298
 
299
  /* 8 bit offset from the tiny data area pointer.  */
300
  HOWTO (R_V850_TDA_7_8_OFFSET,         /* type */
301
         1,                             /* rightshift */
302
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
303
         8,                             /* bitsize */
304
         false,                         /* pc_relative */
305
         0,                              /* bitpos */
306
         complain_overflow_dont,        /* complain_on_overflow */
307
         v850_elf_reloc,                /* special_function */
308
         "R_V850_TDA_7_8_OFFSET",       /* name */
309
         false,                         /* partial_inplace */
310
         0x7f,                          /* src_mask */
311
         0x7f,                          /* dst_mask */
312
         false),                        /* pcrel_offset */
313
 
314
  /* 7 bit offset from the tiny data area pointer.  */
315
  HOWTO (R_V850_TDA_7_7_OFFSET,         /* type */
316
         0,                              /* rightshift */
317
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
318
         7,                             /* bitsize */
319
         false,                         /* pc_relative */
320
         0,                              /* bitpos */
321
         complain_overflow_dont,        /* complain_on_overflow */
322
         v850_elf_reloc,                /* special_function */
323
         "R_V850_TDA_7_7_OFFSET",       /* name */
324
         false,                         /* partial_inplace */
325
         0x7f,                          /* src_mask */
326
         0x7f,                          /* dst_mask */
327
         false),                        /* pcrel_offset */
328
 
329
  /* 16 bit offset from the tiny data area pointer!  */
330
  HOWTO (R_V850_TDA_16_16_OFFSET,       /* type */
331
         0,                              /* rightshift */
332
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
333
         16,                            /* bitsize */
334
         false,                         /* pc_relative */
335
         0,                              /* bitpos */
336
         complain_overflow_dont,        /* complain_on_overflow */
337
         v850_elf_reloc,                /* special_function */
338
         "R_V850_TDA_16_16_OFFSET",     /* name */
339
         false,                         /* partial_inplace */
340
         0xffff,                        /* src_mask */
341
         0xfff,                         /* dst_mask */
342
         false),                        /* pcrel_offset */
343
 
344
  /* 5 bit offset from the tiny data area pointer.  */
345
  HOWTO (R_V850_TDA_4_5_OFFSET,         /* type */
346
         1,                             /* rightshift */
347
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
348
         5,                             /* bitsize */
349
         false,                         /* pc_relative */
350
         0,                              /* bitpos */
351
         complain_overflow_dont,        /* complain_on_overflow */
352
         v850_elf_reloc,                /* special_function */
353
         "R_V850_TDA_4_5_OFFSET",       /* name */
354
         false,                         /* partial_inplace */
355
         0x0f,                          /* src_mask */
356
         0x0f,                          /* dst_mask */
357
         false),                        /* pcrel_offset */
358
 
359
  /* 4 bit offset from the tiny data area pointer.  */
360
  HOWTO (R_V850_TDA_4_4_OFFSET,         /* type */
361
         0,                              /* rightshift */
362
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
363
         4,                             /* bitsize */
364
         false,                         /* pc_relative */
365
         0,                              /* bitpos */
366
         complain_overflow_dont,        /* complain_on_overflow */
367
         v850_elf_reloc,                /* special_function */
368
         "R_V850_TDA_4_4_OFFSET",       /* name */
369
         false,                         /* partial_inplace */
370
         0x0f,                          /* src_mask */
371
         0x0f,                          /* dst_mask */
372
         false),                        /* pcrel_offset */
373
 
374
  /* 16 bit offset from the short data area pointer.  */
375
  HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* type */
376
         0,                              /* rightshift */
377
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
378
         16,                            /* bitsize */
379
         false,                         /* pc_relative */
380
         0,                              /* bitpos */
381
         complain_overflow_dont,        /* complain_on_overflow */
382
         v850_elf_reloc,                /* special_function */
383
         "R_V850_SDA_16_16_SPLIT_OFFSET",/* name */
384
         false,                         /* partial_inplace */
385
         0xfffe0020,                    /* src_mask */
386
         0xfffe0020,                    /* dst_mask */
387
         false),                        /* pcrel_offset */
388
 
389
  /* 16 bit offset from the zero data area pointer.  */
390
  HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* type */
391
         0,                              /* rightshift */
392
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
393
         16,                            /* bitsize */
394
         false,                         /* pc_relative */
395
         0,                              /* bitpos */
396
         complain_overflow_dont,        /* complain_on_overflow */
397
         v850_elf_reloc,                /* special_function */
398
         "R_V850_ZDA_16_16_SPLIT_OFFSET",/* name */
399
         false,                         /* partial_inplace */
400
         0xfffe0020,                    /* src_mask */
401
         0xfffe0020,                    /* dst_mask */
402
         false),                        /* pcrel_offset */
403
 
404
  /* 6 bit offset from the call table base pointer.  */
405
  HOWTO (R_V850_CALLT_6_7_OFFSET,       /* type */
406
         0,                              /* rightshift */
407
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
408
         7,                             /* bitsize */
409
         false,                         /* pc_relative */
410
         0,                              /* bitpos */
411
         complain_overflow_dont,        /* complain_on_overflow */
412
         v850_elf_reloc,                /* special_function */
413
         "R_V850_CALLT_6_7_OFFSET",     /* name */
414
         false,                         /* partial_inplace */
415
         0x3f,                          /* src_mask */
416
         0x3f,                          /* dst_mask */
417
         false),                        /* pcrel_offset */
418
 
419
  /* 16 bit offset from the call table base pointer.  */
420
  HOWTO (R_V850_CALLT_16_16_OFFSET,     /* type */
421
         0,                              /* rightshift */
422
         1,                             /* size (0 = byte, 1 = short, 2 = long) */
423
         16,                            /* bitsize */
424
         false,                         /* pc_relative */
425
         0,                              /* bitpos */
426
         complain_overflow_dont,        /* complain_on_overflow */
427
         v850_elf_reloc,                /* special_function */
428
         "R_V850_CALLT_16_16_OFFSET",   /* name */
429
         false,                         /* partial_inplace */
430
         0xffff,                        /* src_mask */
431
         0xffff,                        /* dst_mask */
432
         false),                        /* pcrel_offset */
433
 
434
  /* GNU extension to record C++ vtable hierarchy */
435
  HOWTO (R_V850_GNU_VTINHERIT, /* type */
436
         0,                     /* rightshift */
437
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
438
         0,                     /* bitsize */
439
         false,                 /* pc_relative */
440
         0,                     /* bitpos */
441
         complain_overflow_dont, /* complain_on_overflow */
442
         NULL,                  /* special_function */
443
         "R_V850_GNU_VTINHERIT", /* name */
444
         false,                 /* partial_inplace */
445
         0,                     /* src_mask */
446
         0,                     /* dst_mask */
447
         false),                /* pcrel_offset */
448
 
449
  /* GNU extension to record C++ vtable member usage */
450
  HOWTO (R_V850_GNU_VTENTRY,     /* type */
451
         0,                     /* rightshift */
452
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
453
         0,                     /* bitsize */
454
         false,                 /* pc_relative */
455
         0,                     /* bitpos */
456
         complain_overflow_dont, /* complain_on_overflow */
457
         _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
458
         "R_V850_GNU_VTENTRY",   /* name */
459
         false,                 /* partial_inplace */
460
         0,                     /* src_mask */
461
         0,                     /* dst_mask */
462
         false),                /* pcrel_offset */
463
 
464
};
465
 
466
/* Map BFD reloc types to V850 ELF reloc types.  */
467
 
468
struct v850_elf_reloc_map
469
{
470
  /* BFD_RELOC_V850_CALLT_16_16_OFFSET is 258, which will not fix in an
471
     unsigned char.  */
472
  bfd_reloc_code_real_type bfd_reloc_val;
473
  unsigned char elf_reloc_val;
474
};
475
 
476
static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
477
{
478
  { BFD_RELOC_NONE,             R_V850_NONE },
479
  { BFD_RELOC_V850_9_PCREL,     R_V850_9_PCREL },
480
  { BFD_RELOC_V850_22_PCREL,    R_V850_22_PCREL },
481
  { BFD_RELOC_HI16_S,           R_V850_HI16_S },
482
  { BFD_RELOC_HI16,             R_V850_HI16 },
483
  { BFD_RELOC_LO16,             R_V850_LO16 },
484
  { BFD_RELOC_32,               R_V850_32 },
485
  { BFD_RELOC_16,               R_V850_16 },
486
  { BFD_RELOC_8,                R_V850_8 },
487
  { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET },
488
  { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET },
489
  { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET },
490
  { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET },
491
  { BFD_RELOC_V850_TDA_6_8_OFFSET,   R_V850_TDA_6_8_OFFSET   },
492
  { BFD_RELOC_V850_TDA_7_8_OFFSET,   R_V850_TDA_7_8_OFFSET   },
493
  { BFD_RELOC_V850_TDA_7_7_OFFSET,   R_V850_TDA_7_7_OFFSET   },
494
  { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET },
495
  { BFD_RELOC_V850_TDA_4_5_OFFSET,         R_V850_TDA_4_5_OFFSET         },
496
  { BFD_RELOC_V850_TDA_4_4_OFFSET,         R_V850_TDA_4_4_OFFSET         },
497
  { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },
498
  { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },
499
  { BFD_RELOC_V850_CALLT_6_7_OFFSET,       R_V850_CALLT_6_7_OFFSET       },
500
  { BFD_RELOC_V850_CALLT_16_16_OFFSET,     R_V850_CALLT_16_16_OFFSET     },
501
  { BFD_RELOC_VTABLE_INHERIT,               R_V850_GNU_VTINHERIT },
502
  { BFD_RELOC_VTABLE_ENTRY,                 R_V850_GNU_VTENTRY },
503
 
504
};
505
 
506
/* Map a bfd relocation into the appropriate howto structure */
507
static reloc_howto_type *
508
v850_elf_reloc_type_lookup (abfd, code)
509
     bfd *                     abfd ATTRIBUTE_UNUSED;
510
     bfd_reloc_code_real_type  code;
511
{
512
  unsigned int i;
513
 
514
  for (i = 0;
515
       i < sizeof (v850_elf_reloc_map) / sizeof (struct v850_elf_reloc_map);
516
       i++)
517
    {
518
      if (v850_elf_reloc_map[i].bfd_reloc_val == code)
519
        {
520
          BFD_ASSERT (v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val].type == v850_elf_reloc_map[i].elf_reloc_val);
521
 
522
          return & v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val];
523
        }
524
    }
525
 
526
  return NULL;
527
}
528
 
529
/* Set the howto pointer for an V850 ELF reloc.  */
530
static void
531
v850_elf_info_to_howto_rel (abfd, cache_ptr, dst)
532
     bfd *                 abfd ATTRIBUTE_UNUSED;
533
     arelent *             cache_ptr;
534
     Elf32_Internal_Rel *  dst;
535
{
536
  unsigned int r_type;
537
 
538
  r_type = ELF32_R_TYPE (dst->r_info);
539
  BFD_ASSERT (r_type < (unsigned int) R_V850_max);
540
  cache_ptr->howto = &v850_elf_howto_table[r_type];
541
}
542
 
543
/* Set the howto pointer for a V850 ELF reloc (type RELA).  */
544
static void
545
v850_elf_info_to_howto_rela (abfd, cache_ptr, dst)
546
     bfd *                 abfd ATTRIBUTE_UNUSED;
547
     arelent *             cache_ptr;
548
     Elf32_Internal_Rela   *dst;
549
{
550
  unsigned int r_type;
551
 
552
  r_type = ELF32_R_TYPE (dst->r_info);
553
  BFD_ASSERT (r_type < (unsigned int) R_V850_max);
554
  cache_ptr->howto = &v850_elf_howto_table[r_type];
555
}
556
 
557
/* Look through the relocs for a section during the first phase, and
558
   allocate space in the global offset table or procedure linkage
559
   table.  */
560
 
561
static boolean
562
v850_elf_check_relocs (abfd, info, sec, relocs)
563
     bfd *                      abfd;
564
     struct bfd_link_info *     info;
565
     asection *                 sec;
566
     const Elf_Internal_Rela *  relocs;
567
{
568
  boolean ret = true;
569
  bfd *dynobj;
570
  Elf_Internal_Shdr *symtab_hdr;
571
  struct elf_link_hash_entry **sym_hashes;
572
  const Elf_Internal_Rela *rel;
573
  const Elf_Internal_Rela *rel_end;
574
  asection *sreloc;
575
  enum v850_reloc_type r_type;
576
  int other = 0;
577
  const char *common = (const char *)0;
578
 
579
  if (info->relocateable)
580
    return true;
581
 
582
#ifdef DEBUG
583
  fprintf (stderr, "v850_elf_check_relocs called for section %s in %s\n",
584
           bfd_get_section_name (abfd, sec),
585
           bfd_get_filename (abfd));
586
#endif
587
 
588
  dynobj = elf_hash_table (info)->dynobj;
589
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
590
  sym_hashes = elf_sym_hashes (abfd);
591
  sreloc = NULL;
592
 
593
  rel_end = relocs + sec->reloc_count;
594
  for (rel = relocs; rel < rel_end; rel++)
595
    {
596
      unsigned long r_symndx;
597
      struct elf_link_hash_entry *h;
598
 
599
      r_symndx = ELF32_R_SYM (rel->r_info);
600
      if (r_symndx < symtab_hdr->sh_info)
601
        h = NULL;
602
      else
603
        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
604
 
605
      r_type = (enum v850_reloc_type) ELF32_R_TYPE (rel->r_info);
606
      switch (r_type)
607
        {
608
        default:
609
        case R_V850_NONE:
610
        case R_V850_9_PCREL:
611
        case R_V850_22_PCREL:
612
        case R_V850_HI16_S:
613
        case R_V850_HI16:
614
        case R_V850_LO16:
615
        case R_V850_32:
616
        case R_V850_16:
617
        case R_V850_8:
618
        case R_V850_CALLT_6_7_OFFSET:
619
        case R_V850_CALLT_16_16_OFFSET:
620
          break;
621
 
622
        /* This relocation describes the C++ object vtable hierarchy.
623
           Reconstruct it for later use during GC.  */
624
        case R_V850_GNU_VTINHERIT:
625
          if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
626
            return false;
627
          break;
628
 
629
        /* This relocation describes which C++ vtable entries are actually
630
           used.  Record for later use during GC.  */
631
        case R_V850_GNU_VTENTRY:
632
          if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
633
            return false;
634
          break;
635
 
636
        case R_V850_SDA_16_16_SPLIT_OFFSET:
637
        case R_V850_SDA_16_16_OFFSET:
638
        case R_V850_SDA_15_16_OFFSET:
639
          other = V850_OTHER_SDA;
640
          common = ".scommon";
641
          goto small_data_common;
642
 
643
        case R_V850_ZDA_16_16_SPLIT_OFFSET:
644
        case R_V850_ZDA_16_16_OFFSET:
645
        case R_V850_ZDA_15_16_OFFSET:
646
          other = V850_OTHER_ZDA;
647
          common = ".zcommon";
648
          goto small_data_common;
649
 
650
        case R_V850_TDA_4_5_OFFSET:
651
        case R_V850_TDA_4_4_OFFSET:
652
        case R_V850_TDA_6_8_OFFSET:
653
        case R_V850_TDA_7_8_OFFSET:
654
        case R_V850_TDA_7_7_OFFSET:
655
        case R_V850_TDA_16_16_OFFSET:
656
          other = V850_OTHER_TDA;
657
          common = ".tcommon";
658
          /* fall through */
659
 
660
#define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
661
 
662
        small_data_common:
663
          if (h)
664
            {
665
              h->other |= other;        /* flag which type of relocation was used */
666
              if ((h->other & V850_OTHER_MASK) != (other & V850_OTHER_MASK)
667
                  && (h->other & V850_OTHER_ERROR) == 0)
668
                {
669
                  const char * msg;
670
                  static char  buff[200]; /* XXX */
671
 
672
                  switch (h->other & V850_OTHER_MASK)
673
                    {
674
                    default:
675
                      msg = _("Variable `%s' cannot occupy in multiple small data regions");
676
                      break;
677
                    case V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA:
678
                      msg = _("Variable `%s' can only be in one of the small, zero, and tiny data regions");
679
                      break;
680
                    case V850_OTHER_SDA | V850_OTHER_ZDA:
681
                      msg = _("Variable `%s' cannot be in both small and zero data regions simultaneously");
682
                      break;
683
                    case V850_OTHER_SDA | V850_OTHER_TDA:
684
                      msg = _("Variable `%s' cannot be in both small and tiny data regions simultaneously");
685
                      break;
686
                    case V850_OTHER_ZDA | V850_OTHER_TDA:
687
                      msg = _("Variable `%s' cannot be in both zero and tiny data regions simultaneously");
688
                      break;
689
                    }
690
 
691
                  sprintf (buff, msg, h->root.root.string);
692
                  info->callbacks->warning (info, buff, h->root.root.string,
693
                                            abfd, h->root.u.def.section, 0);
694
 
695
                  bfd_set_error (bfd_error_bad_value);
696
                  h->other |= V850_OTHER_ERROR;
697
                  ret = false;
698
                }
699
            }
700
 
701
          if (h && h->root.type == bfd_link_hash_common
702
              && h->root.u.c.p
703
              && !strcmp (bfd_get_section_name (abfd, h->root.u.c.p->section), "COMMON"))
704
            {
705
              asection *section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common);
706
              section->flags |= SEC_IS_COMMON;
707
            }
708
 
709
#ifdef DEBUG
710
          fprintf (stderr, "v850_elf_check_relocs, found %s relocation for %s%s\n",
711
                   v850_elf_howto_table[ (int)r_type ].name,
712
                   (h && h->root.root.string) ? h->root.root.string : "<unknown>",
713
                   (h->root.type == bfd_link_hash_common) ? ", symbol is common" : "");
714
#endif
715
          break;
716
        }
717
    }
718
 
719
  return ret;
720
}
721
 
722
/*
723
 * In the old version, when an entry was checked out from the table,
724
 * it was deleted.  This produced an error if the entry was needed
725
 * more than once, as the second attempted retry failed.
726
 *
727
 * In the current version, the entry is not deleted, instead we set
728
 * the field 'found' to true.  If a second lookup matches the same
729
 * entry, then we know that the hi16s reloc has already been updated
730
 * and does not need to be updated a second time.
731
 *
732
 * TODO - TOFIX: If it is possible that we need to restore 2 different
733
 * addresses from the same table entry, where the first generates an
734
 * overflow, whilst the second do not, then this code will fail.
735
 */
736
 
737
typedef struct hi16s_location
738
{
739
  bfd_vma       addend;
740
  bfd_byte *    address;
741
  unsigned long counter;
742
  boolean       found;
743
  struct hi16s_location * next;
744
}
745
hi16s_location;
746
 
747
static hi16s_location *  previous_hi16s;
748
static hi16s_location *  free_hi16s;
749
static unsigned long     hi16s_counter;
750
 
751
static void
752
remember_hi16s_reloc (abfd, addend, address)
753
     bfd *      abfd;
754
     bfd_vma    addend;
755
     bfd_byte * address;
756
{
757
  hi16s_location * entry = NULL;
758
 
759
  /* Find a free structure.  */
760
  if (free_hi16s == NULL)
761
    free_hi16s = (hi16s_location *) bfd_zalloc (abfd, sizeof (* free_hi16s));
762
 
763
  entry      = free_hi16s;
764
  free_hi16s = free_hi16s->next;
765
 
766
  entry->addend  = addend;
767
  entry->address = address;
768
  entry->counter = hi16s_counter ++;
769
  entry->found   = false;
770
  entry->next    = previous_hi16s;
771
  previous_hi16s = entry;
772
 
773
  /* Cope with wrap around of our counter.  */
774
  if (hi16s_counter == 0)
775
    {
776
      /* XXX - Assume that all counter entries differ only in their low 16 bits.  */
777
      for (entry = previous_hi16s; entry != NULL; entry = entry->next)
778
        entry->counter &= 0xffff;
779
 
780
      hi16s_counter = 0x10000;
781
    }
782
 
783
  return;
784
}
785
 
786
static bfd_byte *
787
find_remembered_hi16s_reloc (addend, already_found)
788
     bfd_vma   addend;
789
     boolean * already_found;
790
{
791
  hi16s_location * match = NULL;
792
  hi16s_location * entry;
793
  hi16s_location * previous = NULL;
794
  hi16s_location * prev;
795
  bfd_byte *       addr;
796
 
797
  /* Search the table.  Record the most recent entry that matches.  */
798
  for (entry = previous_hi16s; entry; entry = entry->next)
799
    {
800
      if (entry->addend == addend
801
          && (match == NULL || match->counter < entry->counter))
802
        {
803
          previous = prev;
804
          match    = entry;
805
        }
806
 
807
      prev = entry;
808
    }
809
 
810
  if (match == NULL)
811
    return NULL;
812
 
813
  /* Extract the address.  */
814
  addr = match->address;
815
 
816
  /* Remeber if this entry has already been used before.  */
817
  if (already_found)
818
    * already_found = match->found;
819
 
820
  /* Note that this entry has now been used.  */
821
  match->found = true;
822
 
823
  return addr;
824
}
825
 
826
/* FIXME:  The code here probably ought to be removed and the code in reloc.c
827
   allowed to do its  stuff instead.  At least for most of the relocs, anwyay.  */
828
static bfd_reloc_status_type
829
v850_elf_perform_relocation (abfd, r_type, addend, address)
830
     bfd *      abfd;
831
     int        r_type;
832
     bfd_vma    addend;
833
     bfd_byte * address;
834
{
835
  unsigned long insn;
836
  bfd_signed_vma saddend = (bfd_signed_vma) addend;
837
 
838
  switch (r_type)
839
    {
840
    default:
841
      /* fprintf (stderr, "reloc type %d not SUPPORTED\n", r_type ); */
842
      return bfd_reloc_notsupported;
843
 
844
    case R_V850_32:
845
      bfd_put_32 (abfd, addend, address);
846
      return bfd_reloc_ok;
847
 
848
    case R_V850_22_PCREL:
849
      if (saddend > 0x1fffff || saddend < -0x200000)
850
        return bfd_reloc_overflow;
851
 
852
      if ((addend % 2) != 0)
853
        return bfd_reloc_dangerous;
854
 
855
      insn  = bfd_get_32 (abfd, address);
856
      insn &= ~0xfffe003f;
857
      insn |= (((addend & 0xfffe) << 16) | ((addend & 0x3f0000) >> 16));
858
      bfd_put_32 (abfd, insn, address);
859
      return bfd_reloc_ok;
860
 
861
    case R_V850_9_PCREL:
862
      if (saddend > 0xff || saddend < -0x100)
863
        return bfd_reloc_overflow;
864
 
865
      if ((addend % 2) != 0)
866
        return bfd_reloc_dangerous;
867
 
868
      insn  = bfd_get_16 (abfd, address);
869
      insn &= ~ 0xf870;
870
      insn |= ((addend & 0x1f0) << 7) | ((addend & 0x0e) << 3);
871
      break;
872
 
873
    case R_V850_HI16:
874
      addend += (bfd_get_16 (abfd, address) << 16);
875
      addend = (addend >> 16);
876
      insn = addend;
877
      break;
878
 
879
    case R_V850_HI16_S:
880
      /* Remember where this relocation took place.  */
881
      remember_hi16s_reloc (abfd, addend, address);
882
 
883
      addend += (bfd_get_16 (abfd, address) << 16);
884
      addend = (addend >> 16) + ((addend & 0x8000) != 0);
885
 
886
      /* This relocation cannot overflow.  */
887
      if (addend > 0x7fff)
888
        addend = 0;
889
 
890
      insn = addend;
891
      break;
892
 
893
    case R_V850_LO16:
894
      /* Calculate the sum of the value stored in the instruction and the
895
         addend and check for overflow from the low 16 bits into the high
896
         16 bits.  The assembler has already done some of this:  If the
897
         value stored in the instruction has its 15th bit set, (counting
898
         from zero) then the assembler will have added 1 to the value
899
         stored in the associated HI16S reloc.  So for example, these
900
         relocations:
901
 
902
             movhi hi( fred ), r0, r1
903
             movea lo( fred ), r1, r1
904
 
905
         will store 0 in the value fields for the MOVHI and MOVEA instructions
906
         and addend will be the address of fred, but for these instructions:
907
 
908
             movhi hi( fred + 0x123456), r0, r1
909
             movea lo( fred + 0x123456), r1, r1
910
 
911
         the value stored in the MOVHI instruction will be 0x12 and the value
912
         stored in the MOVEA instruction will be 0x3456.  If however the
913
         instructions were:
914
 
915
             movhi hi( fred + 0x10ffff), r0, r1
916
             movea lo( fred + 0x10ffff), r1, r1
917
 
918
         then the value stored in the MOVHI instruction would be 0x11 (not
919
         0x10) and the value stored in the MOVEA instruction would be 0xffff.
920
         Thus (assuming for the moment that the addend is 0), at run time the
921
         MOVHI instruction loads 0x110000 into r1, then the MOVEA instruction
922
         adds 0xffffffff (sign extension!) producing 0x10ffff.  Similarly if
923
         the instructions were:
924
 
925
             movhi hi( fred - 1), r0, r1
926
             movea lo( fred - 1), r1, r1
927
 
928
         then 0 is stored in the MOVHI instruction and -1 is stored in the
929
         MOVEA instruction.
930
 
931
         Overflow can occur if the addition of the value stored in the
932
         instruction plus the addend sets the 15th bit when before it was clear.
933
         This is because the 15th bit will be sign extended into the high part,
934
         thus reducing its value by one, but since the 15th bit was originally
935
         clear, the assembler will not have added 1 to the previous HI16S reloc
936
         to compensate for this effect.  For example:
937
 
938
            movhi hi( fred + 0x123456), r0, r1
939
            movea lo( fred + 0x123456), r1, r1
940
 
941
         The value stored in HI16S reloc is 0x12, the value stored in the LO16
942
         reloc is 0x3456.  If we assume that the address of fred is 0x00007000
943
         then the relocations become:
944
 
945
           HI16S: 0x0012 + (0x00007000 >> 16)    = 0x12
946
           LO16:  0x3456 + (0x00007000 & 0xffff) = 0xa456
947
 
948
         but when the instructions are executed, the MOVEA instruction's value
949
         is signed extended, so the sum becomes:
950
 
951
              0x00120000
952
            + 0xffffa456
953
            ------------
954
              0x0011a456    but 'fred + 0x123456' = 0x0012a456
955
 
956
         Note that if the 15th bit was set in the value stored in the LO16
957
         reloc, then we do not have to do anything:
958
 
959
            movhi hi( fred + 0x10ffff), r0, r1
960
            movea lo( fred + 0x10ffff), r1, r1
961
 
962
            HI16S:  0x0011 + (0x00007000 >> 16)    = 0x11
963
            LO16:   0xffff + (0x00007000 & 0xffff) = 0x6fff
964
 
965
              0x00110000
966
            + 0x00006fff
967
            ------------
968
              0x00116fff  = fred + 0x10ffff = 0x7000 + 0x10ffff
969
 
970
         Overflow can also occur if the computation carries into the 16th bit
971
         and it also results in the 15th bit having the same value as the 15th
972
         bit of the original value.   What happens is that the HI16S reloc
973
         will have already examined the 15th bit of the original value and
974
         added 1 to the high part if the bit is set.  This compensates for the
975
         sign extension of 15th bit of the result of the computation.  But now
976
         there is a carry into the 16th bit, and this has not been allowed for.
977
 
978
         So, for example if fred is at address 0xf000:
979
 
980
           movhi hi( fred + 0xffff), r0, r1    [bit 15 of the offset is set]
981
           movea lo( fred + 0xffff), r1, r1
982
 
983
           HI16S: 0x0001 + (0x0000f000 >> 16)    = 0x0001
984
           LO16:  0xffff + (0x0000f000 & 0xffff) = 0xefff   (carry into bit 16 is lost)
985
 
986
             0x00010000
987
           + 0xffffefff
988
           ------------
989
             0x0000efff   but 'fred + 0xffff' = 0x0001efff
990
 
991
         Similarly, if the 15th bit remains clear, but overflow occurs into
992
         the 16th bit then (assuming the address of fred is 0xf000):
993
 
994
           movhi hi( fred + 0x7000), r0, r1    [bit 15 of the offset is clear]
995
           movea lo( fred + 0x7000), r1, r1
996
 
997
           HI16S: 0x0000 + (0x0000f000 >> 16)    = 0x0000
998
           LO16:  0x7000 + (0x0000f000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)
999
 
1000
             0x00000000
1001
           + 0x00006fff
1002
           ------------
1003
             0x00006fff   but 'fred + 0x7000' = 0x00016fff
1004
 
1005
         Note - there is no need to change anything if a carry occurs, and the
1006
         15th bit changes its value from being set to being clear, as the HI16S
1007
         reloc will have already added in 1 to the high part for us:
1008
 
1009
           movhi hi( fred + 0xffff), r0, r1     [bit 15 of the offset is set]
1010
           movea lo( fred + 0xffff), r1, r1
1011
 
1012
           HI16S: 0x0001 + (0x00007000 >> 16)
1013
           LO16:  0xffff + (0x00007000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)
1014
 
1015
             0x00010000
1016
           + 0x00006fff   (bit 15 not set, so the top half is zero)
1017
           ------------
1018
             0x00016fff   which is right (assuming that fred is at 0x7000)
1019
 
1020
         but if the 15th bit goes from being clear to being set, then we must
1021
         once again handle overflow:
1022
 
1023
           movhi hi( fred + 0x7000), r0, r1     [bit 15 of the offset is clear]
1024
           movea lo( fred + 0x7000), r1, r1
1025
 
1026
           HI16S: 0x0000 + (0x0000ffff >> 16)
1027
           LO16:  0x7000 + (0x0000ffff & 0xffff) = 0x6fff  (carry into bit 16)
1028
 
1029
             0x00000000
1030
           + 0x00006fff   (bit 15 not set, so the top half is zero)
1031
           ------------
1032
             0x00006fff   which is wrong (assuming that fred is at 0xffff)
1033
         */
1034
 
1035
      {
1036
        long result;
1037
 
1038
        insn   = bfd_get_16 (abfd, address);
1039
        result = insn + addend;
1040
 
1041
#define BIT15_SET(x) ((x) & 0x8000)
1042
#define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)
1043
 
1044
        if ((BIT15_SET (result) && ! BIT15_SET (addend))
1045
            || (OVERFLOWS (addend, insn)
1046
                && ((! BIT15_SET (insn)) || (BIT15_SET (addend)))))
1047
          {
1048
            boolean already_updated;
1049
            bfd_byte * hi16s_address = find_remembered_hi16s_reloc
1050
              (addend, & already_updated);
1051
 
1052
            /* Amend the matching HI16_S relocation.  */
1053
            if (hi16s_address != NULL)
1054
              {
1055
                if (! already_updated)
1056
                  {
1057
                    insn = bfd_get_16 (abfd, hi16s_address);
1058
                    insn += 1;
1059
                    bfd_put_16 (abfd, insn, hi16s_address);
1060
                  }
1061
              }
1062
            else
1063
              {
1064
                fprintf (stderr, _("FAILED to find previous HI16 reloc\n"));
1065
                return bfd_reloc_overflow;
1066
              }
1067
          }
1068
 
1069
        /* Do not complain if value has top bit set, as this has been anticipated.  */
1070
        insn = result & 0xffff;
1071
        break;
1072
      }
1073
 
1074
    case R_V850_8:
1075
      addend += (char) bfd_get_8 (abfd, address);
1076
 
1077
      saddend = (bfd_signed_vma) addend;
1078
 
1079
      if (saddend > 0x7f || saddend < -0x80)
1080
        return bfd_reloc_overflow;
1081
 
1082
      bfd_put_8 (abfd, addend, address);
1083
      return bfd_reloc_ok;
1084
 
1085
    case R_V850_CALLT_16_16_OFFSET:
1086
      addend += bfd_get_16 (abfd, address);
1087
 
1088
      saddend = (bfd_signed_vma) addend;
1089
 
1090
      if (saddend > 0xffff || saddend < 0)
1091
        return bfd_reloc_overflow;
1092
 
1093
      insn = addend;
1094
      break;
1095
 
1096
    case R_V850_16:
1097
 
1098
      /* drop through */
1099
    case R_V850_SDA_16_16_OFFSET:
1100
    case R_V850_ZDA_16_16_OFFSET:
1101
    case R_V850_TDA_16_16_OFFSET:
1102
      addend += bfd_get_16 (abfd, address);
1103
 
1104
      saddend = (bfd_signed_vma) addend;
1105
 
1106
      if (saddend > 0x7fff || saddend < -0x8000)
1107
        return bfd_reloc_overflow;
1108
 
1109
      insn = addend;
1110
      break;
1111
 
1112
    case R_V850_SDA_15_16_OFFSET:
1113
    case R_V850_ZDA_15_16_OFFSET:
1114
      insn = bfd_get_16 (abfd, address);
1115
      addend += (insn & 0xfffe);
1116
 
1117
      saddend = (bfd_signed_vma) addend;
1118
 
1119
      if (saddend > 0x7ffe || saddend < -0x8000)
1120
        return bfd_reloc_overflow;
1121
 
1122
      if (addend & 1)
1123
        return bfd_reloc_dangerous;
1124
 
1125
      insn = (addend & ~1) | (insn & 1);
1126
      break;
1127
 
1128
    case R_V850_TDA_6_8_OFFSET:
1129
      insn = bfd_get_16 (abfd, address);
1130
      addend += ((insn & 0x7e) << 1);
1131
 
1132
      saddend = (bfd_signed_vma) addend;
1133
 
1134
      if (saddend > 0xfc || saddend < 0)
1135
        return bfd_reloc_overflow;
1136
 
1137
      if (addend & 3)
1138
        return bfd_reloc_dangerous;
1139
 
1140
      insn &= 0xff81;
1141
      insn |= (addend >> 1);
1142
      break;
1143
 
1144
    case R_V850_TDA_7_8_OFFSET:
1145
      insn = bfd_get_16 (abfd, address);
1146
      addend += ((insn & 0x7f) << 1);
1147
 
1148
      saddend = (bfd_signed_vma) addend;
1149
 
1150
      if (saddend > 0xfe || saddend < 0)
1151
        return bfd_reloc_overflow;
1152
 
1153
      if (addend & 1)
1154
        return bfd_reloc_dangerous;
1155
 
1156
      insn &= 0xff80;
1157
      insn |= (addend >> 1);
1158
      break;
1159
 
1160
    case R_V850_TDA_7_7_OFFSET:
1161
      insn = bfd_get_16 (abfd, address);
1162
      addend += insn & 0x7f;
1163
 
1164
      saddend = (bfd_signed_vma) addend;
1165
 
1166
      if (saddend > 0x7f || saddend < 0)
1167
        return bfd_reloc_overflow;
1168
 
1169
      insn &= 0xff80;
1170
      insn |= addend;
1171
      break;
1172
 
1173
    case R_V850_TDA_4_5_OFFSET:
1174
      insn = bfd_get_16 (abfd, address);
1175
      addend += ((insn & 0xf) << 1);
1176
 
1177
      saddend = (bfd_signed_vma) addend;
1178
 
1179
      if (saddend > 0x1e || saddend < 0)
1180
        return bfd_reloc_overflow;
1181
 
1182
      if (addend & 1)
1183
        return bfd_reloc_dangerous;
1184
 
1185
      insn &= 0xfff0;
1186
      insn |= (addend >> 1);
1187
      break;
1188
 
1189
    case R_V850_TDA_4_4_OFFSET:
1190
      insn = bfd_get_16 (abfd, address);
1191
      addend += insn & 0xf;
1192
 
1193
      saddend = (bfd_signed_vma) addend;
1194
 
1195
      if (saddend > 0xf || saddend < 0)
1196
        return bfd_reloc_overflow;
1197
 
1198
      insn &= 0xfff0;
1199
      insn |= addend;
1200
      break;
1201
 
1202
    case R_V850_ZDA_16_16_SPLIT_OFFSET:
1203
    case R_V850_SDA_16_16_SPLIT_OFFSET:
1204
      insn = bfd_get_32 (abfd, address);
1205
      addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5);
1206
 
1207
      saddend = (bfd_signed_vma) addend;
1208
 
1209
      if (saddend > 0x7fff || saddend < -0x8000)
1210
        return bfd_reloc_overflow;
1211
 
1212
      insn &= 0x0001ffdf;
1213
      insn |= (addend & 1) << 5;
1214
      insn |= (addend & ~1) << 16;
1215
 
1216
      bfd_put_32 (abfd, insn, address);
1217
      return bfd_reloc_ok;
1218
 
1219
    case R_V850_CALLT_6_7_OFFSET:
1220
      insn = bfd_get_16 (abfd, address);
1221
      addend += ((insn & 0x3f) << 1);
1222
 
1223
      saddend = (bfd_signed_vma) addend;
1224
 
1225
      if (saddend > 0x7e || saddend < 0)
1226
        return bfd_reloc_overflow;
1227
 
1228
      if (addend & 1)
1229
        return bfd_reloc_dangerous;
1230
 
1231
      insn &= 0xff80;
1232
      insn |= (addend >> 1);
1233
      break;
1234
 
1235
    case R_V850_GNU_VTINHERIT:
1236
    case R_V850_GNU_VTENTRY:
1237
      return bfd_reloc_ok;
1238
 
1239
    }
1240
 
1241
  bfd_put_16 (abfd, insn, address);
1242
  return bfd_reloc_ok;
1243
}
1244
 
1245
/* Insert the addend into the instruction.  */
1246
static bfd_reloc_status_type
1247
v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
1248
     bfd *       abfd ATTRIBUTE_UNUSED;
1249
     arelent *   reloc;
1250
     asymbol *   symbol;
1251
     PTR         data ATTRIBUTE_UNUSED;
1252
     asection *  isection;
1253
     bfd *       obfd;
1254
     char **     err ATTRIBUTE_UNUSED;
1255
{
1256
  long relocation;
1257
 
1258
  /* If there is an output BFD,
1259
     and the symbol is not a section name (which is only defined at final link time),
1260
     and either we are not putting the addend into the instruction
1261
         or the addend is zero, so there is nothing to add into the instruction
1262
     then just fixup the address and return.  */
1263
  if (obfd != (bfd *) NULL
1264
      && (symbol->flags & BSF_SECTION_SYM) == 0
1265
      && (! reloc->howto->partial_inplace
1266
          || reloc->addend == 0))
1267
    {
1268
      reloc->address += isection->output_offset;
1269
      return bfd_reloc_ok;
1270
    }
1271
#if 0
1272
  else if (obfd != NULL)
1273
    {
1274
      return bfd_reloc_continue;
1275
    }
1276
#endif
1277
 
1278
  /* Catch relocs involving undefined symbols.  */
1279
  if (bfd_is_und_section (symbol->section)
1280
      && (symbol->flags & BSF_WEAK) == 0
1281
      && obfd == NULL)
1282
    return bfd_reloc_undefined;
1283
 
1284
  /* We handle final linking of some relocs ourselves.  */
1285
 
1286
  /* Is the address of the relocation really within the section?  */
1287
  if (reloc->address > isection->_cooked_size)
1288
    return bfd_reloc_outofrange;
1289
 
1290
  /* Work out which section the relocation is targetted at and the
1291
     initial relocation command value.  */
1292
 
1293
  /* Get symbol value.  (Common symbols are special.)  */
1294
  if (bfd_is_com_section (symbol->section))
1295
    relocation = 0;
1296
  else
1297
    relocation = symbol->value;
1298
 
1299
  /* Convert input-section-relative symbol value to absolute + addend.  */
1300
  relocation += symbol->section->output_section->vma;
1301
  relocation += symbol->section->output_offset;
1302
  relocation += reloc->addend;
1303
 
1304
#if 0 /* Since this reloc is going to be processed later on, we should
1305
         not make it pc-relative here.  To test this, try assembling and
1306
         linking this program:
1307
 
1308
                .text
1309
                .globl _start
1310
                nop
1311
        _start:
1312
                jr foo
1313
 
1314
                .section ".foo","ax"
1315
                nop
1316
        foo:
1317
                nop
1318
      */
1319
  if (reloc->howto->pc_relative == true)
1320
    {
1321
      /* Here the variable relocation holds the final address of the
1322
         symbol we are relocating against, plus any addend.  */
1323
      relocation -= isection->output_section->vma + isection->output_offset;
1324
 
1325
      /* Deal with pcrel_offset */
1326
      relocation -= reloc->address;
1327
    }
1328
#endif
1329
  reloc->addend = relocation;
1330
  return bfd_reloc_ok;
1331
}
1332
 
1333
static boolean
1334
v850_elf_is_local_label_name (abfd, name)
1335
     bfd *         abfd ATTRIBUTE_UNUSED;
1336
     const char *  name;
1337
{
1338
  return (   (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
1339
          || (name[0] == '_' &&  name[1] == '.' && name[2] == 'L' && name[3] == '_'));
1340
}
1341
 
1342
/* Perform a relocation as part of a final link.  */
1343
static bfd_reloc_status_type
1344
v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
1345
                                    input_section, contents, offset, value,
1346
                                    addend, info, sym_sec, is_local)
1347
     reloc_howto_type *      howto;
1348
     bfd *                   input_bfd;
1349
     bfd *                   output_bfd ATTRIBUTE_UNUSED;
1350
     asection *              input_section;
1351
     bfd_byte *              contents;
1352
     bfd_vma                 offset;
1353
     bfd_vma                 value;
1354
     bfd_vma                 addend;
1355
     struct bfd_link_info *  info;
1356
     asection *              sym_sec;
1357
     int                     is_local ATTRIBUTE_UNUSED;
1358
{
1359
  unsigned long  r_type   = howto->type;
1360
  bfd_byte *     hit_data = contents + offset;
1361
 
1362
  /* Adjust the value according to the relocation.  */
1363
  switch (r_type)
1364
    {
1365
    case R_V850_9_PCREL:
1366
      value -= (input_section->output_section->vma
1367
                + input_section->output_offset);
1368
      value -= offset;
1369
      break;
1370
 
1371
    case R_V850_22_PCREL:
1372
      value -= (input_section->output_section->vma
1373
                + input_section->output_offset
1374
                + offset);
1375
 
1376
      /* If the sign extension will corrupt the value then we have overflowed.  */
1377
      if (((value & 0xff000000) != 0x0) && ((value & 0xff000000) != 0xff000000))
1378
        return bfd_reloc_overflow;
1379
 
1380
      value = SEXT24 (value);  /* Only the bottom 24 bits of the PC are valid */
1381
      break;
1382
 
1383
    case R_V850_HI16_S:
1384
    case R_V850_HI16:
1385
    case R_V850_LO16:
1386
    case R_V850_16:
1387
    case R_V850_32:
1388
    case R_V850_8:
1389
      break;
1390
 
1391
    case R_V850_ZDA_15_16_OFFSET:
1392
    case R_V850_ZDA_16_16_OFFSET:
1393
    case R_V850_ZDA_16_16_SPLIT_OFFSET:
1394
      if (sym_sec == NULL)
1395
        return bfd_reloc_undefined;
1396
 
1397
      value -= sym_sec->output_section->vma;
1398
      break;
1399
 
1400
    case R_V850_SDA_15_16_OFFSET:
1401
    case R_V850_SDA_16_16_OFFSET:
1402
    case R_V850_SDA_16_16_SPLIT_OFFSET:
1403
      {
1404
        unsigned long                gp;
1405
        struct bfd_link_hash_entry * h;
1406
 
1407
        if (sym_sec == NULL)
1408
          return bfd_reloc_undefined;
1409
 
1410
        /* Get the value of __gp.  */
1411
        h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1412
        if (h == (struct bfd_link_hash_entry *) NULL
1413
            || h->type != bfd_link_hash_defined)
1414
          return bfd_reloc_other;
1415
 
1416
        gp = (h->u.def.value
1417
              + h->u.def.section->output_section->vma
1418
              + h->u.def.section->output_offset);
1419
 
1420
        value -= sym_sec->output_section->vma;
1421
        value -= (gp - sym_sec->output_section->vma);
1422
      }
1423
    break;
1424
 
1425
    case R_V850_TDA_4_4_OFFSET:
1426
    case R_V850_TDA_4_5_OFFSET:
1427
    case R_V850_TDA_16_16_OFFSET:
1428
    case R_V850_TDA_7_7_OFFSET:
1429
    case R_V850_TDA_7_8_OFFSET:
1430
    case R_V850_TDA_6_8_OFFSET:
1431
      {
1432
        unsigned long                ep;
1433
        struct bfd_link_hash_entry * h;
1434
 
1435
        /* Get the value of __ep.  */
1436
        h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1437
        if (h == (struct bfd_link_hash_entry *) NULL
1438
            || h->type != bfd_link_hash_defined)
1439
          return bfd_reloc_continue;  /* Actually this indicates that __ep could not be found.  */
1440
 
1441
        ep = (h->u.def.value
1442
              + h->u.def.section->output_section->vma
1443
              + h->u.def.section->output_offset);
1444
 
1445
        value -= ep;
1446
      }
1447
    break;
1448
 
1449
    case R_V850_CALLT_6_7_OFFSET:
1450
      {
1451
        unsigned long                ctbp;
1452
        struct bfd_link_hash_entry * h;
1453
 
1454
        /* Get the value of __ctbp.  */
1455
        h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
1456
        if (h == (struct bfd_link_hash_entry *) NULL
1457
            || h->type != bfd_link_hash_defined)
1458
          return (bfd_reloc_dangerous + 1);  /* Actually this indicates that __ctbp could not be found.  */
1459
 
1460
        ctbp = (h->u.def.value
1461
              + h->u.def.section->output_section->vma
1462
              + h->u.def.section->output_offset);
1463
        value -= ctbp;
1464
      }
1465
    break;
1466
 
1467
    case R_V850_CALLT_16_16_OFFSET:
1468
      {
1469
        unsigned long                ctbp;
1470
        struct bfd_link_hash_entry * h;
1471
 
1472
        if (sym_sec == NULL)
1473
          return bfd_reloc_undefined;
1474
 
1475
        /* Get the value of __ctbp.  */
1476
        h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
1477
        if (h == (struct bfd_link_hash_entry *) NULL
1478
            || h->type != bfd_link_hash_defined)
1479
          return (bfd_reloc_dangerous + 1);
1480
 
1481
        ctbp = (h->u.def.value
1482
              + h->u.def.section->output_section->vma
1483
              + h->u.def.section->output_offset);
1484
 
1485
        value -= sym_sec->output_section->vma;
1486
        value -= (ctbp - sym_sec->output_section->vma);
1487
      }
1488
    break;
1489
 
1490
    case R_V850_NONE:
1491
    case R_V850_GNU_VTINHERIT:
1492
    case R_V850_GNU_VTENTRY:
1493
      return bfd_reloc_ok;
1494
 
1495
    default:
1496
      return bfd_reloc_notsupported;
1497
    }
1498
 
1499
  /* Perform the relocation.  */
1500
  return v850_elf_perform_relocation (input_bfd, r_type, value + addend, hit_data);
1501
}
1502
 
1503
/* Relocate an V850 ELF section.  */
1504
static boolean
1505
v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
1506
                           contents, relocs, local_syms, local_sections)
1507
     bfd *                  output_bfd;
1508
     struct bfd_link_info * info;
1509
     bfd *                  input_bfd;
1510
     asection *             input_section;
1511
     bfd_byte *             contents;
1512
     Elf_Internal_Rela *    relocs;
1513
     Elf_Internal_Sym *     local_syms;
1514
     asection **            local_sections;
1515
{
1516
  Elf_Internal_Shdr *           symtab_hdr;
1517
  struct elf_link_hash_entry ** sym_hashes;
1518
  Elf_Internal_Rela *           rel;
1519
  Elf_Internal_Rela *           relend;
1520
 
1521
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
1522
  sym_hashes = elf_sym_hashes (input_bfd);
1523
 
1524
  if (sym_hashes == NULL)
1525
    {
1526
      info->callbacks->warning
1527
        (info, "no hash table available", NULL, input_bfd, input_section, 0);
1528
 
1529
      return false;
1530
    }
1531
 
1532
  /* Reset the list of remembered HI16S relocs to empty.  */
1533
  free_hi16s     = previous_hi16s;
1534
  previous_hi16s = NULL;
1535
  hi16s_counter  = 0;
1536
 
1537
  rel    = relocs;
1538
  relend = relocs + input_section->reloc_count;
1539
  for (; rel < relend; rel++)
1540
    {
1541
      int                          r_type;
1542
      reloc_howto_type *           howto;
1543
      unsigned long                r_symndx;
1544
      Elf_Internal_Sym *           sym;
1545
      asection *                   sec;
1546
      struct elf_link_hash_entry * h;
1547
      bfd_vma                      relocation;
1548
      bfd_reloc_status_type        r;
1549
 
1550
      r_symndx = ELF32_R_SYM (rel->r_info);
1551
      r_type   = ELF32_R_TYPE (rel->r_info);
1552
 
1553
      if (r_type == R_V850_GNU_VTENTRY
1554
          || r_type == R_V850_GNU_VTINHERIT)
1555
        continue;
1556
 
1557
      howto = v850_elf_howto_table + r_type;
1558
 
1559
      if (info->relocateable)
1560
        {
1561
          /* This is a relocateable link.  We don't have to change
1562
             anything, unless the reloc is against a section symbol,
1563
             in which case we have to adjust according to where the
1564
             section symbol winds up in the output section.  */
1565
          if (r_symndx < symtab_hdr->sh_info)
1566
            {
1567
              sym = local_syms + r_symndx;
1568
              if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1569
                {
1570
                  sec = local_sections[r_symndx];
1571
                  rel->r_addend += sec->output_offset + sym->st_value;
1572
                }
1573
            }
1574
 
1575
          continue;
1576
        }
1577
 
1578
      /* This is a final link.  */
1579
      h = NULL;
1580
      sym = NULL;
1581
      sec = NULL;
1582
      if (r_symndx < symtab_hdr->sh_info)
1583
        {
1584
          sym = local_syms + r_symndx;
1585
          sec = local_sections[r_symndx];
1586
          relocation = (sec->output_section->vma
1587
                        + sec->output_offset
1588
                        + sym->st_value);
1589
#if 0
1590
          {
1591
            char * name;
1592
            name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name);
1593
            name = (name == NULL) ? "<none>" : name;
1594
fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
1595
         sec->name, name, sym->st_name,
1596
         sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend);
1597
          }
1598
#endif
1599
        }
1600
      else
1601
        {
1602
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1603
 
1604
          while (h->root.type == bfd_link_hash_indirect
1605
                 || h->root.type == bfd_link_hash_warning)
1606
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
1607
 
1608
          if (h->root.type == bfd_link_hash_defined
1609
              || h->root.type == bfd_link_hash_defweak)
1610
            {
1611
              sec = h->root.u.def.section;
1612
              relocation = (h->root.u.def.value
1613
                            + sec->output_section->vma
1614
                            + sec->output_offset);
1615
#if 0
1616
fprintf (stderr, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
1617
         sec->name, h->root.root.string, h->root.u.def.value, sec->output_section->vma, sec->output_offset, relocation);
1618
#endif
1619
            }
1620
          else if (h->root.type == bfd_link_hash_undefweak)
1621
            {
1622
#if 0
1623
fprintf (stderr, "undefined: sec: %s, name: %s\n",
1624
         sec->name, h->root.root.string);
1625
#endif
1626
              relocation = 0;
1627
            }
1628
          else
1629
            {
1630
              if (! ((*info->callbacks->undefined_symbol)
1631
                     (info, h->root.root.string, input_bfd,
1632
                      input_section, rel->r_offset, true)))
1633
                return false;
1634
#if 0
1635
fprintf (stderr, "unknown: name: %s\n", h->root.root.string);
1636
#endif
1637
              relocation = 0;
1638
            }
1639
        }
1640
 
1641
      /* FIXME: We should use the addend, but the COFF relocations
1642
         don't.  */
1643
      r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
1644
                                        input_section,
1645
                                        contents, rel->r_offset,
1646
                                        relocation, rel->r_addend,
1647
                                        info, sec, h == NULL);
1648
 
1649
      if (r != bfd_reloc_ok)
1650
        {
1651
          const char * name;
1652
          const char * msg = (const char *)0;
1653
 
1654
          if (h != NULL)
1655
            name = h->root.root.string;
1656
          else
1657
            {
1658
              name = (bfd_elf_string_from_elf_section
1659
                      (input_bfd, symtab_hdr->sh_link, sym->st_name));
1660
              if (name == NULL || *name == '\0')
1661
                name = bfd_section_name (input_bfd, sec);
1662
            }
1663
 
1664
          switch (r)
1665
            {
1666
            case bfd_reloc_overflow:
1667
              if (! ((*info->callbacks->reloc_overflow)
1668
                     (info, name, howto->name, (bfd_vma) 0,
1669
                      input_bfd, input_section, rel->r_offset)))
1670
                return false;
1671
              break;
1672
 
1673
            case bfd_reloc_undefined:
1674
              if (! ((*info->callbacks->undefined_symbol)
1675
                     (info, name, input_bfd, input_section,
1676
                      rel->r_offset, true)))
1677
                return false;
1678
              break;
1679
 
1680
            case bfd_reloc_outofrange:
1681
              msg = _("internal error: out of range error");
1682
              goto common_error;
1683
 
1684
            case bfd_reloc_notsupported:
1685
              msg = _("internal error: unsupported relocation error");
1686
              goto common_error;
1687
 
1688
            case bfd_reloc_dangerous:
1689
              msg = _("internal error: dangerous relocation");
1690
              goto common_error;
1691
 
1692
            case bfd_reloc_other:
1693
              msg = _("could not locate special linker symbol __gp");
1694
              goto common_error;
1695
 
1696
            case bfd_reloc_continue:
1697
              msg = _("could not locate special linker symbol __ep");
1698
              goto common_error;
1699
 
1700
            case (bfd_reloc_dangerous + 1):
1701
              msg = _("could not locate special linker symbol __ctbp");
1702
              goto common_error;
1703
 
1704
            default:
1705
              msg = _("internal error: unknown error");
1706
              /* fall through */
1707
 
1708
            common_error:
1709
              if (!((*info->callbacks->warning)
1710
                    (info, msg, name, input_bfd, input_section,
1711
                     rel->r_offset)))
1712
                return false;
1713
              break;
1714
            }
1715
        }
1716
    }
1717
 
1718
  return true;
1719
}
1720
 
1721
static boolean
1722
v850_elf_gc_sweep_hook (abfd, info, sec, relocs)
1723
     bfd *abfd ATTRIBUTE_UNUSED;
1724
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
1725
     asection *sec ATTRIBUTE_UNUSED;
1726
     const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
1727
{
1728
  /* No got and plt entries for v850-elf */
1729
  return true;
1730
}
1731
 
1732
static asection *
1733
v850_elf_gc_mark_hook (abfd, info, rel, h, sym)
1734
       bfd *abfd;
1735
       struct bfd_link_info *info ATTRIBUTE_UNUSED;
1736
       Elf_Internal_Rela *rel;
1737
       struct elf_link_hash_entry *h;
1738
       Elf_Internal_Sym *sym;
1739
{
1740
  if (h != NULL)
1741
    {
1742
      switch (ELF32_R_TYPE (rel->r_info))
1743
      {
1744
      case R_V850_GNU_VTINHERIT:
1745
      case R_V850_GNU_VTENTRY:
1746
        break;
1747
 
1748
      default:
1749
        switch (h->root.type)
1750
          {
1751
          case bfd_link_hash_defined:
1752
          case bfd_link_hash_defweak:
1753
            return h->root.u.def.section;
1754
 
1755
          case bfd_link_hash_common:
1756
            return h->root.u.c.p->section;
1757
 
1758
          default:
1759
            break;
1760
          }
1761
       }
1762
     }
1763
   else
1764
     {
1765
       if (!(elf_bad_symtab (abfd)
1766
           && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
1767
         && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
1768
                && sym->st_shndx != SHN_COMMON))
1769
          {
1770
            return bfd_section_from_elf_index (abfd, sym->st_shndx);
1771
          }
1772
      }
1773
  return NULL;
1774
}
1775
/* Set the right machine number.  */
1776
static boolean
1777
v850_elf_object_p (abfd)
1778
     bfd *abfd;
1779
{
1780
  switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1781
    {
1782
    default:
1783
    case E_V850_ARCH:   (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, 0); break;
1784
    case E_V850E_ARCH:  (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e); break;
1785
    case E_V850EA_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850ea); break;
1786
    }
1787
  return true;
1788
}
1789
 
1790
/* Store the machine number in the flags field.  */
1791
static void
1792
v850_elf_final_write_processing (abfd, linker)
1793
     bfd *   abfd;
1794
     boolean linker ATTRIBUTE_UNUSED;
1795
{
1796
  unsigned long val;
1797
 
1798
  switch (bfd_get_mach (abfd))
1799
    {
1800
    default:
1801
    case 0: val = E_V850_ARCH; break;
1802
    case bfd_mach_v850e:  val = E_V850E_ARCH; break;
1803
    case bfd_mach_v850ea: val = E_V850EA_ARCH;  break;
1804
    }
1805
 
1806
  elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
1807
  elf_elfheader (abfd)->e_flags |= val;
1808
}
1809
 
1810
/* Function to keep V850 specific file flags.  */
1811
static boolean
1812
v850_elf_set_private_flags (abfd, flags)
1813
     bfd *    abfd;
1814
     flagword flags;
1815
{
1816
  BFD_ASSERT (!elf_flags_init (abfd)
1817
              || elf_elfheader (abfd)->e_flags == flags);
1818
 
1819
  elf_elfheader (abfd)->e_flags = flags;
1820
  elf_flags_init (abfd) = true;
1821
  return true;
1822
}
1823
 
1824
/* Copy backend specific data from one object module to another */
1825
static boolean
1826
v850_elf_copy_private_bfd_data (ibfd, obfd)
1827
     bfd * ibfd;
1828
     bfd * obfd;
1829
{
1830
  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1831
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1832
    return true;
1833
 
1834
  BFD_ASSERT (!elf_flags_init (obfd)
1835
              || (elf_elfheader (obfd)->e_flags
1836
                  == elf_elfheader (ibfd)->e_flags));
1837
 
1838
  elf_gp (obfd) = elf_gp (ibfd);
1839
  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
1840
  elf_flags_init (obfd) = true;
1841
  return true;
1842
}
1843
 
1844
/* Merge backend specific data from an object file to the output
1845
   object file when linking.  */
1846
static boolean
1847
v850_elf_merge_private_bfd_data (ibfd, obfd)
1848
     bfd * ibfd;
1849
     bfd * obfd;
1850
{
1851
  flagword out_flags;
1852
  flagword in_flags;
1853
 
1854
  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1855
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1856
    return true;
1857
 
1858
  in_flags = elf_elfheader (ibfd)->e_flags;
1859
  out_flags = elf_elfheader (obfd)->e_flags;
1860
 
1861
  if (! elf_flags_init (obfd))
1862
    {
1863
      /* If the input is the default architecture then do not
1864
         bother setting the flags for the output architecture,
1865
         instead allow future merges to do this.  If no future
1866
         merges ever set these flags then they will retain their
1867
         unitialised values, which surprise surprise, correspond
1868
         to the default values.  */
1869
      if (bfd_get_arch_info (ibfd)->the_default)
1870
        return true;
1871
 
1872
      elf_flags_init (obfd) = true;
1873
      elf_elfheader (obfd)->e_flags = in_flags;
1874
 
1875
      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1876
          && bfd_get_arch_info (obfd)->the_default)
1877
        {
1878
          return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1879
        }
1880
 
1881
      return true;
1882
    }
1883
 
1884
  /* Check flag compatibility.  */
1885
  if (in_flags == out_flags)
1886
    return true;
1887
 
1888
  if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)
1889
      && (in_flags & EF_V850_ARCH) != E_V850_ARCH)
1890
    _bfd_error_handler (_("%s: Architecture mismatch with previous modules"),
1891
                        bfd_get_filename (ibfd));
1892
 
1893
  return true;
1894
}
1895
/* Display the flags field */
1896
 
1897
static boolean
1898
v850_elf_print_private_bfd_data (abfd, ptr)
1899
     bfd *   abfd;
1900
     PTR     ptr;
1901
{
1902
  FILE * file = (FILE *) ptr;
1903
 
1904
  BFD_ASSERT (abfd != NULL && ptr != NULL);
1905
 
1906
  _bfd_elf_print_private_bfd_data (abfd, ptr);
1907
 
1908
  /* xgettext:c-format */
1909
  fprintf (file, _("private flags = %lx: "), elf_elfheader (abfd)->e_flags);
1910
 
1911
  switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1912
    {
1913
    default:
1914
    case E_V850_ARCH: fprintf (file, _("v850 architecture")); break;
1915
    case E_V850E_ARCH:  fprintf (file, _("v850e architecture")); break;
1916
    case E_V850EA_ARCH: fprintf (file, _("v850ea architecture")); break;
1917
    }
1918
 
1919
  fputc ('\n', file);
1920
 
1921
  return true;
1922
}
1923
 
1924
/* V850 ELF uses four common sections.  One is the usual one, and the
1925
   others are for (small) objects in one of the special data areas:
1926
   small, tiny and zero.  All the objects are kept together, and then
1927
   referenced via the gp register, the ep register or the r0 register
1928
   respectively, which yields smaller, faster assembler code.  This
1929
   approach is copied from elf32-mips.c.  */
1930
 
1931
static asection  v850_elf_scom_section;
1932
static asymbol   v850_elf_scom_symbol;
1933
static asymbol * v850_elf_scom_symbol_ptr;
1934
static asection  v850_elf_tcom_section;
1935
static asymbol   v850_elf_tcom_symbol;
1936
static asymbol * v850_elf_tcom_symbol_ptr;
1937
static asection  v850_elf_zcom_section;
1938
static asymbol   v850_elf_zcom_symbol;
1939
static asymbol * v850_elf_zcom_symbol_ptr;
1940
 
1941
/* Given a BFD section, try to locate the corresponding ELF section
1942
   index.  */
1943
 
1944
static boolean
1945
v850_elf_section_from_bfd_section (abfd, hdr, sec, retval)
1946
     bfd *                 abfd ATTRIBUTE_UNUSED;
1947
     Elf32_Internal_Shdr * hdr ATTRIBUTE_UNUSED;
1948
     asection *            sec;
1949
     int *                 retval;
1950
{
1951
  if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
1952
    *retval = SHN_V850_SCOMMON;
1953
  else if (strcmp (bfd_get_section_name (abfd, sec), ".tcommon") == 0)
1954
    *retval = SHN_V850_TCOMMON;
1955
  else if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
1956
    *retval = SHN_V850_ZCOMMON;
1957
  else
1958
    return false;
1959
 
1960
  return true;
1961
}
1962
 
1963
/* Handle the special V850 section numbers that a symbol may use.  */
1964
 
1965
static void
1966
v850_elf_symbol_processing (abfd, asym)
1967
     bfd *     abfd;
1968
     asymbol * asym;
1969
{
1970
  elf_symbol_type * elfsym = (elf_symbol_type *) asym;
1971
  unsigned short index;
1972
 
1973
  index = elfsym->internal_elf_sym.st_shndx;
1974
 
1975
  /* If the section index is an "ordinary" index, then it may
1976
     refer to a v850 specific section created by the assembler.
1977
     Check the section's type and change the index it matches.
1978
 
1979
     FIXME: Should we alter the st_shndx field as well ?  */
1980
 
1981
  if (index < elf_elfheader(abfd)[0].e_shnum)
1982
    switch (elf_elfsections(abfd)[index]->sh_type)
1983
      {
1984
      case SHT_V850_SCOMMON:
1985
        index = SHN_V850_SCOMMON;
1986
        break;
1987
 
1988
      case SHT_V850_TCOMMON:
1989
        index = SHN_V850_TCOMMON;
1990
        break;
1991
 
1992
      case SHT_V850_ZCOMMON:
1993
        index = SHN_V850_ZCOMMON;
1994
        break;
1995
 
1996
      default:
1997
        break;
1998
      }
1999
 
2000
  switch (index)
2001
    {
2002
    case SHN_V850_SCOMMON:
2003
      if (v850_elf_scom_section.name == NULL)
2004
        {
2005
          /* Initialize the small common section.  */
2006
          v850_elf_scom_section.name           = ".scommon";
2007
          v850_elf_scom_section.flags          = SEC_IS_COMMON | SEC_ALLOC | SEC_DATA;
2008
          v850_elf_scom_section.output_section = & v850_elf_scom_section;
2009
          v850_elf_scom_section.symbol         = & v850_elf_scom_symbol;
2010
          v850_elf_scom_section.symbol_ptr_ptr = & v850_elf_scom_symbol_ptr;
2011
          v850_elf_scom_symbol.name            = ".scommon";
2012
          v850_elf_scom_symbol.flags           = BSF_SECTION_SYM;
2013
          v850_elf_scom_symbol.section         = & v850_elf_scom_section;
2014
          v850_elf_scom_symbol_ptr             = & v850_elf_scom_symbol;
2015
        }
2016
      asym->section = & v850_elf_scom_section;
2017
      asym->value = elfsym->internal_elf_sym.st_size;
2018
      break;
2019
 
2020
    case SHN_V850_TCOMMON:
2021
      if (v850_elf_tcom_section.name == NULL)
2022
        {
2023
          /* Initialize the tcommon section.  */
2024
          v850_elf_tcom_section.name           = ".tcommon";
2025
          v850_elf_tcom_section.flags          = SEC_IS_COMMON;
2026
          v850_elf_tcom_section.output_section = & v850_elf_tcom_section;
2027
          v850_elf_tcom_section.symbol         = & v850_elf_tcom_symbol;
2028
          v850_elf_tcom_section.symbol_ptr_ptr = & v850_elf_tcom_symbol_ptr;
2029
          v850_elf_tcom_symbol.name            = ".tcommon";
2030
          v850_elf_tcom_symbol.flags           = BSF_SECTION_SYM;
2031
          v850_elf_tcom_symbol.section         = & v850_elf_tcom_section;
2032
          v850_elf_tcom_symbol_ptr             = & v850_elf_tcom_symbol;
2033
        }
2034
      asym->section = & v850_elf_tcom_section;
2035
      asym->value = elfsym->internal_elf_sym.st_size;
2036
      break;
2037
 
2038
    case SHN_V850_ZCOMMON:
2039
      if (v850_elf_zcom_section.name == NULL)
2040
        {
2041
          /* Initialize the zcommon section.  */
2042
          v850_elf_zcom_section.name           = ".zcommon";
2043
          v850_elf_zcom_section.flags          = SEC_IS_COMMON;
2044
          v850_elf_zcom_section.output_section = & v850_elf_zcom_section;
2045
          v850_elf_zcom_section.symbol         = & v850_elf_zcom_symbol;
2046
          v850_elf_zcom_section.symbol_ptr_ptr = & v850_elf_zcom_symbol_ptr;
2047
          v850_elf_zcom_symbol.name            = ".zcommon";
2048
          v850_elf_zcom_symbol.flags           = BSF_SECTION_SYM;
2049
          v850_elf_zcom_symbol.section         = & v850_elf_zcom_section;
2050
          v850_elf_zcom_symbol_ptr             = & v850_elf_zcom_symbol;
2051
        }
2052
      asym->section = & v850_elf_zcom_section;
2053
      asym->value = elfsym->internal_elf_sym.st_size;
2054
      break;
2055
    }
2056
}
2057
 
2058
/* Hook called by the linker routine which adds symbols from an object
2059
   file.  We must handle the special v850 section numbers here.  */
2060
 
2061
static boolean
2062
v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
2063
     bfd *                    abfd;
2064
     struct bfd_link_info *   info ATTRIBUTE_UNUSED;
2065
     const Elf_Internal_Sym * sym;
2066
     const char **            namep ATTRIBUTE_UNUSED;
2067
     flagword *               flagsp ATTRIBUTE_UNUSED;
2068
     asection **              secp;
2069
     bfd_vma *                valp;
2070
{
2071
  int index = sym->st_shndx;
2072
 
2073
  /* If the section index is an "ordinary" index, then it may
2074
     refer to a v850 specific section created by the assembler.
2075
     Check the section's type and change the index it matches.
2076
 
2077
     FIXME: Should we alter the st_shndx field as well ?  */
2078
 
2079
  if (index < elf_elfheader(abfd)[0].e_shnum)
2080
    switch (elf_elfsections(abfd)[index]->sh_type)
2081
      {
2082
      case SHT_V850_SCOMMON:
2083
        index = SHN_V850_SCOMMON;
2084
        break;
2085
 
2086
      case SHT_V850_TCOMMON:
2087
        index = SHN_V850_TCOMMON;
2088
        break;
2089
 
2090
      case SHT_V850_ZCOMMON:
2091
        index = SHN_V850_ZCOMMON;
2092
        break;
2093
 
2094
      default:
2095
        break;
2096
      }
2097
 
2098
  switch (index)
2099
    {
2100
    case SHN_V850_SCOMMON:
2101
      *secp = bfd_make_section_old_way (abfd, ".scommon");
2102
      (*secp)->flags |= SEC_IS_COMMON;
2103
      *valp = sym->st_size;
2104
      break;
2105
 
2106
    case SHN_V850_TCOMMON:
2107
      *secp = bfd_make_section_old_way (abfd, ".tcommon");
2108
      (*secp)->flags |= SEC_IS_COMMON;
2109
      *valp = sym->st_size;
2110
      break;
2111
 
2112
    case SHN_V850_ZCOMMON:
2113
      *secp = bfd_make_section_old_way (abfd, ".zcommon");
2114
      (*secp)->flags |= SEC_IS_COMMON;
2115
      *valp = sym->st_size;
2116
      break;
2117
    }
2118
 
2119
  return true;
2120
}
2121
 
2122
/*ARGSIGNORED*/
2123
static boolean
2124
v850_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
2125
     bfd *                  abfd ATTRIBUTE_UNUSED;
2126
     struct bfd_link_info * info ATTRIBUTE_UNUSED;
2127
     const char *           name ATTRIBUTE_UNUSED;
2128
     Elf_Internal_Sym *     sym;
2129
     asection *             input_sec;
2130
{
2131
  /* If we see a common symbol, which implies a relocatable link, then
2132
     if a symbol was in a special common section in an input file, mark
2133
     it as a special common in the output file.  */
2134
 
2135
  if (sym->st_shndx == SHN_COMMON)
2136
    {
2137
      if (strcmp (input_sec->name, ".scommon") == 0)
2138
        sym->st_shndx = SHN_V850_SCOMMON;
2139
      else if (strcmp (input_sec->name, ".tcommon") == 0)
2140
        sym->st_shndx = SHN_V850_TCOMMON;
2141
      else if (strcmp (input_sec->name, ".zcommon") == 0)
2142
        sym->st_shndx = SHN_V850_ZCOMMON;
2143
    }
2144
 
2145
  return true;
2146
}
2147
 
2148
static boolean
2149
v850_elf_section_from_shdr (abfd, hdr, name)
2150
     bfd *               abfd;
2151
     Elf_Internal_Shdr * hdr;
2152
     char *              name;
2153
{
2154
  /* There ought to be a place to keep ELF backend specific flags, but
2155
     at the moment there isn't one.  We just keep track of the
2156
     sections by their name, instead.  */
2157
 
2158
  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
2159
    return false;
2160
 
2161
  switch (hdr->sh_type)
2162
    {
2163
    case SHT_V850_SCOMMON:
2164
    case SHT_V850_TCOMMON:
2165
    case SHT_V850_ZCOMMON:
2166
      if (! bfd_set_section_flags (abfd, hdr->bfd_section,
2167
                                   (bfd_get_section_flags (abfd,
2168
                                                           hdr->bfd_section)
2169
                                    | SEC_IS_COMMON)))
2170
        return false;
2171
    }
2172
 
2173
  return true;
2174
}
2175
 
2176
/* Set the correct type for a V850 ELF section.  We do this by the
2177
   section name, which is a hack, but ought to work.  */
2178
static boolean
2179
v850_elf_fake_sections (abfd, hdr, sec)
2180
     bfd *                 abfd ATTRIBUTE_UNUSED;
2181
     Elf32_Internal_Shdr * hdr;
2182
     asection *            sec;
2183
{
2184
  register const char * name;
2185
 
2186
  name = bfd_get_section_name (abfd, sec);
2187
 
2188
  if (strcmp (name, ".scommon") == 0)
2189
    {
2190
      hdr->sh_type = SHT_V850_SCOMMON;
2191
    }
2192
  else if (strcmp (name, ".tcommon") == 0)
2193
    {
2194
      hdr->sh_type = SHT_V850_TCOMMON;
2195
    }
2196
  else if (strcmp (name, ".zcommon") == 0)
2197
    hdr->sh_type = SHT_V850_ZCOMMON;
2198
 
2199
  return true;
2200
}
2201
 
2202
#define TARGET_LITTLE_SYM                       bfd_elf32_v850_vec
2203
#define TARGET_LITTLE_NAME                      "elf32-v850"
2204
#define ELF_ARCH                                bfd_arch_v850
2205
#define ELF_MACHINE_CODE                        EM_CYGNUS_V850
2206
#define ELF_MAXPAGESIZE                         0x1000
2207
 
2208
#define elf_info_to_howto                       v850_elf_info_to_howto_rela
2209
#define elf_info_to_howto_rel                   v850_elf_info_to_howto_rel
2210
 
2211
#define elf_backend_check_relocs                v850_elf_check_relocs
2212
#define elf_backend_relocate_section            v850_elf_relocate_section
2213
#define elf_backend_object_p                    v850_elf_object_p
2214
#define elf_backend_final_write_processing      v850_elf_final_write_processing
2215
#define elf_backend_section_from_bfd_section    v850_elf_section_from_bfd_section
2216
#define elf_backend_symbol_processing           v850_elf_symbol_processing
2217
#define elf_backend_add_symbol_hook             v850_elf_add_symbol_hook
2218
#define elf_backend_link_output_symbol_hook     v850_elf_link_output_symbol_hook
2219
#define elf_backend_section_from_shdr           v850_elf_section_from_shdr
2220
#define elf_backend_fake_sections               v850_elf_fake_sections
2221
#define elf_backend_gc_mark_hook                v850_elf_gc_mark_hook
2222
#define elf_backend_gc_sweep_hook               v850_elf_gc_sweep_hook
2223
 
2224
#define elf_backend_can_gc_sections 1
2225
 
2226
#define bfd_elf32_bfd_is_local_label_name       v850_elf_is_local_label_name
2227
#define bfd_elf32_bfd_reloc_type_lookup         v850_elf_reloc_type_lookup
2228
#define bfd_elf32_bfd_copy_private_bfd_data     v850_elf_copy_private_bfd_data
2229
#define bfd_elf32_bfd_merge_private_bfd_data    v850_elf_merge_private_bfd_data
2230
#define bfd_elf32_bfd_set_private_flags         v850_elf_set_private_flags
2231
#define bfd_elf32_bfd_print_private_bfd_data    v850_elf_print_private_bfd_data
2232
 
2233
#define elf_symbol_leading_char                 '_'
2234
 
2235
#include "elf32-target.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.