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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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