00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define N_HEADER_IN_TEXT(x) 1
00024 #define N_SHARED_LIB(x) 0
00025 #define N_TXTADDR(x) \
00026 (N_MAGIC(x) != ZMAGIC ? (x).a_entry : \
00027 TEXT_START_ADDR + EXEC_BYTES_SIZE \
00028 )
00029 #define N_DATADDR(x) (N_TXTADDR(x)+N_TXTSIZE(x))
00030 #define TEXT_START_ADDR 4096
00031 #define TARGET_PAGE_SIZE 4096
00032 #define SEGMENT_SIZE TARGET_PAGE_SIZE
00033 #define DEFAULT_ARCH bfd_arch_mips
00034 #define MACHTYPE_OK(mtype) ((mtype) == M_UNKNOWN \
00035 || (mtype) == M_MIPS1 || (mtype) == M_MIPS2)
00036 #define MY_symbol_leading_char '\0'
00037
00038
00039
00040
00041 #define MY(OP) CONCAT2 (mipsbsd_,OP)
00042
00043 #include "bfd.h"
00044 #include "sysdep.h"
00045 #include "libbfd.h"
00046 #include "libaout.h"
00047
00048 #define SET_ARCH_MACH(ABFD, EXEC) \
00049 MY(set_arch_mach) (ABFD, N_MACHTYPE (EXEC)); \
00050 MY(choose_reloc_size) (ABFD);
00051 static void MY(set_arch_mach) PARAMS ((bfd *abfd, unsigned long machtype));
00052 static void MY(choose_reloc_size) PARAMS ((bfd *abfd));
00053
00054 #define MY_write_object_contents MY(write_object_contents)
00055 static bfd_boolean MY(write_object_contents) PARAMS ((bfd *abfd));
00056
00057
00058
00059 #define MY_bfd_reloc_type_lookup mipsbsd_reloc_howto_type_lookup
00060 #define MY_canonicalize_reloc mipsbsd_canonicalize_reloc
00061
00062 #define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
00063 #define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols
00064 #define MY_final_link_callback unused
00065 #define MY_bfd_final_link _bfd_generic_final_link
00066
00067 #define MY_backend_data &MY(backend_data)
00068 #define MY_BFD_TARGET
00069
00070 #include "aout-target.h"
00071
00072 static bfd_reloc_status_type mips_fix_jmp_addr
00073 PARAMS ((bfd *, arelent *, struct bfd_symbol *, PTR, asection *,
00074 bfd *, char **));
00075 static reloc_howto_type *MY(reloc_howto_type_lookup)
00076 PARAMS ((bfd *, bfd_reloc_code_real_type));
00077
00078 long MY(canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
00079
00080 static void
00081 MY(set_arch_mach) (abfd, machtype)
00082 bfd *abfd;
00083 unsigned long machtype;
00084 {
00085 enum bfd_architecture arch;
00086 unsigned int machine;
00087
00088
00089 switch (machtype)
00090 {
00091 case M_MIPS1:
00092 arch = bfd_arch_mips;
00093 machine = bfd_mach_mips3000;
00094 break;
00095
00096 case M_MIPS2:
00097 arch = bfd_arch_mips;
00098 machine = bfd_mach_mips4000;
00099 break;
00100
00101 default:
00102 arch = bfd_arch_obscure;
00103 machine = 0;
00104 break;
00105 }
00106
00107 bfd_set_arch_mach (abfd, arch, machine);
00108 }
00109
00110
00111 static void
00112 MY (choose_reloc_size) (abfd)
00113 bfd *abfd;
00114 {
00115 switch (bfd_get_arch (abfd))
00116 {
00117 case bfd_arch_sparc:
00118 case bfd_arch_a29k:
00119 case bfd_arch_mips:
00120 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
00121 break;
00122 default:
00123 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
00124 break;
00125 }
00126 }
00127
00128
00129
00130
00131
00132 static bfd_boolean
00133 MY (write_object_contents) (abfd)
00134 bfd *abfd;
00135 {
00136 struct external_exec exec_bytes;
00137 struct internal_exec *execp = exec_hdr (abfd);
00138
00139
00140 switch (bfd_get_arch (abfd))
00141 {
00142 case bfd_arch_m68k:
00143 switch (bfd_get_mach (abfd))
00144 {
00145 case bfd_mach_m68010:
00146 N_SET_MACHTYPE (*execp, M_68010);
00147 break;
00148 default:
00149 case bfd_mach_m68020:
00150 N_SET_MACHTYPE (*execp, M_68020);
00151 break;
00152 }
00153 break;
00154 case bfd_arch_sparc:
00155 N_SET_MACHTYPE (*execp, M_SPARC);
00156 break;
00157 case bfd_arch_i386:
00158 N_SET_MACHTYPE (*execp, M_386);
00159 break;
00160 case bfd_arch_a29k:
00161 N_SET_MACHTYPE (*execp, M_29K);
00162 break;
00163 case bfd_arch_mips:
00164 switch (bfd_get_mach (abfd))
00165 {
00166 case bfd_mach_mips4000:
00167 case bfd_mach_mips6000:
00168 N_SET_MACHTYPE (*execp, M_MIPS2);
00169 break;
00170 default:
00171 N_SET_MACHTYPE (*execp, M_MIPS1);
00172 break;
00173 }
00174 break;
00175 default:
00176 N_SET_MACHTYPE (*execp, M_UNKNOWN);
00177 }
00178
00179 MY (choose_reloc_size) (abfd);
00180
00181 WRITE_HEADERS (abfd, execp);
00182
00183 return TRUE;
00184 }
00185
00186
00187 #define MIPS_RELOC_32 0
00188 #define MIPS_RELOC_JMP 1
00189 #define MIPS_RELOC_WDISP16 2
00190 #define MIPS_RELOC_HI16 3
00191 #define MIPS_RELOC_HI16_S 4
00192 #define MIPS_RELOC_LO16 5
00193
00194
00195
00196
00197
00198
00199
00200
00201 static bfd_reloc_status_type
00202 mips_fix_jmp_addr (abfd, reloc_entry, symbol, data, input_section, output_bfd,
00203 error_message)
00204 bfd *abfd ATTRIBUTE_UNUSED;
00205 arelent *reloc_entry;
00206 struct bfd_symbol *symbol;
00207 PTR data ATTRIBUTE_UNUSED;
00208 asection *input_section;
00209 bfd *output_bfd;
00210 char **error_message ATTRIBUTE_UNUSED;
00211 {
00212 bfd_vma relocation, pc;
00213
00214
00215 if (output_bfd != (bfd *)NULL)
00216 return bfd_reloc_continue;
00217
00218
00219 if (bfd_is_und_section (symbol->section)
00220 && (symbol->flags & BSF_WEAK) == 0)
00221 return bfd_reloc_undefined;
00222
00223
00224
00225 if (bfd_is_com_section (symbol->section))
00226 relocation = 0;
00227 else
00228 relocation = symbol->value;
00229
00230 relocation += symbol->section->output_section->vma;
00231 relocation += symbol->section->output_offset;
00232 relocation += reloc_entry->addend;
00233
00234 pc = input_section->output_section->vma + input_section->output_offset +
00235 reloc_entry->address + 4;
00236
00237 if ((relocation & 0xF0000000) != (pc & 0xF0000000))
00238 return bfd_reloc_overflow;
00239
00240 return bfd_reloc_continue;
00241 }
00242
00243
00244
00245
00246
00247
00248 static bfd_reloc_status_type
00249 mips_fix_hi16_s PARAMS ((bfd *, arelent *, asymbol *, PTR,
00250 asection *, bfd *, char **));
00251
00252 static bfd_reloc_status_type
00253 mips_fix_hi16_s (abfd, reloc_entry, symbol, data, input_section,
00254 output_bfd, error_message)
00255 bfd *abfd ATTRIBUTE_UNUSED;
00256 arelent *reloc_entry;
00257 asymbol *symbol;
00258 PTR data ATTRIBUTE_UNUSED;
00259 asection *input_section ATTRIBUTE_UNUSED;
00260 bfd *output_bfd;
00261 char **error_message ATTRIBUTE_UNUSED;
00262 {
00263 bfd_vma relocation;
00264
00265
00266 if (output_bfd != (bfd *)NULL)
00267 return bfd_reloc_continue;
00268
00269
00270 if (bfd_is_und_section (symbol->section)
00271 && (symbol->flags & BSF_WEAK) == 0)
00272 return bfd_reloc_undefined;
00273
00274
00275
00276 if (bfd_is_com_section (symbol->section))
00277 relocation = 0;
00278 else
00279 relocation = symbol->value;
00280
00281 relocation += symbol->section->output_section->vma;
00282 relocation += symbol->section->output_offset;
00283 relocation += reloc_entry->addend;
00284
00285 if (relocation & 0x8000)
00286 reloc_entry->addend += 0x10000;
00287
00288 return bfd_reloc_continue;
00289 }
00290
00291 static reloc_howto_type mips_howto_table_ext[] = {
00292 {MIPS_RELOC_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0,
00293 "32", FALSE, 0, 0xffffffff, FALSE},
00294 {MIPS_RELOC_JMP, 2, 2, 26, FALSE, 0, complain_overflow_dont,
00295 mips_fix_jmp_addr,
00296 "MIPS_JMP", FALSE, 0, 0x03ffffff, FALSE},
00297 {MIPS_RELOC_WDISP16, 2, 2, 16, TRUE, 0, complain_overflow_signed, 0,
00298 "WDISP16", FALSE, 0, 0x0000ffff, FALSE},
00299 {MIPS_RELOC_HI16, 16, 2, 16, FALSE, 0, complain_overflow_bitfield, 0,
00300 "HI16", FALSE, 0, 0x0000ffff, FALSE},
00301 {MIPS_RELOC_HI16_S, 16, 2, 16, FALSE, 0, complain_overflow_bitfield,
00302 mips_fix_hi16_s,
00303 "HI16_S", FALSE, 0, 0x0000ffff, FALSE},
00304 {MIPS_RELOC_LO16, 0, 2, 16, FALSE, 0, complain_overflow_dont, 0,
00305 "LO16", FALSE, 0, 0x0000ffff, FALSE},
00306 };
00307
00308 static reloc_howto_type *
00309 MY(reloc_howto_type_lookup) (abfd, code)
00310 bfd *abfd;
00311 bfd_reloc_code_real_type code;
00312 {
00313
00314 if (bfd_get_arch (abfd) != bfd_arch_mips)
00315 return 0;
00316
00317 switch (code)
00318 {
00319 case BFD_RELOC_CTOR:
00320 case BFD_RELOC_32:
00321 return (&mips_howto_table_ext[MIPS_RELOC_32]);
00322 case BFD_RELOC_MIPS_JMP:
00323 return (&mips_howto_table_ext[MIPS_RELOC_JMP]);
00324 case BFD_RELOC_16_PCREL_S2:
00325 return (&mips_howto_table_ext[MIPS_RELOC_WDISP16]);
00326 case BFD_RELOC_HI16:
00327 return (&mips_howto_table_ext[MIPS_RELOC_HI16]);
00328 case BFD_RELOC_HI16_S:
00329 return (&mips_howto_table_ext[MIPS_RELOC_HI16_S]);
00330 case BFD_RELOC_LO16:
00331 return (&mips_howto_table_ext[MIPS_RELOC_LO16]);
00332 default:
00333 return 0;
00334 }
00335 }
00336
00337
00338
00339 long
00340 MY(canonicalize_reloc) (abfd, section, relptr, symbols)
00341 bfd *abfd;
00342 sec_ptr section;
00343 arelent **relptr;
00344 asymbol **symbols;
00345 {
00346 arelent *tblptr = section->relocation;
00347 unsigned int count, c;
00348 extern reloc_howto_type NAME(aout,ext_howto_table)[];
00349
00350
00351 if (section->flags & SEC_CONSTRUCTOR)
00352 {
00353 arelent_chain *chain = section->constructor_chain;
00354
00355 for (count = 0; count < section->reloc_count; count++)
00356 {
00357 *relptr++ = &chain->relent;
00358 chain = chain->next;
00359 }
00360 *relptr = 0;
00361 return section->reloc_count;
00362 }
00363
00364 if (tblptr && section->reloc_count)
00365 {
00366 for (count = 0; count++ < section->reloc_count;)
00367 *relptr++ = tblptr++;
00368 *relptr = 0;
00369 return section->reloc_count;
00370 }
00371
00372 if (!NAME(aout,slurp_reloc_table) (abfd, section, symbols))
00373 return -1;
00374 tblptr = section->relocation;
00375
00376
00377 for (count = 0; count++ < section->reloc_count;)
00378 {
00379 c = tblptr->howto - NAME(aout,ext_howto_table);
00380 tblptr->howto = &mips_howto_table_ext[c];
00381
00382 *relptr++ = tblptr++;
00383 }
00384 *relptr = 0;
00385 return section->reloc_count;
00386 }
00387
00388 static const struct aout_backend_data MY(backend_data) = {
00389 0,
00390 1,
00391 0,
00392 0,
00393 TARGET_PAGE_SIZE,
00394 MY_set_sizes,
00395 0,
00396 0,
00397 0,
00398 0,
00399 0,
00400 0,
00401 0
00402 };
00403
00404 extern const bfd_target aout_mips_big_vec;
00405
00406 const bfd_target aout_mips_little_vec =
00407 {
00408 "a.out-mips-little",
00409 bfd_target_aout_flavour,
00410 BFD_ENDIAN_LITTLE,
00411 BFD_ENDIAN_LITTLE,
00412 (HAS_RELOC | EXEC_P |
00413 HAS_LINENO | HAS_DEBUG |
00414 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
00415 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
00416 MY_symbol_leading_char,
00417 ' ',
00418 15,
00419 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
00420 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
00421 bfd_getl16, bfd_getl_signed_16, bfd_putl16,
00422 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
00423 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
00424 bfd_getl16, bfd_getl_signed_16, bfd_putl16,
00425 {_bfd_dummy_target, MY_object_p,
00426 bfd_generic_archive_p, MY_core_file_p},
00427 {bfd_false, MY_mkobject,
00428 _bfd_generic_mkarchive, bfd_false},
00429 {bfd_false, MY_write_object_contents,
00430 _bfd_write_archive_contents, bfd_false},
00431
00432 BFD_JUMP_TABLE_GENERIC (MY),
00433 BFD_JUMP_TABLE_COPY (MY),
00434 BFD_JUMP_TABLE_CORE (MY),
00435 BFD_JUMP_TABLE_ARCHIVE (MY),
00436 BFD_JUMP_TABLE_SYMBOLS (MY),
00437 BFD_JUMP_TABLE_RELOCS (MY),
00438 BFD_JUMP_TABLE_WRITE (MY),
00439 BFD_JUMP_TABLE_LINK (MY),
00440 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
00441
00442 & aout_mips_big_vec,
00443
00444 (PTR) MY_backend_data
00445 };
00446
00447 const bfd_target aout_mips_big_vec =
00448 {
00449 "a.out-mips-big",
00450 bfd_target_aout_flavour,
00451 BFD_ENDIAN_BIG,
00452 BFD_ENDIAN_BIG,
00453 (HAS_RELOC | EXEC_P |
00454 HAS_LINENO | HAS_DEBUG |
00455 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
00456 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
00457 MY_symbol_leading_char,
00458 ' ',
00459 15,
00460 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
00461 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
00462 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
00463 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
00464 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
00465 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
00466 {_bfd_dummy_target, MY_object_p,
00467 bfd_generic_archive_p, MY_core_file_p},
00468 {bfd_false, MY_mkobject,
00469 _bfd_generic_mkarchive, bfd_false},
00470 {bfd_false, MY_write_object_contents,
00471 _bfd_write_archive_contents, bfd_false},
00472
00473 BFD_JUMP_TABLE_GENERIC (MY),
00474 BFD_JUMP_TABLE_COPY (MY),
00475 BFD_JUMP_TABLE_CORE (MY),
00476 BFD_JUMP_TABLE_ARCHIVE (MY),
00477 BFD_JUMP_TABLE_SYMBOLS (MY),
00478 BFD_JUMP_TABLE_RELOCS (MY),
00479 BFD_JUMP_TABLE_WRITE (MY),
00480 BFD_JUMP_TABLE_LINK (MY),
00481 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
00482
00483 & aout_mips_little_vec,
00484
00485 (PTR) MY_backend_data
00486 };