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