Add prototypes for static functions.
[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_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 };
440
441 /* Map BFD reloc types to V850 ELF reloc types.  */
442
443 struct v850_elf_reloc_map
444 {
445   unsigned char bfd_reloc_val;
446   unsigned char elf_reloc_val;
447 };
448
449 static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
450 {
451   { BFD_RELOC_NONE,             R_V850_NONE },
452   { BFD_RELOC_V850_9_PCREL,     R_V850_9_PCREL },
453   { BFD_RELOC_V850_22_PCREL,    R_V850_22_PCREL },
454   { BFD_RELOC_HI16_S,           R_V850_HI16_S },
455   { BFD_RELOC_HI16,             R_V850_HI16 },
456   { BFD_RELOC_LO16,             R_V850_LO16 },
457   { BFD_RELOC_32,               R_V850_32 },
458   { BFD_RELOC_16,               R_V850_16 },
459   { BFD_RELOC_8,                R_V850_8 },
460   { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET },
461   { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET },
462   { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET },
463   { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET },
464   { BFD_RELOC_V850_TDA_6_8_OFFSET,   R_V850_TDA_6_8_OFFSET   },
465   { BFD_RELOC_V850_TDA_7_8_OFFSET,   R_V850_TDA_7_8_OFFSET   },
466   { BFD_RELOC_V850_TDA_7_7_OFFSET,   R_V850_TDA_7_7_OFFSET   },
467   { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET },
468 /* start-sanitize-v850e */
469   { BFD_RELOC_V850_TDA_4_5_OFFSET,         R_V850_TDA_4_5_OFFSET         },
470   { BFD_RELOC_V850_TDA_4_4_OFFSET,         R_V850_TDA_4_4_OFFSET         },
471   { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },
472   { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },
473   { BFD_RELOC_V850_CALLT_6_7_OFFSET,       R_V850_CALLT_6_7_OFFSET       },
474   { BFD_RELOC_V850_CALLT_16_16_OFFSET,     R_V850_CALLT_16_16_OFFSET     },
475 /* end-sanitize-v850e */
476 };
477
478 \f
479 /* Map a bfd relocation into the appropriate howto structure */
480 static reloc_howto_type *
481 v850_elf_reloc_type_lookup (abfd, code)
482      bfd *                     abfd;
483      bfd_reloc_code_real_type  code;
484 {
485   unsigned int i;
486
487   for (i = 0;
488        i < sizeof (v850_elf_reloc_map) / sizeof (struct v850_elf_reloc_map);
489        i++)
490     {
491       if (v850_elf_reloc_map[i].bfd_reloc_val == code)
492         {
493           BFD_ASSERT (v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val].type == v850_elf_reloc_map[i].elf_reloc_val);
494           
495           return & v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val];
496         }
497     }
498
499   return NULL;
500 }
501
502 \f
503 /* Set the howto pointer for an V850 ELF reloc.  */
504 static void
505 v850_elf_info_to_howto_rel (abfd, cache_ptr, dst)
506      bfd *                 abfd;
507      arelent *             cache_ptr;
508      Elf32_Internal_Rel *  dst;
509 {
510   unsigned int r_type;
511
512   r_type = ELF32_R_TYPE (dst->r_info);
513   BFD_ASSERT (r_type < (unsigned int) R_V850_max);
514   cache_ptr->howto = &v850_elf_howto_table[r_type];
515 }
516
517 /* Set the howto pointer for a V850 ELF reloc (type RELA). */
518 static void
519 v850_elf_info_to_howto_rela (abfd, cache_ptr, dst)
520      bfd *                 abfd;
521      arelent *             cache_ptr;
522      Elf32_Internal_Rela   *dst;
523 {
524   unsigned int r_type;
525
526   r_type = ELF32_R_TYPE (dst->r_info);
527   BFD_ASSERT (r_type < (unsigned int) R_V850_max);
528   cache_ptr->howto = &v850_elf_howto_table[r_type];
529 }
530
531 \f
532 /* Look through the relocs for a section during the first phase, and
533    allocate space in the global offset table or procedure linkage
534    table.  */
535
536 static boolean
537 v850_elf_check_relocs (abfd, info, sec, relocs)
538      bfd *                      abfd;
539      struct bfd_link_info *     info;
540      asection *                 sec;
541      const Elf_Internal_Rela *  relocs;
542 {
543   boolean ret = true;
544   bfd *dynobj;
545   Elf_Internal_Shdr *symtab_hdr;
546   struct elf_link_hash_entry **sym_hashes;
547   const Elf_Internal_Rela *rel;
548   const Elf_Internal_Rela *rel_end;
549   asection *sreloc;
550   enum v850_reloc_type r_type;
551   int other = 0;
552   const char *common = (const char *)0;
553
554   if (info->relocateable)
555     return true;
556
557 #ifdef DEBUG
558   fprintf (stderr, "v850_elf_check_relocs called for section %s in %s\n",
559            bfd_get_section_name (abfd, sec),
560            bfd_get_filename (abfd));
561 #endif
562
563   dynobj = elf_hash_table (info)->dynobj;
564   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
565   sym_hashes = elf_sym_hashes (abfd);
566   sreloc = NULL;
567
568   rel_end = relocs + sec->reloc_count;
569   for (rel = relocs; rel < rel_end; rel++)
570     {
571       unsigned long r_symndx;
572       struct elf_link_hash_entry *h;
573
574       r_symndx = ELF32_R_SYM (rel->r_info);
575       if (r_symndx < symtab_hdr->sh_info)
576         h = NULL;
577       else
578         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
579
580       r_type = (enum v850_reloc_type) ELF32_R_TYPE (rel->r_info);
581       switch (r_type)
582         {
583         default:
584         case R_V850_NONE:
585         case R_V850_9_PCREL:
586         case R_V850_22_PCREL:
587         case R_V850_HI16_S:
588         case R_V850_HI16:
589         case R_V850_LO16:
590         case R_V850_32:
591         case R_V850_16:
592         case R_V850_8:
593 /* start-sanitize-v850e */
594         case R_V850_CALLT_6_7_OFFSET:
595         case R_V850_CALLT_16_16_OFFSET:
596 /* end-sanitize-v850e */
597           break;
598
599 /* start-sanitize-v850e */
600         case R_V850_SDA_16_16_SPLIT_OFFSET:
601 /* end-sanitize-v850e */
602         case R_V850_SDA_16_16_OFFSET:
603         case R_V850_SDA_15_16_OFFSET:
604           other = V850_OTHER_SDA;
605           common = ".scommon";
606           goto small_data_common;
607           
608 /* start-sanitize-v850e */
609         case R_V850_ZDA_16_16_SPLIT_OFFSET:
610 /* end-sanitize-v850e */
611         case R_V850_ZDA_16_16_OFFSET:
612         case R_V850_ZDA_15_16_OFFSET:
613           other = V850_OTHER_ZDA;
614           common = ".zcommon";
615           goto small_data_common;
616           
617 /* start-sanitize-v850e */
618         case R_V850_TDA_4_5_OFFSET:
619         case R_V850_TDA_4_4_OFFSET:
620 /* end-sanitize-v850e */          
621         case R_V850_TDA_6_8_OFFSET:
622         case R_V850_TDA_7_8_OFFSET:
623         case R_V850_TDA_7_7_OFFSET:
624         case R_V850_TDA_16_16_OFFSET:
625           other = V850_OTHER_TDA;
626           common = ".tcommon";
627           /* fall through */
628
629 #define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
630
631         small_data_common:
632           if (h)
633             {
634               h->other |= other;        /* flag which type of relocation was used */
635               if ((h->other & V850_OTHER_MASK) != (other & V850_OTHER_MASK)
636                   && (h->other & V850_OTHER_ERROR) == 0)
637                 {
638                   const char * msg;
639                   static char  buff[200]; /* XXX */
640
641                   switch (h->other & V850_OTHER_MASK)
642                     {
643                     default:
644                       msg = _("Variable `%s' cannot occupy in multiple small data regions");
645                       break;
646                     case V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA:
647                       msg = _("Variable `%s' can only be in one of the small, zero, and tiny data regions");
648                       break;
649                     case V850_OTHER_SDA | V850_OTHER_ZDA:
650                       msg = _("Variable `%s' cannot be in both small and zero data regions simultaneously");
651                       break;
652                     case V850_OTHER_SDA | V850_OTHER_TDA:
653                       msg = _("Variable `%s' cannot be in both small and tiny data regions simultaneously");
654                       break;
655                     case V850_OTHER_ZDA | V850_OTHER_TDA:
656                       msg = _("Variable `%s' cannot be in both zero and tiny data regions simultaneously");
657                       break;
658                     }
659
660                   sprintf (buff, msg, h->root.root.string);
661                   info->callbacks->warning (info, buff, h->root.root.string,
662                                             abfd, h->root.u.def.section, 0);
663
664                   bfd_set_error (bfd_error_bad_value);
665                   h->other |= V850_OTHER_ERROR;
666                   ret = false;
667                 }
668             }
669
670           if (h && h->root.type == bfd_link_hash_common
671               && h->root.u.c.p
672               && !strcmp (bfd_get_section_name (abfd, h->root.u.c.p->section), "COMMON"))
673             {
674               asection *section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common);
675               section->flags |= SEC_IS_COMMON;
676             }
677
678 #ifdef DEBUG
679           fprintf (stderr, "v850_elf_check_relocs, found %s relocation for %s%s\n",
680                    v850_elf_howto_table[ (int)r_type ].name,
681                    (h && h->root.root.string) ? h->root.root.string : "<unknown>",
682                    (h->root.type == bfd_link_hash_common) ? ", symbol is common" : "");
683 #endif
684           break;
685         }
686     }
687
688   return ret;
689 }
690
691 typedef struct
692 {
693   bfd_vma       addend;
694   bfd_byte *    address;
695   unsigned long counter;
696 }
697 hi16s_location;
698
699 static hi16s_location  previous_hi16s[ 10 ]; /* XXX is this enough ? */
700 static unsigned long   hi16s_counter;
701
702 static void
703 remember_hi16s_reloc (addend, address)
704      bfd_vma    addend;
705      bfd_byte * address;
706 {
707   hi16s_location * oldest = NULL;
708   int              i;
709   
710   /* Find a free slot.  */
711   for (i = sizeof (previous_hi16s) / sizeof (previous_hi16s[0]); i--;)
712     {
713       hi16s_location * entry = previous_hi16s + i;
714       
715       if (entry->addend == 0 && entry->address == 0)
716         {
717           /* Use this entry.  */
718           oldest = entry;
719           break;
720         }
721
722       /* Remember the least recently added entry.  */
723       if (oldest == NULL || oldest->counter > entry->counter)
724         oldest = entry;
725     }
726
727   oldest->addend  = addend;
728   oldest->address = address;
729   oldest->counter = hi16s_counter ++;
730
731   /* Cope with wrap around of our counter.  */
732   if (hi16s_counter == 0)
733     {
734       /* XXX - Assume that all counter entries differ only in their low 16 bits.  */
735       for (i = sizeof (previous_hi16s) / sizeof (previous_hi16s[0]); i--;)
736         {
737           hi16s_location * entry = previous_hi16s + i;
738
739           entry->counter &= 0xffff;
740         }
741
742       hi16s_counter = 0x10000;
743     }
744   
745   return;
746 }
747
748 static bfd_byte *
749 find_remembered_hi16s_reloc (addend)
750      bfd_vma addend;
751 {
752   hi16s_location * match = NULL;
753   int              i;
754   
755   /* Search the table.  Record the most recent entry that matches.  */
756   for (i = sizeof (previous_hi16s) / sizeof (previous_hi16s[0]); i--;)
757     {
758       hi16s_location * entry = previous_hi16s + i;
759
760       if (entry->addend == addend)
761         {
762           if (match == NULL || match->counter < entry->counter)
763             match = entry;
764         }
765     }
766
767   if (match != NULL)
768     {
769       bfd_byte * addr;
770
771       /* Empty the table entry.  */
772       match->addend = 0;
773       
774       addr = match->address;
775       match->address = NULL;
776       
777       return addr;
778     }
779   
780   return NULL;
781 }     
782
783 static bfd_reloc_status_type
784 v850_elf_perform_relocation (abfd, r_type, addend, address)
785      bfd *      abfd;
786      int        r_type;
787      bfd_vma    addend;
788      bfd_byte * address;
789 {
790   unsigned long insn;
791   
792   switch (r_type)
793     {
794     default:
795       /* fprintf (stderr, "reloc type %d not SUPPORTED\n", r_type ); */
796       return bfd_reloc_notsupported;
797       
798     case R_V850_32:
799       addend += bfd_get_32 (abfd, address);
800       bfd_put_32 (abfd, addend, address);
801       return bfd_reloc_ok;
802       
803     case R_V850_22_PCREL:
804       if (addend > 0x1fffff || addend < -0x200000)
805         return bfd_reloc_overflow;
806       
807       if ((addend % 2) != 0)
808         return bfd_reloc_dangerous;
809       
810       insn  = bfd_get_32 (abfd, address);
811       insn &= ~0xfffe003f;
812       insn |= (((addend & 0xfffe) << 16) | ((addend & 0x3f0000) >> 16));
813       bfd_put_32 (abfd, insn, address);
814       return bfd_reloc_ok;
815       
816     case R_V850_9_PCREL:
817       if (addend > 0xff || addend < -0x100)
818         return bfd_reloc_overflow;
819       
820       if ((addend % 2) != 0)
821         return bfd_reloc_dangerous;
822       
823       insn  = bfd_get_16 (abfd, address);
824       insn &= ~ 0xf870;
825       insn |= ((addend & 0x1f0) << 7) | ((addend & 0x0e) << 3);
826       break;
827       
828     case R_V850_HI16:
829       addend += (bfd_get_16 (abfd, address) << 16);
830       addend = (addend >> 16);
831       insn = addend;
832       break;
833       
834     case R_V850_HI16_S:
835       /* Remember where this relocation took place.  */
836       remember_hi16s_reloc (addend, address);
837
838       addend += (bfd_get_16 (abfd, address) << 16);
839       addend = (addend >> 16) + ((addend & 0x8000) != 0);
840       
841       /* This relocation cannot overflow. */
842       if (addend > 0x7fff || addend < -0x8000)
843         addend = 0;
844       
845       insn = addend;
846       break;
847       
848     case R_V850_LO16:
849       /* Calculate the sum of the value stored in the instruction and the
850          addend and check for overflow from the low 16 bits into the high
851          16 bits.  The assembler has already done some of this:  If the
852          value stored in the instruction has its 15th bit set, (counting
853          from zero) then the assembler will have added 1 to the value
854          stored in the associated HI16S reloc.  So for example, these
855          relocations:
856
857              movhi hi( fred ), r0, r1
858              movea lo( fred ), r1, r1
859
860          will store 0 in the value fields for the MOVHI and MOVEA instructions
861          and addend will be the address of fred, but for these instructions:
862
863              movhi hi( fred + 0x123456), r0, r1
864              movea lo( fred + 0x123456), r1, r1
865
866          the value stored in the MOVHI instruction will be 0x12 and the value
867          stored in the MOVEA instruction will be 0x3456.  If however the
868          instructions were:
869
870              movhi hi( fred + 0x10ffff), r0, r1
871              movea lo( fred + 0x10ffff), r1, r1
872
873          then the value stored in the MOVHI instruction would be 0x11 (not
874          0x10) and the value stored in the MOVEA instruction would be 0xffff.
875          Thus (assuming for the moment that the addend is 0), at run time the
876          MOVHI instruction loads 0x110000 into r1, then the MOVEA instruction
877          adds 0xffffffff (sign extension!) producing 0x10ffff.  Similarly if
878          the instructions were:
879
880              movhi hi( fred - 1), r0, r1
881              movea lo( fred - 1), r1, r1
882
883          then 0 is stored in the MOVHI instruction and -1 is stored in the
884          MOVEA instruction.
885
886          Overflow can occur if the addition of the value stored in the
887          instruction plus the addend sets the 15th bit when before it was clear.
888          This is because the 15th bit will be sign extended into the high part,
889          thus reducing its value by one, but since the 15th bit was originally
890          clear, the assembler will not have added 1 to the previous HI16S reloc
891          to compensate for this effect.  For example:
892
893             movhi hi( fred + 0x123456), r0, r1
894             movea lo( fred + 0x123456), r1, r1
895
896          The value stored in HI16S reloc is 0x12, the value stored in the LO16
897          reloc is 0x3456.  If we assume that the address of fred is 0x00007000
898          then the relocations become:
899
900            HI16S: 0x0012 + (0x00007000 >> 16)    = 0x12
901            LO16:  0x3456 + (0x00007000 & 0xffff) = 0xa456
902
903          but when the instructions are executed, the MOVEA instruction's value
904          is signed extended, so the sum becomes:
905
906               0x00120000
907             + 0xffffa456
908             ------------
909               0x0011a456    but 'fred + 0x123456' = 0x0012a456
910
911          Note that if the 15th bit was set in the value stored in the LO16
912          reloc, then we do not have to do anything:
913
914             movhi hi( fred + 0x10ffff), r0, r1
915             movea lo( fred + 0x10ffff), r1, r1
916
917             HI16S:  0x0011 + (0x00007000 >> 16)    = 0x11
918             LO16:   0xffff + (0x00007000 & 0xffff) = 0x6fff
919
920               0x00110000
921             + 0x00006fff
922             ------------
923               0x00116fff  = fred + 0x10ffff = 0x7000 + 0x10ffff
924
925          
926          Overflow can also occur if the computation carries into the 16th bit
927          and it also results in the 15th bit having the same value as the 15th
928          bit of the original value.   What happens is that the HI16S reloc
929          will have already examined the 15th bit of the original value and
930          added 1 to the high part if the bit is set.  This compensates for the
931          sign extension of 15th bit of the result of the computation.  But now
932          there is a carry into the 16th bit, and this has not been allowed for.
933
934          So, for example if fred is at address 0xf000:
935
936            movhi hi( fred + 0xffff), r0, r1    [bit 15 of the offset is set]
937            movea lo( fred + 0xffff), r1, r1
938
939            HI16S: 0x0001 + (0x0000f000 >> 16)    = 0x0001
940            LO16:  0xffff + (0x0000f000 & 0xffff) = 0xefff   (carry into bit 16 is lost)
941
942              0x00010000
943            + 0xffffefff
944            ------------
945              0x0000efff   but 'fred + 0xffff' = 0x0001efff
946
947          Similarly, if the 15th bit remains clear, but overflow occurs into
948          the 16th bit then (assuming the address of fred is 0xf000):
949
950            movhi hi( fred + 0x7000), r0, r1    [bit 15 of the offset is clear]
951            movea lo( fred + 0x7000), r1, r1
952
953            HI16S: 0x0000 + (0x0000f000 >> 16)    = 0x0000
954            LO16:  0x7000 + (0x0000f000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)
955
956              0x00000000
957            + 0x00006fff
958            ------------
959              0x00006fff   but 'fred + 0x7000' = 0x00016fff
960            
961          Note - there is no need to change anything if a carry occurs, and the
962          15th bit changes its value from being set to being clear, as the HI16S
963          reloc will have already added in 1 to the high part for us:
964
965            movhi hi( fred + 0xffff), r0, r1     [bit 15 of the offset is set]
966            movea lo( fred + 0xffff), r1, r1
967
968            HI16S: 0x0001 + (0x00007000 >> 16)
969            LO16:  0xffff + (0x00007000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)
970
971              0x00010000
972            + 0x00006fff   (bit 15 not set, so the top half is zero)
973            ------------
974              0x00016fff   which is right (assuming that fred is at 0x7000)
975
976          but if the 15th bit goes from being clear to being set, then we must
977          once again handle overflow:
978
979            movhi hi( fred + 0x7000), r0, r1     [bit 15 of the offset is clear]
980            movea lo( fred + 0x7000), r1, r1
981
982            HI16S: 0x0000 + (0x0000ffff >> 16)
983            LO16:  0x7000 + (0x0000ffff & 0xffff) = 0x6fff  (carry into bit 16)
984
985              0x00000000
986            + 0x00006fff   (bit 15 not set, so the top half is zero)
987            ------------
988              0x00006fff   which is wrong (assuming that fred is at 0xffff)
989          */
990
991       {
992         long result;
993
994         insn   = bfd_get_16 (abfd, address);
995         result = insn + addend;
996
997 #define BIT15_SET(x) ((x) & 0x8000)
998 #define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)
999         
1000         if ((BIT15_SET (result) && ! BIT15_SET (addend))
1001             || (OVERFLOWS (addend, insn)
1002                 && ((! BIT15_SET (insn)) || (BIT15_SET (addend)))))
1003           {
1004             bfd_byte * hi16s_address = find_remembered_hi16s_reloc (addend);
1005             
1006             /* Amend the matching HI16_S relocation.  */
1007             if (hi16s_address != NULL)
1008               {
1009                 insn = bfd_get_16 (abfd, hi16s_address);
1010                 insn += 1;
1011                 bfd_put_16 (abfd, insn, hi16s_address);
1012               }
1013             else
1014               {
1015                 fprintf (stderr, _("FAILED to find previous HI16 reloc\n"));
1016                 return bfd_reloc_overflow;
1017               }
1018           }
1019         
1020         /* Do not complain if value has top bit set, as this has been anticipated.  */
1021         insn = result & 0xffff;
1022         break;
1023       }
1024
1025     case R_V850_8:
1026       addend += (char) bfd_get_8 (abfd, address);
1027
1028       if (addend > 0x7f || addend < -0x80)
1029         return bfd_reloc_overflow;
1030
1031       bfd_put_8 (abfd, addend, address);
1032       return bfd_reloc_ok;
1033
1034 /* start-sanitize-v850e */
1035     case R_V850_CALLT_16_16_OFFSET:
1036       addend += bfd_get_16 (abfd, address);
1037       
1038       if (addend > 0xffff || addend < 0)
1039         return bfd_reloc_overflow;
1040
1041       insn = addend;
1042       break;
1043 /* end-sanitize-v850e */
1044       
1045     case R_V850_16:
1046
1047       /* drop through */            
1048     case R_V850_SDA_16_16_OFFSET:
1049     case R_V850_ZDA_16_16_OFFSET:
1050     case R_V850_TDA_16_16_OFFSET:
1051       addend += bfd_get_16 (abfd, address);
1052       
1053       if (addend > 0x7fff || addend < -0x8000)
1054         return bfd_reloc_overflow;
1055
1056       insn = addend;
1057       break;
1058       
1059     case R_V850_SDA_15_16_OFFSET:
1060     case R_V850_ZDA_15_16_OFFSET:
1061       insn = bfd_get_16 (abfd, address);
1062       addend += (insn & 0xfffe);
1063       
1064       if (addend > 0x7ffe || addend < -0x8000)
1065         return bfd_reloc_overflow;
1066       
1067       if (addend & 1)
1068         return bfd_reloc_dangerous;
1069       
1070       insn = (addend & ~1) | (insn & 1);
1071       break;
1072       
1073     case R_V850_TDA_6_8_OFFSET:
1074       insn = bfd_get_16 (abfd, address);
1075       addend += ((insn & 0x7e) << 1);
1076       
1077       if (addend > 0xfc || addend < 0)
1078         return bfd_reloc_overflow;
1079       
1080       if (addend & 3)
1081         return bfd_reloc_dangerous;
1082       
1083       insn &= 0xff81;
1084       insn |= (addend >> 1);
1085       break;
1086       
1087     case R_V850_TDA_7_8_OFFSET:
1088       insn = bfd_get_16 (abfd, address);
1089       addend += ((insn & 0x7f) << 1);
1090       
1091       if (addend > 0xfe || addend < 0)
1092         return bfd_reloc_overflow;
1093       
1094       if (addend & 1)
1095         return bfd_reloc_dangerous;
1096       
1097       insn &= 0xff80;
1098       insn |= (addend >> 1);
1099       break;
1100       
1101     case R_V850_TDA_7_7_OFFSET:
1102       insn = bfd_get_16 (abfd, address);
1103       addend += insn & 0x7f;
1104         
1105       if (addend > 0x7f || addend < 0)
1106         return bfd_reloc_overflow;
1107       
1108       insn &= 0xff80;
1109       insn |= addend;
1110       break;
1111       
1112 /* start-sanitize-v850e */
1113     case R_V850_TDA_4_5_OFFSET:
1114       insn = bfd_get_16 (abfd, address);
1115       addend += ((insn & 0xf) << 1);
1116       
1117       if (addend > 0x1e || addend < 0)
1118         return bfd_reloc_overflow;
1119       
1120       if (addend & 1)
1121         return bfd_reloc_dangerous;
1122       
1123       insn &= 0xfff0;
1124       insn |= (addend >> 1);
1125       break;
1126       
1127     case R_V850_TDA_4_4_OFFSET:
1128       insn = bfd_get_16 (abfd, address);
1129       addend += insn & 0xf;
1130       
1131       if (addend > 0xf || addend < 0)
1132         return bfd_reloc_overflow;
1133       
1134       insn &= 0xfff0;
1135       insn |= addend;
1136       break;
1137       
1138     case R_V850_ZDA_16_16_SPLIT_OFFSET:
1139     case R_V850_SDA_16_16_SPLIT_OFFSET:
1140       insn = bfd_get_32 (abfd, address);
1141       addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5);
1142       
1143       if (addend > 0x7fff || addend < -0x8000)
1144         return bfd_reloc_overflow;
1145       
1146       insn &= 0x0001ffdf;
1147       insn |= (addend & 1) << 5;
1148       insn |= (addend & ~1) << 16;
1149       
1150       bfd_put_32 (abfd, insn, address);
1151       return bfd_reloc_ok;
1152       
1153     case R_V850_CALLT_6_7_OFFSET:
1154       insn = bfd_get_16 (abfd, address);
1155       addend += ((insn & 0x3f) << 1);
1156       
1157       if (addend > 0x7e || addend < 0)
1158         return bfd_reloc_overflow;
1159       
1160       if (addend & 1)
1161         return bfd_reloc_dangerous;
1162       
1163       insn &= 0xff80;
1164       insn |= (addend >> 1);
1165       break;
1166 /* end-sanitize-v850e */
1167     }
1168
1169   bfd_put_16 (abfd, insn, address);
1170   return bfd_reloc_ok;
1171 }
1172
1173 \f
1174 /* Insert the addend into the instruction.  */
1175 static bfd_reloc_status_type
1176 v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
1177      bfd *       abfd;
1178      arelent *   reloc;
1179      asymbol *   symbol;
1180      PTR         data;
1181      asection *  isection;
1182      bfd *       obfd;
1183      char **     err;
1184 {
1185   long relocation;
1186   
1187   /* If there is an output BFD,
1188      and the symbol is not a section name (which is only defined at final link time),
1189      and either we are not putting the addend into the instruction
1190          or the addend is zero, so there is nothing to add into the instruction
1191      then just fixup the address and return.  */
1192   if (obfd != (bfd *) NULL
1193       && (symbol->flags & BSF_SECTION_SYM) == 0
1194       && (! reloc->howto->partial_inplace
1195           || reloc->addend == 0))
1196     {
1197       reloc->address += isection->output_offset;
1198       return bfd_reloc_ok;
1199     }
1200 #if 0  
1201   else if (obfd != NULL)
1202     {
1203       return bfd_reloc_continue;
1204     }
1205 #endif
1206   
1207   /* Catch relocs involving undefined symbols.  */
1208   if (bfd_is_und_section (symbol->section)
1209       && (symbol->flags & BSF_WEAK) == 0
1210       && obfd == NULL)
1211     return bfd_reloc_undefined;
1212
1213   /* We handle final linking of some relocs ourselves.  */
1214
1215   /* Is the address of the relocation really within the section?  */
1216   if (reloc->address > isection->_cooked_size)
1217     return bfd_reloc_outofrange;
1218   
1219   /* Work out which section the relocation is targetted at and the
1220      initial relocation command value.  */
1221   
1222   /* Get symbol value.  (Common symbols are special.)  */
1223   if (bfd_is_com_section (symbol->section))
1224     relocation = 0;
1225   else
1226     relocation = symbol->value;
1227   
1228   /* Convert input-section-relative symbol value to absolute + addend.  */
1229   relocation += symbol->section->output_section->vma;
1230   relocation += symbol->section->output_offset;
1231   relocation += reloc->addend;
1232   
1233   if (reloc->howto->pc_relative == true)
1234     {
1235       /* Here the variable relocation holds the final address of the
1236          symbol we are relocating against, plus any addend.  */
1237       relocation -= isection->output_section->vma + isection->output_offset;
1238       
1239       /* Deal with pcrel_offset */
1240       relocation -= reloc->address;
1241     }
1242
1243   reloc->addend = relocation;   
1244   return bfd_reloc_ok;
1245 }
1246
1247 \f
1248 /*ARGSUSED*/
1249 static boolean
1250 v850_elf_is_local_label_name (abfd, name)
1251      bfd *         abfd;
1252      const char *  name;
1253 {
1254   return (   (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
1255           || (name[0] == '_' &&  name[1] == '.' && name[2] == 'L' && name[3] == '_'));
1256 }
1257
1258 \f
1259 /* Perform a relocation as part of a final link.  */
1260 static bfd_reloc_status_type
1261 v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
1262                                     input_section, contents, offset, value,
1263                                     addend, info, sym_sec, is_local)
1264      reloc_howto_type *      howto;
1265      bfd *                   input_bfd;
1266      bfd *                   output_bfd;
1267      asection *              input_section;
1268      bfd_byte *              contents;
1269      bfd_vma                 offset;
1270      bfd_vma                 value;
1271      bfd_vma                 addend;
1272      struct bfd_link_info *  info;
1273      asection *              sym_sec;
1274      int                     is_local;
1275 {
1276   unsigned long  r_type   = howto->type;
1277   bfd_byte *     hit_data = contents + offset;
1278
1279   /* Adjust the value according to the relocation.  */
1280   switch (r_type)
1281     {
1282     case R_V850_9_PCREL:
1283       value -= (input_section->output_section->vma
1284                 + input_section->output_offset);
1285       value -= offset;
1286       break;
1287     
1288     case R_V850_22_PCREL:
1289       value -= (input_section->output_section->vma
1290                 + input_section->output_offset
1291                 + offset);
1292
1293       value = SEXT24 (value);  /* Only the bottom 24 bits of the PC are valid */
1294       break;
1295       
1296     case R_V850_HI16_S:
1297     case R_V850_HI16:
1298     case R_V850_LO16:
1299     case R_V850_16:
1300     case R_V850_32:
1301     case R_V850_8:
1302       break;
1303
1304     case R_V850_ZDA_15_16_OFFSET:       
1305     case R_V850_ZDA_16_16_OFFSET:
1306 /* start-sanitize-v850e */
1307     case R_V850_ZDA_16_16_SPLIT_OFFSET:
1308 /* end-sanitize-v850e */
1309       if (sym_sec == NULL)
1310         return bfd_reloc_undefined;
1311           
1312       value -= sym_sec->output_section->vma;
1313       break;
1314
1315     case R_V850_SDA_15_16_OFFSET:
1316     case R_V850_SDA_16_16_OFFSET:
1317 /* start-sanitize-v850e */
1318     case R_V850_SDA_16_16_SPLIT_OFFSET:
1319 /* end-sanitize-v850e */
1320       {
1321         unsigned long                gp;
1322         struct bfd_link_hash_entry * h;
1323
1324         if (sym_sec == NULL)
1325           return bfd_reloc_undefined;
1326           
1327         /* Get the value of __gp.  */
1328         h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
1329         if (h == (struct bfd_link_hash_entry *) NULL
1330             || h->type != bfd_link_hash_defined)
1331           return bfd_reloc_other;
1332
1333         gp = (h->u.def.value
1334               + h->u.def.section->output_section->vma
1335               + h->u.def.section->output_offset);
1336
1337         value -= sym_sec->output_section->vma;
1338         value -= (gp - sym_sec->output_section->vma);
1339       }
1340     break;
1341
1342 /* start-sanitize-v850e */
1343     case R_V850_TDA_4_4_OFFSET:
1344     case R_V850_TDA_4_5_OFFSET:
1345 /* end-sanitize-v850e */
1346     case R_V850_TDA_16_16_OFFSET:
1347     case R_V850_TDA_7_7_OFFSET:
1348     case R_V850_TDA_7_8_OFFSET:
1349     case R_V850_TDA_6_8_OFFSET:
1350       {
1351         unsigned long                ep;
1352         struct bfd_link_hash_entry * h;
1353         
1354         /* Get the value of __ep.  */
1355         h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
1356         if (h == (struct bfd_link_hash_entry *) NULL
1357             || h->type != bfd_link_hash_defined)
1358           return bfd_reloc_continue;  /* Actually this indicates that __ep could not be found. */
1359
1360         ep = (h->u.def.value
1361               + h->u.def.section->output_section->vma
1362               + h->u.def.section->output_offset);
1363
1364         value -= ep;
1365       }
1366     break;
1367     
1368 /* start-sanitize-v850e */
1369     case R_V850_CALLT_6_7_OFFSET:
1370       {
1371         unsigned long                ctbp;
1372         struct bfd_link_hash_entry * h;
1373         
1374         /* Get the value of __ctbp.  */
1375         h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
1376         if (h == (struct bfd_link_hash_entry *) NULL
1377             || h->type != bfd_link_hash_defined)
1378           return (bfd_reloc_dangerous + 1);  /* Actually this indicates that __ctbp could not be found. */
1379
1380         ctbp = (h->u.def.value
1381               + h->u.def.section->output_section->vma
1382               + h->u.def.section->output_offset);
1383         value -= ctbp;
1384       }
1385     break;
1386     
1387     case R_V850_CALLT_16_16_OFFSET:
1388       {
1389         unsigned long                ctbp;
1390         struct bfd_link_hash_entry * h;
1391
1392         if (sym_sec == NULL)
1393           return bfd_reloc_undefined;
1394           
1395         /* Get the value of __ctbp.  */
1396         h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
1397         if (h == (struct bfd_link_hash_entry *) NULL
1398             || h->type != bfd_link_hash_defined)
1399           return (bfd_reloc_dangerous + 1);
1400
1401         ctbp = (h->u.def.value
1402               + h->u.def.section->output_section->vma
1403               + h->u.def.section->output_offset);
1404
1405         value -= sym_sec->output_section->vma;
1406         value -= (ctbp - sym_sec->output_section->vma);
1407       }
1408     break;
1409 /* end-sanitize-v850e */
1410       
1411     case R_V850_NONE:
1412       return bfd_reloc_ok;
1413
1414     default:
1415       return bfd_reloc_notsupported;
1416     }
1417
1418   /* Perform the relocation.  */
1419   return v850_elf_perform_relocation (input_bfd, r_type, value + addend, hit_data); 
1420 }
1421
1422 \f
1423 /* Relocate an V850 ELF section.  */
1424 static boolean
1425 v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
1426                            contents, relocs, local_syms, local_sections)
1427      bfd *                  output_bfd;
1428      struct bfd_link_info * info;
1429      bfd *                  input_bfd;
1430      asection *             input_section;
1431      bfd_byte *             contents;
1432      Elf_Internal_Rela *    relocs;
1433      Elf_Internal_Sym *     local_syms;
1434      asection **            local_sections;
1435 {
1436   Elf_Internal_Shdr *           symtab_hdr;
1437   struct elf_link_hash_entry ** sym_hashes;
1438   Elf_Internal_Rela *           rel;
1439   Elf_Internal_Rela *           relend;
1440
1441   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
1442   sym_hashes = elf_sym_hashes (input_bfd);
1443
1444   rel    = relocs;
1445   relend = relocs + input_section->reloc_count;
1446   for (; rel < relend; rel++)
1447     {
1448       int                          r_type;
1449       reloc_howto_type *           howto;
1450       unsigned long                r_symndx;
1451       Elf_Internal_Sym *           sym;
1452       asection *                   sec;
1453       struct elf_link_hash_entry * h;
1454       bfd_vma                      relocation;
1455       bfd_reloc_status_type        r;
1456
1457       r_symndx = ELF32_R_SYM (rel->r_info);
1458       r_type   = ELF32_R_TYPE (rel->r_info);
1459       howto    = v850_elf_howto_table + r_type;
1460
1461       if (info->relocateable)
1462         {
1463           /* This is a relocateable link.  We don't have to change
1464              anything, unless the reloc is against a section symbol,
1465              in which case we have to adjust according to where the
1466              section symbol winds up in the output section.  */
1467           if (r_symndx < symtab_hdr->sh_info)
1468             {
1469               sym = local_syms + r_symndx;
1470               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1471                 {
1472                   sec = local_sections[r_symndx];
1473                   rel->r_addend += sec->output_offset + sym->st_value;
1474                 }
1475             }
1476
1477           continue;
1478         }
1479
1480       /* This is a final link.  */
1481       h = NULL;
1482       sym = NULL;
1483       sec = NULL;
1484       if (r_symndx < symtab_hdr->sh_info)
1485         {
1486           sym = local_syms + r_symndx;
1487           sec = local_sections[r_symndx];
1488           relocation = (sec->output_section->vma
1489                         + sec->output_offset
1490                         + sym->st_value);
1491 #if 0
1492           {
1493             char * name;
1494             name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name);
1495             name = (name == NULL) ? "<none>" : name;
1496 fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
1497          sec->name, name, sym->st_name,
1498          sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend);
1499           }
1500 #endif
1501         }
1502       else
1503         {
1504           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1505           
1506           while (h->root.type == bfd_link_hash_indirect
1507                  || h->root.type == bfd_link_hash_warning)
1508             h = (struct elf_link_hash_entry *) h->root.u.i.link;
1509           
1510           if (h->root.type == bfd_link_hash_defined
1511               || h->root.type == bfd_link_hash_defweak)
1512             {
1513               sec = h->root.u.def.section;
1514               relocation = (h->root.u.def.value
1515                             + sec->output_section->vma
1516                             + sec->output_offset);
1517 #if 0
1518 fprintf (stderr, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
1519          sec->name, h->root.root.string, h->root.u.def.value, sec->output_section->vma, sec->output_offset, relocation);
1520 #endif
1521             }
1522           else if (h->root.type == bfd_link_hash_undefweak)
1523             {
1524 #if 0
1525 fprintf (stderr, "undefined: sec: %s, name: %s\n",
1526          sec->name, h->root.root.string);
1527 #endif
1528               relocation = 0;
1529             }
1530           else
1531             {
1532               if (! ((*info->callbacks->undefined_symbol)
1533                      (info, h->root.root.string, input_bfd,
1534                       input_section, rel->r_offset)))
1535                 return false;
1536 #if 0
1537 fprintf (stderr, "unknown: name: %s\n", h->root.root.string);
1538 #endif
1539               relocation = 0;
1540             }
1541         }
1542
1543       /* FIXME: We should use the addend, but the COFF relocations
1544          don't.  */
1545       r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
1546                                         input_section,
1547                                         contents, rel->r_offset,
1548                                         relocation, rel->r_addend,
1549                                         info, sec, h == NULL);
1550
1551       if (r != bfd_reloc_ok)
1552         {
1553           const char * name;
1554           const char * msg = (const char *)0;
1555
1556           if (h != NULL)
1557             name = h->root.root.string;
1558           else
1559             {
1560               name = (bfd_elf_string_from_elf_section
1561                       (input_bfd, symtab_hdr->sh_link, sym->st_name));
1562               if (name == NULL || *name == '\0')
1563                 name = bfd_section_name (input_bfd, sec);
1564             }
1565
1566           switch (r)
1567             {
1568             case bfd_reloc_overflow:
1569               if (! ((*info->callbacks->reloc_overflow)
1570                      (info, name, howto->name, (bfd_vma) 0,
1571                       input_bfd, input_section, rel->r_offset)))
1572                 return false;
1573               break;
1574
1575             case bfd_reloc_undefined:
1576               if (! ((*info->callbacks->undefined_symbol)
1577                      (info, name, input_bfd, input_section,
1578                       rel->r_offset)))
1579                 return false;
1580               break;
1581
1582             case bfd_reloc_outofrange:
1583               msg = _("internal error: out of range error");
1584               goto common_error;
1585
1586             case bfd_reloc_notsupported:
1587               msg = _("internal error: unsupported relocation error");
1588               goto common_error;
1589
1590             case bfd_reloc_dangerous:
1591               msg = _("internal error: dangerous relocation");
1592               goto common_error;
1593
1594             case bfd_reloc_other:
1595               msg = _("could not locate special linker symbol __gp");
1596               goto common_error;
1597
1598             case bfd_reloc_continue:
1599               msg = _("could not locate special linker symbol __ep");
1600               goto common_error;
1601
1602             case (bfd_reloc_dangerous + 1):
1603               msg = _("could not locate special linker symbol __ctbp");
1604               goto common_error;
1605               
1606             default:
1607               msg = _("internal error: unknown error");
1608               /* fall through */
1609
1610             common_error:
1611               if (!((*info->callbacks->warning)
1612                     (info, msg, name, input_bfd, input_section,
1613                      rel->r_offset)))
1614                 return false;
1615               break;
1616             }
1617         }
1618     }
1619
1620   return true;
1621 }
1622
1623 /* Set the right machine number.  */
1624 static boolean
1625 v850_elf_object_p (abfd)
1626      bfd *abfd;
1627 {
1628   switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1629     {
1630     default:
1631     case E_V850_ARCH:   (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, 0); break;
1632 /* start-sanitize-v850e */
1633     case E_V850E_ARCH:  (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e); break;
1634     case E_V850EA_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850ea); break;
1635 /* end-sanitize-v850e */
1636     }
1637   return true;
1638 }
1639
1640 /* Store the machine number in the flags field.  */
1641 static void
1642 v850_elf_final_write_processing (abfd, linker)
1643      bfd *   abfd;
1644      boolean linker;
1645 {
1646   unsigned long val;
1647
1648   switch (bfd_get_mach (abfd))
1649     {
1650     default:
1651     case 0: val = E_V850_ARCH; break;
1652 /* start-sanitize-v850e */
1653     case bfd_mach_v850e:  val = E_V850E_ARCH; break;
1654     case bfd_mach_v850ea: val = E_V850EA_ARCH;  break;
1655 /* end-sanitize-v850e */
1656     }
1657
1658   elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
1659   elf_elfheader (abfd)->e_flags |= val;
1660 }
1661
1662 /* Function to keep V850 specific file flags. */
1663 static boolean
1664 v850_elf_set_private_flags (abfd, flags)
1665      bfd *    abfd;
1666      flagword flags;
1667 {
1668   BFD_ASSERT (!elf_flags_init (abfd)
1669               || elf_elfheader (abfd)->e_flags == flags);
1670
1671   elf_elfheader (abfd)->e_flags = flags;
1672   elf_flags_init (abfd) = true;
1673   return true;
1674 }
1675
1676 /* Copy backend specific data from one object module to another */
1677 static boolean
1678 v850_elf_copy_private_bfd_data (ibfd, obfd)
1679      bfd * ibfd;
1680      bfd * obfd;
1681 {
1682   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1683       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1684     return true;
1685
1686   BFD_ASSERT (!elf_flags_init (obfd)
1687               || (elf_elfheader (obfd)->e_flags
1688                   == elf_elfheader (ibfd)->e_flags));
1689
1690   elf_gp (obfd) = elf_gp (ibfd);
1691   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
1692   elf_flags_init (obfd) = true;
1693   return true;
1694 }
1695
1696 /* Merge backend specific data from an object file to the output
1697    object file when linking.  */
1698 static boolean
1699 v850_elf_merge_private_bfd_data (ibfd, obfd)
1700      bfd * ibfd;
1701      bfd * obfd;
1702 {
1703   flagword out_flags;
1704   flagword in_flags;
1705
1706   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1707       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1708     return true;
1709
1710   in_flags = elf_elfheader (ibfd)->e_flags;
1711   out_flags = elf_elfheader (obfd)->e_flags;
1712
1713   if (! elf_flags_init (obfd))
1714     {
1715       /* If the input is the default architecture then do not
1716          bother setting the flags for the output architecture,
1717          instead allow future merges to do this.  If no future
1718          merges ever set these flags then they will retain their
1719          unitialised values, which surprise surprise, correspond
1720          to the default values.  */
1721       if (bfd_get_arch_info (ibfd)->the_default)
1722         return true;
1723       
1724       elf_flags_init (obfd) = true;
1725       elf_elfheader (obfd)->e_flags = in_flags;
1726
1727       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1728           && bfd_get_arch_info (obfd)->the_default)
1729         {
1730           return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
1731         }
1732
1733       return true;
1734     }
1735
1736   /* Check flag compatibility.  */
1737   if (in_flags == out_flags)
1738     return true;
1739
1740   if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)
1741       && (in_flags & EF_V850_ARCH) != E_V850_ARCH)
1742     _bfd_error_handler (_("%s: Architecture mismatch with previous modules"),
1743                         bfd_get_filename (ibfd));
1744
1745   return true;
1746 }
1747 /* Display the flags field */
1748
1749 static boolean
1750 v850_elf_print_private_bfd_data (abfd, ptr)
1751      bfd *   abfd;
1752      PTR     ptr;
1753 {
1754   FILE * file = (FILE *) ptr;
1755   
1756   BFD_ASSERT (abfd != NULL && ptr != NULL);
1757   
1758   _bfd_elf_print_private_bfd_data (abfd, ptr);
1759   
1760   /* xgettext:c-format */
1761   fprintf (file, _("private flags = %lx: "), elf_elfheader (abfd)->e_flags);
1762   
1763   switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
1764     {
1765     default:
1766     case E_V850_ARCH: fprintf (file, _("v850 architecture")); break;
1767 /* start-sanitize-v850e */
1768     case E_V850E_ARCH:  fprintf (file, _("v850e architecture")); break;
1769     case E_V850EA_ARCH: fprintf (file, _("v850ea architecture")); break;
1770 /* end-sanitize-v850e */
1771     }
1772   
1773   fputc ('\n', file);
1774   
1775   return true;
1776 }
1777
1778 /* V850 ELF uses four common sections.  One is the usual one, and the
1779    others are for (small) objects in one of the special data areas:
1780    small, tiny and zero.  All the objects are kept together, and then
1781    referenced via the gp register, the ep register or the r0 register
1782    respectively, which yields smaller, faster assembler code.  This
1783    approach is copied from elf32-mips.c.  */
1784
1785 static asection  v850_elf_scom_section;
1786 static asymbol   v850_elf_scom_symbol;
1787 static asymbol * v850_elf_scom_symbol_ptr;
1788 static asection  v850_elf_tcom_section;
1789 static asymbol   v850_elf_tcom_symbol;
1790 static asymbol * v850_elf_tcom_symbol_ptr;
1791 static asection  v850_elf_zcom_section;
1792 static asymbol   v850_elf_zcom_symbol;
1793 static asymbol * v850_elf_zcom_symbol_ptr;
1794
1795
1796 /* Given a BFD section, try to locate the corresponding ELF section
1797    index.  */
1798
1799 static boolean
1800 v850_elf_section_from_bfd_section (abfd, hdr, sec, retval)
1801      bfd *                 abfd;
1802      Elf32_Internal_Shdr * hdr;
1803      asection *            sec;
1804      int *                 retval;
1805 {
1806   if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
1807     {
1808       *retval = SHN_V850_SCOMMON;
1809       return true;
1810     }
1811   if (strcmp (bfd_get_section_name (abfd, sec), ".tcommon") == 0)
1812     {
1813       *retval = SHN_V850_TCOMMON;
1814       return true;
1815     }
1816   if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
1817     {
1818       *retval = SHN_V850_ZCOMMON;
1819       return true;
1820     }
1821   return false;
1822 }
1823
1824 /* Handle the special V850 section numbers that a symbol may use.  */
1825
1826 static void
1827 v850_elf_symbol_processing (abfd, asym)
1828      bfd *     abfd;
1829      asymbol * asym;
1830 {
1831   elf_symbol_type * elfsym = (elf_symbol_type *) asym;
1832
1833   switch (elfsym->internal_elf_sym.st_shndx)
1834     {
1835     case SHN_V850_SCOMMON:
1836       if (v850_elf_scom_section.name == NULL)
1837         {
1838           /* Initialize the small common section.  */
1839           v850_elf_scom_section.name           = ".scommon";
1840           v850_elf_scom_section.flags          = SEC_IS_COMMON | SEC_ALLOC | SEC_DATA;
1841           v850_elf_scom_section.output_section = & v850_elf_scom_section;
1842           v850_elf_scom_section.symbol         = & v850_elf_scom_symbol;
1843           v850_elf_scom_section.symbol_ptr_ptr = & v850_elf_scom_symbol_ptr;
1844           v850_elf_scom_symbol.name            = ".scommon";
1845           v850_elf_scom_symbol.flags           = BSF_SECTION_SYM;
1846           v850_elf_scom_symbol.section         = & v850_elf_scom_section;
1847           v850_elf_scom_symbol_ptr             = & v850_elf_scom_symbol;
1848         }
1849       asym->section = & v850_elf_scom_section;
1850       asym->value = elfsym->internal_elf_sym.st_size;
1851       break;
1852       
1853     case SHN_V850_TCOMMON:
1854       if (v850_elf_tcom_section.name == NULL)
1855         {
1856           /* Initialize the tcommon section.  */
1857           v850_elf_tcom_section.name           = ".tcommon";
1858           v850_elf_tcom_section.flags          = SEC_IS_COMMON;
1859           v850_elf_tcom_section.output_section = & v850_elf_tcom_section;
1860           v850_elf_tcom_section.symbol         = & v850_elf_tcom_symbol;
1861           v850_elf_tcom_section.symbol_ptr_ptr = & v850_elf_tcom_symbol_ptr;
1862           v850_elf_tcom_symbol.name            = ".tcommon";
1863           v850_elf_tcom_symbol.flags           = BSF_SECTION_SYM;
1864           v850_elf_tcom_symbol.section         = & v850_elf_tcom_section;
1865           v850_elf_tcom_symbol_ptr             = & v850_elf_tcom_symbol;
1866         }
1867       asym->section = & v850_elf_tcom_section;
1868       asym->value = elfsym->internal_elf_sym.st_size;
1869       break;
1870
1871     case SHN_V850_ZCOMMON:
1872       if (v850_elf_zcom_section.name == NULL)
1873         {
1874           /* Initialize the zcommon section.  */
1875           v850_elf_zcom_section.name           = ".zcommon";
1876           v850_elf_zcom_section.flags          = SEC_IS_COMMON;
1877           v850_elf_zcom_section.output_section = & v850_elf_zcom_section;
1878           v850_elf_zcom_section.symbol         = & v850_elf_zcom_symbol;
1879           v850_elf_zcom_section.symbol_ptr_ptr = & v850_elf_zcom_symbol_ptr;
1880           v850_elf_zcom_symbol.name            = ".zcommon";
1881           v850_elf_zcom_symbol.flags           = BSF_SECTION_SYM;
1882           v850_elf_zcom_symbol.section         = & v850_elf_zcom_section;
1883           v850_elf_zcom_symbol_ptr             = & v850_elf_zcom_symbol;
1884         }
1885       asym->section = & v850_elf_zcom_section;
1886       asym->value = elfsym->internal_elf_sym.st_size;
1887       break;
1888     }
1889 }
1890
1891 /* Hook called by the linker routine which adds symbols from an object
1892    file.  We must handle the special MIPS section numbers here.  */
1893
1894 /*ARGSUSED*/
1895 static boolean
1896 v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1897      bfd *                    abfd;
1898      struct bfd_link_info *   info;
1899      const Elf_Internal_Sym * sym;
1900      const char **            namep;
1901      flagword *               flagsp;
1902      asection **              secp;
1903      bfd_vma *                valp;
1904 {
1905   switch (sym->st_shndx)
1906     {
1907     case SHN_V850_SCOMMON:
1908       *secp = bfd_make_section_old_way (abfd, ".scommon");
1909       (*secp)->flags |= SEC_IS_COMMON;
1910       *valp = sym->st_size;
1911       break;
1912       
1913     case SHN_V850_TCOMMON:
1914       *secp = bfd_make_section_old_way (abfd, ".tcommon");
1915       (*secp)->flags |= SEC_IS_COMMON;
1916       *valp = sym->st_size;
1917       break;
1918       
1919     case SHN_V850_ZCOMMON:
1920       *secp = bfd_make_section_old_way (abfd, ".zcommon");
1921       (*secp)->flags |= SEC_IS_COMMON;
1922       *valp = sym->st_size;
1923       break;
1924     }
1925
1926   return true;
1927 }
1928
1929 /*ARGSIGNORED*/
1930 static boolean
1931 v850_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
1932      bfd *                  abfd;
1933      struct bfd_link_info * info;
1934      const char *           name;
1935      Elf_Internal_Sym *     sym;
1936      asection *             input_sec;
1937 {
1938   /* If we see a common symbol, which implies a relocatable link, then
1939      if a symbol was in a special common section in an input file, mark
1940      it as a special common in the output file.  */
1941   
1942   if (sym->st_shndx == SHN_COMMON)
1943     {
1944       if (strcmp (input_sec->name, ".scommon") == 0)
1945         sym->st_shndx = SHN_V850_SCOMMON;
1946       else if (strcmp (input_sec->name, ".tcommon") == 0)
1947         sym->st_shndx = SHN_V850_TCOMMON;
1948       else if (strcmp (input_sec->name, ".zcommon") == 0)
1949         sym->st_shndx = SHN_V850_ZCOMMON;
1950     }
1951
1952   return true;
1953 }
1954
1955 static boolean
1956 v850_elf_section_from_shdr (abfd, hdr, name)
1957      bfd *               abfd;
1958      Elf_Internal_Shdr * hdr;
1959      char *              name;
1960 {
1961   /* There ought to be a place to keep ELF backend specific flags, but
1962      at the moment there isn't one.  We just keep track of the
1963      sections by their name, instead.  */
1964
1965   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
1966     return false;
1967
1968   switch (hdr->sh_type)
1969     {
1970     case SHT_V850_SCOMMON:
1971     case SHT_V850_TCOMMON:
1972     case SHT_V850_ZCOMMON:
1973       if (! bfd_set_section_flags (abfd, hdr->bfd_section,
1974                                    (bfd_get_section_flags (abfd,
1975                                                            hdr->bfd_section)
1976                                     | SEC_IS_COMMON)))
1977         return false;
1978     }
1979
1980   return true;
1981 }
1982
1983 /* Set the correct type for a V850 ELF section.  We do this by the
1984    section name, which is a hack, but ought to work.  */
1985 static boolean
1986 v850_elf_fake_sections (abfd, hdr, sec)
1987      bfd *                 abfd;
1988      Elf32_Internal_Shdr * hdr;
1989      asection *            sec;
1990 {
1991   register const char * name;
1992
1993   name = bfd_get_section_name (abfd, sec);
1994
1995   if (strcmp (name, ".scommon") == 0)
1996     {
1997       hdr->sh_type = SHT_V850_SCOMMON;
1998     }
1999   else if (strcmp (name, ".tcommon") == 0)
2000     {
2001       hdr->sh_type = SHT_V850_TCOMMON;
2002     }
2003   else if (strcmp (name, ".zcommon") == 0)
2004     hdr->sh_type = SHT_V850_ZCOMMON;
2005   
2006   return true;
2007 }
2008
2009
2010 \f
2011 #define TARGET_LITTLE_SYM                       bfd_elf32_v850_vec
2012 #define TARGET_LITTLE_NAME                      "elf32-v850"
2013 #define ELF_ARCH                                bfd_arch_v850
2014 #define ELF_MACHINE_CODE                        EM_CYGNUS_V850
2015 #define ELF_MAXPAGESIZE                         0x1000
2016         
2017 #define elf_info_to_howto                       v850_elf_info_to_howto_rela
2018 #define elf_info_to_howto_rel                   v850_elf_info_to_howto_rel
2019
2020 #define elf_backend_check_relocs                v850_elf_check_relocs
2021 #define elf_backend_relocate_section            v850_elf_relocate_section
2022 #define elf_backend_object_p                    v850_elf_object_p
2023 #define elf_backend_final_write_processing      v850_elf_final_write_processing
2024 #define elf_backend_section_from_bfd_section    v850_elf_section_from_bfd_section
2025 #define elf_backend_symbol_processing           v850_elf_symbol_processing
2026 #define elf_backend_add_symbol_hook             v850_elf_add_symbol_hook
2027 #define elf_backend_link_output_symbol_hook     v850_elf_link_output_symbol_hook
2028 #define elf_backend_section_from_shdr           v850_elf_section_from_shdr
2029 #define elf_backend_fake_sections               v850_elf_fake_sections
2030
2031 #define bfd_elf32_bfd_is_local_label_name       v850_elf_is_local_label_name
2032 #define bfd_elf32_bfd_reloc_type_lookup         v850_elf_reloc_type_lookup
2033 #define bfd_elf32_bfd_copy_private_bfd_data     v850_elf_copy_private_bfd_data
2034 #define bfd_elf32_bfd_merge_private_bfd_data    v850_elf_merge_private_bfd_data
2035 #define bfd_elf32_bfd_set_private_flags         v850_elf_set_private_flags
2036 #define bfd_elf32_bfd_print_private_bfd_data    v850_elf_print_private_bfd_data
2037
2038 #define elf_symbol_leading_char                 '_'
2039
2040 #include "elf32-target.h"