start-sanitize-d10v
[external/binutils.git] / bfd / elf32-d10v.c
1 /* D10V-specific support for 32-bit ELF
2    Copyright (C) 1996 Free Software Foundation, Inc.
3    Contributed by Martin Hunt (hunt@cygnus.com).
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 /* #include "elf/d10v.h" */
26
27 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
28   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
29 static void d10v_info_to_howto_rel
30   PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
31
32
33 /* Use REL instead of RELA to save space */
34 #define USE_REL
35
36 enum reloc_type
37 {
38   R_D10V_NONE = 0,
39   R_D10V_10_PCREL_R,
40   R_D10V_10_PCREL_L,
41   R_D10V_16,
42   R_D10V_18,
43   R_D10V_18_PCREL,
44   R_D10V_max
45 };
46
47 static reloc_howto_type elf_d10v_howto_table[] =
48 {
49   /* This reloc does nothing.  */
50   HOWTO (R_D10V_NONE,           /* type */
51          0,                     /* rightshift */
52          2,                     /* size (0 = byte, 1 = short, 2 = long) */
53          32,                    /* bitsize */
54          false,                 /* pc_relative */
55          0,                     /* bitpos */
56          complain_overflow_bitfield, /* complain_on_overflow */
57          bfd_elf_generic_reloc, /* special_function */
58          "R_D10V_NONE",         /* name */
59          false,                 /* partial_inplace */
60          0,                     /* src_mask */
61          0,                     /* dst_mask */
62          false),                /* pcrel_offset */
63
64   /* An PC Relative 10-bit relocation, shifted by 2  */
65   /* right container */
66   HOWTO (R_D10V_10_PCREL_R,     /* type */
67          2,                     /* rightshift */
68          0,                     /* size (0 = byte, 1 = short, 2 = long) */
69          10,                    /* bitsize */
70          true,                  /* pc_relative */
71          0,                     /* bitpos */
72          complain_overflow_bitfield, /* complain_on_overflow */
73          bfd_elf_generic_reloc, /* special_function */
74          "R_D10V_10_PCREL_R",   /* name */
75          false,                 /* partial_inplace */
76          0xff,                  /* src_mask */
77          0xff,                  /* dst_mask */
78          true),                 /* pcrel_offset */
79
80   /* An PC Relative 10-bit relocation, shifted by 2  */
81   /* left container */
82   HOWTO (R_D10V_10_PCREL_L,     /* type */
83          2,                     /* rightshift */
84          0,                     /* size (0 = byte, 1 = short, 2 = long) */
85          10,                    /* bitsize */
86          true,                  /* pc_relative */
87          15,                    /* bitpos */
88          complain_overflow_bitfield, /* complain_on_overflow */
89          bfd_elf_generic_reloc, /* special_function */
90          "R_D10V_10_PCREL_L",   /* name */
91          false,                 /* partial_inplace */
92          0xff,                  /* src_mask */
93          0xff,                  /* dst_mask */
94          true),                 /* pcrel_offset */
95
96   /* A 16 bit absolute relocation */
97   HOWTO (R_D10V_16,             /* type */
98          0,                     /* rightshift */
99          1,                     /* size (0 = byte, 1 = short, 2 = long) */
100          16,                    /* bitsize */
101          false,                 /* pc_relative */
102          0,                     /* bitpos */
103          complain_overflow_bitfield, /* complain_on_overflow */
104          bfd_elf_generic_reloc, /* special_function */
105          "R_D10V_16",           /* name */
106          false,                 /* partial_inplace */
107          0xffff,                /* src_mask */
108          0xffff,                /* dst_mask */
109          false),                /* pcrel_offset */
110
111   /* An 18 bit absolute relocation, right shifted 2 */
112   HOWTO (R_D10V_18,             /* type */
113          2,                     /* rightshift */
114          1,                     /* size (0 = byte, 1 = short, 2 = long) */
115          18,                    /* bitsize */
116          false,                 /* pc_relative */
117          0,                     /* bitpos */
118          complain_overflow_bitfield, /* complain_on_overflow */
119          bfd_elf_generic_reloc, /* special_function */
120          "R_D10V_18",           /* name */
121          false,                 /* partial_inplace */
122          0xffff,                /* src_mask */
123          0xffff,                /* dst_mask */
124          false),                /* pcrel_offset */
125
126   /* A relative 18 bit relocation, right shifted by 2  */
127   HOWTO (R_D10V_18_PCREL,       /* type */
128          2,                     /* rightshift */
129          1,                     /* size (0 = byte, 1 = short, 2 = long) */
130          18,                    /* bitsize */
131          true,                  /* pc_relative */
132          0,                     /* bitpos */
133          complain_overflow_signed, /* complain_on_overflow */
134          bfd_elf_generic_reloc, /* special_function */
135          "R_D10V_18_PCREL",     /* name */
136          false,                 /* partial_inplace */
137          0xffff,                /* src_mask */
138          0xffff,                /* dst_mask */
139          true),                 /* pcrel_offset */
140
141 };
142
143 /* Map BFD reloc types to D10V ELF reloc types.  */
144
145 struct d10v_reloc_map
146 {
147   unsigned char bfd_reloc_val;
148   unsigned char elf_reloc_val;
149 };
150
151  static const struct d10v_reloc_map d10v_reloc_map[] =
152 {
153   { BFD_RELOC_NONE, R_D10V_NONE, },
154   { BFD_RELOC_D10V_10_PCREL_R, R_D10V_10_PCREL_R },
155   { BFD_RELOC_D10V_10_PCREL_L, R_D10V_10_PCREL_L },
156   { BFD_RELOC_16, R_D10V_16 },
157   { BFD_RELOC_D10V_18, R_D10V_18 },
158   { BFD_RELOC_D10V_18_PCREL, R_D10V_18_PCREL },
159 };
160
161 static reloc_howto_type *
162 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
163      bfd *abfd;
164      bfd_reloc_code_real_type code;
165 {
166   unsigned int i;
167
168   for (i = 0;
169        i < sizeof (d10v_reloc_map) / sizeof (struct d10v_reloc_map);
170        i++)
171     {
172       if (d10v_reloc_map[i].bfd_reloc_val == code)
173         return &elf_d10v_howto_table[d10v_reloc_map[i].elf_reloc_val];
174     }
175
176   return NULL;
177 }
178
179 /* Set the howto pointer for an D10V ELF reloc.  */
180
181 static void
182 d10v_info_to_howto_rel (abfd, cache_ptr, dst)
183      bfd *abfd;
184      arelent *cache_ptr;
185      Elf32_Internal_Rel *dst;
186 {
187   unsigned int r_type;
188
189   r_type = ELF32_R_TYPE (dst->r_info);
190   BFD_ASSERT (r_type < (unsigned int) R_D10V_max);
191   cache_ptr->howto = &elf_d10v_howto_table[r_type];
192 }
193
194 #define ELF_ARCH                bfd_arch_d10v
195 #define ELF_MACHINE_CODE        EM_CYGNUS_D10V
196 #define ELF_MAXPAGESIZE         0x1000
197
198 #define TARGET_BIG_SYM          bfd_elf32_d10v_vec
199 #define TARGET_BIG_NAME         "elf32-d10v"
200
201 #define elf_info_to_howto       0
202 #define elf_info_to_howto_rel   d10v_info_to_howto_rel
203 #define elf_backend_object_p    0
204 #define elf_backend_final_write_processing      0
205
206 #include "elf32-target.h"