aout-arm.c revision 130561
160484Sobrien/* BFD back-end for raw ARM a.out binaries. 2130561Sobrien Copyright 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002 378828Sobrien Free Software Foundation, Inc. 460484Sobrien Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) 577298Sobrien 660484SobrienThis file is part of BFD, the Binary File Descriptor library. 760484Sobrien 860484SobrienThis program is free software; you can redistribute it and/or modify 960484Sobrienit under the terms of the GNU General Public License as published by 1060484Sobrienthe Free Software Foundation; either version 2 of the License, or 1160484Sobrien(at your option) any later version. 1260484Sobrien 1360484SobrienThis program is distributed in the hope that it will be useful, 1460484Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of 1560484SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1660484SobrienGNU General Public License for more details. 1760484Sobrien 1860484SobrienYou should have received a copy of the GNU General Public License 1960484Sobrienalong with this program; if not, write to the Free Software 2060484SobrienFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 2160484Sobrien 2289857Sobrien#include "bfd.h" 2389857Sobrien#include "sysdep.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 5360484Sobrien 5460484Sobrien#include "libaout.h" 5560484Sobrien#include "aout/aout64.h" 5660484Sobrien 57130561Sobrienstatic bfd_boolean MY(write_object_contents) 5889857Sobrien PARAMS ((bfd *)); 5989857Sobrienstatic bfd_reloc_status_type MY(fix_pcrel_26_done) 6089857Sobrien PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); 6189857Sobrienstatic bfd_reloc_status_type MY(fix_pcrel_26) 6289857Sobrien PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); 6389857Sobrienstatic void MY(swap_std_reloc_in) 6489857Sobrien PARAMS ((bfd *, struct reloc_std_external *, arelent *, asymbol **, 6589857Sobrien bfd_size_type)); 6689857Sobrienreloc_howto_type *MY(bfd_reloc_type_lookup) 6789857Sobrien PARAMS ((bfd *, bfd_reloc_code_real_type)); 6889857Sobrienreloc_howto_type * MY(reloc_howto) 6989857Sobrien PARAMS ((bfd *, struct reloc_std_external *, int *, int *, int *)); 7089857Sobrienvoid MY(put_reloc) 7189857Sobrien PARAMS ((bfd *, int, int, bfd_vma, reloc_howto_type *, 7289857Sobrien struct reloc_std_external *)); 7389857Sobrienvoid MY(relocatable_reloc) 7489857Sobrien PARAMS ((reloc_howto_type *, bfd *, struct reloc_std_external *, bfd_vma *, 7589857Sobrien bfd_vma)); 7689857Sobrienvoid MY(swap_std_reloc_out) 7789857Sobrien PARAMS ((bfd *, arelent *, struct reloc_std_external *)); 7889857Sobrien 7960484Sobrienreloc_howto_type MY(howto_table)[] = 8089857Sobrien { 8189857Sobrien /* Type rs size bsz pcrel bitpos ovrf sf name part_inpl 8289857Sobrien readmask setmask pcdone. */ 83130561Sobrien HOWTO (0, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "8", TRUE, 84130561Sobrien 0x000000ff, 0x000000ff, FALSE), 85130561Sobrien HOWTO (1, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, 0, "16", TRUE, 86130561Sobrien 0x0000ffff, 0x0000ffff, FALSE), 87130561Sobrien HOWTO (2, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "32", TRUE, 88130561Sobrien 0xffffffff, 0xffffffff, FALSE), 89130561Sobrien HOWTO (3, 2, 2, 26, TRUE, 0, complain_overflow_signed, MY(fix_pcrel_26), 90130561Sobrien "ARM26", TRUE, 0x00ffffff, 0x00ffffff, TRUE), 91130561Sobrien HOWTO (4, 0, 0, 8, TRUE, 0, complain_overflow_signed, 0, "DISP8", TRUE, 92130561Sobrien 0x000000ff, 0x000000ff, TRUE), 93130561Sobrien HOWTO (5, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0, "DISP16", TRUE, 94130561Sobrien 0x0000ffff, 0x0000ffff, TRUE), 95130561Sobrien HOWTO (6, 0, 2, 32, TRUE, 0, complain_overflow_signed, 0, "DISP32", TRUE, 96130561Sobrien 0xffffffff, 0xffffffff, TRUE), 97130561Sobrien HOWTO (7, 2, 2, 26, FALSE, 0, complain_overflow_signed, 98130561Sobrien MY(fix_pcrel_26_done), "ARM26D", TRUE, 0x0, 0x0, 99130561Sobrien FALSE), 10089857Sobrien EMPTY_HOWTO (-1), 101130561Sobrien HOWTO (9, 0, -1, 16, FALSE, 0, complain_overflow_bitfield, 0, "NEG16", TRUE, 102130561Sobrien 0x0000ffff, 0x0000ffff, FALSE), 103130561Sobrien HOWTO (10, 0, -2, 32, FALSE, 0, complain_overflow_bitfield, 0, "NEG32", TRUE, 104130561Sobrien 0xffffffff, 0xffffffff, FALSE) 10589857Sobrien }; 10660484Sobrien 10760484Sobrien#define RELOC_ARM_BITS_NEG_BIG ((unsigned int) 0x08) 10860484Sobrien#define RELOC_ARM_BITS_NEG_LITTLE ((unsigned int) 0x10) 10960484Sobrien 11060484Sobrienreloc_howto_type * 11177298SobrienMY(reloc_howto) (abfd, rel, r_index, r_extern, r_pcrel) 11260484Sobrien bfd *abfd; 11360484Sobrien struct reloc_std_external *rel; 11460484Sobrien int *r_index; 11560484Sobrien int *r_extern; 11660484Sobrien int *r_pcrel; 11760484Sobrien{ 11860484Sobrien unsigned int r_length; 11960484Sobrien unsigned int r_pcrel_done; 12060484Sobrien unsigned int r_neg; 12160484Sobrien int index; 12260484Sobrien 12360484Sobrien *r_pcrel = 0; 12460484Sobrien if (bfd_header_big_endian (abfd)) 12560484Sobrien { 12660484Sobrien *r_index = ((rel->r_index[0] << 16) 12760484Sobrien | (rel->r_index[1] << 8) 12860484Sobrien | rel->r_index[2]); 12960484Sobrien *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); 13060484Sobrien r_pcrel_done = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG)); 13160484Sobrien r_neg = (0 != (rel->r_type[0] & RELOC_ARM_BITS_NEG_BIG)); 13260484Sobrien r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) 13360484Sobrien >> RELOC_STD_BITS_LENGTH_SH_BIG); 13460484Sobrien } 13560484Sobrien else 13660484Sobrien { 13760484Sobrien *r_index = ((rel->r_index[2] << 16) 13860484Sobrien | (rel->r_index[1] << 8) 13960484Sobrien | rel->r_index[0]); 14060484Sobrien *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE)); 14160484Sobrien r_pcrel_done = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE)); 14260484Sobrien r_neg = (0 != (rel->r_type[0] & RELOC_ARM_BITS_NEG_LITTLE)); 14360484Sobrien r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) 14460484Sobrien >> RELOC_STD_BITS_LENGTH_SH_LITTLE); 14560484Sobrien } 14660484Sobrien index = r_length + 4 * r_pcrel_done + 8 * r_neg; 14760484Sobrien if (index == 3) 14860484Sobrien *r_pcrel = 1; 14960484Sobrien 15060484Sobrien return MY(howto_table) + index; 15160484Sobrien} 15277298Sobrien 15360484Sobrien#define MY_reloc_howto(BFD, REL, IN, EX, PC) \ 15460484Sobrien MY(reloc_howto) (BFD, REL, &IN, &EX, &PC) 15560484Sobrien 15660484Sobrienvoid 15777298SobrienMY(put_reloc) (abfd, r_extern, r_index, value, howto, reloc) 15860484Sobrien bfd *abfd; 15960484Sobrien int r_extern; 16060484Sobrien int r_index; 16189857Sobrien bfd_vma value; 16260484Sobrien reloc_howto_type *howto; 16360484Sobrien struct reloc_std_external *reloc; 16460484Sobrien{ 16560484Sobrien unsigned int r_length; 16660484Sobrien int r_pcrel; 16760484Sobrien int r_neg; 16860484Sobrien 16960484Sobrien PUT_WORD (abfd, value, reloc->r_address); 17089857Sobrien /* Size as a power of two. */ 17189857Sobrien r_length = howto->size; 17260484Sobrien 17377298Sobrien /* Special case for branch relocations. */ 17460484Sobrien if (howto->type == 3 || howto->type == 7) 17560484Sobrien r_length = 3; 17660484Sobrien 17789857Sobrien r_pcrel = howto->type & 4; /* PC Relative done? */ 17889857Sobrien r_neg = howto->type & 8; /* Negative relocation. */ 17989857Sobrien 18060484Sobrien if (bfd_header_big_endian (abfd)) 18160484Sobrien { 18260484Sobrien reloc->r_index[0] = r_index >> 16; 18360484Sobrien reloc->r_index[1] = r_index >> 8; 18460484Sobrien reloc->r_index[2] = r_index; 18560484Sobrien reloc->r_type[0] = 18660484Sobrien ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0) 18760484Sobrien | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0) 18860484Sobrien | (r_neg ? RELOC_ARM_BITS_NEG_BIG : 0) 18960484Sobrien | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); 19060484Sobrien } 19160484Sobrien else 19260484Sobrien { 19360484Sobrien reloc->r_index[2] = r_index >> 16; 19460484Sobrien reloc->r_index[1] = r_index >> 8; 19560484Sobrien reloc->r_index[0] = r_index; 19660484Sobrien reloc->r_type[0] = 19760484Sobrien ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0) 19860484Sobrien | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0) 19960484Sobrien | (r_neg ? RELOC_ARM_BITS_NEG_LITTLE : 0) 20060484Sobrien | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); 20160484Sobrien } 20260484Sobrien} 20377298Sobrien 20460484Sobrien#define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \ 20577298Sobrien MY(put_reloc) (BFD, EXT, IDX, VAL, HOWTO, RELOC) 20660484Sobrien 20760484Sobrienvoid 20877298SobrienMY(relocatable_reloc) (howto, abfd, reloc, amount, r_addr) 20960484Sobrien reloc_howto_type *howto; 21060484Sobrien bfd *abfd; 21160484Sobrien struct reloc_std_external *reloc; 21260484Sobrien bfd_vma *amount; 21360484Sobrien bfd_vma r_addr; 21460484Sobrien{ 21560484Sobrien if (howto->type == 3) 21660484Sobrien { 21777298Sobrien if (reloc->r_type[0] 21860484Sobrien & (bfd_header_big_endian (abfd) 21960484Sobrien ? RELOC_STD_BITS_EXTERN_BIG : RELOC_STD_BITS_EXTERN_LITTLE)) 22060484Sobrien { 22177298Sobrien /* The reloc is still external, so don't modify anything. */ 22260484Sobrien *amount = 0; 22360484Sobrien } 22460484Sobrien else 22560484Sobrien { 22660484Sobrien *amount -= r_addr; 22760484Sobrien /* Change the r_pcrel value -- on the ARM, this bit is set once the 22860484Sobrien relocation is done. */ 22960484Sobrien if (bfd_header_big_endian (abfd)) 23060484Sobrien reloc->r_type[0] |= RELOC_STD_BITS_PCREL_BIG; 23160484Sobrien else 23260484Sobrien reloc->r_type[0] |= RELOC_STD_BITS_PCREL_LITTLE; 23360484Sobrien } 23460484Sobrien } 23560484Sobrien else if (howto->type == 7) 23660484Sobrien *amount = 0; 23760484Sobrien} 23860484Sobrien 23960484Sobrien#define MY_relocatable_reloc(HOW, BFD, REL, AMOUNT, ADDR) \ 24077298Sobrien MY(relocatable_reloc) (HOW, BFD, REL, &(AMOUNT), ADDR) 24160484Sobrien 24260484Sobrienstatic bfd_reloc_status_type 24360484SobrienMY(fix_pcrel_26_done) (abfd, reloc_entry, symbol, data, input_section, 24460484Sobrien output_bfd, error_message) 24560484Sobrien bfd *abfd ATTRIBUTE_UNUSED; 24660484Sobrien arelent *reloc_entry ATTRIBUTE_UNUSED; 24760484Sobrien asymbol *symbol ATTRIBUTE_UNUSED; 24860484Sobrien PTR data ATTRIBUTE_UNUSED; 24960484Sobrien asection *input_section ATTRIBUTE_UNUSED; 25060484Sobrien bfd *output_bfd ATTRIBUTE_UNUSED; 25160484Sobrien char **error_message ATTRIBUTE_UNUSED; 25260484Sobrien{ 25360484Sobrien /* This is dead simple at present. */ 25460484Sobrien return bfd_reloc_ok; 25560484Sobrien} 25660484Sobrien 25760484Sobrienstatic bfd_reloc_status_type 25860484SobrienMY(fix_pcrel_26) (abfd, reloc_entry, symbol, data, input_section, 25960484Sobrien output_bfd, error_message) 26060484Sobrien bfd *abfd; 26160484Sobrien arelent *reloc_entry; 26260484Sobrien asymbol *symbol; 26360484Sobrien PTR data; 26460484Sobrien asection *input_section; 26560484Sobrien bfd *output_bfd; 26660484Sobrien char **error_message ATTRIBUTE_UNUSED; 26760484Sobrien{ 26860484Sobrien bfd_vma relocation; 26960484Sobrien bfd_size_type addr = reloc_entry->address; 27089857Sobrien bfd_vma target = bfd_get_32 (abfd, (bfd_byte *) data + addr); 27160484Sobrien bfd_reloc_status_type flag = bfd_reloc_ok; 27277298Sobrien 27389857Sobrien /* If this is an undefined symbol, return error. */ 27460484Sobrien if (symbol->section == &bfd_und_section 27560484Sobrien && (symbol->flags & BSF_WEAK) == 0) 27660484Sobrien return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined; 27760484Sobrien 27860484Sobrien /* If the sections are different, and we are doing a partial relocation, 27960484Sobrien just ignore it for now. */ 28060484Sobrien if (symbol->section->name != input_section->name 28160484Sobrien && output_bfd != (bfd *)NULL) 28260484Sobrien return bfd_reloc_ok; 28360484Sobrien 28460484Sobrien relocation = (target & 0x00ffffff) << 2; 28589857Sobrien relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend. */ 28660484Sobrien relocation += symbol->value; 28760484Sobrien relocation += symbol->section->output_section->vma; 28860484Sobrien relocation += symbol->section->output_offset; 28960484Sobrien relocation += reloc_entry->addend; 29060484Sobrien relocation -= input_section->output_section->vma; 29160484Sobrien relocation -= input_section->output_offset; 29260484Sobrien relocation -= addr; 29360484Sobrien if (relocation & 3) 29460484Sobrien return bfd_reloc_overflow; 29560484Sobrien 29689857Sobrien /* Check for overflow. */ 29760484Sobrien if (relocation & 0x02000000) 29860484Sobrien { 29960484Sobrien if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff) 30060484Sobrien flag = bfd_reloc_overflow; 30160484Sobrien } 30289857Sobrien else if (relocation & ~ (bfd_vma) 0x03ffffff) 30360484Sobrien flag = bfd_reloc_overflow; 30460484Sobrien 30589857Sobrien target &= ~ (bfd_vma) 0x00ffffff; 30660484Sobrien target |= (relocation >> 2) & 0x00ffffff; 30760484Sobrien bfd_put_32 (abfd, target, (bfd_byte *) data + addr); 30860484Sobrien 30960484Sobrien /* Now the ARM magic... Change the reloc type so that it is marked as done. 31060484Sobrien Strictly this is only necessary if we are doing a partial relocation. */ 31160484Sobrien reloc_entry->howto = &MY(howto_table)[7]; 31277298Sobrien 31360484Sobrien return flag; 31460484Sobrien} 31560484Sobrien 31660484Sobrienreloc_howto_type * 31777298SobrienMY(bfd_reloc_type_lookup) (abfd,code) 31860484Sobrien bfd *abfd; 31960484Sobrien bfd_reloc_code_real_type code; 32060484Sobrien{ 32160484Sobrien#define ASTD(i,j) case i: return &MY(howto_table)[j] 32260484Sobrien if (code == BFD_RELOC_CTOR) 32360484Sobrien switch (bfd_get_arch_info (abfd)->bits_per_address) 32460484Sobrien { 32560484Sobrien case 32: 32660484Sobrien code = BFD_RELOC_32; 32760484Sobrien break; 32889857Sobrien default: 32989857Sobrien return (const struct reloc_howto_struct *) 0; 33060484Sobrien } 33160484Sobrien 33260484Sobrien switch (code) 33360484Sobrien { 33460484Sobrien ASTD (BFD_RELOC_16, 1); 33560484Sobrien ASTD (BFD_RELOC_32, 2); 33660484Sobrien ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3); 33760484Sobrien ASTD (BFD_RELOC_8_PCREL, 4); 33860484Sobrien ASTD (BFD_RELOC_16_PCREL, 5); 33960484Sobrien ASTD (BFD_RELOC_32_PCREL, 6); 34089857Sobrien default: 34189857Sobrien return (const struct reloc_howto_struct *) 0; 34260484Sobrien } 34360484Sobrien} 34460484Sobrien 34560484Sobrien#define MY_swap_std_reloc_in MY(swap_std_reloc_in) 34660484Sobrien#define MY_swap_std_reloc_out MY(swap_std_reloc_out) 34760484Sobrien#define MY_get_section_contents _bfd_generic_get_section_contents 34860484Sobrien/* #define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create */ 34960484Sobrien/* #define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols */ 35060484Sobrien/* #define MY_bfd_final_link _bfd_generic_final_link */ 35160484Sobrien 35260484Sobrien#include "aoutx.h" 35360484Sobrien 35460484Sobrienstatic void 35560484SobrienMY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols, symcount) 35660484Sobrien bfd *abfd; 35760484Sobrien struct reloc_std_external *bytes; 35860484Sobrien arelent *cache_ptr; 35960484Sobrien asymbol **symbols; 36060484Sobrien bfd_size_type symcount ATTRIBUTE_UNUSED; 36160484Sobrien{ 36260484Sobrien int r_index; 36360484Sobrien int r_extern; 36460484Sobrien int r_pcrel; 36560484Sobrien struct aoutdata *su = &(abfd->tdata.aout_data->a); 36660484Sobrien 36789857Sobrien cache_ptr->address = H_GET_32 (abfd, bytes->r_address); 36860484Sobrien 36960484Sobrien cache_ptr->howto = MY_reloc_howto (abfd, bytes, r_index, r_extern, r_pcrel); 37060484Sobrien 37160484Sobrien MOVE_ADDRESS (0); 37260484Sobrien} 37360484Sobrien 37460484Sobrienvoid 37560484SobrienMY_swap_std_reloc_out (abfd, g, natptr) 37660484Sobrien bfd *abfd; 37760484Sobrien arelent *g; 37860484Sobrien struct reloc_std_external *natptr; 37960484Sobrien{ 38060484Sobrien int r_index; 38160484Sobrien asymbol *sym = *(g->sym_ptr_ptr); 38260484Sobrien int r_extern; 38360484Sobrien int r_length; 38460484Sobrien int r_pcrel; 38560484Sobrien int r_neg = 0; /* Negative relocs use the BASEREL bit. */ 38660484Sobrien asection *output_section = sym->section->output_section; 38760484Sobrien 38860484Sobrien PUT_WORD(abfd, g->address, natptr->r_address); 38960484Sobrien 39060484Sobrien r_length = g->howto->size ; /* Size as a power of two */ 39160484Sobrien if (r_length < 0) 39260484Sobrien { 39360484Sobrien r_length = -r_length; 39460484Sobrien r_neg = 1; 39560484Sobrien } 39660484Sobrien 39760484Sobrien r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ 39860484Sobrien 39960484Sobrien /* For RISC iX, in pc-relative relocs the r_pcrel bit means that the 40060484Sobrien relocation has been done already (Only for the 26-bit one I think)???!!! 40160484Sobrien */ 40260484Sobrien 40360484Sobrien if (g->howto->type == 3) 40460484Sobrien { 40560484Sobrien r_length = 3; 40660484Sobrien r_pcrel = 0; 40760484Sobrien } 40860484Sobrien else if (g->howto->type == 7) 40977298Sobrien { 41060484Sobrien r_length = 3; 41160484Sobrien r_pcrel = 1; 41260484Sobrien } 41360484Sobrien 41460484Sobrien#if 0 41560484Sobrien /* For a standard reloc, the addend is in the object file. */ 41660484Sobrien r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; 41760484Sobrien#endif 41860484Sobrien 41960484Sobrien /* name was clobbered by aout_write_syms to be symbol index */ 42060484Sobrien 42160484Sobrien /* If this relocation is relative to a symbol then set the 42260484Sobrien r_index to the symbols index, and the r_extern bit. 42360484Sobrien 42460484Sobrien Absolute symbols can come in in two ways, either as an offset 42560484Sobrien from the abs section, or as a symbol which has an abs value. 42660484Sobrien check for that here 42760484Sobrien */ 42860484Sobrien 42960484Sobrien if (bfd_is_com_section (output_section) 43060484Sobrien || output_section == &bfd_abs_section 43160484Sobrien || output_section == &bfd_und_section) 43260484Sobrien { 43360484Sobrien if (bfd_abs_section.symbol == sym) 43460484Sobrien { 43560484Sobrien /* Whoops, looked like an abs symbol, but is really an offset 43689857Sobrien from the abs section. */ 43760484Sobrien r_index = 0; 43860484Sobrien r_extern = 0; 43960484Sobrien } 44060484Sobrien else 44160484Sobrien { 44289857Sobrien /* Fill in symbol. */ 44360484Sobrien r_extern = 1; 44460484Sobrien r_index = (*(g->sym_ptr_ptr))->KEEPIT; 44560484Sobrien } 44660484Sobrien } 44760484Sobrien else 44860484Sobrien { 44989857Sobrien /* Just an ordinary section. */ 45060484Sobrien r_extern = 0; 45160484Sobrien r_index = output_section->target_index; 45260484Sobrien } 45360484Sobrien 45489857Sobrien /* Now the fun stuff. */ 45560484Sobrien if (bfd_header_big_endian (abfd)) 45660484Sobrien { 45760484Sobrien natptr->r_index[0] = r_index >> 16; 45860484Sobrien natptr->r_index[1] = r_index >> 8; 45960484Sobrien natptr->r_index[2] = r_index; 46060484Sobrien natptr->r_type[0] = 46160484Sobrien ( (r_extern ? RELOC_STD_BITS_EXTERN_BIG: 0) 46260484Sobrien | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG: 0) 46360484Sobrien | (r_neg ? RELOC_ARM_BITS_NEG_BIG: 0) 46460484Sobrien | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); 46560484Sobrien } 46660484Sobrien else 46760484Sobrien { 46860484Sobrien natptr->r_index[2] = r_index >> 16; 46960484Sobrien natptr->r_index[1] = r_index >> 8; 47060484Sobrien natptr->r_index[0] = r_index; 47160484Sobrien natptr->r_type[0] = 47260484Sobrien ( (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE: 0) 47360484Sobrien | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE: 0) 47460484Sobrien | (r_neg ? RELOC_ARM_BITS_NEG_LITTLE: 0) 47560484Sobrien | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); 47660484Sobrien } 47760484Sobrien} 47860484Sobrien 47960484Sobrien#define MY_BFD_TARGET 48060484Sobrien 48160484Sobrien#include "aout-target.h" 48260484Sobrien 48360484Sobrienextern const bfd_target aout_arm_big_vec; 48460484Sobrien 48560484Sobrienconst bfd_target aout_arm_little_vec = 48689857Sobrien { 48789857Sobrien "a.out-arm-little", /* name */ 48889857Sobrien bfd_target_aout_flavour, 48989857Sobrien BFD_ENDIAN_LITTLE, /* target byte order (little) */ 49089857Sobrien BFD_ENDIAN_LITTLE, /* target headers byte order (little) */ 49189857Sobrien (HAS_RELOC | EXEC_P | /* object flags */ 49289857Sobrien HAS_LINENO | HAS_DEBUG | 49389857Sobrien HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), 49489857Sobrien (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA), 49589857Sobrien MY_symbol_leading_char, 49689857Sobrien AR_PAD_CHAR, /* ar_pad_char */ 49789857Sobrien 15, /* ar_max_namelen */ 49889857Sobrien bfd_getl64, bfd_getl_signed_64, bfd_putl64, 49989857Sobrien bfd_getl32, bfd_getl_signed_32, bfd_putl32, 50089857Sobrien bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ 50189857Sobrien bfd_getl64, bfd_getl_signed_64, bfd_putl64, 50289857Sobrien bfd_getl32, bfd_getl_signed_32, bfd_putl32, 50389857Sobrien bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ 50489857Sobrien {_bfd_dummy_target, MY_object_p, /* bfd_check_format */ 50589857Sobrien bfd_generic_archive_p, MY_core_file_p}, 50689857Sobrien {bfd_false, MY_mkobject, /* bfd_set_format */ 50789857Sobrien _bfd_generic_mkarchive, bfd_false}, 50889857Sobrien {bfd_false, MY_write_object_contents, /* bfd_write_contents */ 50989857Sobrien _bfd_write_archive_contents, bfd_false}, 51060484Sobrien 51189857Sobrien BFD_JUMP_TABLE_GENERIC (MY), 51289857Sobrien BFD_JUMP_TABLE_COPY (MY), 51389857Sobrien BFD_JUMP_TABLE_CORE (MY), 51489857Sobrien BFD_JUMP_TABLE_ARCHIVE (MY), 51589857Sobrien BFD_JUMP_TABLE_SYMBOLS (MY), 51689857Sobrien BFD_JUMP_TABLE_RELOCS (MY), 51789857Sobrien BFD_JUMP_TABLE_WRITE (MY), 51889857Sobrien BFD_JUMP_TABLE_LINK (MY), 51989857Sobrien BFD_JUMP_TABLE_DYNAMIC (MY), 52060484Sobrien 52189857Sobrien & aout_arm_big_vec, 52277298Sobrien 52389857Sobrien (PTR) MY_backend_data, 52489857Sobrien }; 52560484Sobrien 52660484Sobrienconst bfd_target aout_arm_big_vec = 52789857Sobrien { 52889857Sobrien "a.out-arm-big", /* name */ 52989857Sobrien bfd_target_aout_flavour, 53089857Sobrien BFD_ENDIAN_BIG, /* target byte order (big) */ 53189857Sobrien BFD_ENDIAN_BIG, /* target headers byte order (big) */ 53289857Sobrien (HAS_RELOC | EXEC_P | /* object flags */ 53389857Sobrien HAS_LINENO | HAS_DEBUG | 53489857Sobrien HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), 53589857Sobrien (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA), 53689857Sobrien MY_symbol_leading_char, 53789857Sobrien AR_PAD_CHAR, /* ar_pad_char */ 53889857Sobrien 15, /* ar_max_namelen */ 53989857Sobrien bfd_getb64, bfd_getb_signed_64, bfd_putb64, 54089857Sobrien bfd_getb32, bfd_getb_signed_32, bfd_putb32, 54189857Sobrien bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ 54289857Sobrien bfd_getb64, bfd_getb_signed_64, bfd_putb64, 54389857Sobrien bfd_getb32, bfd_getb_signed_32, bfd_putb32, 54489857Sobrien bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ 54589857Sobrien {_bfd_dummy_target, MY_object_p, /* bfd_check_format */ 54689857Sobrien bfd_generic_archive_p, MY_core_file_p}, 54789857Sobrien {bfd_false, MY_mkobject, /* bfd_set_format */ 54889857Sobrien _bfd_generic_mkarchive, bfd_false}, 54989857Sobrien {bfd_false, MY_write_object_contents, /* bfd_write_contents */ 55089857Sobrien _bfd_write_archive_contents, bfd_false}, 55160484Sobrien 55289857Sobrien BFD_JUMP_TABLE_GENERIC (MY), 55389857Sobrien BFD_JUMP_TABLE_COPY (MY), 55489857Sobrien BFD_JUMP_TABLE_CORE (MY), 55589857Sobrien BFD_JUMP_TABLE_ARCHIVE (MY), 55689857Sobrien BFD_JUMP_TABLE_SYMBOLS (MY), 55789857Sobrien BFD_JUMP_TABLE_RELOCS (MY), 55889857Sobrien BFD_JUMP_TABLE_WRITE (MY), 55989857Sobrien BFD_JUMP_TABLE_LINK (MY), 56089857Sobrien BFD_JUMP_TABLE_DYNAMIC (MY), 56160484Sobrien 56289857Sobrien & aout_arm_little_vec, 56377298Sobrien 56489857Sobrien (PTR) MY_backend_data, 56589857Sobrien }; 566