From a86285ac7a9bcc0fb695031b308e4710daa6160d Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 11 May 2006 08:48:58 +0000 Subject: [PATCH] Apply fixes to allow arm WinCE toolchain to produce working executables. --- bfd/ChangeLog | 7 +++++++ bfd/coff-arm.c | 14 ++++++++------ gas/ChangeLog | 6 ++++++ gas/config/tc-arm.c | 27 ++++++++++++++++++++++++--- ld/ChangeLog | 14 ++++++++++++++ ld/emultempl/pe.em | 2 +- ld/pe-dll.c | 52 +++++++++++++++++++++++++++++++++++++++------------- 7 files changed, 99 insertions(+), 23 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index e757fc5583..414e706404 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2006-05-11 Pedro Alves + + * coff-arm.c (ARM_26D, ARM_32, ARM_RVA_32, ARM_SECTION, + ARM_SECREL): Mark WinCE versions of these relocs as partial + inplace. + (coff_arm_relocate_section): Adjust addend for WinCE. + 2006-05-10 Alan Modra PR 2342 diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c index 6b83dc7af7..c5b4765210 100644 --- a/bfd/coff-arm.c +++ b/bfd/coff-arm.c @@ -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), @@ -1209,12 +1209,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 diff --git a/gas/ChangeLog b/gas/ChangeLog index 4596052f18..9b08640d4b 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2006-05-11 Pedro Alves + + * config/tc-arm.c (md_pcrel_from_section): Force a bias for + relocs against external symbols for WinCE targets. + (md_apply_fix): Likewise. + 2006-05-09 David Ung * config/tc-mips.c (append_insn): Only warn about an out-of-range diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 5ccbfc1f13..690f59f7bd 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -15561,10 +15561,16 @@ md_pcrel_from_section (fixS * fixP, segT seg) /* If this is pc-relative and we are going to emit a relocation then we just want to put out any pipeline compensation that the linker - will need. Otherwise we want to use the calculated base. */ + will need. Otherwise we want to use the calculated base. + For WinCE we skip the bias for externals as well, since this + is how the MS ARM-CE assembler behaves and we want to be compatible. */ if (fixP->fx_pcrel && ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg) - || arm_force_relocation (fixP))) + || (arm_force_relocation (fixP) +#ifdef TE_WINCE + && !S_IS_EXTERNAL (fixP->fx_addsy) +#endif + ))) base = 0; switch (fixP->fx_r_type) @@ -15601,6 +15607,17 @@ md_pcrel_from_section (fixS * fixP, segT seg) case BFD_RELOC_ARM_PCREL_BLX: case BFD_RELOC_ARM_PLT32: #ifdef TE_WINCE + /* When handling fixups immediately, because we have already + discovered the value of a symbol, or the address of the frag involved + we must account for the offset by +8, as the OS loader will never see the reloc. + see fixup_segment() in write.c + The S_IS_EXTERNAL test handles the case of global symbols. + Those need the calculated base, not just the pipe compensation the linker will need. */ + if (fixP->fx_pcrel + && fixP->fx_addsy != NULL + && (S_GET_SEGMENT (fixP->fx_addsy) == seg) + && (S_IS_EXTERNAL (fixP->fx_addsy) || !arm_force_relocation (fixP))) + return base + 8; return base; #else return base + 8; @@ -16512,7 +16529,11 @@ md_apply_fix (fixS * fixP, case BFD_RELOC_ARM_SBREL32: case BFD_RELOC_32_PCREL: if (fixP->fx_done || !seg->use_rela_p) - md_number_to_chars (buf, value, 4); +#ifdef TE_WINCE + /* For WinCE we only do this for pcrel fixups. */ + if (fixP->fx_done || fixP->fx_pcrel) +#endif + md_number_to_chars (buf, value, 4); break; #ifdef OBJ_ELF diff --git a/ld/ChangeLog b/ld/ChangeLog index 3f76d99b5f..33500491f7 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,17 @@ +2006-05-11 Pedro Alves + + * pe-dll.c (autofilter_symbollist): Add Dllmain, + DllMainCRTStartup, _DllMainCRTStartup and .text. + (autofilter_liblist): Add libcegcc. + (autofilter_symbolprefixlist): Add __imp_ and .idata$. + (generate_reloc): Do not skip sections without a SEC_LOAD flag, + they can still contain relocs that need processing. + Skip the .idata$6 section. + (jmp_arm_bytes): New array: Contains byte codes for an ARM jump. + (make_one): Use the new array. + (make_import_fixup_entry): Use .idata$2 instead of .idata$3. + * emultempl/pe.em (MajorSubsystemVersion): Set to 3 for armpe. + 2006-05-05 Alan Modra * ld.texinfo: Document PowerPC and PowerPC64 options. diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index 5afa8da00f..33ac71e546 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -283,7 +283,7 @@ static definfo init[] = D(MajorImageVersion,"__major_image_version__", 1), D(MinorImageVersion,"__minor_image_version__", 0), #ifdef TARGET_IS_armpe - D(MajorSubsystemVersion,"__major_subsystem_version__", 2), + D(MajorSubsystemVersion,"__major_subsystem_version__", 3), #else D(MajorSubsystemVersion,"__major_subsystem_version__", 4), #endif diff --git a/ld/pe-dll.c b/ld/pe-dll.c index d4d42e4d36..2edfdecb71 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -1,5 +1,5 @@ /* Routines to help build PEI-format DLLs (Win32 etc) - Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Written by DJ Delorie @@ -95,7 +95,7 @@ For each reference of data symbol to be imported from DLL (to set of which belong symbols with name , if __imp_ is found in implib), the import fixup entry is generated. That entry is of type - IMAGE_IMPORT_DESCRIPTOR and stored in .idata$3 subsection. Each + IMAGE_IMPORT_DESCRIPTOR and stored in .idata$2 subsection. Each fixup entry contains pointer to symbol's address within .text section (marked with __fuN_ symbol, where N is integer), pointer to DLL name (so, DLL name is referenced by multiple entries), and pointer to symbol @@ -216,6 +216,9 @@ static pe_details_type *pe_details; static autofilter_entry_type autofilter_symbollist[] = { + { "DllMain", 7 }, + { "DllMainCRTStartup", 17 }, + { "_DllMainCRTStartup", 18 }, { "DllMain@12", 10 }, { "DllEntryPoint@0", 15 }, { "DllMainCRTStartup@12", 20 }, @@ -226,12 +229,14 @@ static autofilter_entry_type autofilter_symbollist[] = { "_pei386_runtime_relocator", 25 }, { "do_pseudo_reloc", 15 }, { "cygwin_crt0", 11 }, + { ".text", 5 }, { NULL, 0 } }; /* Do not specify library suffix explicitly, to allow for dllized versions. */ static autofilter_entry_type autofilter_liblist[] = { + { "libcegcc", 8 }, { "libcygwin", 9 }, { "libgcc", 6 }, { "libstdc++", 9 }, @@ -261,9 +266,10 @@ static autofilter_entry_type autofilter_objlist[] = static autofilter_entry_type autofilter_symbolprefixlist[] = { - /* { "__imp_", 6 }, */ + { "__imp_", 6 }, /* Do __imp_ explicitly to save time. */ { "__rtti_", 7 }, + { ".idata$", 7 }, /* Don't re-export auto-imported symbols. */ { "_nm_", 4 }, { "__builtin_", 10 }, @@ -1131,8 +1137,13 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info) int nsyms, symsize; /* If it's not loaded, we don't need to relocate it this way. */ +#if 0 /* Some toolchains can generate .data sections without a SEC_LOAD flag but with relocs. */ if (!(s->output_section->flags & SEC_LOAD)) continue; +#endif + /* Huh ? */ + if (strncmp (bfd_get_section_name (abfd, s), ".idata",6) == 0) + continue; /* I don't know why there would be a reloc for these, but I've seen it happen - DJ */ @@ -1780,6 +1791,14 @@ static unsigned char jmp_mips_bytes[] = 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 }; +static unsigned char jmp_arm_bytes[] = +{ + 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */ + 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */ + 0, 0, 0, 0 +}; + + static bfd * make_one (def_file_export *exp, bfd *parent) { @@ -1805,6 +1824,10 @@ make_one (def_file_export *exp, bfd *parent) jmp_bytes = jmp_mips_bytes; jmp_byte_count = sizeof (jmp_mips_bytes); break; + case PE_ARCH_arm: + jmp_bytes = jmp_arm_bytes; + jmp_byte_count = sizeof (jmp_arm_bytes); + break; default: abort (); } @@ -1878,6 +1901,9 @@ make_one (def_file_export *exp, bfd *parent) quick_reloc (abfd, 0, BFD_RELOC_LO16, 0); /* MIPS_R_PAIR */ quick_reloc (abfd, 4, BFD_RELOC_LO16, 2); break; + case PE_ARCH_arm: + quick_reloc (abfd, 8, BFD_RELOC_32, 2); + break; default: abort (); } @@ -2048,7 +2074,7 @@ make_import_fixup_mark (arelent *rel) return fixup_name; } -/* .section .idata$3 +/* .section .idata$2 .rva __nm_thnk_SYM (singleton thunk with name of func) .long 0 .long 0 @@ -2061,8 +2087,8 @@ make_import_fixup_entry (const char *name, const char *dll_symname, bfd *parent) { - asection *id3; - unsigned char *d3; + asection *id2; + unsigned char *d2; char *oname; bfd *abfd; @@ -2079,25 +2105,25 @@ make_import_fixup_entry (const char *name, symptr = 0; symtab = xmalloc (6 * sizeof (asymbol *)); - id3 = quick_section (abfd, ".idata$3", SEC_HAS_CONTENTS, 2); + id2 = quick_section (abfd, ".idata$2", SEC_HAS_CONTENTS, 2); quick_symbol (abfd, U ("_nm_thnk_"), name, "", UNDSEC, BSF_GLOBAL, 0); quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0); quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0); - bfd_set_section_size (abfd, id3, 20); - d3 = xmalloc (20); - id3->contents = d3; - memset (d3, 0, 20); + bfd_set_section_size (abfd, id2, 20); + d2 = xmalloc (20); + id2->contents = d2; + memset (d2, 0, 20); quick_reloc (abfd, 0, BFD_RELOC_RVA, 1); quick_reloc (abfd, 12, BFD_RELOC_RVA, 2); quick_reloc (abfd, 16, BFD_RELOC_RVA, 3); - save_relocs (id3); + save_relocs (id2); bfd_set_symtab (abfd, symtab, symptr); - bfd_set_section_contents (abfd, id3, d3, 0, 20); + bfd_set_section_contents (abfd, id2, d2, 0, 20); bfd_make_readable (abfd); return abfd; -- 2.11.0