160484Sobrien/* BFD back-end for raw ARM a.out binaries. 2218822Sdim Copyright 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 3218822Sdim 2007 Free Software Foundation, Inc. 460484Sobrien Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) 577298Sobrien 6218822Sdim This file is part of BFD, the Binary File Descriptor library. 760484Sobrien 8218822Sdim This program is free software; you can redistribute it and/or modify 9218822Sdim it under the terms of the GNU General Public License as published by 10218822Sdim the Free Software Foundation; either version 2 of the License, or 11218822Sdim (at your option) any later version. 1260484Sobrien 13218822Sdim This program is distributed in the hope that it will be useful, 14218822Sdim but WITHOUT ANY WARRANTY; without even the implied warranty of 15218822Sdim MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16218822Sdim GNU General Public License for more details. 1760484Sobrien 18218822Sdim You should have received a copy of the GNU General Public License 19218822Sdim along with this program; if not, write to the Free Software 20218822Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2160484Sobrien 22218822Sdim#include "sysdep.h" 2389857Sobrien#include "bfd.h" 2460484Sobrien 25130561Sobrien/* Avoid multiple definitions from aoutx if supporting standard a.out 2689857Sobrien as well as our own. */ 2789857Sobrien/* Do not "beautify" the CONCAT* macro args. Traditional C will not 2889857Sobrien remove whitespace added here, and thus will fail to concatenate 2989857Sobrien the tokens. */ 3089857Sobrien#define NAME(x,y) CONCAT3 (aoutarm,_32_,y) 3189857Sobrien 3289857Sobrien#define N_TXTADDR(x) \ 3389857Sobrien ((N_MAGIC (x) == NMAGIC) \ 3489857Sobrien ? (bfd_vma) 0x8000 \ 3589857Sobrien : ((N_MAGIC (x) != ZMAGIC) \ 3689857Sobrien ? (bfd_vma) 0 \ 3789857Sobrien : ((N_SHARED_LIB (x)) \ 3889857Sobrien ? ((x).a_entry & ~(bfd_vma) (TARGET_PAGE_SIZE - 1)) \ 3989857Sobrien : (bfd_vma) TEXT_START_ADDR))) 4089857Sobrien 4160484Sobrien#define TEXT_START_ADDR 0x8000 4260484Sobrien#define TARGET_PAGE_SIZE 0x8000 4360484Sobrien#define SEGMENT_SIZE TARGET_PAGE_SIZE 4460484Sobrien#define DEFAULT_ARCH bfd_arch_arm 4560484Sobrien 4689857Sobrien#define MY(OP) CONCAT2 (aoutarm_,OP) 4760484Sobrien#define N_BADMAG(x) ((((x).a_info & ~007200) != ZMAGIC) && \ 4860484Sobrien (((x).a_info & ~006000) != OMAGIC) && \ 4960484Sobrien ((x).a_info != NMAGIC)) 5060484Sobrien#define N_MAGIC(x) ((x).a_info & ~07200) 5160484Sobrien 5260484Sobrien#define MY_bfd_reloc_type_lookup aoutarm_bfd_reloc_type_lookup 53218822Sdim#define MY_bfd_reloc_name_lookup aoutarm_bfd_reloc_name_lookup 5460484Sobrien 5560484Sobrien#include "libaout.h" 5660484Sobrien#include "aout/aout64.h" 5760484Sobrien 5889857Sobrien 59218822Sdimstatic bfd_reloc_status_type 60218822Sdim MY (fix_pcrel_26) (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 61218822Sdimstatic bfd_reloc_status_type 62218822Sdim MY (fix_pcrel_26_done) (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 6360484Sobrien 64218822Sdimreloc_howto_type MY (howto_table)[] = 65218822Sdim{ 66218822Sdim /* Type rs size bsz pcrel bitpos ovrf sf name part_inpl 67218822Sdim readmask setmask pcdone. */ 68218822Sdim HOWTO (0, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "8", TRUE, 69218822Sdim 0x000000ff, 0x000000ff, FALSE), 70218822Sdim HOWTO (1, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, 0, "16", TRUE, 71218822Sdim 0x0000ffff, 0x0000ffff, FALSE), 72218822Sdim HOWTO (2, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "32", TRUE, 73218822Sdim 0xffffffff, 0xffffffff, FALSE), 74218822Sdim HOWTO (3, 2, 2, 26, TRUE, 0, complain_overflow_signed, MY (fix_pcrel_26), 75218822Sdim "ARM26", TRUE, 0x00ffffff, 0x00ffffff, TRUE), 76218822Sdim HOWTO (4, 0, 0, 8, TRUE, 0, complain_overflow_signed, 0, "DISP8", TRUE, 77218822Sdim 0x000000ff, 0x000000ff, TRUE), 78218822Sdim HOWTO (5, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0, "DISP16", TRUE, 79218822Sdim 0x0000ffff, 0x0000ffff, TRUE), 80218822Sdim HOWTO (6, 0, 2, 32, TRUE, 0, complain_overflow_signed, 0, "DISP32", TRUE, 81218822Sdim 0xffffffff, 0xffffffff, TRUE), 82218822Sdim HOWTO (7, 2, 2, 26, FALSE, 0, complain_overflow_signed, 83218822Sdim MY (fix_pcrel_26_done), "ARM26D", TRUE, 0x0, 0x0, 84218822Sdim FALSE), 85218822Sdim EMPTY_HOWTO (-1), 86218822Sdim HOWTO (9, 0, -1, 16, FALSE, 0, complain_overflow_bitfield, 0, "NEG16", TRUE, 87218822Sdim 0x0000ffff, 0x0000ffff, FALSE), 88218822Sdim HOWTO (10, 0, -2, 32, FALSE, 0, complain_overflow_bitfield, 0, "NEG32", TRUE, 89218822Sdim 0xffffffff, 0xffffffff, FALSE) 90218822Sdim}; 91218822Sdim 9260484Sobrien#define RELOC_ARM_BITS_NEG_BIG ((unsigned int) 0x08) 9360484Sobrien#define RELOC_ARM_BITS_NEG_LITTLE ((unsigned int) 0x10) 9460484Sobrien 95218822Sdimstatic reloc_howto_type * 96218822SdimMY (reloc_howto) (bfd *abfd, 97218822Sdim struct reloc_std_external *rel, 98218822Sdim int *r_index, 99218822Sdim int *r_extern, 100218822Sdim int *r_pcrel) 10160484Sobrien{ 10260484Sobrien unsigned int r_length; 10360484Sobrien unsigned int r_pcrel_done; 10460484Sobrien unsigned int r_neg; 10560484Sobrien int index; 10660484Sobrien 10760484Sobrien *r_pcrel = 0; 10860484Sobrien if (bfd_header_big_endian (abfd)) 10960484Sobrien { 11060484Sobrien *r_index = ((rel->r_index[0] << 16) 11160484Sobrien | (rel->r_index[1] << 8) 11260484Sobrien | rel->r_index[2]); 11360484Sobrien *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); 11460484Sobrien r_pcrel_done = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG)); 11560484Sobrien r_neg = (0 != (rel->r_type[0] & RELOC_ARM_BITS_NEG_BIG)); 11660484Sobrien r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) 11760484Sobrien >> RELOC_STD_BITS_LENGTH_SH_BIG); 11860484Sobrien } 11960484Sobrien else 12060484Sobrien { 12160484Sobrien *r_index = ((rel->r_index[2] << 16) 12260484Sobrien | (rel->r_index[1] << 8) 12360484Sobrien | rel->r_index[0]); 12460484Sobrien *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE)); 12560484Sobrien r_pcrel_done = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE)); 12660484Sobrien r_neg = (0 != (rel->r_type[0] & RELOC_ARM_BITS_NEG_LITTLE)); 12760484Sobrien r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) 12860484Sobrien >> RELOC_STD_BITS_LENGTH_SH_LITTLE); 12960484Sobrien } 13060484Sobrien index = r_length + 4 * r_pcrel_done + 8 * r_neg; 13160484Sobrien if (index == 3) 13260484Sobrien *r_pcrel = 1; 13360484Sobrien 134218822Sdim return MY (howto_table) + index; 13560484Sobrien} 13677298Sobrien 13760484Sobrien#define MY_reloc_howto(BFD, REL, IN, EX, PC) \ 138218822Sdim MY (reloc_howto) (BFD, REL, &IN, &EX, &PC) 13960484Sobrien 140218822Sdimstatic void 141218822SdimMY (put_reloc) (bfd *abfd, 142218822Sdim int r_extern, 143218822Sdim int r_index, 144218822Sdim bfd_vma value, 145218822Sdim reloc_howto_type *howto, 146218822Sdim struct reloc_std_external *reloc) 14760484Sobrien{ 14860484Sobrien unsigned int r_length; 14960484Sobrien int r_pcrel; 15060484Sobrien int r_neg; 15160484Sobrien 15260484Sobrien PUT_WORD (abfd, value, reloc->r_address); 15389857Sobrien /* Size as a power of two. */ 15489857Sobrien r_length = howto->size; 15560484Sobrien 15677298Sobrien /* Special case for branch relocations. */ 15760484Sobrien if (howto->type == 3 || howto->type == 7) 15860484Sobrien r_length = 3; 15960484Sobrien 16089857Sobrien r_pcrel = howto->type & 4; /* PC Relative done? */ 16189857Sobrien r_neg = howto->type & 8; /* Negative relocation. */ 16289857Sobrien 16360484Sobrien if (bfd_header_big_endian (abfd)) 16460484Sobrien { 16560484Sobrien reloc->r_index[0] = r_index >> 16; 16660484Sobrien reloc->r_index[1] = r_index >> 8; 16760484Sobrien reloc->r_index[2] = r_index; 16860484Sobrien reloc->r_type[0] = 16960484Sobrien ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0) 17060484Sobrien | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0) 17160484Sobrien | (r_neg ? RELOC_ARM_BITS_NEG_BIG : 0) 17260484Sobrien | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); 17360484Sobrien } 17460484Sobrien else 17560484Sobrien { 17660484Sobrien reloc->r_index[2] = r_index >> 16; 17760484Sobrien reloc->r_index[1] = r_index >> 8; 17860484Sobrien reloc->r_index[0] = r_index; 17960484Sobrien reloc->r_type[0] = 18060484Sobrien ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0) 18160484Sobrien | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0) 18260484Sobrien | (r_neg ? RELOC_ARM_BITS_NEG_LITTLE : 0) 18360484Sobrien | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); 18460484Sobrien } 18560484Sobrien} 18677298Sobrien 18760484Sobrien#define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \ 188218822Sdim MY (put_reloc) (BFD, EXT, IDX, VAL, HOWTO, RELOC) 18960484Sobrien 190218822Sdimstatic void 191218822SdimMY (relocatable_reloc) (reloc_howto_type *howto, 192218822Sdim bfd *abfd, 193218822Sdim struct reloc_std_external *reloc, 194218822Sdim bfd_vma *amount, 195218822Sdim bfd_vma r_addr) 19660484Sobrien{ 19760484Sobrien if (howto->type == 3) 19860484Sobrien { 19977298Sobrien if (reloc->r_type[0] 20060484Sobrien & (bfd_header_big_endian (abfd) 20160484Sobrien ? RELOC_STD_BITS_EXTERN_BIG : RELOC_STD_BITS_EXTERN_LITTLE)) 202218822Sdim /* The reloc is still external, so don't modify anything. */ 203218822Sdim *amount = 0; 20460484Sobrien else 20560484Sobrien { 20660484Sobrien *amount -= r_addr; 20760484Sobrien /* Change the r_pcrel value -- on the ARM, this bit is set once the 20860484Sobrien relocation is done. */ 20960484Sobrien if (bfd_header_big_endian (abfd)) 21060484Sobrien reloc->r_type[0] |= RELOC_STD_BITS_PCREL_BIG; 21160484Sobrien else 21260484Sobrien reloc->r_type[0] |= RELOC_STD_BITS_PCREL_LITTLE; 21360484Sobrien } 21460484Sobrien } 21560484Sobrien else if (howto->type == 7) 21660484Sobrien *amount = 0; 21760484Sobrien} 21860484Sobrien 21960484Sobrien#define MY_relocatable_reloc(HOW, BFD, REL, AMOUNT, ADDR) \ 220218822Sdim MY (relocatable_reloc) (HOW, BFD, REL, &(AMOUNT), ADDR) 22160484Sobrien 22260484Sobrienstatic bfd_reloc_status_type 223218822SdimMY (fix_pcrel_26_done) (bfd *abfd ATTRIBUTE_UNUSED, 224218822Sdim arelent *reloc_entry ATTRIBUTE_UNUSED, 225218822Sdim asymbol *symbol ATTRIBUTE_UNUSED, 226218822Sdim void * data ATTRIBUTE_UNUSED, 227218822Sdim asection *input_section ATTRIBUTE_UNUSED, 228218822Sdim bfd *output_bfd ATTRIBUTE_UNUSED, 229218822Sdim char **error_message ATTRIBUTE_UNUSED) 23060484Sobrien{ 23160484Sobrien /* This is dead simple at present. */ 23260484Sobrien return bfd_reloc_ok; 23360484Sobrien} 23460484Sobrien 23560484Sobrienstatic bfd_reloc_status_type 236218822SdimMY (fix_pcrel_26) (bfd *abfd, 237218822Sdim arelent *reloc_entry, 238218822Sdim asymbol *symbol, 239218822Sdim void * data, 240218822Sdim asection *input_section, 241218822Sdim bfd *output_bfd, 242218822Sdim char **error_message ATTRIBUTE_UNUSED) 24360484Sobrien{ 24460484Sobrien bfd_vma relocation; 24560484Sobrien bfd_size_type addr = reloc_entry->address; 24689857Sobrien bfd_vma target = bfd_get_32 (abfd, (bfd_byte *) data + addr); 24760484Sobrien bfd_reloc_status_type flag = bfd_reloc_ok; 24877298Sobrien 24989857Sobrien /* If this is an undefined symbol, return error. */ 25060484Sobrien if (symbol->section == &bfd_und_section 25160484Sobrien && (symbol->flags & BSF_WEAK) == 0) 25260484Sobrien return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined; 25360484Sobrien 25460484Sobrien /* If the sections are different, and we are doing a partial relocation, 25560484Sobrien just ignore it for now. */ 25660484Sobrien if (symbol->section->name != input_section->name 257218822Sdim && output_bfd != NULL) 25860484Sobrien return bfd_reloc_ok; 25960484Sobrien 26060484Sobrien relocation = (target & 0x00ffffff) << 2; 26189857Sobrien relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend. */ 26260484Sobrien relocation += symbol->value; 26360484Sobrien relocation += symbol->section->output_section->vma; 26460484Sobrien relocation += symbol->section->output_offset; 26560484Sobrien relocation += reloc_entry->addend; 26660484Sobrien relocation -= input_section->output_section->vma; 26760484Sobrien relocation -= input_section->output_offset; 26860484Sobrien relocation -= addr; 26960484Sobrien if (relocation & 3) 27060484Sobrien return bfd_reloc_overflow; 27160484Sobrien 27289857Sobrien /* Check for overflow. */ 27360484Sobrien if (relocation & 0x02000000) 27460484Sobrien { 27560484Sobrien if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff) 27660484Sobrien flag = bfd_reloc_overflow; 27760484Sobrien } 27889857Sobrien else if (relocation & ~ (bfd_vma) 0x03ffffff) 27960484Sobrien flag = bfd_reloc_overflow; 28060484Sobrien 28189857Sobrien target &= ~ (bfd_vma) 0x00ffffff; 28260484Sobrien target |= (relocation >> 2) & 0x00ffffff; 28360484Sobrien bfd_put_32 (abfd, target, (bfd_byte *) data + addr); 28460484Sobrien 28560484Sobrien /* Now the ARM magic... Change the reloc type so that it is marked as done. 28660484Sobrien Strictly this is only necessary if we are doing a partial relocation. */ 287218822Sdim reloc_entry->howto = &MY (howto_table)[7]; 28877298Sobrien 28960484Sobrien return flag; 29060484Sobrien} 29160484Sobrien 292218822Sdimstatic reloc_howto_type * 293218822SdimMY (bfd_reloc_type_lookup) (bfd *abfd, 294218822Sdim bfd_reloc_code_real_type code) 29560484Sobrien{ 296218822Sdim#define ASTD(i,j) case i: return & MY (howto_table)[j] 297218822Sdim 29860484Sobrien if (code == BFD_RELOC_CTOR) 29960484Sobrien switch (bfd_get_arch_info (abfd)->bits_per_address) 30060484Sobrien { 30160484Sobrien case 32: 30260484Sobrien code = BFD_RELOC_32; 30360484Sobrien break; 30489857Sobrien default: 305218822Sdim return NULL; 30660484Sobrien } 30760484Sobrien 30860484Sobrien switch (code) 30960484Sobrien { 31060484Sobrien ASTD (BFD_RELOC_16, 1); 31160484Sobrien ASTD (BFD_RELOC_32, 2); 31260484Sobrien ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3); 31360484Sobrien ASTD (BFD_RELOC_8_PCREL, 4); 31460484Sobrien ASTD (BFD_RELOC_16_PCREL, 5); 31560484Sobrien ASTD (BFD_RELOC_32_PCREL, 6); 31689857Sobrien default: 317218822Sdim return NULL; 31860484Sobrien } 31960484Sobrien} 32060484Sobrien 321218822Sdimstatic reloc_howto_type * 322218822SdimMY (bfd_reloc_name_lookup) (bfd *abfd ATTRIBUTE_UNUSED, 323218822Sdim const char *r_name) 324218822Sdim{ 325218822Sdim unsigned int i; 32660484Sobrien 327218822Sdim for (i = 0; 328218822Sdim i < sizeof (MY (howto_table)) / sizeof (MY (howto_table)[0]); 329218822Sdim i++) 330218822Sdim if (MY (howto_table)[i].name != NULL 331218822Sdim && strcasecmp (MY (howto_table)[i].name, r_name) == 0) 332218822Sdim return &MY (howto_table)[i]; 333218822Sdim 334218822Sdim return NULL; 335218822Sdim} 336218822Sdim 337218822Sdim#define MY_swap_std_reloc_in MY (swap_std_reloc_in) 338218822Sdim#define MY_swap_std_reloc_out MY (swap_std_reloc_out) 339218822Sdim#define MY_get_section_contents _bfd_generic_get_section_contents 340218822Sdim 341218822Sdimvoid MY_swap_std_reloc_in (bfd *, struct reloc_std_external *, arelent *, asymbol **, bfd_size_type); 342218822Sdimvoid MY_swap_std_reloc_out (bfd *, arelent *, struct reloc_std_external *); 343218822Sdim 34460484Sobrien#include "aoutx.h" 34560484Sobrien 346218822Sdimvoid 347218822SdimMY_swap_std_reloc_in (bfd *abfd, 348218822Sdim struct reloc_std_external *bytes, 349218822Sdim arelent *cache_ptr, 350218822Sdim asymbol **symbols, 351218822Sdim bfd_size_type symcount ATTRIBUTE_UNUSED) 35260484Sobrien{ 35360484Sobrien int r_index; 35460484Sobrien int r_extern; 35560484Sobrien int r_pcrel; 35660484Sobrien struct aoutdata *su = &(abfd->tdata.aout_data->a); 35760484Sobrien 35889857Sobrien cache_ptr->address = H_GET_32 (abfd, bytes->r_address); 35960484Sobrien 36060484Sobrien cache_ptr->howto = MY_reloc_howto (abfd, bytes, r_index, r_extern, r_pcrel); 36160484Sobrien 36260484Sobrien MOVE_ADDRESS (0); 36360484Sobrien} 36460484Sobrien 36560484Sobrienvoid 366218822SdimMY_swap_std_reloc_out (bfd *abfd, 367218822Sdim arelent *g, 368218822Sdim struct reloc_std_external *natptr) 36960484Sobrien{ 37060484Sobrien int r_index; 37160484Sobrien asymbol *sym = *(g->sym_ptr_ptr); 37260484Sobrien int r_extern; 37360484Sobrien int r_length; 37460484Sobrien int r_pcrel; 37560484Sobrien int r_neg = 0; /* Negative relocs use the BASEREL bit. */ 37660484Sobrien asection *output_section = sym->section->output_section; 37760484Sobrien 378218822Sdim PUT_WORD (abfd, g->address, natptr->r_address); 37960484Sobrien 380218822Sdim r_length = g->howto->size ; /* Size as a power of two. */ 38160484Sobrien if (r_length < 0) 38260484Sobrien { 38360484Sobrien r_length = -r_length; 38460484Sobrien r_neg = 1; 38560484Sobrien } 38660484Sobrien 387218822Sdim r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ 38860484Sobrien 38960484Sobrien /* For RISC iX, in pc-relative relocs the r_pcrel bit means that the 390218822Sdim relocation has been done already (Only for the 26-bit one I think). */ 39160484Sobrien if (g->howto->type == 3) 39260484Sobrien { 39360484Sobrien r_length = 3; 39460484Sobrien r_pcrel = 0; 39560484Sobrien } 39660484Sobrien else if (g->howto->type == 7) 39777298Sobrien { 39860484Sobrien r_length = 3; 39960484Sobrien r_pcrel = 1; 40060484Sobrien } 40160484Sobrien 402218822Sdim /* Name was clobbered by aout_write_syms to be symbol index. */ 40360484Sobrien 40460484Sobrien /* If this relocation is relative to a symbol then set the 40560484Sobrien r_index to the symbols index, and the r_extern bit. 40660484Sobrien 40760484Sobrien Absolute symbols can come in in two ways, either as an offset 40860484Sobrien from the abs section, or as a symbol which has an abs value. 409218822Sdim check for that here. */ 41060484Sobrien 41160484Sobrien if (bfd_is_com_section (output_section) 41260484Sobrien || output_section == &bfd_abs_section 41360484Sobrien || output_section == &bfd_und_section) 41460484Sobrien { 41560484Sobrien if (bfd_abs_section.symbol == sym) 41660484Sobrien { 41760484Sobrien /* Whoops, looked like an abs symbol, but is really an offset 41889857Sobrien from the abs section. */ 41960484Sobrien r_index = 0; 42060484Sobrien r_extern = 0; 42160484Sobrien } 42260484Sobrien else 42360484Sobrien { 42489857Sobrien /* Fill in symbol. */ 42560484Sobrien r_extern = 1; 42660484Sobrien r_index = (*(g->sym_ptr_ptr))->KEEPIT; 42760484Sobrien } 42860484Sobrien } 42960484Sobrien else 43060484Sobrien { 43189857Sobrien /* Just an ordinary section. */ 43260484Sobrien r_extern = 0; 43360484Sobrien r_index = output_section->target_index; 43460484Sobrien } 43560484Sobrien 43689857Sobrien /* Now the fun stuff. */ 43760484Sobrien if (bfd_header_big_endian (abfd)) 43860484Sobrien { 43960484Sobrien natptr->r_index[0] = r_index >> 16; 44060484Sobrien natptr->r_index[1] = r_index >> 8; 44160484Sobrien natptr->r_index[2] = r_index; 44260484Sobrien natptr->r_type[0] = 44360484Sobrien ( (r_extern ? RELOC_STD_BITS_EXTERN_BIG: 0) 44460484Sobrien | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG: 0) 44560484Sobrien | (r_neg ? RELOC_ARM_BITS_NEG_BIG: 0) 44660484Sobrien | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); 44760484Sobrien } 44860484Sobrien else 44960484Sobrien { 45060484Sobrien natptr->r_index[2] = r_index >> 16; 45160484Sobrien natptr->r_index[1] = r_index >> 8; 45260484Sobrien natptr->r_index[0] = r_index; 45360484Sobrien natptr->r_type[0] = 45460484Sobrien ( (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE: 0) 45560484Sobrien | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE: 0) 45660484Sobrien | (r_neg ? RELOC_ARM_BITS_NEG_LITTLE: 0) 45760484Sobrien | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); 45860484Sobrien } 45960484Sobrien} 46060484Sobrien 46160484Sobrien#define MY_BFD_TARGET 46260484Sobrien 46360484Sobrien#include "aout-target.h" 46460484Sobrien 46560484Sobrienextern const bfd_target aout_arm_big_vec; 46660484Sobrien 46760484Sobrienconst bfd_target aout_arm_little_vec = 468218822Sdim{ 469218822Sdim "a.out-arm-little", /* Name. */ 470218822Sdim bfd_target_aout_flavour, 471218822Sdim BFD_ENDIAN_LITTLE, /* Target byte order (little). */ 472218822Sdim BFD_ENDIAN_LITTLE, /* Target headers byte order (little). */ 473218822Sdim (HAS_RELOC | EXEC_P | /* Object flags. */ 474218822Sdim HAS_LINENO | HAS_DEBUG | 475218822Sdim HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), 476218822Sdim (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA), 477218822Sdim MY_symbol_leading_char, 478218822Sdim AR_PAD_CHAR, /* AR_pad_char. */ 479218822Sdim 15, /* AR_max_namelen. */ 480218822Sdim bfd_getl64, bfd_getl_signed_64, bfd_putl64, 481218822Sdim bfd_getl32, bfd_getl_signed_32, bfd_putl32, 482218822Sdim bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */ 483218822Sdim bfd_getl64, bfd_getl_signed_64, bfd_putl64, 484218822Sdim bfd_getl32, bfd_getl_signed_32, bfd_putl32, 485218822Sdim bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers. */ 486218822Sdim {_bfd_dummy_target, MY_object_p, /* bfd_check_format. */ 487218822Sdim bfd_generic_archive_p, MY_core_file_p}, 488218822Sdim {bfd_false, MY_mkobject, /* bfd_set_format. */ 489218822Sdim _bfd_generic_mkarchive, bfd_false}, 490218822Sdim {bfd_false, MY_write_object_contents, /* bfd_write_contents. */ 491218822Sdim _bfd_write_archive_contents, bfd_false}, 49260484Sobrien 493218822Sdim BFD_JUMP_TABLE_GENERIC (MY), 494218822Sdim BFD_JUMP_TABLE_COPY (MY), 495218822Sdim BFD_JUMP_TABLE_CORE (MY), 496218822Sdim BFD_JUMP_TABLE_ARCHIVE (MY), 497218822Sdim BFD_JUMP_TABLE_SYMBOLS (MY), 498218822Sdim BFD_JUMP_TABLE_RELOCS (MY), 499218822Sdim BFD_JUMP_TABLE_WRITE (MY), 500218822Sdim BFD_JUMP_TABLE_LINK (MY), 501218822Sdim BFD_JUMP_TABLE_DYNAMIC (MY), 50260484Sobrien 503218822Sdim & aout_arm_big_vec, 50477298Sobrien 505218822Sdim (void *) MY_backend_data, 506218822Sdim}; 50760484Sobrien 50860484Sobrienconst bfd_target aout_arm_big_vec = 509218822Sdim{ 510218822Sdim "a.out-arm-big", /* Name. */ 511218822Sdim bfd_target_aout_flavour, 512218822Sdim BFD_ENDIAN_BIG, /* Target byte order (big). */ 513218822Sdim BFD_ENDIAN_BIG, /* Target headers byte order (big). */ 514218822Sdim (HAS_RELOC | EXEC_P | /* Object flags. */ 515218822Sdim HAS_LINENO | HAS_DEBUG | 516218822Sdim HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), 517218822Sdim (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA), 518218822Sdim MY_symbol_leading_char, 519218822Sdim AR_PAD_CHAR, /* AR_pad_char. */ 520218822Sdim 15, /* AR_max_namelen. */ 521218822Sdim bfd_getb64, bfd_getb_signed_64, bfd_putb64, 522218822Sdim bfd_getb32, bfd_getb_signed_32, bfd_putb32, 523218822Sdim bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */ 524218822Sdim bfd_getb64, bfd_getb_signed_64, bfd_putb64, 525218822Sdim bfd_getb32, bfd_getb_signed_32, bfd_putb32, 526218822Sdim bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */ 527218822Sdim {_bfd_dummy_target, MY_object_p, /* bfd_check_format. */ 528218822Sdim bfd_generic_archive_p, MY_core_file_p}, 529218822Sdim {bfd_false, MY_mkobject, /* bfd_set_format. */ 530218822Sdim _bfd_generic_mkarchive, bfd_false}, 531218822Sdim {bfd_false, MY_write_object_contents, /* bfd_write_contents. */ 532218822Sdim _bfd_write_archive_contents, bfd_false}, 53360484Sobrien 534218822Sdim BFD_JUMP_TABLE_GENERIC (MY), 535218822Sdim BFD_JUMP_TABLE_COPY (MY), 536218822Sdim BFD_JUMP_TABLE_CORE (MY), 537218822Sdim BFD_JUMP_TABLE_ARCHIVE (MY), 538218822Sdim BFD_JUMP_TABLE_SYMBOLS (MY), 539218822Sdim BFD_JUMP_TABLE_RELOCS (MY), 540218822Sdim BFD_JUMP_TABLE_WRITE (MY), 541218822Sdim BFD_JUMP_TABLE_LINK (MY), 542218822Sdim BFD_JUMP_TABLE_DYNAMIC (MY), 54360484Sobrien 544218822Sdim & aout_arm_little_vec, 54577298Sobrien 546218822Sdim (void *) MY_backend_data, 547218822Sdim}; 548