?? aout-arm.c
字號(hào):
/* BFD back-end for raw ARM a.out binaries. Copyright 1994, 1995, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)This file is part of BFD, the Binary File Descriptor library.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#define N_TXTADDR(x) \ ((N_MAGIC(x) == NMAGIC) ? 0x8000 : \ (N_MAGIC(x) != ZMAGIC) ? 0 : \ (N_SHARED_LIB(x)) ? ((x).a_entry & ~(TARGET_PAGE_SIZE - 1)) : \ TEXT_START_ADDR)#define TEXT_START_ADDR 0x8000#define TARGET_PAGE_SIZE 0x8000#define SEGMENT_SIZE TARGET_PAGE_SIZE#define DEFAULT_ARCH bfd_arch_arm#define MY(OP) CAT(aoutarm_,OP)#define N_BADMAG(x) ((((x).a_info & ~007200) != ZMAGIC) && \ (((x).a_info & ~006000) != OMAGIC) && \ ((x).a_info != NMAGIC))#define N_MAGIC(x) ((x).a_info & ~07200)#include "bfd.h"#include "sysdep.h"#define MYARM(OP) CAT(aoutarm_,OP)reloc_howto_type *MYARM(bfd_reloc_type_lookup) PARAMS((bfd *, bfd_reloc_code_real_type));static boolean MYARM(write_object_contents) PARAMS((bfd *));/* Avoid multiple defininitions from aoutx if supporting standarad a.out as well as our own. */#define NAME(x,y) CAT3(aoutarm,_32_,y)#define MY_bfd_reloc_type_lookup aoutarm_bfd_reloc_type_lookup#include "libaout.h"#include "aout/aout64.h"static bfd_reloc_status_typeMY(fix_pcrel_26_done) PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));static bfd_reloc_status_typeMY(fix_pcrel_26) PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));static void MY(swap_std_reloc_in) PARAMS ((bfd *, struct reloc_std_external *, arelent *, asymbol **, bfd_size_type));void MY(swap_std_reloc_out) PARAMS ((bfd *, arelent *, struct reloc_std_external *));reloc_howto_type MY(howto_table)[] ={ /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */ HOWTO (0, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "8", true, 0x000000ff, 0x000000ff, false), HOWTO (1, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "16", true, 0x0000ffff, 0x0000ffff, false), HOWTO (2, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "32", true, 0xffffffff, 0xffffffff, false), HOWTO (3, 2, 2, 26, true, 0, complain_overflow_signed, MY(fix_pcrel_26), "ARM26", true, 0x00ffffff, 0x00ffffff, true), HOWTO (4, 0, 0, 8, true, 0, complain_overflow_signed, 0, "DISP8", true, 0x000000ff, 0x000000ff, true), HOWTO (5, 0, 1, 16, true, 0, complain_overflow_signed, 0, "DISP16", true, 0x0000ffff, 0x0000ffff, true), HOWTO (6, 0, 2, 32, true, 0, complain_overflow_signed, 0, "DISP32", true, 0xffffffff, 0xffffffff, true), HOWTO (7, 2, 2, 26, false, 0, complain_overflow_signed, MY(fix_pcrel_26_done), "ARM26D", true, 0x0, 0x0, false), EMPTY_HOWTO (-1), HOWTO (9, 0, -1, 16, false, 0, complain_overflow_bitfield, 0, "NEG16", true, 0x0000ffff, 0x0000ffff, false), HOWTO (10, 0, -2, 32, false, 0, complain_overflow_bitfield, 0, "NEG32", true, 0xffffffff, 0xffffffff, false)};#define RELOC_ARM_BITS_NEG_BIG ((unsigned int) 0x08)#define RELOC_ARM_BITS_NEG_LITTLE ((unsigned int) 0x10)reloc_howto_type *MY(reloc_howto) (abfd, rel, r_index, r_extern, r_pcrel) bfd *abfd; struct reloc_std_external *rel; int *r_index; int *r_extern; int *r_pcrel;{ unsigned int r_length; unsigned int r_pcrel_done; unsigned int r_neg; int index; *r_pcrel = 0; if (bfd_header_big_endian (abfd)) { *r_index = ((rel->r_index[0] << 16) | (rel->r_index[1] << 8) | rel->r_index[2]); *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); r_pcrel_done = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG)); r_neg = (0 != (rel->r_type[0] & RELOC_ARM_BITS_NEG_BIG)); r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) >> RELOC_STD_BITS_LENGTH_SH_BIG); } else { *r_index = ((rel->r_index[2] << 16) | (rel->r_index[1] << 8) | rel->r_index[0]); *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE)); r_pcrel_done = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE)); r_neg = (0 != (rel->r_type[0] & RELOC_ARM_BITS_NEG_LITTLE)); r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) >> RELOC_STD_BITS_LENGTH_SH_LITTLE); } index = r_length + 4 * r_pcrel_done + 8 * r_neg; if (index == 3) *r_pcrel = 1; return MY(howto_table) + index;}#define MY_reloc_howto(BFD, REL, IN, EX, PC) \ MY(reloc_howto) (BFD, REL, &IN, &EX, &PC)voidMY(put_reloc) (abfd, r_extern, r_index, value, howto, reloc) bfd *abfd; int r_extern; int r_index; long value; reloc_howto_type *howto; struct reloc_std_external *reloc;{ unsigned int r_length; int r_pcrel; int r_neg; PUT_WORD (abfd, value, reloc->r_address); r_length = howto->size ; /* Size as a power of two */ /* Special case for branch relocations. */ if (howto->type == 3 || howto->type == 7) r_length = 3; r_pcrel = howto->type & 4; /* PC Relative done? */ r_neg = howto->type & 8; /* Negative relocation */ if (bfd_header_big_endian (abfd)) { reloc->r_index[0] = r_index >> 16; reloc->r_index[1] = r_index >> 8; reloc->r_index[2] = r_index; reloc->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0) | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0) | (r_neg ? RELOC_ARM_BITS_NEG_BIG : 0) | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); } else { reloc->r_index[2] = r_index >> 16; reloc->r_index[1] = r_index >> 8; reloc->r_index[0] = r_index; reloc->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0) | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0) | (r_neg ? RELOC_ARM_BITS_NEG_LITTLE : 0) | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); }}#define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \ MY(put_reloc) (BFD, EXT, IDX, VAL, HOWTO, RELOC)voidMY(relocatable_reloc) (howto, abfd, reloc, amount, r_addr) reloc_howto_type *howto; bfd *abfd; struct reloc_std_external *reloc; bfd_vma *amount; bfd_vma r_addr;{ if (howto->type == 3) { if (reloc->r_type[0] & (bfd_header_big_endian (abfd) ? RELOC_STD_BITS_EXTERN_BIG : RELOC_STD_BITS_EXTERN_LITTLE)) { /* The reloc is still external, so don't modify anything. */ *amount = 0; } else { *amount -= r_addr; /* Change the r_pcrel value -- on the ARM, this bit is set once the relocation is done. */ if (bfd_header_big_endian (abfd)) reloc->r_type[0] |= RELOC_STD_BITS_PCREL_BIG; else reloc->r_type[0] |= RELOC_STD_BITS_PCREL_LITTLE; } } else if (howto->type == 7) *amount = 0;}#define MY_relocatable_reloc(HOW, BFD, REL, AMOUNT, ADDR) \ MY(relocatable_reloc) (HOW, BFD, REL, &(AMOUNT), ADDR)static bfd_reloc_status_typeMY(fix_pcrel_26_done) (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) bfd *abfd ATTRIBUTE_UNUSED; arelent *reloc_entry ATTRIBUTE_UNUSED; asymbol *symbol ATTRIBUTE_UNUSED; PTR data ATTRIBUTE_UNUSED; asection *input_section ATTRIBUTE_UNUSED; bfd *output_bfd ATTRIBUTE_UNUSED; char **error_message ATTRIBUTE_UNUSED;{ /* This is dead simple at present. */ return bfd_reloc_ok;}static bfd_reloc_status_typeMY(fix_pcrel_26) (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) bfd *abfd; arelent *reloc_entry; asymbol *symbol; PTR data; asection *input_section; bfd *output_bfd; char **error_message ATTRIBUTE_UNUSED;{ bfd_vma relocation; bfd_size_type addr = reloc_entry->address; long target = bfd_get_32 (abfd, (bfd_byte *) data + addr); bfd_reloc_status_type flag = bfd_reloc_ok; /* If this is an undefined symbol, return error */ if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0) return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined; /* If the sections are different, and we are doing a partial relocation, just ignore it for now. */ if (symbol->section->name != input_section->name && output_bfd != (bfd *)NULL) return bfd_reloc_ok; relocation = (target & 0x00ffffff) << 2; relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */ relocation += symbol->value; relocation += symbol->section->output_section->vma; relocation += symbol->section->output_offset;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -