This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / bfd / elf32-v850.c
1 /* V850-specific support for 32-bit ELF
2    Copyright (C) 1996, 1997, 1998 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 addend));
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          true,                          /* 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          true,                          /* 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          true,                          /* 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          true,                          /* 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          true,                          /* 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          true,                          /* 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 /* start-sanitize-v850e */
347   
348   /* 5 bit offset from the tiny data area pointer.  */
349   HOWTO (R_V850_TDA_4_5_OFFSET,         /* type */
350          1,                             /* rightshift */
351          1,                             /* size (0 = byte, 1 = short, 2 = long) */
352          5,                             /* bitsize */
353          false,                         /* pc_relative */
354          0,                             /* bitpos */
355          complain_overflow_dont,        /* complain_on_overflow */
356          v850_elf_reloc,                /* special_function */
357          "R_V850_TDA_4_5_OFFSET",       /* name */
358          false,                         /* partial_inplace */
359          0x0f,                          /* src_mask */
360          0x0f,                          /* dst_mask */
361          false),                        /* pcrel_offset */
362
363   /* 4 bit offset from the tiny data area pointer.  */
364   HOWTO (R_V850_TDA_4_4_OFFSET,         /* type */
365          0,                             /* rightshift */
366          1,                             /* size (0 = byte, 1 = short, 2 = long) */
367          4,                             /* bitsize */
368          false,                         /* pc_relative */
369          0,                             /* bitpos */
370          complain_overflow_dont,        /* complain_on_overflow */
371          v850_elf_reloc,                /* special_function */
372          "R_V850_TDA_4_4_OFFSET",       /* name */
373          false,                         /* partial_inplace */
374          0x0f,                          /* src_mask */
375          0x0f,                          /* dst_mask */
376          false),                        /* pcrel_offset */
377
378   /* 16 bit offset from the short data area pointer.  */
379   HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* type */
380          0,                             /* rightshift */
381          2,                             /* size (0 = byte, 1 = short, 2 = long) */
382          16,                            /* bitsize */
383          false,                         /* pc_relative */
384          0,                             /* bitpos */
385          complain_overflow_dont,        /* complain_on_overflow */
386          v850_elf_reloc,                /* special_function */
387          "R_V850_SDA_16_16_SPLIT_OFFSET",/* name */
388          false,                         /* partial_inplace */
389          0xfffe0020,                    /* src_mask */
390          0xfffe0020,                    /* dst_mask */
391          false),                        /* pcrel_offset */
392
393   /* 16 bit offset from the zero data area pointer.  */
394   HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* type */
395          0,                             /* rightshift */
396          2,                             /* size (0 = byte, 1 = short, 2 = long) */
397          16,                            /* bitsize */
398          false,                         /* pc_relative */
399          0,                             /* bitpos */
400          complain_overflow_dont,        /* complain_on_overflow */
401          v850_elf_reloc,                /* special_function */
402          "R_V850_ZDA_16_16_SPLIT_OFFSET",/* name */
403          false,                         /* partial_inplace */
404          0xfffe0020,                    /* src_mask */
405          0xfffe0020,                    /* dst_mask */
406          false),                        /* pcrel_offset */
407
408   /* 6 bit offset from the call table base pointer.  */
409   HOWTO (R_V850_CALLT_6_7_OFFSET,       /* type */
410          0,                             /* rightshift */
411          1,                             /* size (0 = byte, 1 = short, 2 = long) */
412          7,                             /* bitsize */
413          false,                         /* pc_relative */
414          0,                             /* bitpos */
415          complain_overflow_dont,        /* complain_on_overflow */
416          v850_elf_reloc,                /* special_function */
417          "R_V850_CALLT_6_7_OFFSET",     /* name */
418          false,                         /* partial_inplace */
419          0x3f,                          /* src_mask */
420          0x3f,                          /* dst_mask */
421          false),                        /* pcrel_offset */
422
423   /* 16 bit offset from the call table base pointer.  */
424   HOWTO (R_V850_CALLT_16_16_OFFSET,     /* type */
425          0,                             /* rightshift */
426          1,                             /* size (0 = byte, 1 = short, 2 = long) */
427          16,                            /* bitsize */
428          false,                         /* pc_relative */
429          0,                             /* bitpos */
430          complain_overflow_dont,        /* complain_on_overflow */
431          v850_elf_reloc,                /* special_function */
432          "R_V850_CALLT_16_16_OFFSET",   /* name */
433          false,                         /* partial_inplace */
434          0xffff,                        /* src_mask */
435          0xffff,                        /* dst_mask */
436          false),                        /* pcrel_offset */
437
438 /* end-sanitize-v850e */
439   /* GNU extension to record C++ vtable hierarchy */
440   HOWTO (R_V850_GNU_VTINHERIT, /* type */
441          0,                     /* rightshift */
442          2,                     /* size (0 = byte, 1 = short, 2 = long) */
443          0,                     /* bitsize */
444          false,                 /* pc_relative */
445          0,                     /* bitpos */
446          complain_overflow_dont, /* complain_on_overflow */
447          NULL,                  /* special_function */
448          "R_V850_GNU_VTINHERIT", /* name */
449          false,                 /* partial_inplace */
450          0,                     /* src_mask */
451          0,                     /* dst_mask */
452          false),                /* pcrel_offset */
453
454   /* GNU extension to record C++ vtable member usage */
455   HOWTO (R_V850_GNU_VTENTRY,     /* type */
456          0,                     /* rightshift */
457          2,                     /* size (0 = byte, 1 = short, 2 = long) */
458          0,                     /* bitsize */
459          false,                 /* pc_relative */
460          0,                     /* bitpos */
461          complain_overflow_dont, /* complain_on_overflow */
462          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
463          "R_V850_GNU_VTENTRY",   /* name */
464          false,                 /* partial_inplace */
465          0,                     /* src_mask */
466          0,                     /* dst_mask */
467          false),                /* pcrel_offset */
468  
469 };
470
471 /* Map BFD reloc types to V850 ELF reloc types.  */
472
473 struct v850_elf_reloc_map
474 {
475   unsigned char bfd_reloc_val;
476   unsigned char elf_reloc_val;
477 };
478
479 static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
480 {
481   { BFD_RELOC_NONE,             R_V850_NONE },
482   { BFD_RELOC_V850_9_PCREL,     R_V850_9_PCREL },
483   { BFD_RELOC_V850_22_PCREL,    R_V850_22_PCREL },
484   { BFD_RELOC_HI16_S,           R_V850_HI16_S },
485   { BFD_RELOC_HI16,             R_V850_HI16 },
486   { BFD_RELOC_LO16,             R_V850_LO16 },
487   { BFD_RELOC_32,               R_V850_32 },
488   { BFD_RELOC_16,               R_V850_16 },
489   { BFD_RELOC_8,                R_V850_8 },
490   { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET },
491   { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET },
492   { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET },
493   { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET },
494   { BFD_RELOC_V850_TDA_6_8_OFFSET,   R_V850_TDA_6_8_OFFSET   },
495   { BFD_RELOC_V850_TDA_7_8_OFFSET,   R_V850_TDA_7_8_OFFSET   },
496   { BFD_RELOC_V850_TDA_7_7_OFFSET,   R_V850_TDA_7_7_OFFSET   },
497   { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET },
498 /* start-sanitize-v850e */
499   { BFD_RELOC_V850_TDA_4_5_OFFSET,         R_V850_TDA_4_5_OFFSET         },
500   { BFD_RELOC_V850_TDA_4_4_OFFSET,         R_V850_TDA_4_4_OFFSET         },
501   { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },
502   { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },
503   { BFD_RELOC_V850_CALLT_6_7_OFFSET,       R_V850_CALLT_6_7_OFFSET       },
504   { BFD_RELOC_V850_CALLT_16_16_OFFSET,     R_V850_CALLT_16_16_OFFSET     },
505 /* end-sanitize-v850e */
506   { BFD_RELOC_VTABLE_INHERIT,               R_V850_GNU_VTINHERIT },
507   { BFD_RELOC_VTABLE_ENTRY,                 R_V850_GNU_VTENTRY },
508
509 };
510
511 \f
512 /* Map a bfd relocation into the appropriate howto structure */
513 static reloc_howto_type *
514 v850_elf_reloc_type_lookup (abfd, code)
515      bfd *                     abfd;
516      bfd_reloc_code_real_type  code;
517 {
518   unsigned int i;
519
520   for (i = 0;
521        i < sizeof (v850_elf_reloc_map) / sizeof (struct v850_elf_reloc_map);
522        i++)
523     {
524       if (v850_elf_reloc_map[i].bfd_reloc_val == code)
525         {
526           BFD_ASSERT (v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val].type == v850_elf_reloc_map[i].elf_reloc_val);
527           
528           return & v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val];
529         }
530     }
531
532   return NULL;
533 }
534
535 \f
536 /* Set the howto pointer for an V850 ELF reloc.  */
537 static void
538 v850_elf_info_to_howto_rel (abfd, cache_ptr, dst)
539      bfd *                 abfd;
540      arelent *             cache_ptr;
541      Elf32_Internal_Rel *  dst;
542 {
543   unsigned int r_type;
544
545   r_type = ELF32_R_TYPE (dst->r_info);
546   BFD_ASSERT (r_type < (unsigned int) R_V850_max);
547   cache_ptr->howto = &v850_elf_howto_table[r_type];
548 }
549
550 /* Set the howto pointer for a V850 ELF reloc (type RELA). */
551 static void
552 v850_elf_info_to_howto_rela (abfd, cache_ptr, dst)
553      bfd *                 abfd;
554      arelent *             cache_ptr;
555      Elf32_Internal_Rela   *dst;
556 {
557   unsigned int r_type;
558
559   r_type = ELF32_R_TYPE (dst->r_info);
560   BFD_ASSERT (r_type < (unsigned int) R_V850_max);
561   cache_ptr->howto = &v850_elf_howto_table[r_type];
562 }
563
564 \f
565 /* Look through the relocs for a section during the first phase, and
566    allocate space in the global offset table or procedure linkage
567    table.  */
568
569 static boolean
570 v850_elf_check_relocs (abfd, info, sec, relocs)
571      bfd *                      abfd;
572      struct bfd_link_info *     info;
573      asection *                 sec;
574      const Elf_Internal_Rela *  relocs;
575 {
576   boolean ret = true;
577   bfd *dynobj;
578   Elf_Internal_Shdr *symtab_hdr;
579   struct elf_link_hash_entry **sym_hashes;
580   const Elf_Internal_Rela *rel;
581   const Elf_Internal_Rela *rel_end;
582   asection *sreloc;
583   enum v850_reloc_type r_type;
584   int other = 0;
585   const char *common = (const char *)0;
586
587   if (info->relocateable)
588     return true;
589
590 #ifdef DEBUG
591   fprintf (stderr, "v850_elf_check_relocs called for section %s in %s\n",
592            bfd_get_section_name (abfd, sec),
593            bfd_get_filename (abfd));
594 #endif
595
596   dynobj = elf_hash_table (info)->dynobj;
597   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
598   sym_hashes = elf_sym_hashes (abfd);
599   sreloc = NULL;
600
601   rel_end = relocs + sec->reloc_count;
602   for (rel = relocs; rel < rel_end; rel++)
603     {
604       unsigned long r_symndx;
605       struct elf_link_hash_entry *h;
606
607       r_symndx = ELF32_R_SYM (rel->r_info);
608       if (r_symndx < symtab_hdr->sh_info)
609         h = NULL;
610       else
611         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
612
613       r_type = (enum v850_reloc_type) ELF32_R_TYPE (rel->r_info);
614       switch (r_type)
615         {
616         default:
617         case R_V850_NONE:
618         case R_V850_9_PCREL:
619         case R_V850_22_PCREL:
620         case R_V850_HI16_S:
621         case R_V850_HI16:
622         case R_V850_LO16:
623         case R_V850_32:
624         case R_V850_16:
625         case R_V850_8:
626 /* start-sanitize-v850e */
627         case R_V850_CALLT_6_7_OFFSET:
628         case R_V850_CALLT_16_16_OFFSET:
629 /* end-sanitize-v850e */
630           break;
631
632         /* This relocation describes the C++ object vtable hierarchy.
633            Reconstruct it for later use during GC.  */
634         case R_V850_GNU_VTINHERIT:
635           if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
636             return false;
637           break;
638
639         /* This relocation describes which C++ vtable entries are actually
640            used.  Record for later use during GC.  */
641         case R_V850_GNU_VTENTRY:
642           if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
643             return false;
644           break;
645
646 /* start-sanitize-v850e */
647         case R_V850_SDA_16_16_SPLIT_OFFSET:
648 /* end-sanitize-v850e */
649         case R_V850_SDA_16_16_OFFSET:
650         case R_V850_SDA_15_16_OFFSET:
651           other = V850_OTHER_SDA;
652           common = ".scommon";
653           goto small_data_common;
654           
655 /* start-sanitize-v850e */
656         case R_V850_ZDA_16_16_SPLIT_OFFSET:
657 /* end-sanitize-v850e */
658         case R_V850_ZDA_16_16_OFFSET:
659         case R_V850_ZDA_15_16_OFFSET:
660           other = V850_OTHER_ZDA;
661           common = ".zcommon";
662           goto small_data_common;
663           
664 /* start-sanitize-v850e */
665         case R_V850_TDA_4_5_OFFSET:
666         case R_V850_TDA_4_4_OFFSET:
667 /* end-sanitize-v850e */          
668         case R_V850_TDA_6_8_OFFSET:
669         case R_V850_TDA_7_8_OFFSET:
670         case R_V850_TDA_7_7_OFFSET:
671         case R_V850_TDA_16_16_OFFSET:
672           other = V850_OTHER_TDA;
673           common = ".tcommon";
674           /* fall through */
675
676 #define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
677
678         small_data_common:
679           if (h)
680             {
681               h->other |= other;        /* flag which type of relocation was used */
682               if ((h->other & V850_OTHER_MASK) != (other & V850_OTHER_MASK)
683                   && (h->other & V850_OTHER_ERROR) == 0)
684                 {
685                   const char * msg;
686                   static char  buff[200]; /* XXX */
687
688                   switch (h->other & V850_OTHER_MASK)
689                     {
690                     default:
691                       msg = _("Variable `%s' cannot occupy in multiple small data regions");
692                       break;
693                     case V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA:
694                       msg = _("Variable `%s' can only be in one of the small, zero, and tiny data regions");
695                       break;
696                     case V850_OTHER_SDA | V850_OTHER_ZDA:
697                       msg = _("Variable `%s' cannot be in both small and zero data regions simultaneously");
698                       break;
699                     case V850_OTHER_SDA | V850_OTHER_TDA:
700                       msg = _("Variable `%s' cannot be in both small and tiny data regions simultaneously");
701                       break;
702                     case V850_OTHER_ZDA | V850_OTHER_TDA:
703                       msg = _("Variable `%s' cannot be in both zero and tiny data regions simultaneously");
704                       break;
705                     }
706
707                   sprintf (buff, msg, h->root.root.string);
708                   info->callbacks->warning (info, buff, h->root.root.string,
709                                             abfd, h->root.u.def.section, 0);
710
711                   bfd_set_error (bfd_error_bad_value);
712                   h->other |= V850_OTHER_ERROR;
713                   ret = false;
714                 }
715             }
716
717           if (h && h->root.type == bfd_link_hash_common
718               && h->root.u.c.p
719               && !strcmp (bfd_get_section_name (abfd, h->root.u.c.p->section), "COMMON"))
720             {
721               asection *section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common);
722               section->flags |= SEC_IS_COMMON;
723             }
724
725 #ifdef DEBUG
726           fprintf (stderr, "v850_elf_check_relocs, found %s relocation for %s%s\n",
727                    v850_elf_howto_table[ (int)r_type ].name,
728                    (h && h->root.root.string) ? h->root.root.string : "<unknown>",
729                    (h->root.type == bfd_link_hash_common) ? ", symbol is common" : "");
730 #endif
731           break;
732         }
733     }
734
735   return ret;
736 }
737
738 typedef struct hi16s_location
739 {
740   bfd_vma       addend;
741   bfd_byte *    address;
742   unsigned long counter;
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->next    = previous_hi16s;
770   previous_hi16s = entry;
771   
772   /* Cope with wrap around of our counter.  */
773   if (hi16s_counter == 0)
774     {
775       /* XXX - Assume that all counter entries differ only in their low 16 bits.  */
776       for (entry = previous_hi16s; entry != NULL; entry = entry->next)
777         entry->counter &= 0xffff;
778
779       hi16s_counter = 0x10000;
780     }
781   
782   return;
783 }
784
785 static bfd_byte *
786 find_remembered_hi16s_reloc (addend)
787      bfd_vma addend;
788 {
789   hi16s_location * match = NULL;
790   hi16s_location * entry;
791   hi16s_location * previous = NULL;
792   hi16s_location * prev;
793   int              i;
794   bfd_byte *       addr;
795   
796   /* Search the table.  Record the most recent entry that matches.  */
797   for (entry = previous_hi16s; entry; entry = entry->next)
798     {
799       if (entry->addend == addend)
800         {
801           if (match == NULL || match->counter < entry->counter)
802             {
803               previous = prev;
804               match    = entry;
805             }
806         }
807           
808       prev = entry;
809     }
810
811   if (match == NULL)
812     return NULL;
813
814   /* Extract the address.  */
815   addr = match->address;
816   
817   /* Attach the entry to the free list.  */
818   if (previous)
819     previous->next = match->next;
820   else
821     previous_hi16s = match->next;
822   
823   match->next = free_hi16s->next;
824   free_hi16s  = match;
825   
826   match->addend  = 0;
827   match->address = NULL;
828   
829   return addr;
830 }     
831
832 /* FIXME:  The code here probably ought to be removed and the code in reloc.c
833    allowed to do its  stuff instead.  At least for most of the relocs, anwyay.  */
834 static bfd_reloc_status_type
835 v850_elf_perform_relocation (abfd, r_type, addend, address)
836      bfd *      abfd;
837      int        r_type;
838      bfd_vma    addend;
839      bfd_byte * address;
840 {
841   unsigned long insn;
842   bfd_signed_vma saddend = (bfd_signed_vma) addend;
843   
844   switch (r_type)
845     {
846     default:
847       /* fprintf (stderr, "reloc type %d not SUPPORTED\n", r_type ); */
848       return bfd_reloc_notsupported;
849       
850     case R_V850_32:
851       bfd_put_32 (abfd, addend, address);
852       return bfd_reloc_ok;
853       
854     case R_V850_22_PCREL:
855       if (saddend > 0x1fffff || saddend < -0x200000)
856         return bfd_reloc_overflow;
857       
858       if ((addend % 2) != 0)
859         return bfd_reloc_dangerous;
860       
861       insn  = bfd_get_32 (abfd, address);
862       insn &= ~0xfffe003f;
863       insn |= (((addend & 0xfffe) << 16) | ((addend & 0x3f0000) >> 16));
864       bfd_put_32 (abfd, insn, address);
865       return bfd_reloc_ok;
866       
867     case R_V850_9_PCREL:
868       if (saddend > 0xff || saddend < -0x100)
869         return bfd_reloc_overflow;
870       
871       if ((addend % 2) != 0)
872         return bfd_reloc_dangerous;
873       
874       insn  = bfd_get_16 (abfd, address);
875       insn &= ~ 0xf870;
876       insn |= ((addend & 0x1f0) << 7) | ((addend & 0x0e) << 3);
877       break;
878       
879     case R_V850_HI16:
880       addend += (bfd_get_16 (abfd, address) << 16);
881       addend = (addend >> 16);
882       insn = addend;
883       break;
884       
885     case R_V850_HI16_S:
886       /* Remember where this relocation took place.  */
887       remember_hi16s_reloc (abfd, addend, address);
888
889       addend += (bfd_get_16 (abfd, address) << 16);
890       addend = (addend >> 16) + ((addend & 0x8000) != 0);
891       
892       /* This relocation cannot overflow. */
893       if (addend > 0x7fff)
894         addend = 0;
895       
896       insn = addend;
897       break;
898       
899     case R_V850_LO16:
900       /* Calculate the sum of the value stored in the instruction and the
901          addend and check for overflow from the low 16 bits into the high
902          16 bits.  The assembler has already done some of this:  If the
903          value stored in the instruction has its 15th bit set, (counting
904          from zero) then the assembler will have added 1 to the value
905          stored in the associated HI16S reloc.  So for example, these
906          relocations:
907
908              movhi hi( fred ), r0, r1
909              movea lo( fred ), r1, r1
910
911          will store 0 in the value fields for the MOVHI and MOVEA instructions
912          and addend will be the address of fred, but for these instructions:
913
914              movhi hi( fred + 0x123456), r0, r1
915              movea lo( fred + 0x123456), r1, r1
916
917          the value stored in the MOVHI instruction will be 0x12 and the value
918          stored in the MOVEA instruction will be 0x3456.  If however the
919          instructions were:
920
921              movhi hi( fred + 0x10ffff), r0, r1
922              movea lo( fred + 0x10ffff), r1, r1
923
924          then the value stored in the MOVHI instruction would be 0x11 (not
925          0x10) and the value stored in the MOVEA instruction would be 0xffff.
926          Thus (assuming for the moment that the addend is 0), at run time the
927          MOVHI instruction loads 0x110000 into r1, then the MOVEA instruction
928          adds 0xffffffff (sign extension!) producing 0x10ffff.  Similarly if
929          the instructions were:
930
931              movhi hi( fred - 1), r0, r1
932              movea lo( fred - 1), r1, r1
933
934          then 0 is stored in the MOVHI instruction and -1 is stored in the
935          MOVEA instruction.
936
937          Overflow can occur if the addition of the value stored in the
938          instruction plus the addend sets the 15th bit when before it was clear.
939          This is because the 15th bit will be sign extended into the high part,
940          thus reducing its value by one, but since the 15th bit was originally
941          clear, the assembler will not have added 1 to the previous HI16S reloc
942          to compensate for this effect.  For example:
943
944             movhi hi( fred + 0x123456), r0, r1
945             movea lo( fred + 0x123456), r1, r1
946
947          The value stored in HI16S reloc is 0x12, the value stored in the LO16
948          reloc is 0x3456.  If we assume that the address of fred is 0x00007000
949          then the relocations become:
950
951            HI16S: 0x0012 + (0x00007000 >> 16)    = 0x12
952            LO16:  0x3456 + (0x00007000 & 0xffff) = 0xa456
953
954          but when the instructions are executed, the MOVEA instruction's value
955          is signed extended, so the sum becomes:
956
957               0x00120000
958             + 0xffffa456
959             ------------
960               0x0011a456    but 'fred + 0x123456' = 0x0012a456
961
962          Note that if the 15th bit was set in the value stored in the LO16
963          reloc, then we do not have to do anything:
964
965             movhi hi( fred + 0x10ffff), r0, r1
966             movea lo( fred + 0x10ffff), r1, r1
967
968             HI16S:  0x0011 + (0x00007000 >> 16)    = 0x11
969             LO16:   0xffff + (0x00007000 & 0xffff) = 0x6fff
970
971               0x00110000
972             + 0x00006fff
973             ------------
974               0x00116fff  = fred + 0x10ffff = 0x7000 + 0x10ffff
975
976          
977          Overflow can also occur if the computation carries into the 16th bit
978          and it also results in the 15th bit having the same value as the 15th
979          bit of the original value.   What happens is that the HI16S reloc
980          will have already examined the 15th bit of the original value and
981          added 1 to the high part if the bit is set.  This compensates for the
982          sign extension of 15th bit of the result of the computation.  But now
983          there is a carry into the 16th bit, and this has not been allowed for.
984
985          So, for example if fred is at address 0xf000:
986
987            movhi hi( fred + 0xffff), r0, r1    [bit 15 of the offset is set]
988            movea lo( fred + 0xffff), r1, r1
989
990            HI16S: 0x0001 + (0x0000f000 >> 16)    = 0x0001
991            LO16:  0xffff + (0x0000f000 & 0xffff) = 0xefff   (carry into bit 16 is lost)
992
993              0x00010000
994            + 0xffffefff
995            ------------
996              0x0000efff   but 'fred + 0xffff' = 0x0001efff
997
998          Similarly, if the 15th bit remains clear, but overflow occurs into
999          the 16th bit then (assuming the address of fred is 0xf000):
1000
1001            movhi hi( fred + 0x7000), r0, r1    [bit 15 of the offset is clear]
1002            movea lo( fred + 0x7000), r1, r1
1003
1004            HI16S: 0x0000 + (0x0000f000 >> 16)    = 0x0000
1005            LO16:  0x7000 + (0x0000f000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)
1006
1007              0x00000000
1008            + 0x00006fff
1009            ------------
1010              0x00006fff   but 'fred + 0x7000' = 0x00016fff
1011            
1012          Note - there is no need to change anything if a carry occurs, and the
1013          15th bit changes its value from being set to being clear, as the HI16S
1014          reloc will have already added in 1 to the high part for us:
1015
1016            movhi hi( fred + 0xffff), r0, r1     [bit 15 of the offset is set]
1017            movea lo( fred + 0xffff), r1, r1
1018
1019            HI16S: 0x0001 + (0x00007000 >> 16)
1020            LO16:  0xffff + (0x00007000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)
1021
1022              0x00010000
1023            + 0x00006fff   (bit 15 not set, so the top half is zero)
1024            ------------
1025              0x00016fff   which is right (assuming that fred is at 0x7000)
1026
1027          but if the 15th bit goes from being clear to being set, then we must
1028          once again handle overflow:
1029
1030            movhi hi( fred + 0x7000), r0, r1     [bit 15 of the offset is clear]
1031            movea lo( fred + 0x7000), r1, r1
1032
1033            HI16S: 0x0000 + (0x0000ffff >> 16)
1034            LO16:  0x7000 + (0x0000ffff & 0xffff) = 0x6fff  (carry into bit 16)
1035
1036              0x00000000
1037            + 0x00006fff   (bit 15 not set, so the top half is zero)
1038            ------------
1039              0x00006fff   which is wrong (assuming that fred is at 0xffff)
1040          */
1041
1042       {
1043         long result;
1044
1045         insn   = bfd_get_16 (abfd, address);
1046         result = insn + addend;
1047
1048 #define BIT15_SET(x) ((x) & 0x8000)
1049 #define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)
1050         
1051         if ((BIT15_SET (result) && ! BIT15_SET (addend))
1052             || (OVERFLOWS (addend, insn)
1053                 && ((! BIT15_SET (insn)) || (BIT15_SET (addend)))))
1054           {
1055             bfd_byte * hi16s_address = find_remembered_hi16s_reloc (addend);
1056             
1057             /* Amend the matching HI16_S relocation.  */
1058             if (hi16s_address != NULL)
1059               {
1060                 insn = bfd_get_16 (abfd, hi16s_address);
1061                 insn += 1;
1062                 bfd_put_16 (abfd, insn, hi16s_address);
1063               }
1064             else
1065               {
1066                 fprintf (stderr, _("FAILED to find previous HI16 reloc\n"));
1067                 return bfd_reloc_overflow;
1068               }
1069           }
1070         
1071         /* Do not complain if value has top bit set, as this has been anticipated.  */
1072         insn = result & 0xffff;
1073         break;
1074       }
1075
1076     case R_V850_8:
1077       addend += (char) bfd_get_8 (abfd, address);
1078
1079       saddend = (bfd_signed_vma) addend;
1080       
1081       if (saddend > 0x7f || saddend < -0x80)
1082         return bfd_reloc_overflow;
1083
1084       bfd_put_8 (abfd, addend, address);
1085       return bfd_reloc_ok;
1086
1087 /* start-sanitize-v850e */
1088     case R_V850_CALLT_16_16_OFFSET:
1089       addend += bfd_get_16 (abfd, address);
1090       
1091       saddend = (bfd_signed_vma) addend;
1092       
1093       if (saddend > 0xffff || saddend < 0)
1094         return bfd_reloc_overflow;
1095
1096       insn = addend;
1097       break;
1098 /* end-sanitize-v850e */
1099       
1100     case R_V850_16:
1101
1102       /* drop through */            
1103     case R_V850_SDA_16_16_OFFSET:
1104     case R_V850_ZDA_16_16_OFFSET:
1105     case R_V850_TDA_16_16_OFFSET:
1106       addend += bfd_get_16 (abfd, address);
1107       
1108       saddend = (bfd_signed_vma) addend;
1109       
1110       if (saddend > 0x7fff || saddend < -0x8000)
1111         return bfd_reloc_overflow;
1112
1113       insn = addend;
1114       break;
1115       
1116     case R_V850_SDA_15_16_OFFSET:
1117     case R_V850_ZDA_15_16_OFFSET:
1118       insn = bfd_get_16 (abfd, address);
1119       addend += (insn & 0xfffe);
1120       
1121       saddend = (bfd_signed_vma) addend;
1122       
1123       if (saddend > 0x7ffe || saddend < -0x8000)
1124         return bfd_reloc_overflow;
1125       
1126       if (addend & 1)
1127         return bfd_reloc_dangerous;
1128       
1129       insn = (addend & ~1) | (insn & 1);
1130       break;
1131       
1132     case R_V850_TDA_6_8_OFFSET:
1133       insn = bfd_get_16 (abfd, address);
1134       addend += ((insn & 0x7e) << 1);
1135       
1136       saddend = (bfd_signed_vma) addend;
1137       
1138       if (saddend > 0xfc || saddend < 0)
1139         return bfd_reloc_overflow;
1140       
1141       if (addend & 3)
1142         return bfd_reloc_dangerous;
1143       
1144       insn &= 0xff81;
1145       insn |= (addend >> 1);
1146       break;
1147       
1148     case R_V850_TDA_7_8_OFFSET:
1149       insn = bfd_get_16 (abfd, address);
1150       addend += ((insn & 0x7f) << 1);
1151       
1152       saddend = (bfd_signed_vma) addend;
1153       
1154       if (saddend > 0xfe || saddend < 0)
1155         return bfd_reloc_overflow;
1156       
1157       if (addend & 1)
1158         return bfd_reloc_dangerous;
1159       
1160       insn &= 0xff80;
1161       insn |= (addend >> 1);
1162       break;
1163       
1164     case R_V850_TDA_7_7_OFFSET:
1165       insn = bfd_get_16 (abfd, address);
1166       addend += insn & 0x7f;
1167         
1168       saddend = (bfd_signed_vma) addend;
1169       
1170       if (saddend > 0x7f || saddend < 0)
1171         return bfd_reloc_overflow;
1172       
1173       insn &= 0xff80;
1174       insn |= addend;
1175       break;
1176       
1177 /* start-sanitize-v850e */
1178     case R_V850_TDA_4_5_OFFSET:
1179       insn = bfd_get_16 (abfd, address);
1180       addend += ((insn & 0xf) << 1);
1181       
1182       saddend = (bfd_signed_vma) addend;
1183       
1184       if (saddend > 0x1e || saddend < 0)
1185         return bfd_reloc_overflow;
1186       
1187       if (addend & 1)
1188         return bfd_reloc_dangerous;
1189       
1190       insn &= 0xfff0;
1191       insn |= (addend >> 1);
1192       break;
1193       
1194     case R_V850_TDA_4_4_OFFSET:
1195       insn = bfd_get_16 (abfd, address);
1196       addend += insn & 0xf;
1197       
1198       saddend = (bfd_signed_vma) addend;
1199       
1200       if (saddend > 0xf || saddend < 0)
1201         return bfd_reloc_overflow;
1202       
1203       insn &= 0xfff0;
1204       insn |= addend;
1205       break;
1206       
1207     case R_V850_ZDA_16_16_SPLIT_OFFSET:
1208     case R_V850_SDA_16_16_SPLIT_OFFSET:
1209       insn = bfd_get_32 (abfd, address);
1210       addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5);
1211       
1212       saddend = (bfd_signed_vma) addend;
1213       
1214       if (saddend > 0x7fff || saddend < -0x8000)
1215         return bfd_reloc_overflow;
1216       
1217       insn &= 0x0001ffdf;
1218       insn |= (addend & 1) << 5;
1219       insn |= (addend & ~1) << 16;
1220       
1221       bfd_put_32 (abfd, insn, address);
1222       return bfd_reloc_ok;
1223       
1224     case R_V850_CALLT_6_7_OFFSET:
1225       insn = bfd_get_16 (abfd, address);
1226       addend += ((insn & 0x3f) << 1);
1227       
1228       saddend = (bfd_signed_vma) addend;
1229       
1230       if (saddend > 0x7e || saddend < 0)
1231         return bfd_reloc_overflow;
1232       
1233       if (addend & 1)
1234         return bfd_reloc_dangerous;
1235       
1236       insn &= 0xff80;
1237       insn |= (addend >> 1);
1238       break;
1239 /* end-sanitize-v850e */
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 \f
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;
1256      arelent *   reloc;
1257      asymbol *   symbol;
1258      PTR         data;
1259      asection *  isection;
1260      bfd *       obfd;
1261      char **     err;
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 \f
1326 /*ARGSUSED*/
1327 static boolean
1328 v850_elf_is_local_label_name (abfd, name)
1329      bfd *         abfd;
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 \f
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;
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;
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       value = SEXT24 (value);  /* Only the bottom 24 bits of the PC are valid */
1372       break;
1373       
1374     case R_V850_HI16_S:
1375     case R_V850_HI16:
1376     case R_V850_LO16:
1377     case R_V850_16:
1378     case R_V850_32:
1379     case R_V850_8:
1380       break;
1381
1382     case R_V850_ZDA_15_16_OFFSET:       
1383     case R_V850_ZDA_16_16_OFFSET:
1384 /* start-sanitize-v850e */
1385     case R_V850_ZDA_16_16_SPLIT_OFFSET:
1386 /* end-sanitize-v850e */
1387       if (sym_sec == NULL)
1388         return bfd_reloc_undefined;
1389           
1390       value -= sym_sec->output_section->vma;
1391       break;
1392
1393     case R_V850_SDA_15_16_OFFSET:
1394     case R_V850_SDA_16_16_OFFSET:
1395 /* start-sanitize-v850e */
1396     case R_V850_SDA_16_16_SPLIT_OFFSET:
1397 /* end-sanitize-v850e */
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 /* start-sanitize-v850e */
1421     case R_V850_TDA_4_4_OFFSET:
1422     case R_V850_TDA_4_5_OFFSET:
1423 /* end-sanitize-v850e */
1424     case R_V850_TDA_16_16_OFFSET:
1425     case R_V850_TDA_7_7_OFFSET:
1426     case R_V850_TDA_7_8_OFFSET:
1427     case R_V850_TDA_6_8_OFFSET:
1428       {
1429         unsigned long                ep;
1430         struct bfd_link_hash_entry * h;
1431         
1432         /* Get the value of __ep.  */
1433         h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1434         if (h == (struct bfd_link_hash_entry *) NULL
1435             || h->type != bfd_link_hash_defined)
1436           return bfd_reloc_continue;  /* Actually this indicates that __ep could not be found. */
1437
1438         ep = (h->u.def.value
1439               + h->u.def.section->output_section->vma
1440               + h->u.def.section->output_offset);
1441
1442         value -= ep;
1443       }
1444     break;
1445     
1446 /* start-sanitize-v850e */
1447     case R_V850_CALLT_6_7_OFFSET:
1448       {
1449         unsigned long                ctbp;
1450         struct bfd_link_hash_entry * h;
1451         
1452         /* Get the value of __ctbp.  */
1453         h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
1454         if (h == (struct bfd_link_hash_entry *) NULL
1455             || h->type != bfd_link_hash_defined)
1456           return (bfd_reloc_dangerous + 1);  /* Actually this indicates that __ctbp could not be found. */
1457
1458         ctbp = (h->u.def.value
1459               + h->u.def.section->output_section->vma
1460               + h->u.def.section->output_offset);
1461         value -= ctbp;
1462       }
1463     break;
1464     
1465     case R_V850_CALLT_16_16_OFFSET:
1466       {
1467         unsigned long                ctbp;
1468         struct bfd_link_hash_entry * h;
1469
1470         if (sym_sec == NULL)
1471           return bfd_reloc_undefined;
1472           
1473         /* Get the value of __ctbp.  */
1474         h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
1475         if (h == (struct bfd_link_hash_entry *) NULL
1476             || h->type != bfd_link_hash_defined)
1477           return (bfd_reloc_dangerous + 1);
1478
1479         ctbp = (h->u.def.value
1480               + h->u.def.section->output_section->vma
1481               + h->u.def.section->output_offset);
1482
1483         value -= sym_sec->output_section->vma;
1484         value -= (ctbp - sym_sec->output_section->vma);
1485       }
1486     break;
1487 /* end-sanitize-v850e */
1488       
1489     case R_V850_NONE:
1490     case R_V850_GNU_VTINHERIT:
1491     case R_V850_GNU_VTENTRY:
1492       return bfd_reloc_ok;
1493
1494     default:
1495       return bfd_reloc_notsupported;
1496     }
1497
1498   /* Perform the relocation.  */
1499   return v850_elf_perform_relocation (input_bfd, r_type, value + addend, hit_data); 
1500 }
1501
1502 \f
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   rel    = relocs;
1525   relend = relocs + input_section->reloc_count;
1526   for (; rel < relend; rel++)
1527     {
1528       int                          r_type;
1529       reloc_howto_type *           howto;
1530       unsigned long                r_symndx;
1531       Elf_Internal_Sym *           sym;
1532       asection *                   sec;
1533       struct elf_link_hash_entry * h;
1534       bfd_vma                      relocation;
1535       bfd_reloc_status_type        r;
1536
1537       r_symndx = ELF32_R_SYM (rel->r_info);
1538       r_type   = ELF32_R_TYPE (rel->r_info);
1539
1540       if (r_type == R_V850_GNU_VTENTRY
1541           || r_type == R_V850_GNU_VTINHERIT)
1542         continue;
1543
1544       howto    = v850_elf_howto_table + r_type;
1545
1546       if (info->relocateable)
1547         {
1548           /* This is a relocateable link.  We don't have to change
1549              anything, unless the reloc is against a section symbol,
1550              in which case we have to adjust according to where the
1551              section symbol winds up in the output section.  */
1552           if (r_symndx < symtab_hdr->sh_info)
1553             {
1554               sym = local_syms + r_symndx;
1555               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1556                 {
1557                   sec = local_sections[r_symndx];
1558                   rel->r_addend += sec->output_offset + sym->st_value;
1559                 }
1560             }
1561
1562           continue;
1563         }
1564
1565       /* This is a final link.  */
1566       h = NULL;
1567       sym = NULL;
1568       sec = NULL;
1569       if (r_symndx < symtab_hdr->sh_info)
1570         {
1571           sym = local_syms + r_symndx;
1572           sec = local_sections[r_symndx];
1573           relocation = (sec->output_section->vma
1574                         + sec->output_offset
1575                         + sym->st_value);
1576 #if 0
1577           {
1578             char * name;
1579             name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name);
1580             name = (name == NULL) ? "<none>" : name;
1581 fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
1582          sec->name, name, sym->st_name,
1583          sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend);
1584           }
1585 #endif
1586         }
1587       else
1588         {
1589           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1590           
1591           while (h->root.type == bfd_link_hash_indirect
1592                  || h->root.type == bfd_link_hash_warning)
1593             h = (struct elf_link_hash_entry *) h->root.u.i.link;
1594           
1595           if (h->root.type == bfd_link_hash_defined
1596               || h->root.type == bfd_link_hash_defweak)
1597             {
1598               sec = h->root.u.def.section;
1599               relocation = (h->root.u.def.value
1600                             + sec->output_section->vma
1601                             + sec->output_offset);
1602 #if 0
1603 fprintf (stderr, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
1604          sec->name, h->root.root.string, h->root.u.def.value, sec->output_section->vma, sec->output_offset, relocation);
1605 #endif
1606             }
1607           else if (h->root.type == bfd_link_hash_undefweak)
1608             {
1609 #if 0
1610 fprintf (stderr, "undefined: sec: %s, name: %s\n",
1611          sec->name, h->root.root.string);
1612 #endif
1613               relocation = 0;
1614             }
1615           else
1616             {
1617               if (! ((*info->callbacks->undefined_symbol)
1618                      (info, h->root.root.string, input_bfd,
1619                       input_section, rel->r_offset)))
1620                 return false;
1621 #if 0
1622 fprintf (stderr, "unknown: name: %s\n", h->root.root.string);
1623 #endif
1624               relocation = 0;
1625             }
1626         }
1627
1628       /* FIXME: We should use the addend, but the COFF relocations
1629          don't.  */
1630       r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
1631                                         input_section,
1632                                         contents, rel->r_offset,
1633                                         relocation, rel->r_addend,
1634                                         info, sec, h == NULL);
1635
1636       if (r != bfd_reloc_ok)
1637         {
1638           const char * name;
1639           const char * msg = (const char *)0;
1640
1641           if (h != NULL)
1642             name = h->root.root.string;
1643           else
1644             {
1645               name = (bfd_elf_string_from_elf_section
1646                       (input_bfd, symtab_hdr->sh_link, sym->st_name));
1647               if (name == NULL || *name == '\0')
1648                 name = bfd_section_name (input_bfd, sec);
1649             }
1650
1651           switch (r)
1652             {
1653             case bfd_reloc_overflow:
1654               if (! ((*info->callbacks->reloc_overflow)
1655                      (info, name, howto->name, (bfd_vma) 0,
1656                       input_bfd, input_section, rel->r_offset)))
1657                 return false;
1658               break;
1659
1660             case bfd_reloc_undefined:
1661               if (! ((*info->callbacks->undefined_symbol)
1662                      (info, name, input_bfd, input_section,
1663                       rel->r_offset)))
1664                 return false;
1665               break;
1666
1667             case bfd_reloc_outofrange:
1668               msg = _("internal error: out of range error");
1669               goto common_error;
1670
1671             case bfd_reloc_notsupported:
1672               msg = _("internal error: unsupported relocation error");
1673               goto common_error;
1674
1675             case bfd_reloc_dangerous:
1676               msg = _("internal error: dangerous relocation");
1677               goto common_error;
1678
1679             case bfd_reloc_other:
1680               msg = _("could not locate special linker symbol __gp");
1681               goto common_error;
1682
1683             case bfd_reloc_continue:
1684               msg = _("could not locate special linker symbol __ep");
1685               goto common_error;
1686
1687             case (bfd_reloc_dangerous + 1):
1688               msg = _("could not locate special linker symbol __ctbp");
1689               goto common_error;
1690               
1691             default:
1692               msg = _("internal error: unknown error");
1693               /* fall through */
1694
1695             common_error:
1696               if (!((*info->callbacks->warning)
1697                     (info, msg, name, input_bfd, input_section,
1698                      rel->r_offset)))
1699                 return false;
1700               break;
1701             }
1702         }
1703     }
1704
1705   return true;
1706 }
1707
1708 static boolean
1709 v850_elf_gc_sweep_hook (abfd, info, sec, relocs)
1710      bfd *abfd;
1711      struct bfd_link_info *info;
1712      asection *sec;
1713      const Elf_Internal_Rela *relocs;
1714 {
1715   /* No got and plt entries for v850-elf */
1716   return true;
1717 }
1718
1719 static asection *
1720 v850_elf_gc_mark_hook (abfd, info, rel, h, sym)
1721        bfd *abfd;
1722        struct bfd_link_info *info;
1723        Elf_Internal_Rela *rel;
1724        struct elf_link_hash_entry *h;
1725        Elf_Internal_Sym *sym;
1726 {
1727   if (h != NULL)
1728     {
1729       switch (ELF32_R_TYPE (rel->r_info))
1730       {
1731       case R_V850_GNU_VTINHERIT:
1732       case R_V850_GNU_VTENTRY:
1733         break;
1734
1735       default:
1736         switch (h->root.type)
1737           {
1738           case bfd_link_hash_defined:
1739           case bfd_link_hash_defweak:
1740             return h->root.u.def.section;
1741
1742           case bfd_link_hash_common:
1743             return h->root.u.c.p->section;
1744           }
1745        }
1746      }
1747    else
1748      {
1749        if (!(elf_bad_symtab (abfd)
1750            && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
1751          && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
1752                 && sym->st_shndx != SHN_COMMON))
1753           {
1754             return bfd_section_from_elf_index (abfd, sym->st_shndx);
1755           }
1756       }
1757   return NULL;
1758 }
1759 /* Set the right machine number.  */
1760 static boolean
1761 v850_elf_object_p (abfd)
1762      bfd *abfd;
1763 {
1764   switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1765     {
1766     default:
1767     case E_V850_ARCH:   (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, 0); break;
1768 /* start-sanitize-v850e */
1769     case E_V850E_ARCH:  (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e); break;
1770     case E_V850EA_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850ea); break;
1771 /* end-sanitize-v850e */
1772     }
1773   return true;
1774 }
1775
1776 /* Store the machine number in the flags field.  */
1777 static void
1778 v850_elf_final_write_processing (abfd, linker)
1779      bfd *   abfd;
1780      boolean linker;
1781 {
1782   unsigned long val;
1783
1784   switch (bfd_get_mach (abfd))
1785     {
1786     default:
1787     case 0: val = E_V850_ARCH; break;
1788 /* start-sanitize-v850e */
1789     case bfd_mach_v850e:  val = E_V850E_ARCH; break;
1790     case bfd_mach_v850ea: val = E_V850EA_ARCH;  break;
1791 /* end-sanitize-v850e */
1792     }
1793
1794   elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
1795   elf_elfheader (abfd)->e_flags |= val;
1796 }
1797
1798 /* Function to keep V850 specific file flags. */
1799 static boolean
1800 v850_elf_set_private_flags (abfd, flags)
1801      bfd *    abfd;
1802      flagword flags;
1803 {
1804   BFD_ASSERT (!elf_flags_init (abfd)
1805               || elf_elfheader (abfd)->e_flags == flags);
1806
1807   elf_elfheader (abfd)->e_flags = flags;
1808   elf_flags_init (abfd) = true;
1809   return true;
1810 }
1811
1812 /* Copy backend specific data from one object module to another */
1813 static boolean
1814 v850_elf_copy_private_bfd_data (ibfd, obfd)
1815      bfd * ibfd;
1816      bfd * obfd;
1817 {
1818   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1819       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1820     return true;
1821
1822   BFD_ASSERT (!elf_flags_init (obfd)
1823               || (elf_elfheader (obfd)->e_flags
1824                   == elf_elfheader (ibfd)->e_flags));
1825
1826   elf_gp (obfd) = elf_gp (ibfd);
1827   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
1828   elf_flags_init (obfd) = true;
1829   return true;
1830 }
1831
1832 /* Merge backend specific data from an object file to the output
1833    object file when linking.  */
1834 static boolean
1835 v850_elf_merge_private_bfd_data (ibfd, obfd)
1836      bfd * ibfd;
1837      bfd * obfd;
1838 {
1839   flagword out_flags;
1840   flagword in_flags;
1841
1842   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1843       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1844     return true;
1845
1846   in_flags = elf_elfheader (ibfd)->e_flags;
1847   out_flags = elf_elfheader (obfd)->e_flags;
1848
1849   if (! elf_flags_init (obfd))
1850     {
1851       /* If the input is the default architecture then do not
1852          bother setting the flags for the output architecture,
1853          instead allow future merges to do this.  If no future
1854          merges ever set these flags then they will retain their
1855          unitialised values, which surprise surprise, correspond
1856          to the default values.  */
1857       if (bfd_get_arch_info (ibfd)->the_default)
1858         return true;
1859       
1860       elf_flags_init (obfd) = true;
1861       elf_elfheader (obfd)->e_flags = in_flags;
1862
1863       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1864           && bfd_get_arch_info (obfd)->the_default)
1865         {
1866           return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1867         }
1868
1869       return true;
1870     }
1871
1872   /* Check flag compatibility.  */
1873   if (in_flags == out_flags)
1874     return true;
1875
1876   if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)
1877       && (in_flags & EF_V850_ARCH) != E_V850_ARCH)
1878     _bfd_error_handler (_("%s: Architecture mismatch with previous modules"),
1879                         bfd_get_filename (ibfd));
1880
1881   return true;
1882 }
1883 /* Display the flags field */
1884
1885 static boolean
1886 v850_elf_print_private_bfd_data (abfd, ptr)
1887      bfd *   abfd;
1888      PTR     ptr;
1889 {
1890   FILE * file = (FILE *) ptr;
1891   
1892   BFD_ASSERT (abfd != NULL && ptr != NULL);
1893   
1894   _bfd_elf_print_private_bfd_data (abfd, ptr);
1895   
1896   /* xgettext:c-format */
1897   fprintf (file, _("private flags = %lx: "), elf_elfheader (abfd)->e_flags);
1898   
1899   switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1900     {
1901     default:
1902     case E_V850_ARCH: fprintf (file, _("v850 architecture")); break;
1903 /* start-sanitize-v850e */
1904     case E_V850E_ARCH:  fprintf (file, _("v850e architecture")); break;
1905     case E_V850EA_ARCH: fprintf (file, _("v850ea architecture")); break;
1906 /* end-sanitize-v850e */
1907     }
1908   
1909   fputc ('\n', file);
1910   
1911   return true;
1912 }
1913
1914 /* V850 ELF uses four common sections.  One is the usual one, and the
1915    others are for (small) objects in one of the special data areas:
1916    small, tiny and zero.  All the objects are kept together, and then
1917    referenced via the gp register, the ep register or the r0 register
1918    respectively, which yields smaller, faster assembler code.  This
1919    approach is copied from elf32-mips.c.  */
1920
1921 static asection  v850_elf_scom_section;
1922 static asymbol   v850_elf_scom_symbol;
1923 static asymbol * v850_elf_scom_symbol_ptr;
1924 static asection  v850_elf_tcom_section;
1925 static asymbol   v850_elf_tcom_symbol;
1926 static asymbol * v850_elf_tcom_symbol_ptr;
1927 static asection  v850_elf_zcom_section;
1928 static asymbol   v850_elf_zcom_symbol;
1929 static asymbol * v850_elf_zcom_symbol_ptr;
1930
1931
1932 /* Given a BFD section, try to locate the corresponding ELF section
1933    index.  */
1934
1935 static boolean
1936 v850_elf_section_from_bfd_section (abfd, hdr, sec, retval)
1937      bfd *                 abfd;
1938      Elf32_Internal_Shdr * hdr;
1939      asection *            sec;
1940      int *                 retval;
1941 {
1942   if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
1943     *retval = SHN_V850_SCOMMON;
1944   else if (strcmp (bfd_get_section_name (abfd, sec), ".tcommon") == 0)
1945     *retval = SHN_V850_TCOMMON;
1946   else if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
1947     *retval = SHN_V850_ZCOMMON;
1948   else
1949     return false;
1950   
1951   return true;
1952 }
1953
1954 /* Handle the special V850 section numbers that a symbol may use.  */
1955
1956 static void
1957 v850_elf_symbol_processing (abfd, asym)
1958      bfd *     abfd;
1959      asymbol * asym;
1960 {
1961   elf_symbol_type * elfsym = (elf_symbol_type *) asym;
1962   unsigned short index;
1963   
1964   index = elfsym->internal_elf_sym.st_shndx;
1965
1966   /* If the section index is an "ordinary" index, then it may
1967      refer to a v850 specific section created by the assembler.
1968      Check the section's type and change the index it matches.
1969      
1970      FIXME: Should we alter the st_shndx field as well ?  */
1971   
1972   if (index < elf_elfheader(abfd)[0].e_shnum)
1973     switch (elf_elfsections(abfd)[index]->sh_type)
1974       {
1975       case SHT_V850_SCOMMON:
1976         index = SHN_V850_SCOMMON;
1977         break;
1978         
1979       case SHT_V850_TCOMMON:
1980         index = SHN_V850_TCOMMON;
1981         break;
1982         
1983       case SHT_V850_ZCOMMON:
1984         index = SHN_V850_ZCOMMON;
1985         break;
1986         
1987       default:
1988         break;
1989       }
1990   
1991   switch (index)
1992     {
1993     case SHN_V850_SCOMMON:
1994       if (v850_elf_scom_section.name == NULL)
1995         {
1996           /* Initialize the small common section.  */
1997           v850_elf_scom_section.name           = ".scommon";
1998           v850_elf_scom_section.flags          = SEC_IS_COMMON | SEC_ALLOC | SEC_DATA;
1999           v850_elf_scom_section.output_section = & v850_elf_scom_section;
2000           v850_elf_scom_section.symbol         = & v850_elf_scom_symbol;
2001           v850_elf_scom_section.symbol_ptr_ptr = & v850_elf_scom_symbol_ptr;
2002           v850_elf_scom_symbol.name            = ".scommon";
2003           v850_elf_scom_symbol.flags           = BSF_SECTION_SYM;
2004           v850_elf_scom_symbol.section         = & v850_elf_scom_section;
2005           v850_elf_scom_symbol_ptr             = & v850_elf_scom_symbol;
2006         }
2007       asym->section = & v850_elf_scom_section;
2008       asym->value = elfsym->internal_elf_sym.st_size;
2009       break;
2010       
2011     case SHN_V850_TCOMMON:
2012       if (v850_elf_tcom_section.name == NULL)
2013         {
2014           /* Initialize the tcommon section.  */
2015           v850_elf_tcom_section.name           = ".tcommon";
2016           v850_elf_tcom_section.flags          = SEC_IS_COMMON;
2017           v850_elf_tcom_section.output_section = & v850_elf_tcom_section;
2018           v850_elf_tcom_section.symbol         = & v850_elf_tcom_symbol;
2019           v850_elf_tcom_section.symbol_ptr_ptr = & v850_elf_tcom_symbol_ptr;
2020           v850_elf_tcom_symbol.name            = ".tcommon";
2021           v850_elf_tcom_symbol.flags           = BSF_SECTION_SYM;
2022           v850_elf_tcom_symbol.section         = & v850_elf_tcom_section;
2023           v850_elf_tcom_symbol_ptr             = & v850_elf_tcom_symbol;
2024         }
2025       asym->section = & v850_elf_tcom_section;
2026       asym->value = elfsym->internal_elf_sym.st_size;
2027       break;
2028
2029     case SHN_V850_ZCOMMON:
2030       if (v850_elf_zcom_section.name == NULL)
2031         {
2032           /* Initialize the zcommon section.  */
2033           v850_elf_zcom_section.name           = ".zcommon";
2034           v850_elf_zcom_section.flags          = SEC_IS_COMMON;
2035           v850_elf_zcom_section.output_section = & v850_elf_zcom_section;
2036           v850_elf_zcom_section.symbol         = & v850_elf_zcom_symbol;
2037           v850_elf_zcom_section.symbol_ptr_ptr = & v850_elf_zcom_symbol_ptr;
2038           v850_elf_zcom_symbol.name            = ".zcommon";
2039           v850_elf_zcom_symbol.flags           = BSF_SECTION_SYM;
2040           v850_elf_zcom_symbol.section         = & v850_elf_zcom_section;
2041           v850_elf_zcom_symbol_ptr             = & v850_elf_zcom_symbol;
2042         }
2043       asym->section = & v850_elf_zcom_section;
2044       asym->value = elfsym->internal_elf_sym.st_size;
2045       break;
2046     }
2047 }
2048
2049 /* Hook called by the linker routine which adds symbols from an object
2050    file.  We must handle the special v850 section numbers here.  */
2051
2052 /*ARGSUSED*/
2053 static boolean
2054 v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
2055      bfd *                    abfd;
2056      struct bfd_link_info *   info;
2057      const Elf_Internal_Sym * sym;
2058      const char **            namep;
2059      flagword *               flagsp;
2060      asection **              secp;
2061      bfd_vma *                valp;
2062 {
2063   int index = sym->st_shndx;
2064   
2065   /* If the section index is an "ordinary" index, then it may
2066      refer to a v850 specific section created by the assembler.
2067      Check the section's type and change the index it matches.
2068      
2069      FIXME: Should we alter the st_shndx field as well ?  */
2070   
2071   if (index < elf_elfheader(abfd)[0].e_shnum)
2072     switch (elf_elfsections(abfd)[index]->sh_type)
2073       {
2074       case SHT_V850_SCOMMON:
2075         index = SHN_V850_SCOMMON;
2076         break;
2077         
2078       case SHT_V850_TCOMMON:
2079         index = SHN_V850_TCOMMON;
2080         break;
2081         
2082       case SHT_V850_ZCOMMON:
2083         index = SHN_V850_ZCOMMON;
2084         break;
2085         
2086       default:
2087         break;
2088       }
2089   
2090   switch (index)
2091     {
2092     case SHN_V850_SCOMMON:
2093       *secp = bfd_make_section_old_way (abfd, ".scommon");
2094       (*secp)->flags |= SEC_IS_COMMON;
2095       *valp = sym->st_size;
2096       break;
2097       
2098     case SHN_V850_TCOMMON:
2099       *secp = bfd_make_section_old_way (abfd, ".tcommon");
2100       (*secp)->flags |= SEC_IS_COMMON;
2101       *valp = sym->st_size;
2102       break;
2103       
2104     case SHN_V850_ZCOMMON:
2105       *secp = bfd_make_section_old_way (abfd, ".zcommon");
2106       (*secp)->flags |= SEC_IS_COMMON;
2107       *valp = sym->st_size;
2108       break;
2109     }
2110
2111   return true;
2112 }
2113
2114 /*ARGSIGNORED*/
2115 static boolean
2116 v850_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
2117      bfd *                  abfd;
2118      struct bfd_link_info * info;
2119      const char *           name;
2120      Elf_Internal_Sym *     sym;
2121      asection *             input_sec;
2122 {
2123   /* If we see a common symbol, which implies a relocatable link, then
2124      if a symbol was in a special common section in an input file, mark
2125      it as a special common in the output file.  */
2126   
2127   if (sym->st_shndx == SHN_COMMON)
2128     {
2129       if (strcmp (input_sec->name, ".scommon") == 0)
2130         sym->st_shndx = SHN_V850_SCOMMON;
2131       else if (strcmp (input_sec->name, ".tcommon") == 0)
2132         sym->st_shndx = SHN_V850_TCOMMON;
2133       else if (strcmp (input_sec->name, ".zcommon") == 0)
2134         sym->st_shndx = SHN_V850_ZCOMMON;
2135     }
2136
2137   return true;
2138 }
2139
2140 static boolean
2141 v850_elf_section_from_shdr (abfd, hdr, name)
2142      bfd *               abfd;
2143      Elf_Internal_Shdr * hdr;
2144      char *              name;
2145 {
2146   /* There ought to be a place to keep ELF backend specific flags, but
2147      at the moment there isn't one.  We just keep track of the
2148      sections by their name, instead.  */
2149
2150   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
2151     return false;
2152
2153   switch (hdr->sh_type)
2154     {
2155     case SHT_V850_SCOMMON:
2156     case SHT_V850_TCOMMON:
2157     case SHT_V850_ZCOMMON:
2158       if (! bfd_set_section_flags (abfd, hdr->bfd_section,
2159                                    (bfd_get_section_flags (abfd,
2160                                                            hdr->bfd_section)
2161                                     | SEC_IS_COMMON)))
2162         return false;
2163     }
2164
2165   return true;
2166 }
2167
2168 /* Set the correct type for a V850 ELF section.  We do this by the
2169    section name, which is a hack, but ought to work.  */
2170 static boolean
2171 v850_elf_fake_sections (abfd, hdr, sec)
2172      bfd *                 abfd;
2173      Elf32_Internal_Shdr * hdr;
2174      asection *            sec;
2175 {
2176   register const char * name;
2177
2178   name = bfd_get_section_name (abfd, sec);
2179
2180   if (strcmp (name, ".scommon") == 0)
2181     {
2182       hdr->sh_type = SHT_V850_SCOMMON;
2183     }
2184   else if (strcmp (name, ".tcommon") == 0)
2185     {
2186       hdr->sh_type = SHT_V850_TCOMMON;
2187     }
2188   else if (strcmp (name, ".zcommon") == 0)
2189     hdr->sh_type = SHT_V850_ZCOMMON;
2190   
2191   return true;
2192 }
2193
2194
2195 \f
2196 #define TARGET_LITTLE_SYM                       bfd_elf32_v850_vec
2197 #define TARGET_LITTLE_NAME                      "elf32-v850"
2198 #define ELF_ARCH                                bfd_arch_v850
2199 #define ELF_MACHINE_CODE                        EM_CYGNUS_V850
2200 #define ELF_MAXPAGESIZE                         0x1000
2201         
2202 #define elf_info_to_howto                       v850_elf_info_to_howto_rela
2203 #define elf_info_to_howto_rel                   v850_elf_info_to_howto_rel
2204
2205 #define elf_backend_check_relocs                v850_elf_check_relocs
2206 #define elf_backend_relocate_section            v850_elf_relocate_section
2207 #define elf_backend_object_p                    v850_elf_object_p
2208 #define elf_backend_final_write_processing      v850_elf_final_write_processing
2209 #define elf_backend_section_from_bfd_section    v850_elf_section_from_bfd_section
2210 #define elf_backend_symbol_processing           v850_elf_symbol_processing
2211 #define elf_backend_add_symbol_hook             v850_elf_add_symbol_hook
2212 #define elf_backend_link_output_symbol_hook     v850_elf_link_output_symbol_hook
2213 #define elf_backend_section_from_shdr           v850_elf_section_from_shdr
2214 #define elf_backend_fake_sections               v850_elf_fake_sections
2215 #define elf_backend_gc_mark_hook                v850_elf_gc_mark_hook
2216 #define elf_backend_gc_sweep_hook               v850_elf_gc_sweep_hook
2217
2218 #define elf_backend_can_gc_sections 1
2219
2220
2221 #define bfd_elf32_bfd_is_local_label_name       v850_elf_is_local_label_name
2222 #define bfd_elf32_bfd_reloc_type_lookup         v850_elf_reloc_type_lookup
2223 #define bfd_elf32_bfd_copy_private_bfd_data     v850_elf_copy_private_bfd_data
2224 #define bfd_elf32_bfd_merge_private_bfd_data    v850_elf_merge_private_bfd_data
2225 #define bfd_elf32_bfd_set_private_flags         v850_elf_set_private_flags
2226 #define bfd_elf32_bfd_print_private_bfd_data    v850_elf_print_private_bfd_data
2227
2228 #define elf_symbol_leading_char                 '_'
2229
2230 #include "elf32-target.h"