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
00026 #include "bfd.h"
00027 #include "aout/aout64.h"
00028 #include "ns32k.h"
00029
00030
00031
00032
00033 #define MYNS(OP) CONCAT2 (ns32kaout_,OP)
00034
00035 reloc_howto_type *
00036 MYNS(bfd_reloc_type_lookup)
00037 PARAMS((bfd *abfd AND
00038 bfd_reloc_code_real_type code));
00039
00040 bfd_boolean
00041 MYNS(write_object_contents)
00042 PARAMS((bfd *abfd));
00043
00044
00045
00046 #define NAME(x,y) CONCAT3 (ns32kaout,_32_,y)
00047
00048 void bfd_ns32k_arch PARAMS ((void));
00049
00050 #include "libaout.h"
00051
00052 #define MY(OP) MYNS(OP)
00053
00054 #define MY_swap_std_reloc_in MY(swap_std_reloc_in)
00055 #define MY_swap_std_reloc_out MY(swap_std_reloc_out)
00056
00057 static void
00058 MY_swap_std_reloc_in PARAMS ((bfd *, struct reloc_std_external *,
00059 arelent *, asymbol **,
00060 bfd_size_type));
00061 static void
00062 MY_swap_std_reloc_out PARAMS ((bfd *, arelent *,
00063 struct reloc_std_external *));
00064 reloc_howto_type *
00065 MY(reloc_howto) PARAMS ((bfd *, struct reloc_std_external *,
00066 int *, int *, int *));
00067 void
00068 MY(put_reloc) PARAMS ((bfd *, int, int, bfd_vma, reloc_howto_type *,
00069 struct reloc_std_external *));
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 reloc_howto_type MY(howto_table)[] =
00102 {
00103
00104
00105 HOWTO (BFD_RELOC_NS32K_IMM_8, 0, 0, 8, FALSE, 0, complain_overflow_signed,
00106 _bfd_ns32k_reloc_imm, "NS32K_IMM_8",
00107 TRUE, 0x000000ff,0x000000ff, FALSE),
00108 HOWTO (BFD_RELOC_NS32K_IMM_16, 0, 1, 16, FALSE, 0, complain_overflow_signed,
00109 _bfd_ns32k_reloc_imm, "NS32K_IMM_16",
00110 TRUE, 0x0000ffff,0x0000ffff, FALSE),
00111 HOWTO (BFD_RELOC_NS32K_IMM_32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
00112 _bfd_ns32k_reloc_imm, "NS32K_IMM_32",
00113 TRUE, 0xffffffff,0xffffffff, FALSE),
00114 HOWTO (BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, TRUE, 0, complain_overflow_signed,
00115 _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_8",
00116 TRUE, 0x000000ff, 0x000000ff, FALSE),
00117 HOWTO (BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, TRUE, 0, complain_overflow_signed,
00118 _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_16",
00119 TRUE, 0x0000ffff,0x0000ffff, FALSE),
00120 HOWTO (BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, TRUE, 0, complain_overflow_signed,
00121 _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_32",
00122 TRUE, 0xffffffff,0xffffffff, FALSE),
00123
00124
00125 HOWTO (BFD_RELOC_NS32K_DISP_8, 0, 0, 7, FALSE, 0, complain_overflow_signed,
00126 _bfd_ns32k_reloc_disp, "NS32K_DISP_8",
00127 TRUE, 0x000000ff,0x000000ff, FALSE),
00128 HOWTO (BFD_RELOC_NS32K_DISP_16, 0, 1, 14, FALSE, 0, complain_overflow_signed,
00129 _bfd_ns32k_reloc_disp, "NS32K_DISP_16",
00130 TRUE, 0x0000ffff, 0x0000ffff, FALSE),
00131 HOWTO (BFD_RELOC_NS32K_DISP_32, 0, 2, 30, FALSE, 0, complain_overflow_signed,
00132 _bfd_ns32k_reloc_disp, "NS32K_DISP_32",
00133 TRUE, 0xffffffff, 0xffffffff, FALSE),
00134 HOWTO (BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 7, TRUE, 0, complain_overflow_signed,
00135 _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_8",
00136 TRUE, 0x000000ff,0x000000ff, FALSE),
00137 HOWTO (BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 14, TRUE, 0, complain_overflow_signed,
00138 _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_16",
00139 TRUE, 0x0000ffff,0x0000ffff, FALSE),
00140 HOWTO (BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 30, TRUE, 0, complain_overflow_signed,
00141 _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_32",
00142 TRUE, 0xffffffff,0xffffffff, FALSE),
00143
00144
00145 HOWTO (BFD_RELOC_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,0,
00146 "8", TRUE, 0x000000ff,0x000000ff, FALSE),
00147 HOWTO (BFD_RELOC_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,0,
00148 "16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
00149 HOWTO (BFD_RELOC_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,0,
00150 "32", TRUE, 0xffffffff,0xffffffff, FALSE),
00151 HOWTO (BFD_RELOC_8_PCREL, 0, 0, 8, TRUE, 0, complain_overflow_signed, 0,
00152 "PCREL_8", TRUE, 0x000000ff,0x000000ff, FALSE),
00153 HOWTO (BFD_RELOC_16_PCREL, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0,
00154 "PCREL_16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
00155 HOWTO (BFD_RELOC_32_PCREL, 0, 2, 32, TRUE, 0, complain_overflow_signed, 0,
00156 "PCREL_32", TRUE, 0xffffffff,0xffffffff, FALSE),
00157 };
00158
00159 #define CTOR_TABLE_RELOC_HOWTO(BFD) (MY(howto_table) + 14)
00160
00161 #define RELOC_STD_BITS_NS32K_TYPE_BIG 0x06
00162 #define RELOC_STD_BITS_NS32K_TYPE_LITTLE 0x60
00163 #define RELOC_STD_BITS_NS32K_TYPE_SH_BIG 1
00164 #define RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE 5
00165
00166 reloc_howto_type *
00167 MY(reloc_howto) (abfd, rel, r_index, r_extern, r_pcrel)
00168 bfd *abfd ATTRIBUTE_UNUSED;
00169 struct reloc_std_external *rel;
00170 int *r_index;
00171 int *r_extern;
00172 int *r_pcrel;
00173 {
00174 unsigned int r_length;
00175 int r_ns32k_type;
00176
00177
00178 *r_index = ((rel->r_index[2] << 16)
00179 | (rel->r_index[1] << 8)
00180 | rel->r_index[0] );
00181 *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
00182 *r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
00183 r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
00184 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
00185 r_ns32k_type = ((rel->r_type[0] & RELOC_STD_BITS_NS32K_TYPE_LITTLE)
00186 >> RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE);
00187 return (MY(howto_table) + r_length + 3 * (*r_pcrel) + 6 * r_ns32k_type);
00188 }
00189
00190 #define MY_reloc_howto(BFD, REL, IN, EX, PC) \
00191 MY(reloc_howto) (BFD, REL, &IN, &EX, &PC)
00192
00193 void
00194 MY(put_reloc) (abfd, r_extern, r_index, value, howto, reloc)
00195 bfd *abfd;
00196 int r_extern;
00197 int r_index;
00198 bfd_vma value;
00199 reloc_howto_type *howto;
00200 struct reloc_std_external *reloc;
00201 {
00202 unsigned int r_length;
00203 int r_pcrel;
00204 int r_ns32k_type;
00205
00206 PUT_WORD (abfd, value, reloc->r_address);
00207 r_length = howto->size ;
00208 r_pcrel = (int) howto->pc_relative;
00209 r_ns32k_type = (howto - MY(howto_table) )/6;
00210
00211
00212 reloc->r_index[2] = r_index >> 16;
00213 reloc->r_index[1] = r_index >> 8;
00214 reloc->r_index[0] = r_index;
00215 reloc->r_type[0] =
00216 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
00217 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
00218 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)
00219 | (r_ns32k_type << RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE);
00220 }
00221
00222 #define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \
00223 MY(put_reloc) (BFD, EXT, IDX, VAL, HOWTO, RELOC)
00224
00225 #define STAT_FOR_EXEC
00226
00227 #define MY_final_link_relocate _bfd_ns32k_final_link_relocate
00228 #define MY_relocate_contents _bfd_ns32k_relocate_contents
00229
00230 #include "aoutx.h"
00231
00232 reloc_howto_type *
00233 MY(bfd_reloc_type_lookup) (abfd,code)
00234 bfd *abfd;
00235 bfd_reloc_code_real_type code;
00236 {
00237
00238 #define ENTRY(i,j) case i: return &MY(howto_table)[j]
00239
00240 int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
00241
00242 BFD_ASSERT(ext == 0);
00243 if (code == BFD_RELOC_CTOR)
00244 switch (bfd_get_arch_info (abfd)->bits_per_address)
00245 {
00246 case 32:
00247 code = BFD_RELOC_32;
00248 break;
00249 default:
00250 break;
00251 }
00252 switch (code)
00253 {
00254 ENTRY(BFD_RELOC_NS32K_IMM_8, 0);
00255 ENTRY(BFD_RELOC_NS32K_IMM_16, 1);
00256 ENTRY(BFD_RELOC_NS32K_IMM_32, 2);
00257 ENTRY(BFD_RELOC_NS32K_IMM_8_PCREL, 3);
00258 ENTRY(BFD_RELOC_NS32K_IMM_16_PCREL, 4);
00259 ENTRY(BFD_RELOC_NS32K_IMM_32_PCREL, 5);
00260 ENTRY(BFD_RELOC_NS32K_DISP_8, 6);
00261 ENTRY(BFD_RELOC_NS32K_DISP_16, 7);
00262 ENTRY(BFD_RELOC_NS32K_DISP_32, 8);
00263 ENTRY(BFD_RELOC_NS32K_DISP_8_PCREL, 9);
00264 ENTRY(BFD_RELOC_NS32K_DISP_16_PCREL, 10);
00265 ENTRY(BFD_RELOC_NS32K_DISP_32_PCREL, 11);
00266 ENTRY(BFD_RELOC_8, 12);
00267 ENTRY(BFD_RELOC_16, 13);
00268 ENTRY(BFD_RELOC_32, 14);
00269 ENTRY(BFD_RELOC_8_PCREL, 15);
00270 ENTRY(BFD_RELOC_16_PCREL, 16);
00271 ENTRY(BFD_RELOC_32_PCREL, 17);
00272 default:
00273 return (reloc_howto_type *) NULL;
00274 }
00275 #undef ENTRY
00276 }
00277
00278 static void
00279 MY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols, symcount)
00280 bfd *abfd;
00281 struct reloc_std_external *bytes;
00282 arelent *cache_ptr;
00283 asymbol **symbols;
00284 bfd_size_type symcount ATTRIBUTE_UNUSED;
00285 {
00286 int r_index;
00287 int r_extern;
00288 int r_pcrel;
00289 struct aoutdata *su = &(abfd->tdata.aout_data->a);
00290
00291 cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
00292
00293
00294 cache_ptr->howto = MY_reloc_howto(abfd, bytes, r_index, r_extern, r_pcrel);
00295
00296 MOVE_ADDRESS (0);
00297 }
00298
00299 static void
00300 MY_swap_std_reloc_out (abfd, g, natptr)
00301 bfd *abfd;
00302 arelent *g;
00303 struct reloc_std_external *natptr;
00304 {
00305 int r_index;
00306 asymbol *sym = *(g->sym_ptr_ptr);
00307 int r_extern;
00308 unsigned int r_addend;
00309 asection *output_section = sym->section->output_section;
00310
00311 r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 if (bfd_is_com_section (output_section)
00322 || output_section == &bfd_abs_section
00323 || output_section == &bfd_und_section)
00324 {
00325 if (bfd_abs_section.symbol == sym)
00326 {
00327
00328
00329 r_index = 0;
00330 r_extern = 0;
00331 }
00332 else
00333 {
00334
00335 r_extern = 1;
00336 #undef KEEPIT
00337 #define KEEPIT udata.i
00338 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
00339 #undef KEEPIT
00340 }
00341 }
00342 else
00343 {
00344
00345 r_extern = 0;
00346 r_index = output_section->target_index;
00347 }
00348
00349 MY_put_reloc (abfd, r_extern, r_index, g->address, g->howto, natptr);
00350 }
00351
00352 bfd_reloc_status_type
00353 _bfd_ns32k_relocate_contents (howto, input_bfd, relocation, location)
00354 reloc_howto_type *howto;
00355 bfd *input_bfd;
00356 bfd_vma relocation;
00357 bfd_byte *location;
00358 {
00359 int r_ns32k_type = (howto - MY(howto_table)) / 6;
00360 bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
00361 void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
00362
00363 switch (r_ns32k_type)
00364 {
00365 case 0:
00366 get_data = _bfd_ns32k_get_immediate;
00367 put_data = _bfd_ns32k_put_immediate;
00368 break;
00369 case 1:
00370 get_data = _bfd_ns32k_get_displacement;
00371 put_data = _bfd_ns32k_put_displacement;
00372 break;
00373 case 2:
00374 return _bfd_relocate_contents (howto, input_bfd, relocation,
00375 location);
00376
00377 break;
00378 default:
00379 return bfd_reloc_notsupported;
00380 }
00381 return _bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation,
00382 location, get_data, put_data);
00383 }