OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [bfd/] [elf32-pj.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 104 markom
/* picoJava specific support for 32-bit ELF
2
   Copyright 1999 Free Software Foundation, Inc.
3
   Contributed by Steve Chamberlan of Transmeta (sac@pobox.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 "bfdlink.h"
24
#include "libbfd.h"
25
#include "elf-bfd.h"
26
#include "elf/pj.h"
27
 
28
static bfd_reloc_status_type pj_elf_reloc
29
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
30
static reloc_howto_type *pj_elf_reloc_type_lookup
31
  PARAMS ((bfd *, bfd_reloc_code_real_type));
32
static void pj_elf_info_to_howto
33
  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
34
 
35
static reloc_howto_type pj_elf_howto_table[] =
36
{
37
  /* No relocation.  */
38
  HOWTO (R_PJ_NONE,             /* type */
39
         0,                      /* rightshift */
40
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
41
         0,                      /* bitsize */
42
         false,                 /* pc_relative */
43
         0,                      /* bitpos */
44
         complain_overflow_dont, /* complain_on_overflow */
45
         pj_elf_reloc,          /* special_function */
46
         "R_PJ_NONE",           /* name */
47
         false,                 /* partial_inplace */
48
         0,                      /* src_mask */
49
         0,                      /* dst_mask */
50
         false),                /* pcrel_offset */
51
 
52
  /* 32 bit absolute relocation.  Setting partial_inplace to true and
53
     src_mask to a non-zero value is similar to the COFF toolchain.  */
54
  HOWTO (R_PJ_DATA_DIR32,               /* type */
55
         0,                      /* rightshift */
56
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
57
         32,                    /* bitsize */
58
         false,                 /* pc_relative */
59
         0,                      /* bitpos */
60
         complain_overflow_bitfield, /* complain_on_overflow */
61
         pj_elf_reloc,          /* special_function */
62
         "R_PJ_DIR32",          /* name */
63
         true,                  /* partial_inplace */
64
         0xffffffff,            /* src_mask */
65
         0xffffffff,            /* dst_mask */
66
         false),                /* pcrel_offset */
67
 
68
  /* 32 bit PC relative relocation.  */
69
  HOWTO (R_PJ_CODE_REL32,               /* type */
70
         0,                      /* rightshift */
71
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
72
         32,                    /* bitsize */
73
         true,                  /* pc_relative */
74
         0,                      /* bitpos */
75
         complain_overflow_signed, /* complain_on_overflow */
76
         pj_elf_reloc,          /* special_function */
77
         "R_PJ_REL32",          /* name */
78
         false,                 /* partial_inplace */
79
         0,                      /* src_mask */
80
         0xffffffff,            /* dst_mask */
81
         true),                 /* pcrel_offset */
82
 
83
/* 16 bit PC relative relocation.  */
84
  HOWTO (R_PJ_CODE_REL16,               /* type */
85
         0,                      /* rightshift */
86
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
87
         16,                    /* bitsize */
88
         true,                  /* pc_relative */
89
         0,                      /* bitpos */
90
         complain_overflow_signed, /* complain_on_overf6w */
91
         pj_elf_reloc,          /* special_function */
92
         "R_PJ_REL16",          /* name */
93
         false,                 /* partial_inplace */
94
         0xffff,                /* src_mask */
95
         0xffff,                /* dst_mask */
96
         true),                 /* pcrel_offset */
97
  EMPTY_HOWTO (4),
98
  EMPTY_HOWTO (5),
99
  HOWTO (R_PJ_CODE_DIR32,       /* type */
100
         0,                      /* rightshift */
101
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
102
         32,                    /* bitsize */
103
         false,                 /* pc_relative */
104
         0,                      /* bitpos */
105
         complain_overflow_bitfield, /* complain_on_overflow */
106
         pj_elf_reloc,          /* special_function */
107
         "R_PJ_CODE_DIR32",     /* name */
108
         true,                  /* partial_inplace */
109
         0xffffffff,            /* src_mask */
110
         0xffffffff,            /* dst_mask */
111
         false),                /* pcrel_offset */
112
 
113
  EMPTY_HOWTO (7),
114
  EMPTY_HOWTO (8),
115
  EMPTY_HOWTO (9),
116
  EMPTY_HOWTO (10),
117
  EMPTY_HOWTO (11),
118
  EMPTY_HOWTO (12),
119
 
120
  HOWTO (R_PJ_CODE_LO16,        /* type */
121
         0,                      /* rightshift */
122
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
123
         16,                    /* bitsize */
124
         false,                 /* pc_relative */
125
         0,                      /* bitpos */
126
         complain_overflow_unsigned, /* complain_on_overflow */
127
         pj_elf_reloc,          /* special_function */
128
         "R_PJ_LO16",           /* name */
129
         false,                 /* partial_inplace */
130
         0xffff,                /* src_mask */
131
         0xffff,                /* dst_mask */
132
         true),                 /* pcrel_offset */
133
 
134
 
135
    HOWTO (R_PJ_CODE_HI16,      /* type */
136
         16,                    /* rightshift */
137
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
138
         16,                    /* bitsize */
139
         false,                 /* pc_relative */
140
         0,                      /* bitpos */
141
         complain_overflow_unsigned, /* complain_on_overflow */
142
         pj_elf_reloc,          /* special_function */
143
         "R_PJ_HI16",           /* name */
144
         false,                 /* partial_inplace */
145
         0xffff,                /* src_mask */
146
         0xffff,                /* dst_mask */
147
         true),                 /* pcrel_offset */
148
 
149
  /* GNU extension to record C++ vtable hierarchy */
150
  HOWTO (R_PJ_GNU_VTINHERIT,    /* type */
151
         0,                     /* rightshift */
152
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
153
         0,                     /* bitsize */
154
         false,                 /* pc_relative */
155
         0,                     /* bitpos */
156
         complain_overflow_dont, /* complain_on_overflow */
157
         NULL,                  /* special_function */
158
         "R_PJ_GNU_VTINHERIT",  /* name */
159
         false,                 /* partial_inplace */
160
         0,                     /* src_mask */
161
         0,                     /* dst_mask */
162
         false),                /* pcrel_offset */
163
 
164
  /* GNU extension to record C++ vtable member usage */
165
  HOWTO (R_PJ_GNU_VTENTRY,     /* type */
166
         0,                     /* rightshift */
167
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
168
         0,                     /* bitsize */
169
         false,                 /* pc_relative */
170
         0,                     /* bitpos */
171
         complain_overflow_dont, /* complain_on_overflow */
172
         _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
173
         "R_PJ_GNU_VTENTRY",   /* name */
174
         false,                 /* partial_inplace */
175
         0,                     /* src_mask */
176
         0,                     /* dst_mask */
177
         false),                /* pcrel_offset */
178
 
179
 
180
};
181
 
182
/* This function is used for normal relocs.  This is like the COFF
183
   function, and is almost certainly incorrect for other ELF targets.  */
184
 
185
static bfd_reloc_status_type
186
pj_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
187
          error_message)
188
     bfd *abfd;
189
     arelent *reloc_entry;
190
     asymbol *symbol_in;
191
     PTR data;
192
     asection *input_section;
193
     bfd *output_bfd;
194
     char **error_message ATTRIBUTE_UNUSED;
195
{
196
  unsigned long insn;
197
  bfd_vma sym_value;
198
  enum elf_pj_reloc_type r_type;
199
  bfd_vma addr = reloc_entry->address;
200
  bfd_byte *hit_data = addr + (bfd_byte *) data;
201
 
202
  r_type = (enum elf_pj_reloc_type) reloc_entry->howto->type;
203
 
204
  if (output_bfd != NULL)
205
    {
206
      /* Partial linking--do nothing.  */
207
      reloc_entry->address += input_section->output_offset;
208
      return bfd_reloc_ok;
209
    }
210
 
211
  if (symbol_in != NULL
212
      && bfd_is_und_section (symbol_in->section))
213
    return bfd_reloc_undefined;
214
 
215
  if (bfd_is_com_section (symbol_in->section))
216
    sym_value = 0;
217
  else
218
    sym_value = (symbol_in->value +
219
                 symbol_in->section->output_section->vma +
220
                 symbol_in->section->output_offset);
221
 
222
  switch (r_type)
223
    {
224
    case R_PJ_DATA_DIR32:
225
      insn = bfd_get_32 (abfd, hit_data);
226
      insn += sym_value + reloc_entry->addend;
227
      bfd_put_32 (abfd, insn, hit_data);
228
      break;
229
 
230
      /* Relocations in code are always bigendian, no matter what the
231
         data endianness is. */
232
 
233
    case R_PJ_CODE_DIR32:
234
      insn = bfd_getb32 (hit_data);
235
      insn += sym_value + reloc_entry->addend;
236
      bfd_putb32 (insn, hit_data);
237
      break;
238
 
239
    case R_PJ_CODE_REL16:
240
      insn = bfd_getb16 (hit_data);
241
      insn += sym_value + reloc_entry->addend
242
        -  (input_section->output_section->vma
243
            + input_section->output_offset);
244
      bfd_putb16 (insn, hit_data);
245
      break;
246
    case R_PJ_CODE_LO16:
247
      insn = bfd_getb16 (hit_data);
248
      insn += sym_value + reloc_entry->addend;
249
      bfd_putb16 (insn, hit_data);
250
      break;
251
 
252
    case R_PJ_CODE_HI16:
253
      insn = bfd_getb16 (hit_data);
254
      insn += (sym_value + reloc_entry->addend) >> 16;
255
      bfd_putb16 (insn, hit_data);
256
      break;
257
 
258
    default:
259
      abort ();
260
      break;
261
    }
262
 
263
  return bfd_reloc_ok;
264
}
265
 
266
/* This structure is used to map BFD reloc codes to PJ ELF relocs.  */
267
 
268
struct elf_reloc_map
269
{
270
  bfd_reloc_code_real_type bfd_reloc_val;
271
  unsigned char elf_reloc_val;
272
};
273
 
274
/* An array mapping BFD reloc codes to PJ ELF relocs.  */
275
 
276
static const struct elf_reloc_map pj_reloc_map[] =
277
{
278
    { BFD_RELOC_NONE,           R_PJ_NONE          },
279
    { BFD_RELOC_32,             R_PJ_DATA_DIR32    },
280
    { BFD_RELOC_PJ_CODE_DIR16,  R_PJ_CODE_DIR16    },
281
    { BFD_RELOC_PJ_CODE_DIR32,  R_PJ_CODE_DIR32    },
282
    { BFD_RELOC_PJ_CODE_LO16,   R_PJ_CODE_LO16     },
283
    { BFD_RELOC_PJ_CODE_HI16,   R_PJ_CODE_HI16     },
284
    { BFD_RELOC_PJ_CODE_REL32,  R_PJ_CODE_REL32    },
285
    { BFD_RELOC_PJ_CODE_REL16,  R_PJ_CODE_REL16    },
286
    { BFD_RELOC_VTABLE_INHERIT, R_PJ_GNU_VTINHERIT },
287
    { BFD_RELOC_VTABLE_ENTRY,   R_PJ_GNU_VTENTRY   },
288
};
289
 
290
/* Given a BFD reloc code, return the howto structure for the
291
   corresponding PJ ELf reloc.  */
292
 
293
static reloc_howto_type *
294
pj_elf_reloc_type_lookup (abfd, code)
295
     bfd *abfd ATTRIBUTE_UNUSED;
296
     bfd_reloc_code_real_type code;
297
{
298
  unsigned int i;
299
 
300
  for (i = 0; i < sizeof (pj_reloc_map) / sizeof (struct elf_reloc_map); i++)
301
    {
302
      if (pj_reloc_map[i].bfd_reloc_val == code)
303
        return &pj_elf_howto_table[(int) pj_reloc_map[i].elf_reloc_val];
304
    }
305
 
306
  return NULL;
307
}
308
 
309
/* Given an ELF reloc, fill in the howto field of a relent.  */
310
 
311
static void
312
pj_elf_info_to_howto (abfd, cache_ptr, dst)
313
     bfd *abfd ATTRIBUTE_UNUSED;
314
     arelent *cache_ptr;
315
     Elf_Internal_Rela *dst;
316
{
317
  unsigned int r;
318
 
319
  r = ELF32_R_TYPE (dst->r_info);
320
 
321
  BFD_ASSERT (r < (unsigned int) R_PJ_max);
322
 
323
  cache_ptr->howto = &pj_elf_howto_table[r];
324
}
325
 
326
/* Take this moment to fill in the special picoJava bits in the
327
   e_flags field. */
328
 
329
static void
330
pj_elf_final_write_processing (abfd, linker)
331
     bfd *abfd;
332
     boolean linker ATTRIBUTE_UNUSED;
333
{
334
    elf_elfheader (abfd)->e_flags |= EF_PICOJAVA_ARCH;
335
    elf_elfheader (abfd)->e_flags |= EF_PICOJAVA_GNUCALLS;
336
}
337
 
338
#define TARGET_BIG_SYM          bfd_elf32_pj_vec
339
#define TARGET_BIG_NAME         "elf32-pj"
340
#define TARGET_LITTLE_SYM       bfd_elf32_pjl_vec
341
#define TARGET_LITTLE_NAME      "elf32-pjl"
342
#define ELF_ARCH                bfd_arch_pj
343
#define ELF_MACHINE_CODE        EM_PJ
344
#define ELF_MAXPAGESIZE         0x1000
345
#define bfd_elf32_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
346
#define bfd_elf32_bfd_reloc_type_lookup              pj_elf_reloc_type_lookup
347
#define elf_backend_final_write_processing           pj_elf_final_write_processing
348
#define elf_info_to_howto                            pj_elf_info_to_howto
349
#include "elf32-target.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.