* Makefile.am (elf32-h8300.lo): New target.
[platform/upstream/binutils.git] / bfd / elf32-h8300.c
1 /* Generic support for 32-bit ELF
2    Copyright 1993, 1995, 1998, 1999 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 #include "elf/h8.h"
25
26 static reloc_howto_type *elf32_h8_reloc_type_lookup
27   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
28 static void elf32_h8_info_to_howto
29   PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
30
31 /* This does not include any relocation information, but should be
32    good enough for GDB or objdump to read the file.  */
33
34 static reloc_howto_type h8_elf_howto_table[] =
35 {
36 #define R_H8_NONE_X 0
37   HOWTO (R_H8_NONE,             /* type */
38          0,                     /* rightshift */
39          0,                     /* size (0 = byte, 1 = short, 2 = long) */
40          0,                     /* bitsize */
41          false,                 /* pc_relative */
42          0,                     /* bitpos */
43          complain_overflow_dont, /* complain_on_overflow */
44          NULL,                  /* special_function */
45          "R_H8_NONE",           /* name */
46          false,                 /* partial_inplace */
47          0,                     /* src_mask */
48          0,                     /* dst_mask */
49          false),                /* pcrel_offset */
50 #define R_H8_DIR32_X (R_H8_NONE_X + 1)
51   HOWTO (R_H8_DIR32,            /* type */
52          0,                     /* rightshift */
53          2,                     /* size (0 = byte, 1 = short, 2 = long) */
54          32,                    /* bitsize */
55          false,                 /* pc_relative */
56          0,                     /* bitpos */
57          complain_overflow_dont, /* complain_on_overflow */
58          NULL,                  /* special_function */
59          "R_H8_DIR32",          /* name */
60          false,                 /* partial_inplace */
61          0,                     /* src_mask */
62          0xffffffff,            /* dst_mask */
63          false),                /* pcrel_offset */
64 #define R_H8_DIR16_X (R_H8_DIR32_X + 1)
65   HOWTO (R_H8_DIR16,            /* type */
66          0,                     /* rightshift */
67          1,                     /* size (0 = byte, 1 = short, 2 = long) */
68          16,                    /* bitsize */
69          false,                 /* pc_relative */
70          0,                     /* bitpos */
71          complain_overflow_dont, /* complain_on_overflow */
72          NULL,                  /* special_function */
73          "R_H8_DIR16",          /* name */
74          false,                 /* partial_inplace */
75          0,                     /* src_mask */
76          0x0000ffff,            /* dst_mask */
77          false),                /* pcrel_offset */
78 #define R_H8_DIR8_X (R_H8_DIR16_X + 1)
79   HOWTO (R_H8_DIR8,             /* type */
80          0,                     /* rightshift */
81          0,                     /* size (0 = byte, 1 = short, 2 = long) */
82          8,                     /* bitsize */
83          false,                 /* pc_relative */
84          0,                     /* bitpos */
85          complain_overflow_dont, /* complain_on_overflow */
86          NULL,                  /* special_function */
87          "R_H8_DIR16",          /* name */
88          false,                 /* partial_inplace */
89          0,                     /* src_mask */
90          0x000000ff,            /* dst_mask */
91          false),                /* pcrel_offset */
92 #define R_H8_DIR16A8_X (R_H8_DIR8_X + 1)
93   HOWTO (R_H8_DIR16A8,          /* type */
94          0,                     /* rightshift */
95          1,                     /* size (0 = byte, 1 = short, 2 = long) */
96          16,                    /* bitsize */
97          false,                 /* pc_relative */
98          0,                     /* bitpos */
99          complain_overflow_bitfield, /* complain_on_overflow */
100          NULL,                  /* special_function */
101          "R_H8_DIR16A8",        /* name */
102          false,                 /* partial_inplace */
103          0,                     /* src_mask */
104          0x0000ffff,            /* dst_mask */
105          false),                /* pcrel_offset */
106 #define R_H8_DIR16R8_X (R_H8_DIR16A8_X + 1)
107   HOWTO (R_H8_DIR16R8,          /* type */
108          0,                     /* rightshift */
109          1,                     /* size (0 = byte, 1 = short, 2 = long) */
110          16,                    /* bitsize */
111          false,                 /* pc_relative */
112          0,                     /* bitpos */
113          complain_overflow_bitfield, /* complain_on_overflow */
114          NULL,                  /* special_function */
115          "R_H8_DIR16R8",        /* name */
116          false,                 /* partial_inplace */
117          0,                     /* src_mask */
118          0x0000ffff,            /* dst_mask */
119          false),                /* pcrel_offset */
120 #define R_H8_DIR24A8_X (R_H8_DIR16R8_X + 1)
121   HOWTO (R_H8_DIR24A8,          /* type */
122          0,                     /* rightshift */
123          2,                     /* size (0 = byte, 1 = short, 2 = long) */
124          24,                    /* bitsize */
125          false,                 /* pc_relative */
126          0,                     /* bitpos */
127          complain_overflow_bitfield, /* complain_on_overflow */
128          NULL,                  /* special_function */
129          "R_H8_DIR24A8",        /* name */
130          true,                  /* partial_inplace */
131          0xff000000,            /* src_mask */
132          0x00ffffff,            /* dst_mask */
133          false),                /* pcrel_offset */
134 #define R_H8_DIR24R8_X (R_H8_DIR24A8_X + 1)
135   HOWTO (R_H8_DIR24R8,          /* type */
136          0,                     /* rightshift */
137          2,                     /* size (0 = byte, 1 = short, 2 = long) */
138          24,                    /* bitsize */
139          false,                 /* pc_relative */
140          0,                     /* bitpos */
141          complain_overflow_bitfield, /* complain_on_overflow */
142          NULL,                  /* special_function */
143          "R_H8_DIR24R8",        /* name */
144          true,                  /* partial_inplace */
145          0xff000000,            /* src_mask */
146          0x00ffffff,            /* dst_mask */
147          false),                /* pcrel_offset */
148 #define R_H8_DIR32A16_X (R_H8_DIR24R8_X + 1)
149   HOWTO (R_H8_DIR32A16,         /* 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          NULL,                  /* special_function */
157          "R_H8_DIR32",          /* name */
158          false,                 /* partial_inplace */
159          0,                     /* src_mask */
160          0xffffffff,            /* dst_mask */
161          false),                /* pcrel_offset */
162 };
163
164 /* This structure is used to map BFD reloc codes to H8 ELF relocs.  */
165
166 struct elf_reloc_map
167 {
168   bfd_reloc_code_real_type bfd_reloc_val;
169   unsigned char howto_index;
170 };
171
172 /* An array mapping BFD reloc codes to SH ELF relocs.  */
173
174 static const struct elf_reloc_map h8_reloc_map[] =
175 {
176   { BFD_RELOC_NONE, R_H8_NONE_X },
177   { BFD_RELOC_32, R_H8_DIR32_X },
178   { BFD_RELOC_16, R_H8_DIR16_X },
179   { BFD_RELOC_8, R_H8_DIR8_X },
180   { BFD_RELOC_H8_DIR16A8, R_H8_DIR16A8_X },
181   { BFD_RELOC_H8_DIR16R8, R_H8_DIR16R8_X },
182   { BFD_RELOC_H8_DIR24A8, R_H8_DIR24A8_X },
183   { BFD_RELOC_H8_DIR24R8, R_H8_DIR24R8_X },
184   { BFD_RELOC_H8_DIR32A16, R_H8_DIR32A16_X },
185 };
186
187 static reloc_howto_type *
188 elf32_h8_reloc_type_lookup (abfd, code)
189      bfd *abfd ATTRIBUTE_UNUSED;
190      bfd_reloc_code_real_type code;
191 {
192   unsigned int i;
193
194   for (i = 0; i < sizeof (h8_reloc_map) / sizeof (struct elf_reloc_map); i++)
195     {
196       if (h8_reloc_map[i].bfd_reloc_val == code)
197         return &h8_elf_howto_table[(int) h8_reloc_map[i].howto_index];
198     }
199   return NULL;
200 }
201
202 static void
203 elf32_h8_info_to_howto (abfd, bfd_reloc, elf_reloc)
204      bfd *abfd ATTRIBUTE_UNUSED;
205      arelent *bfd_reloc;
206      Elf32_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED;
207 {
208   unsigned int r;
209   unsigned int i;
210
211   r = ELF32_R_TYPE (elf_reloc->r_info);
212   for (i = 0; i < sizeof (h8_elf_howto_table) / sizeof (reloc_howto_type); i++)
213     if (h8_elf_howto_table[i].type== r)
214       {
215         bfd_reloc->howto = &h8_elf_howto_table[i];
216         return;
217       }
218   abort ();
219 }
220
221 static void
222 elf32_h8_info_to_howto_rel (abfd, bfd_reloc, elf_reloc)
223      bfd *abfd ATTRIBUTE_UNUSED;
224      arelent *bfd_reloc;
225      Elf32_Internal_Rel *elf_reloc ATTRIBUTE_UNUSED;
226 {
227   unsigned int r;
228
229   abort ();
230   r = ELF32_R_TYPE (elf_reloc->r_info);
231   bfd_reloc->howto = &h8_elf_howto_table[r];
232 }
233
234 #define TARGET_BIG_SYM                  bfd_elf32_h8300_vec
235 #define TARGET_BIG_NAME                 "elf32-h8300"
236 #define ELF_ARCH                        bfd_arch_h8300
237 #define ELF_MACHINE_CODE                EM_H8_300
238 #define ELF_MAXPAGESIZE                 0x1
239 #define bfd_elf32_bfd_reloc_type_lookup elf32_h8_reloc_type_lookup
240 #define elf_info_to_howto               elf32_h8_info_to_howto
241 #define elf_info_to_howto_rel           elf32_h8_info_to_howto_rel
242
243 /* ??? when elf_backend_relocate_section is not defined, elf32-target.h
244    defaults to using _bfd_generic_link_hash_table_create, but
245    elflink.h:bfd_elf32_size_dynamic_sections uses
246    dynobj = elf_hash_table (info)->dynobj;
247    and thus requires an elf hash table.  */
248 #define bfd_elf32_bfd_link_hash_table_create _bfd_elf_link_hash_table_create
249
250 #include "elf32-target.h"