X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fcoff-arm.c;h=bdadfb2cd4ab866304b5415a198f392914085fe1;hb=425b145b6ec65eefa2c23131c7c9997f08ebf88c;hp=6b83dc7af7fd6c7c1efee572be0114e8be3a49ee;hpb=66eb6687c96edd3c969bd644574c649fd0be23cd;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c index 6b83dc7af7..bdadfb2cd4 100644 --- a/bfd/coff-arm.c +++ b/bfd/coff-arm.c @@ -1,6 +1,6 @@ /* BFD back-end for ARM COFF files. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006 + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Written by Cygnus Support. @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -18,10 +18,11 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "libbfd.h" #include "coff/arm.h" #include "coff/internal.h" @@ -163,6 +164,19 @@ coff_arm_reloc (bfd *abfd, /* These most certainly belong somewhere else. Just had to get rid of the manifest constants in the code. */ + +#ifdef ARM_WINCE + +#define ARM_26D 0 +#define ARM_32 1 +#define ARM_RVA32 2 +#define ARM_26 3 +#define ARM_THUMB12 4 +#define ARM_SECTION 14 +#define ARM_SECREL 15 + +#else + #define ARM_8 0 #define ARM_16 1 #define ARM_32 2 @@ -179,20 +193,6 @@ coff_arm_reloc (bfd *abfd, #define ARM_THUMB12 13 #define ARM_THUMB23 14 -#ifdef ARM_WINCE -#undef ARM_32 -#undef ARM_RVA32 -#undef ARM_26 -#undef ARM_THUMB12 -#undef ARM_26D - -#define ARM_26D 0 -#define ARM_32 1 -#define ARM_RVA32 2 -#define ARM_26 3 -#define ARM_THUMB12 4 -#define ARM_SECTION 14 -#define ARM_SECREL 15 #endif static bfd_reloc_status_type aoutarm_fix_pcrel_26_done @@ -220,7 +220,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = complain_overflow_dont, aoutarm_fix_pcrel_26_done, "ARM_26D", - FALSE, + TRUE, /* partial_inplace. */ 0x00ffffff, 0x0, PCRELOFFSET), @@ -233,7 +233,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = complain_overflow_bitfield, coff_arm_reloc, "ARM_32", - FALSE, + TRUE, /* partial_inplace. */ 0xffffffff, 0xffffffff, PCRELOFFSET), @@ -246,7 +246,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = complain_overflow_bitfield, coff_arm_reloc, "ARM_RVA32", - FALSE, + TRUE, /* partial_inplace. */ 0xffffffff, 0xffffffff, PCRELOFFSET), @@ -294,7 +294,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = complain_overflow_bitfield, coff_arm_reloc, "ARM_SECTION", - FALSE, + TRUE, /* partial_inplace. */ 0x0000ffff, 0x0000ffff, PCRELOFFSET), @@ -307,7 +307,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = complain_overflow_bitfield, coff_arm_reloc, "ARM_SECREL", - FALSE, + TRUE, /* partial_inplace. */ 0xffffffff, 0xffffffff, PCRELOFFSET), @@ -539,6 +539,31 @@ coff_arm_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, if (rel->r_type == ARM_RVA32) *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase; +#if defined COFF_WITH_PE && defined ARM_WINCE + if (rel->r_type == ARM_SECREL) + { + bfd_vma osect_vma; + + if (h && (h->type == bfd_link_hash_defined + || h->type == bfd_link_hash_defweak)) + osect_vma = h->root.u.def.section->output_section->vma; + else + { + int i; + + /* Sigh, the only way to get the section to offset against + is to find it the hard way. */ + + for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++) + sec = sec->next; + + osect_vma = sec->output_section->vma; + } + + *addendp -= osect_vma; + } +#endif + return howto; } @@ -792,7 +817,7 @@ coff_arm_reloc_type_lookup (bfd * abfd, bfd_reloc_code_real_type code) #define ASTD(i,j) case i: return aoutarm_std_reloc_howto + j if (code == BFD_RELOC_CTOR) - switch (bfd_get_arch_info (abfd)->bits_per_address) + switch (bfd_arch_bits_per_address (abfd)) { case 32: code = BFD_RELOC_32; @@ -808,6 +833,7 @@ coff_arm_reloc_type_lookup (bfd * abfd, bfd_reloc_code_real_type code) ASTD (BFD_RELOC_RVA, ARM_RVA32); ASTD (BFD_RELOC_ARM_PCREL_BRANCH, ARM_26); ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12); + ASTD (BFD_RELOC_32_SECREL, ARM_SECREL); #else ASTD (BFD_RELOC_8, ARM_8); ASTD (BFD_RELOC_16, ARM_16); @@ -827,6 +853,23 @@ coff_arm_reloc_type_lookup (bfd * abfd, bfd_reloc_code_real_type code) } } +static reloc_howto_type * +coff_arm_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + unsigned int i; + + for (i = 0; + i < (sizeof (aoutarm_std_reloc_howto) + / sizeof (aoutarm_std_reloc_howto[0])); + i++) + if (aoutarm_std_reloc_howto[i].name != NULL + && strcasecmp (aoutarm_std_reloc_howto[i].name, r_name) == 0) + return &aoutarm_std_reloc_howto[i]; + + return NULL; +} + #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2 #define COFF_PAGE_SIZE 0x1000 @@ -895,21 +938,24 @@ coff_arm_link_hash_table_create (bfd * abfd) return & ret->root.root; } -static void +static bfd_boolean arm_emit_base_file_entry (struct bfd_link_info *info, bfd *output_bfd, asection *input_section, bfd_vma reloc_offset) { - bfd_vma addr = reloc_offset - - input_section->vma - + input_section->output_offset - + input_section->output_section->vma; + bfd_vma addr = (reloc_offset + - input_section->vma + + input_section->output_offset + + input_section->output_section->vma); if (coff_data (output_bfd)->pe) addr -= pe_data (output_bfd)->pe_opthdr.ImageBase; - fwrite (& addr, 1, sizeof (addr), (FILE *) info->base_file); + if (fwrite (&addr, sizeof (addr), 1, (FILE *) info->base_file) == 1) + return TRUE; + bfd_set_error (bfd_error_system_call); + return FALSE; } #ifndef ARM_WINCE @@ -1209,12 +1255,14 @@ coff_arm_relocate_section (bfd *output_bfd, generation of bl's instruction offset. */ addend -= 8; #endif - howto = &fake_arm26_reloc; + howto = & fake_arm26_reloc; } #ifdef ARM_WINCE /* MS ARM-CE makes the reloc relative to the opcode's pc, not the next opcode's pc, so is off by one. */ + if (howto->pc_relative && !info->relocatable) + addend -= 8; #endif /* If we are doing a relocatable link, then we can just ignore @@ -1283,8 +1331,8 @@ coff_arm_relocate_section (bfd *output_bfd, if (howto->type == ARM_26) { - if ( h->class == C_THUMBSTATFUNC - || h->class == C_THUMBEXTFUNC) + if ( h->symbol_class == C_THUMBSTATFUNC + || h->symbol_class == C_THUMBEXTFUNC) { /* Arm code calling a Thumb function. */ unsigned long int tmp; @@ -1335,10 +1383,10 @@ coff_arm_relocate_section (bfd *output_bfd, bfd_put_32 (output_bfd, h_val | a2t3_func_addr_insn, s->contents + my_offset + 8); - if (info->base_file) - arm_emit_base_file_entry (info, output_bfd, s, - my_offset + 8); - + if (info->base_file + && !arm_emit_base_file_entry (info, output_bfd, + s, my_offset + 8)) + return FALSE; } BFD_ASSERT (my_offset <= globals->arm_glue_size); @@ -1370,9 +1418,9 @@ coff_arm_relocate_section (bfd *output_bfd, /* Note: We used to check for ARM_THUMB9 and ARM_THUMB12. */ else if (howto->type == ARM_THUMB23) { - if ( h->class == C_EXT - || h->class == C_STAT - || h->class == C_LABEL) + if ( h->symbol_class == C_EXT + || h->symbol_class == C_STAT + || h->symbol_class == C_LABEL) { /* Thumb code calling an ARM function. */ asection * s = 0; @@ -1440,9 +1488,11 @@ coff_arm_relocate_section (bfd *output_bfd, bfd_put_32 (output_bfd, h_val, s->contents + my_offset + 16); - if (info->base_file) - arm_emit_base_file_entry (info, output_bfd, s, - my_offset + 16); + if (info->base_file + && !arm_emit_base_file_entry (info, + output_bfd, s, + my_offset + 16)) + return FALSE; } else { @@ -1526,13 +1576,13 @@ coff_arm_relocate_section (bfd *output_bfd, } } - if (info->base_file) - { - /* Emit a reloc if the backend thinks it needs it. */ - if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto)) - arm_emit_base_file_entry (info, output_bfd, input_section, - rel->r_vaddr); - } + /* Emit a reloc if the backend thinks it needs it. */ + if (info->base_file + && sym + && pe_data(output_bfd)->in_reloc_p(output_bfd, howto) + && !arm_emit_base_file_entry (info, output_bfd, input_section, + rel->r_vaddr)) + return FALSE; if (done) rstat = bfd_reloc_ok; @@ -1670,8 +1720,8 @@ coff_arm_relocate_section (bfd *output_bfd, int patchit = FALSE; if (h != NULL - && ( h->class == C_THUMBSTATFUNC - || h->class == C_THUMBEXTFUNC)) + && ( h->symbol_class == C_THUMBSTATFUNC + || h->symbol_class == C_THUMBEXTFUNC)) { patchit = TRUE; } @@ -1881,7 +1931,7 @@ record_thumb_to_arm_glue (struct bfd_link_info * info, /* If we mark it 'thumb', the disassembler will do a better job. */ myh = (struct coff_link_hash_entry *) bh; - myh->class = C_THUMBEXTFUNC; + myh->symbol_class = C_THUMBEXTFUNC; free (tmp_name); @@ -1938,12 +1988,11 @@ bfd_arm_get_bfd_for_interworking (bfd * abfd, if (sec == NULL) { - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE | SEC_READONLY; - - sec = bfd_make_section (abfd, ARM2THUMB_GLUE_SECTION_NAME); - + flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY + | SEC_CODE | SEC_READONLY); + sec = bfd_make_section_with_flags (abfd, ARM2THUMB_GLUE_SECTION_NAME, + flags); if (sec == NULL - || ! bfd_set_section_flags (abfd, sec, flags) || ! bfd_set_section_alignment (abfd, sec, 2)) return FALSE; } @@ -1952,12 +2001,12 @@ bfd_arm_get_bfd_for_interworking (bfd * abfd, if (sec == NULL) { - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE | SEC_READONLY; - - sec = bfd_make_section (abfd, THUMB2ARM_GLUE_SECTION_NAME); + flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY + | SEC_CODE | SEC_READONLY); + sec = bfd_make_section_with_flags (abfd, THUMB2ARM_GLUE_SECTION_NAME, + flags); if (sec == NULL - || ! bfd_set_section_flags (abfd, sec, flags) || ! bfd_set_section_alignment (abfd, sec, 2)) return FALSE; } @@ -2046,7 +2095,7 @@ bfd_arm_process_before_allocation (bfd * abfd, the target of the call. If it is a thumb target, we insert glue. */ - if (h->class == C_THUMBEXTFUNC) + if (h->symbol_class == C_THUMBEXTFUNC) record_arm_to_thumb_glue (info, h); break; @@ -2060,7 +2109,7 @@ bfd_arm_process_before_allocation (bfd * abfd, for it. This is not really a problem, since the link is doomed anyway. */ - switch (h->class) + switch (h->symbol_class) { case C_EXT: case C_STAT: @@ -2085,6 +2134,7 @@ bfd_arm_process_before_allocation (bfd * abfd, #endif /* ! defined (COFF_IMAGE_WITH_PE) */ #define coff_bfd_reloc_type_lookup coff_arm_reloc_type_lookup +#define coff_bfd_reloc_name_lookup coff_arm_reloc_name_lookup #define coff_relocate_section coff_arm_relocate_section #define coff_bfd_is_local_label_name coff_arm_is_local_label_name #define coff_adjust_symndx coff_arm_adjust_symndx @@ -2157,7 +2207,7 @@ coff_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd) { _bfd_error_handler /* xgettext: c-format */ - (_("ERROR: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"), + (_("error: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"), ibfd, obfd, APCS_26_FLAG (ibfd) ? 26 : 32, APCS_26_FLAG (obfd) ? 26 : 32 @@ -2173,10 +2223,10 @@ coff_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd) if (APCS_FLOAT_FLAG (ibfd)) /* xgettext: c-format */ - msg = _("ERROR: %B passes floats in float registers, whereas %B passes them in integer registers"); + msg = _("error: %B passes floats in float registers, whereas %B passes them in integer registers"); else /* xgettext: c-format */ - msg = _("ERROR: %B passes floats in integer registers, whereas %B passes them in float registers"); + msg = _("error: %B passes floats in integer registers, whereas %B passes them in float registers"); _bfd_error_handler (msg, ibfd, obfd); @@ -2190,10 +2240,10 @@ coff_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd) if (PIC_FLAG (ibfd)) /* xgettext: c-format */ - msg = _("ERROR: %B is compiled as position independent code, whereas target %B is absolute position"); + msg = _("error: %B is compiled as position independent code, whereas target %B is absolute position"); else /* xgettext: c-format */ - msg = _("ERROR: %B is compiled as absolute position code, whereas target %B is position independent"); + msg = _("error: %B is compiled as absolute position code, whereas target %B is position independent"); _bfd_error_handler (msg, ibfd, obfd); bfd_set_error (bfd_error_wrong_format); @@ -2397,7 +2447,9 @@ Warning: Clearing the interworking flag of %B because non-interworking code in % /* Note: the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX *must* match the definitions in gcc/config/arm/{coff|semi|aout}.h. */ +#ifndef LOCAL_LABEL_PREFIX #define LOCAL_LABEL_PREFIX "" +#endif #ifndef USER_LABEL_PREFIX #define USER_LABEL_PREFIX "_" #endif @@ -2475,6 +2527,10 @@ coff_arm_final_link_postscript (bfd * abfd ATTRIBUTE_UNUSED, return bfd_arm_update_notes (abfd, ARM_NOTE_SECTION); } +#ifndef bfd_pe_print_pdata +#define bfd_pe_print_pdata NULL +#endif + #include "coffcode.h" #ifndef TARGET_LITTLE_SYM