00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "bfd.h"
00022 #include "sysdep.h"
00023 #include "bfdlink.h"
00024 #include "libbfd.h"
00025 #include "elf-bfd.h"
00026 #include "elf/pj.h"
00027
00028 static bfd_reloc_status_type pj_elf_reloc
00029 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00030 static reloc_howto_type *pj_elf_reloc_type_lookup
00031 PARAMS ((bfd *, bfd_reloc_code_real_type));
00032 static void pj_elf_info_to_howto
00033 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
00034 static void pj_elf_final_write_processing
00035 PARAMS ((bfd *, bfd_boolean));
00036
00037 static reloc_howto_type pj_elf_howto_table[] =
00038 {
00039
00040 HOWTO (R_PJ_NONE,
00041 0,
00042 0,
00043 0,
00044 FALSE,
00045 0,
00046 complain_overflow_dont,
00047 pj_elf_reloc,
00048 "R_PJ_NONE",
00049 FALSE,
00050 0,
00051 0,
00052 FALSE),
00053
00054
00055
00056 HOWTO (R_PJ_DATA_DIR32,
00057 0,
00058 2,
00059 32,
00060 FALSE,
00061 0,
00062 complain_overflow_bitfield,
00063 pj_elf_reloc,
00064 "R_PJ_DIR32",
00065 TRUE,
00066 0xffffffff,
00067 0xffffffff,
00068 FALSE),
00069
00070
00071 HOWTO (R_PJ_CODE_REL32,
00072 0,
00073 2,
00074 32,
00075 TRUE,
00076 0,
00077 complain_overflow_signed,
00078 pj_elf_reloc,
00079 "R_PJ_REL32",
00080 FALSE,
00081 0,
00082 0xffffffff,
00083 TRUE),
00084
00085
00086 HOWTO (R_PJ_CODE_REL16,
00087 0,
00088 1,
00089 16,
00090 TRUE,
00091 0,
00092 complain_overflow_signed,
00093 pj_elf_reloc,
00094 "R_PJ_REL16",
00095 FALSE,
00096 0xffff,
00097 0xffff,
00098 TRUE),
00099 EMPTY_HOWTO (4),
00100 EMPTY_HOWTO (5),
00101 HOWTO (R_PJ_CODE_DIR32,
00102 0,
00103 2,
00104 32,
00105 FALSE,
00106 0,
00107 complain_overflow_bitfield,
00108 pj_elf_reloc,
00109 "R_PJ_CODE_DIR32",
00110 TRUE,
00111 0xffffffff,
00112 0xffffffff,
00113 FALSE),
00114
00115 EMPTY_HOWTO (7),
00116 EMPTY_HOWTO (8),
00117 EMPTY_HOWTO (9),
00118 EMPTY_HOWTO (10),
00119 EMPTY_HOWTO (11),
00120 EMPTY_HOWTO (12),
00121
00122 HOWTO (R_PJ_CODE_LO16,
00123 0,
00124 1,
00125 16,
00126 FALSE,
00127 0,
00128 complain_overflow_unsigned,
00129 pj_elf_reloc,
00130 "R_PJ_LO16",
00131 FALSE,
00132 0xffff,
00133 0xffff,
00134 TRUE),
00135
00136 HOWTO (R_PJ_CODE_HI16,
00137 16,
00138 1,
00139 16,
00140 FALSE,
00141 0,
00142 complain_overflow_unsigned,
00143 pj_elf_reloc,
00144 "R_PJ_HI16",
00145 FALSE,
00146 0xffff,
00147 0xffff,
00148 TRUE),
00149
00150
00151 HOWTO (R_PJ_GNU_VTINHERIT,
00152 0,
00153 2,
00154 0,
00155 FALSE,
00156 0,
00157 complain_overflow_dont,
00158 NULL,
00159 "R_PJ_GNU_VTINHERIT",
00160 FALSE,
00161 0,
00162 0,
00163 FALSE),
00164
00165
00166 HOWTO (R_PJ_GNU_VTENTRY,
00167 0,
00168 2,
00169 0,
00170 FALSE,
00171 0,
00172 complain_overflow_dont,
00173 _bfd_elf_rel_vtable_reloc_fn,
00174 "R_PJ_GNU_VTENTRY",
00175 FALSE,
00176 0,
00177 0,
00178 FALSE),
00179 };
00180
00181
00182
00183
00184 static bfd_reloc_status_type
00185 pj_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
00186 error_message)
00187 bfd *abfd;
00188 arelent *reloc_entry;
00189 asymbol *symbol_in;
00190 PTR data;
00191 asection *input_section;
00192 bfd *output_bfd;
00193 char **error_message ATTRIBUTE_UNUSED;
00194 {
00195 unsigned long insn;
00196 bfd_vma sym_value;
00197 enum elf_pj_reloc_type r_type;
00198 bfd_vma addr = reloc_entry->address;
00199 bfd_byte *hit_data = addr + (bfd_byte *) data;
00200
00201 r_type = (enum elf_pj_reloc_type) reloc_entry->howto->type;
00202
00203 if (output_bfd != NULL)
00204 {
00205
00206 reloc_entry->address += input_section->output_offset;
00207 return bfd_reloc_ok;
00208 }
00209
00210 if (symbol_in != NULL
00211 && bfd_is_und_section (symbol_in->section))
00212 return bfd_reloc_undefined;
00213
00214 if (bfd_is_com_section (symbol_in->section))
00215 sym_value = 0;
00216 else
00217 sym_value = (symbol_in->value +
00218 symbol_in->section->output_section->vma +
00219 symbol_in->section->output_offset);
00220
00221 switch (r_type)
00222 {
00223 case R_PJ_DATA_DIR32:
00224 insn = bfd_get_32 (abfd, hit_data);
00225 insn += sym_value + reloc_entry->addend;
00226 bfd_put_32 (abfd, (bfd_vma) insn, hit_data);
00227 break;
00228
00229
00230
00231
00232 case R_PJ_CODE_DIR32:
00233 insn = bfd_getb32 (hit_data);
00234 insn += sym_value + reloc_entry->addend;
00235 bfd_putb32 ((bfd_vma) insn, hit_data);
00236 break;
00237
00238 case R_PJ_CODE_REL16:
00239 insn = bfd_getb16 (hit_data);
00240 insn += sym_value + reloc_entry->addend
00241 - (input_section->output_section->vma
00242 + input_section->output_offset);
00243 bfd_putb16 ((bfd_vma) insn, hit_data);
00244 break;
00245 case R_PJ_CODE_LO16:
00246 insn = bfd_getb16 (hit_data);
00247 insn += sym_value + reloc_entry->addend;
00248 bfd_putb16 ((bfd_vma) insn, hit_data);
00249 break;
00250
00251 case R_PJ_CODE_HI16:
00252 insn = bfd_getb16 (hit_data);
00253 insn += (sym_value + reloc_entry->addend) >> 16;
00254 bfd_putb16 ((bfd_vma) insn, hit_data);
00255 break;
00256
00257 default:
00258 abort ();
00259 break;
00260 }
00261
00262 return bfd_reloc_ok;
00263 }
00264
00265
00266
00267 struct elf_reloc_map
00268 {
00269 bfd_reloc_code_real_type bfd_reloc_val;
00270 unsigned char elf_reloc_val;
00271 };
00272
00273
00274
00275 static const struct elf_reloc_map pj_reloc_map[] =
00276 {
00277 { BFD_RELOC_NONE, R_PJ_NONE },
00278 { BFD_RELOC_32, R_PJ_DATA_DIR32 },
00279 { BFD_RELOC_PJ_CODE_DIR16, R_PJ_CODE_DIR16 },
00280 { BFD_RELOC_PJ_CODE_DIR32, R_PJ_CODE_DIR32 },
00281 { BFD_RELOC_PJ_CODE_LO16, R_PJ_CODE_LO16 },
00282 { BFD_RELOC_PJ_CODE_HI16, R_PJ_CODE_HI16 },
00283 { BFD_RELOC_PJ_CODE_REL32, R_PJ_CODE_REL32 },
00284 { BFD_RELOC_PJ_CODE_REL16, R_PJ_CODE_REL16 },
00285 { BFD_RELOC_VTABLE_INHERIT, R_PJ_GNU_VTINHERIT },
00286 { BFD_RELOC_VTABLE_ENTRY, R_PJ_GNU_VTENTRY },
00287 };
00288
00289
00290
00291
00292 static reloc_howto_type *
00293 pj_elf_reloc_type_lookup (abfd, code)
00294 bfd *abfd ATTRIBUTE_UNUSED;
00295 bfd_reloc_code_real_type code;
00296 {
00297 unsigned int i;
00298
00299 for (i = 0; i < sizeof (pj_reloc_map) / sizeof (struct elf_reloc_map); i++)
00300 {
00301 if (pj_reloc_map[i].bfd_reloc_val == code)
00302 return &pj_elf_howto_table[(int) pj_reloc_map[i].elf_reloc_val];
00303 }
00304
00305 return NULL;
00306 }
00307
00308
00309
00310 static void
00311 pj_elf_info_to_howto (abfd, cache_ptr, dst)
00312 bfd *abfd ATTRIBUTE_UNUSED;
00313 arelent *cache_ptr;
00314 Elf_Internal_Rela *dst;
00315 {
00316 unsigned int r;
00317
00318 r = ELF32_R_TYPE (dst->r_info);
00319
00320 BFD_ASSERT (r < (unsigned int) R_PJ_max);
00321
00322 cache_ptr->howto = &pj_elf_howto_table[r];
00323 }
00324
00325
00326
00327
00328 static void
00329 pj_elf_final_write_processing (abfd, linker)
00330 bfd *abfd;
00331 bfd_boolean linker ATTRIBUTE_UNUSED;
00332 {
00333 elf_elfheader (abfd)->e_flags |= EF_PICOJAVA_ARCH;
00334 elf_elfheader (abfd)->e_flags |= EF_PICOJAVA_GNUCALLS;
00335 }
00336
00337 #define TARGET_BIG_SYM bfd_elf32_pj_vec
00338 #define TARGET_BIG_NAME "elf32-pj"
00339 #define TARGET_LITTLE_SYM bfd_elf32_pjl_vec
00340 #define TARGET_LITTLE_NAME "elf32-pjl"
00341 #define ELF_ARCH bfd_arch_pj
00342 #define ELF_MACHINE_CODE EM_PJ
00343 #define ELF_MACHINE_ALT1 EM_PJ_OLD
00344 #define ELF_MAXPAGESIZE 0x1000
00345 #define bfd_elf32_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
00346 #define bfd_elf32_bfd_reloc_type_lookup pj_elf_reloc_type_lookup
00347 #define elf_backend_final_write_processing pj_elf_final_write_processing
00348 #define elf_info_to_howto pj_elf_info_to_howto
00349 #include "elf32-target.h"