00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "bfd.h"
00026 #include "sysdep.h"
00027 #include "libbfd.h"
00028 #include "elf-bfd.h"
00029 #include "elf/or32.h"
00030 #include "libiberty.h"
00031
00032 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
00033 PARAMS ((bfd *, bfd_reloc_code_real_type));
00034 static void or32_info_to_howto_rel
00035 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
00036 static bfd_boolean or32_elf_object_p
00037 PARAMS ((bfd *));
00038 static void or32_elf_final_write_processing
00039 PARAMS ((bfd *, bfd_boolean));
00040 static bfd_reloc_status_type or32_elf_32_reloc
00041 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00042 static bfd_reloc_status_type or32_elf_16_reloc
00043 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00044 static bfd_reloc_status_type or32_elf_8_reloc
00045 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00046 static bfd_reloc_status_type or32_elf_const_reloc
00047 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00048 static bfd_reloc_status_type or32_elf_consth_reloc
00049 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00050 static bfd_reloc_status_type or32_elf_jumptarg_reloc
00051 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00052
00053
00054
00055 #define USE_REL 1
00056
00057 static reloc_howto_type elf_or32_howto_table[] =
00058 {
00059
00060 HOWTO (R_OR32_NONE,
00061 0,
00062 2,
00063 32,
00064 FALSE,
00065 0,
00066 complain_overflow_bitfield,
00067 bfd_elf_generic_reloc,
00068 "R_OR32_NONE",
00069 FALSE,
00070 0,
00071 0,
00072 FALSE),
00073
00074
00075 HOWTO (R_OR32_32,
00076 0,
00077 2,
00078 32,
00079 FALSE,
00080 0,
00081 complain_overflow_bitfield,
00082 or32_elf_32_reloc,
00083 "R_OR32_32",
00084 FALSE,
00085 0xffffffff,
00086 0xffffffff,
00087 FALSE),
00088
00089
00090 HOWTO (R_OR32_16,
00091 0,
00092 1,
00093 16,
00094 FALSE,
00095 0,
00096 complain_overflow_bitfield,
00097 or32_elf_16_reloc,
00098 "R_OR32_16",
00099 FALSE,
00100 0x0000ffff,
00101 0x0000ffff,
00102 FALSE),
00103
00104
00105 HOWTO (R_OR32_8,
00106 0,
00107 0,
00108 8,
00109 FALSE,
00110 0,
00111 complain_overflow_bitfield,
00112 or32_elf_8_reloc,
00113 "R_OR32_8",
00114 FALSE,
00115 0x000000ff,
00116 0x000000ff,
00117 FALSE),
00118
00119
00120 HOWTO (R_OR32_CONST,
00121 0,
00122 2,
00123 16,
00124 FALSE,
00125 0,
00126 complain_overflow_dont,
00127 or32_elf_const_reloc,
00128 "R_OR32_CONST",
00129 FALSE,
00130 0x0000ffff,
00131 0x0000ffff,
00132 FALSE),
00133
00134
00135 HOWTO (R_OR32_CONSTH,
00136 16,
00137 2,
00138 16,
00139 TRUE,
00140 0,
00141 complain_overflow_dont,
00142 or32_elf_consth_reloc,
00143 "R_OR32_CONSTH",
00144 FALSE,
00145 0xffff0000,
00146 0x0000ffff,
00147 FALSE),
00148
00149
00150 HOWTO (R_OR32_JUMPTARG,
00151 2,
00152 2,
00153 28,
00154 TRUE,
00155 0,
00156 complain_overflow_signed,
00157 or32_elf_jumptarg_reloc,
00158 "R_OR32_JUMPTARG",
00159 FALSE,
00160 0,
00161 0x03ffffff,
00162 TRUE),
00163
00164
00165 HOWTO (R_OR32_GNU_VTINHERIT,
00166 0,
00167 2,
00168 0,
00169 FALSE,
00170 0,
00171 complain_overflow_dont,
00172 NULL,
00173 "R_OR32_GNU_VTINHERIT",
00174 FALSE,
00175 0,
00176 0,
00177 FALSE),
00178
00179
00180 HOWTO (R_OR32_GNU_VTENTRY,
00181 0,
00182 2,
00183 0,
00184 FALSE,
00185 0,
00186 complain_overflow_dont,
00187 _bfd_elf_rel_vtable_reloc_fn,
00188 "R_OR32_GNU_VTENTRY",
00189 FALSE,
00190 0,
00191 0,
00192 FALSE),
00193 };
00194
00195
00196
00197 struct or32_reloc_map
00198 {
00199 bfd_reloc_code_real_type bfd_reloc_val;
00200 unsigned char elf_reloc_val;
00201 };
00202
00203 static const struct or32_reloc_map or32_reloc_map[] =
00204 {
00205 { BFD_RELOC_NONE, R_OR32_NONE },
00206 { BFD_RELOC_32, R_OR32_32 },
00207 { BFD_RELOC_16, R_OR32_16 },
00208 { BFD_RELOC_8, R_OR32_8 },
00209 { BFD_RELOC_LO16, R_OR32_CONST },
00210 { BFD_RELOC_HI16, R_OR32_CONSTH },
00211 { BFD_RELOC_32_GOT_PCREL, R_OR32_JUMPTARG },
00212 { BFD_RELOC_VTABLE_INHERIT, R_OR32_GNU_VTINHERIT },
00213 { BFD_RELOC_VTABLE_ENTRY, R_OR32_GNU_VTENTRY },
00214 };
00215
00216 static reloc_howto_type *
00217 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
00218 bfd *abfd ATTRIBUTE_UNUSED;
00219 bfd_reloc_code_real_type code;
00220 {
00221 unsigned int i;
00222
00223 for (i = ARRAY_SIZE (or32_reloc_map); i--;)
00224 {
00225 if (or32_reloc_map[i].bfd_reloc_val == code)
00226 return &elf_or32_howto_table[or32_reloc_map[i].elf_reloc_val];
00227 }
00228
00229 return NULL;
00230 }
00231
00232
00233
00234 static void
00235 or32_info_to_howto_rel (abfd, cache_ptr, dst)
00236 bfd *abfd ATTRIBUTE_UNUSED;
00237 arelent *cache_ptr;
00238 Elf_Internal_Rela *dst;
00239 {
00240 unsigned int r_type;
00241
00242 r_type = ELF32_R_TYPE (dst->r_info);
00243 BFD_ASSERT (r_type < (unsigned int) R_OR32_max);
00244 cache_ptr->howto = &elf_or32_howto_table[r_type];
00245 }
00246
00247
00248
00249 static bfd_boolean
00250 or32_elf_object_p (abfd)
00251 bfd *abfd;
00252 {
00253 (void) bfd_default_set_arch_mach (abfd, bfd_arch_or32, 0);
00254 return TRUE;
00255 }
00256
00257
00258
00259
00260 static void
00261 or32_elf_final_write_processing (abfd, linker)
00262 bfd *abfd;
00263 bfd_boolean linker ATTRIBUTE_UNUSED;
00264 {
00265 int mach;
00266 unsigned long val;
00267
00268 switch (mach = bfd_get_mach (abfd))
00269 {
00270
00271
00272
00273
00274
00275 default:
00276 val = 0;
00277 return;
00278 }
00279
00280 elf_elfheader (abfd)->e_flags &=~ EF_OR32_MACH;
00281 elf_elfheader (abfd)->e_flags |= val;
00282 }
00283
00284 bfd_reloc_status_type
00285 or32_elf_32_reloc (abfd, reloc_entry, symbol, data, input_section,
00286 output_bfd, error_message)
00287 bfd *abfd;
00288 arelent *reloc_entry;
00289 asymbol *symbol;
00290 PTR data;
00291 asection *input_section;
00292 bfd *output_bfd;
00293 char **error_message ATTRIBUTE_UNUSED;
00294 {
00295 if (output_bfd != (bfd *) NULL)
00296 {
00297 unsigned long insn;
00298 bfd_size_type addr = reloc_entry->address;
00299
00300 reloc_entry->address += input_section->output_offset;
00301
00302 insn = bfd_get_32 (abfd, (bfd_byte *) data + addr);
00303 insn += symbol->section->output_section->vma;
00304 insn += symbol->section->output_offset;
00305 insn += symbol->value;
00306 bfd_put_32 (abfd, insn, (bfd_byte *) data + addr);
00307
00308 return bfd_reloc_ok;
00309 }
00310
00311 return bfd_reloc_continue;
00312 }
00313
00314 bfd_reloc_status_type
00315 or32_elf_16_reloc (abfd, reloc_entry, symbol, data, input_section,
00316 output_bfd, error_message)
00317 bfd *abfd;
00318 arelent *reloc_entry;
00319 asymbol *symbol;
00320 PTR data;
00321 asection *input_section;
00322 bfd *output_bfd;
00323 char **error_message ATTRIBUTE_UNUSED;
00324 {
00325 if (output_bfd != (bfd *) NULL)
00326 {
00327 unsigned short insn;
00328 bfd_size_type addr = reloc_entry->address;
00329
00330 reloc_entry->address += input_section->output_offset;
00331
00332 insn = bfd_get_16 (abfd, (bfd_byte *) data + addr);
00333 insn += symbol->section->output_section->vma;
00334 insn += symbol->section->output_offset;
00335 insn += symbol->value;
00336 bfd_put_16 (abfd, insn, (bfd_byte *) data + addr);
00337
00338 return bfd_reloc_ok;
00339 }
00340
00341 return bfd_reloc_continue;
00342 }
00343
00344 bfd_reloc_status_type
00345 or32_elf_8_reloc (abfd, reloc_entry, symbol, data, input_section,
00346 output_bfd, error_message)
00347 bfd *abfd ATTRIBUTE_UNUSED;
00348 arelent *reloc_entry;
00349 asymbol *symbol;
00350 PTR data;
00351 asection *input_section;
00352 bfd *output_bfd;
00353 char **error_message ATTRIBUTE_UNUSED;
00354 {
00355 if (output_bfd != (bfd *) NULL)
00356 {
00357 unsigned char insn;
00358 bfd_size_type addr = reloc_entry->address;
00359
00360 reloc_entry->address += input_section->output_offset;
00361
00362 insn = bfd_get_8 (abfd, (bfd_byte *) data + addr);
00363 insn += symbol->section->output_section->vma;
00364 insn += symbol->section->output_offset;
00365 insn += symbol->value;
00366 bfd_put_8 (abfd, insn, (bfd_byte *) data + addr);
00367
00368 return bfd_reloc_ok;
00369 }
00370
00371 return bfd_reloc_continue;
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 struct or32_consth
00384 {
00385 struct or32_consth *next;
00386 bfd_byte *addr;
00387 bfd_vma addend;
00388 };
00389
00390
00391
00392 static struct or32_consth *or32_consth_list;
00393
00394 bfd_reloc_status_type
00395 or32_elf_consth_reloc (abfd, reloc_entry, symbol, data, input_section,
00396 output_bfd, error_message)
00397 bfd *abfd ATTRIBUTE_UNUSED;
00398 arelent *reloc_entry;
00399 asymbol *symbol;
00400 PTR data;
00401 asection *input_section;
00402 bfd *output_bfd;
00403 char **error_message ATTRIBUTE_UNUSED;
00404 {
00405 bfd_reloc_status_type ret;
00406 bfd_vma relocation;
00407 struct or32_consth *n;
00408
00409 ret = bfd_reloc_ok;
00410
00411 if (bfd_is_und_section (symbol->section)
00412 && output_bfd == (bfd *) NULL)
00413 ret = bfd_reloc_undefined;
00414
00415 if (bfd_is_com_section (symbol->section))
00416 relocation = 0;
00417 else
00418 relocation = symbol->value;
00419
00420 relocation += symbol->section->output_section->vma;
00421 relocation += symbol->section->output_offset;
00422 relocation += reloc_entry->addend;
00423
00424 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
00425 return bfd_reloc_outofrange;
00426
00427
00428 n = (struct or32_consth *) bfd_malloc (sizeof *n);
00429 if (n == NULL)
00430 return bfd_reloc_outofrange;
00431 n->addr = (bfd_byte *) data + reloc_entry->address;
00432 n->addend = relocation;
00433 n->next = or32_consth_list;
00434 or32_consth_list = n;
00435
00436 if (output_bfd != (bfd *) NULL)
00437 reloc_entry->address += input_section->output_offset;
00438
00439 return ret;
00440 }
00441
00442
00443
00444
00445
00446 bfd_reloc_status_type
00447 or32_elf_const_reloc (abfd, reloc_entry, symbol, data, input_section,
00448 output_bfd, error_message)
00449 bfd *abfd;
00450 arelent *reloc_entry;
00451 asymbol *symbol;
00452 PTR data;
00453 asection *input_section;
00454 bfd *output_bfd;
00455 char **error_message;
00456 {
00457 if (or32_consth_list != NULL)
00458 {
00459 struct or32_consth *l;
00460
00461 l = or32_consth_list;
00462 while (l != NULL)
00463 {
00464 unsigned long insn;
00465 unsigned long val;
00466 unsigned long vallo;
00467 struct or32_consth *next;
00468
00469
00470
00471
00472 insn = bfd_get_32 (abfd, l->addr);
00473 vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
00474 & 0xffff);
00475 val = ((insn & 0xffff) << 16) + vallo;
00476 val += l->addend;
00477
00478 insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
00479 bfd_put_32 (abfd, insn, l->addr);
00480
00481 next = l->next;
00482 free (l);
00483 l = next;
00484 }
00485
00486 or32_consth_list = NULL;
00487 }
00488
00489 if (output_bfd != (bfd *) NULL)
00490 {
00491 unsigned long insn, tmp;
00492 bfd_size_type addr = reloc_entry->address;
00493
00494 reloc_entry->address += input_section->output_offset;
00495
00496 insn = bfd_get_32 (abfd, (bfd_byte *) data + addr);
00497 tmp = insn & 0x0000ffff;
00498 tmp += symbol->section->output_section->vma;
00499 tmp += symbol->section->output_offset;
00500 tmp += symbol->value;
00501 insn = (insn & 0xffff0000) | (tmp & 0x0000ffff);
00502 bfd_put_32 (abfd, insn, (bfd_byte *) data + addr);
00503
00504 return bfd_reloc_ok;
00505 }
00506
00507
00508 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
00509 input_section, output_bfd, error_message);
00510 }
00511
00512 bfd_reloc_status_type
00513 or32_elf_jumptarg_reloc (abfd, reloc_entry, symbol, data, input_section,
00514 output_bfd, error_message)
00515 bfd *abfd;
00516 arelent *reloc_entry;
00517 asymbol *symbol ATTRIBUTE_UNUSED;
00518 PTR data;
00519 asection *input_section;
00520 bfd *output_bfd;
00521 char **error_message ATTRIBUTE_UNUSED;
00522 {
00523 if (output_bfd != (bfd *) NULL)
00524 {
00525 unsigned long insn, tmp;
00526 bfd_size_type addr = reloc_entry->address;
00527
00528 reloc_entry->address += input_section->output_offset;
00529
00530 insn = bfd_get_32 (abfd, (bfd_byte *) data + addr);
00531 tmp = insn | 0xfc000000;
00532 tmp -= (input_section->output_offset >> 2);
00533 insn = (insn & 0xfc000000) | (tmp & 0x03ffffff);
00534 bfd_put_32 (abfd, insn, (bfd_byte *) data + addr);
00535
00536 return bfd_reloc_ok;
00537 }
00538
00539 return bfd_reloc_continue;
00540 }
00541
00542 #define TARGET_LITTLE_SYM bfd_elf32_or32_little_vec
00543 #define TARGET_LITTLE_NAME "elf32-littleor32"
00544 #define TARGET_BIG_SYM bfd_elf32_or32_big_vec
00545 #define TARGET_BIG_NAME "elf32-or32"
00546 #define ELF_ARCH bfd_arch_or32
00547 #define ELF_MACHINE_CODE EM_OR32
00548 #define ELF_MAXPAGESIZE 0x1000
00549
00550 #define elf_info_to_howto 0
00551 #define elf_info_to_howto_rel or32_info_to_howto_rel
00552 #define elf_backend_object_p or32_elf_object_p
00553 #define elf_backend_final_write_processing \
00554 or32_elf_final_write_processing
00555
00556 #include "elf32-target.h"