* elf32-v850.c (enum reloc_type): Add R_V850_{32,16,8}.
[external/binutils.git] / bfd / elf32-v850.c
1 /* V850-specific support for 32-bit ELF
2    Copyright (C) 1994, 1995 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 #include "bfd.h"
21 #include "sysdep.h"
22 #include "libbfd.h"
23 #include "elf-bfd.h"
24
25 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
26   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
27 static void v850_info_to_howto_rel
28   PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
29
30
31 /* Try to minimize the amount of space occupied by relocation tables
32    on the ROM (not that the ROM won't be swamped by other ELF overhead).  */
33 #define USE_REL
34
35 enum reloc_type
36 {
37   R_V850_NONE = 0,
38   R_V850_9_PCREL,
39   R_V850_22_PCREL,
40   R_V850_HI16_S,
41   R_V850_HI16,
42   R_V850_LO16,
43   R_V850_32,
44   R_V850_16,
45   R_V850_8,
46   R_V850_max
47 };
48
49 static reloc_howto_type elf_v850_howto_table[] =
50 {
51   /* This reloc does nothing.  */
52   HOWTO (R_V850_NONE,           /* type */
53          0,                     /* rightshift */
54          2,                     /* size (0 = byte, 1 = short, 2 = long) */
55          32,                    /* bitsize */
56          false,                 /* pc_relative */
57          0,                     /* bitpos */
58          complain_overflow_bitfield, /* complain_on_overflow */
59          bfd_elf_generic_reloc, /* special_function */
60          "R_V850_NONE",         /* name */
61          false,                 /* partial_inplace */
62          0,                     /* src_mask */
63          0,                     /* dst_mask */
64          false),                /* pcrel_offset */
65
66   /* A PC relative 9 bit branch. */
67   HOWTO (R_V850_9_PCREL,        /* type */
68          2,                     /* rightshift */
69          2,                     /* size (0 = byte, 1 = short, 2 = long) */
70          26,                    /* bitsize */
71          true,                  /* pc_relative */
72          0,                     /* bitpos */
73          complain_overflow_bitfield, /* complain_on_overflow */
74          bfd_elf_generic_reloc, /* special_function */
75          "R_V850_9_PCREL",      /* name */
76          false,                 /* partial_inplace */
77          0x00ffffff,            /* src_mask */
78          0x00ffffff,            /* dst_mask */
79          true),                 /* pcrel_offset */
80
81   /* A PC relative 22 bit branch. */
82   HOWTO (R_V850_22_PCREL,       /* type */
83          2,                     /* rightshift */
84          2,                     /* size (0 = byte, 1 = short, 2 = long) */
85          22,                    /* bitsize */
86          true,                  /* pc_relative */
87          7,                     /* bitpos */
88          complain_overflow_signed, /* complain_on_overflow */
89          bfd_elf_generic_reloc, /* special_function */
90          "R_V850_22_PCREL",     /* name */
91          false,                 /* partial_inplace */
92          0x07ffff80,            /* src_mask */
93          0x07ffff80,            /* dst_mask */
94          true),                 /* pcrel_offset */
95
96   /* High 16 bits of symbol value.  */
97   HOWTO (R_V850_HI16_S,         /* type */
98          0,                     /* rightshift */
99          1,                     /* size (0 = byte, 1 = short, 2 = long) */
100          16,                    /* bitsize */
101          false,                 /* pc_relative */
102          16,                    /* bitpos */
103          complain_overflow_dont,/* complain_on_overflow */
104          bfd_elf_generic_reloc, /* special_function */
105          "R_V850_HI16_S",       /* name */
106          true,                  /* partial_inplace */
107          0xffff,                /* src_mask */
108          0xffff,                /* dst_mask */
109          false),                /* pcrel_offset */
110
111   /* High 16 bits of symbol value.  */
112   HOWTO (R_V850_HI16,           /* type */
113          0,                     /* rightshift */
114          1,                     /* size (0 = byte, 1 = short, 2 = long) */
115          16,                    /* bitsize */
116          false,                 /* pc_relative */
117          16,                    /* bitpos */
118          complain_overflow_dont,/* complain_on_overflow */
119          bfd_elf_generic_reloc, /* special_function */
120          "R_V850_HI16",         /* name */
121          true,                  /* partial_inplace */
122          0xffff,                /* src_mask */
123          0xffff,                /* dst_mask */
124          false),                /* pcrel_offset */
125
126   /* Low 16 bits of symbol value.  */
127   HOWTO (R_V850_LO16,           /* type */
128          0,                     /* rightshift */
129          1,                     /* size (0 = byte, 1 = short, 2 = long) */
130          16,                    /* bitsize */
131          false,                 /* pc_relative */
132          16,                     /* bitpos */
133          complain_overflow_dont,/* complain_on_overflow */
134          bfd_elf_generic_reloc, /* special_function */
135          "R_V850_LO16",         /* name */
136          true,                  /* partial_inplace */
137          0xffff,                /* src_mask */
138          0xffff,                /* dst_mask */
139          false),                /* pcrel_offset */
140
141   /* Simple 32bit reloc.  */
142   HOWTO (R_V850_32,           /* type */
143          0,                     /* rightshift */
144          2,                     /* size (0 = byte, 1 = short, 2 = long) */
145          32,                    /* bitsize */
146          false,                 /* pc_relative */
147          0,                     /* bitpos */
148          complain_overflow_dont,/* complain_on_overflow */
149          bfd_elf_generic_reloc, /* special_function */
150          "R_V850_32",         /* name */
151          false,                  /* partial_inplace */
152          0,                /* src_mask */
153          0xffffffff,                /* dst_mask */
154          false),                /* pcrel_offset */
155
156   /* Simple 16bit reloc.  */
157   HOWTO (R_V850_16,           /* type */
158          0,                     /* rightshift */
159          1,                     /* size (0 = byte, 1 = short, 2 = long) */
160          16,                    /* bitsize */
161          false,                 /* pc_relative */
162          0,                     /* bitpos */
163          complain_overflow_dont,/* complain_on_overflow */
164          bfd_elf_generic_reloc, /* special_function */
165          "R_V850_16",         /* name */
166          false,                  /* partial_inplace */
167          0,                /* src_mask */
168          0xffff,                /* dst_mask */
169          false),                /* pcrel_offset */
170
171   /* Simple 8bit reloc.  */
172   HOWTO (R_V850_8,           /* type */
173          0,                     /* rightshift */
174          0,                     /* size (0 = byte, 1 = short, 2 = long) */
175          8,                    /* bitsize */
176          false,                 /* pc_relative */
177          0,                     /* bitpos */
178          complain_overflow_dont,/* complain_on_overflow */
179          bfd_elf_generic_reloc, /* special_function */
180          "R_V850_8",         /* name */
181          false,                  /* partial_inplace */
182          0,                /* src_mask */
183          0xff,                /* dst_mask */
184          false),                /* pcrel_offset */
185 };
186
187 /* Map BFD reloc types to V850 ELF reloc types.  */
188
189 struct v850_reloc_map
190 {
191   unsigned char bfd_reloc_val;
192   unsigned char elf_reloc_val;
193 };
194
195 static const struct v850_reloc_map v850_reloc_map[] =
196 {
197   { BFD_RELOC_NONE, R_V850_NONE, },
198   { BFD_RELOC_V850_9_PCREL, R_V850_9_PCREL, },
199   { BFD_RELOC_V850_22_PCREL, R_V850_22_PCREL, },
200   { BFD_RELOC_HI16_S, R_V850_HI16_S, },
201   { BFD_RELOC_HI16, R_V850_HI16, },
202   { BFD_RELOC_LO16, R_V850_LO16, },
203   { BFD_RELOC_32, R_V850_32, },
204   { BFD_RELOC_16, R_V850_16, },
205   { BFD_RELOC_8, R_V850_8, },
206 };
207
208 static reloc_howto_type *
209 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
210      bfd *abfd;
211      bfd_reloc_code_real_type code;
212 {
213   unsigned int i;
214
215   for (i = 0;
216        i < sizeof (v850_reloc_map) / sizeof (struct v850_reloc_map);
217        i++)
218     {
219       if (v850_reloc_map[i].bfd_reloc_val == code)
220         return &elf_v850_howto_table[v850_reloc_map[i].elf_reloc_val];
221     }
222
223   return NULL;
224 }
225
226 /* Set the howto pointer for an V850 ELF reloc.  */
227
228 static void
229 v850_info_to_howto_rel (abfd, cache_ptr, dst)
230      bfd *abfd;
231      arelent *cache_ptr;
232      Elf32_Internal_Rel *dst;
233 {
234   unsigned int r_type;
235
236   r_type = ELF32_R_TYPE (dst->r_info);
237   BFD_ASSERT (r_type < (unsigned int) R_V850_max);
238   cache_ptr->howto = &elf_v850_howto_table[r_type];
239 }
240
241 #define TARGET_BIG_SYM          bfd_elf32_v850_vec
242 #define TARGET_BIG_NAME         "elf32-v850"
243 #define ELF_ARCH                bfd_arch_v850
244 #define ELF_MACHINE_CODE        EM_CYGNUS_V850
245 #define ELF_MAXPAGESIZE         0x1000
246
247 #define elf_info_to_howto       0
248 #define elf_info_to_howto_rel   v850_info_to_howto_rel
249
250 #include "elf32-target.h"