Browse Source

Apply fixes to allow arm WinCE toolchain to produce working executables.

cr-0x5f1
Nick Clifton 21 years ago
parent
commit
53baae4870
  1. 7
      bfd/ChangeLog
  2. 12
      bfd/coff-arm.c
  3. 6
      gas/ChangeLog
  4. 25
      gas/config/tc-arm.c
  5. 14
      ld/ChangeLog
  6. 2
      ld/emultempl/pe.em
  7. 52
      ld/pe-dll.c

7
bfd/ChangeLog

@ -1,3 +1,10 @@
2006-05-11 Pedro Alves <pedro_alves@portugalmail.pt>
* 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 <amodra@bigpond.net.au> 2006-05-10 Alan Modra <amodra@bigpond.net.au>
PR 2342 PR 2342

12
bfd/coff-arm.c

@ -220,7 +220,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
complain_overflow_dont, complain_overflow_dont,
aoutarm_fix_pcrel_26_done, aoutarm_fix_pcrel_26_done,
"ARM_26D", "ARM_26D",
FALSE, TRUE, /* partial_inplace. */
0x00ffffff, 0x00ffffff,
0x0, 0x0,
PCRELOFFSET), PCRELOFFSET),
@ -233,7 +233,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
complain_overflow_bitfield, complain_overflow_bitfield,
coff_arm_reloc, coff_arm_reloc,
"ARM_32", "ARM_32",
FALSE, TRUE, /* partial_inplace. */
0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff,
PCRELOFFSET), PCRELOFFSET),
@ -246,7 +246,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
complain_overflow_bitfield, complain_overflow_bitfield,
coff_arm_reloc, coff_arm_reloc,
"ARM_RVA32", "ARM_RVA32",
FALSE, TRUE, /* partial_inplace. */
0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff,
PCRELOFFSET), PCRELOFFSET),
@ -294,7 +294,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
complain_overflow_bitfield, complain_overflow_bitfield,
coff_arm_reloc, coff_arm_reloc,
"ARM_SECTION", "ARM_SECTION",
FALSE, TRUE, /* partial_inplace. */
0x0000ffff, 0x0000ffff,
0x0000ffff, 0x0000ffff,
PCRELOFFSET), PCRELOFFSET),
@ -307,7 +307,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
complain_overflow_bitfield, complain_overflow_bitfield,
coff_arm_reloc, coff_arm_reloc,
"ARM_SECREL", "ARM_SECREL",
FALSE, TRUE, /* partial_inplace. */
0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff,
PCRELOFFSET), PCRELOFFSET),
@ -1215,6 +1215,8 @@ coff_arm_relocate_section (bfd *output_bfd,
#ifdef ARM_WINCE #ifdef ARM_WINCE
/* MS ARM-CE makes the reloc relative to the opcode's pc, not /* MS ARM-CE makes the reloc relative to the opcode's pc, not
the next opcode's pc, so is off by one. */ the next opcode's pc, so is off by one. */
if (howto->pc_relative && !info->relocatable)
addend -= 8;
#endif #endif
/* If we are doing a relocatable link, then we can just ignore /* If we are doing a relocatable link, then we can just ignore

6
gas/ChangeLog

@ -1,3 +1,9 @@
2006-05-11 Pedro Alves <pedro_alves@portugalmail.pt>
* 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 <davidu@mips.com> 2006-05-09 David Ung <davidu@mips.com>
* config/tc-mips.c (append_insn): Only warn about an out-of-range * config/tc-mips.c (append_insn): Only warn about an out-of-range

25
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 /* 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 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 if (fixP->fx_pcrel
&& ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg) && ((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; base = 0;
switch (fixP->fx_r_type) 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_PCREL_BLX:
case BFD_RELOC_ARM_PLT32: case BFD_RELOC_ARM_PLT32:
#ifdef TE_WINCE #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; return base;
#else #else
return base + 8; return base + 8;
@ -16512,6 +16529,10 @@ md_apply_fix (fixS * fixP,
case BFD_RELOC_ARM_SBREL32: case BFD_RELOC_ARM_SBREL32:
case BFD_RELOC_32_PCREL: case BFD_RELOC_32_PCREL:
if (fixP->fx_done || !seg->use_rela_p) if (fixP->fx_done || !seg->use_rela_p)
#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); md_number_to_chars (buf, value, 4);
break; break;

14
ld/ChangeLog

@ -1,3 +1,17 @@
2006-05-11 Pedro Alves <pedro_alves@portugalmail.pt>
* 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 <amodra@bigpond.net.au> 2006-05-05 Alan Modra <amodra@bigpond.net.au>
* ld.texinfo: Document PowerPC and PowerPC64 options. * ld.texinfo: Document PowerPC and PowerPC64 options.

2
ld/emultempl/pe.em

@ -283,7 +283,7 @@ static definfo init[] =
D(MajorImageVersion,"__major_image_version__", 1), D(MajorImageVersion,"__major_image_version__", 1),
D(MinorImageVersion,"__minor_image_version__", 0), D(MinorImageVersion,"__minor_image_version__", 0),
#ifdef TARGET_IS_armpe #ifdef TARGET_IS_armpe
D(MajorSubsystemVersion,"__major_subsystem_version__", 2), D(MajorSubsystemVersion,"__major_subsystem_version__", 3),
#else #else
D(MajorSubsystemVersion,"__major_subsystem_version__", 4), D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
#endif #endif

52
ld/pe-dll.c

@ -1,5 +1,5 @@
/* Routines to help build PEI-format DLLs (Win32 etc) /* 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. Free Software Foundation, Inc.
Written by DJ Delorie <dj@cygnus.com> Written by DJ Delorie <dj@cygnus.com>
@ -95,7 +95,7 @@
For each reference of data symbol to be imported from DLL (to set of which For each reference of data symbol to be imported from DLL (to set of which
belong symbols with name <sym>, if __imp_<sym> is found in implib), the belong symbols with name <sym>, if __imp_<sym> is found in implib), the
import fixup entry is generated. That entry is of type 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 fixup entry contains pointer to symbol's address within .text section
(marked with __fuN_<sym> symbol, where N is integer), pointer to DLL name (marked with __fuN_<sym> symbol, where N is integer), pointer to DLL name
(so, DLL name is referenced by multiple entries), and pointer to symbol (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[] = static autofilter_entry_type autofilter_symbollist[] =
{ {
{ "DllMain", 7 },
{ "DllMainCRTStartup", 17 },
{ "_DllMainCRTStartup", 18 },
{ "DllMain@12", 10 }, { "DllMain@12", 10 },
{ "DllEntryPoint@0", 15 }, { "DllEntryPoint@0", 15 },
{ "DllMainCRTStartup@12", 20 }, { "DllMainCRTStartup@12", 20 },
@ -226,12 +229,14 @@ static autofilter_entry_type autofilter_symbollist[] =
{ "_pei386_runtime_relocator", 25 }, { "_pei386_runtime_relocator", 25 },
{ "do_pseudo_reloc", 15 }, { "do_pseudo_reloc", 15 },
{ "cygwin_crt0", 11 }, { "cygwin_crt0", 11 },
{ ".text", 5 },
{ NULL, 0 } { NULL, 0 }
}; };
/* Do not specify library suffix explicitly, to allow for dllized versions. */ /* Do not specify library suffix explicitly, to allow for dllized versions. */
static autofilter_entry_type autofilter_liblist[] = static autofilter_entry_type autofilter_liblist[] =
{ {
{ "libcegcc", 8 },
{ "libcygwin", 9 }, { "libcygwin", 9 },
{ "libgcc", 6 }, { "libgcc", 6 },
{ "libstdc++", 9 }, { "libstdc++", 9 },
@ -261,9 +266,10 @@ static autofilter_entry_type autofilter_objlist[] =
static autofilter_entry_type autofilter_symbolprefixlist[] = static autofilter_entry_type autofilter_symbolprefixlist[] =
{ {
/* { "__imp_", 6 }, */ { "__imp_", 6 },
/* Do __imp_ explicitly to save time. */ /* Do __imp_ explicitly to save time. */
{ "__rtti_", 7 }, { "__rtti_", 7 },
{ ".idata$", 7 },
/* Don't re-export auto-imported symbols. */ /* Don't re-export auto-imported symbols. */
{ "_nm_", 4 }, { "_nm_", 4 },
{ "__builtin_", 10 }, { "__builtin_", 10 },
@ -1131,8 +1137,13 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
int nsyms, symsize; int nsyms, symsize;
/* If it's not loaded, we don't need to relocate it this way. */ /* 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)) if (!(s->output_section->flags & SEC_LOAD))
continue; 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 /* I don't know why there would be a reloc for these, but I've
seen it happen - DJ */ seen it happen - DJ */
@ -1780,6 +1791,14 @@ static unsigned char jmp_mips_bytes[] =
0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 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 * static bfd *
make_one (def_file_export *exp, bfd *parent) 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_bytes = jmp_mips_bytes;
jmp_byte_count = sizeof (jmp_mips_bytes); jmp_byte_count = sizeof (jmp_mips_bytes);
break; break;
case PE_ARCH_arm:
jmp_bytes = jmp_arm_bytes;
jmp_byte_count = sizeof (jmp_arm_bytes);
break;
default: default:
abort (); 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, 0, BFD_RELOC_LO16, 0); /* MIPS_R_PAIR */
quick_reloc (abfd, 4, BFD_RELOC_LO16, 2); quick_reloc (abfd, 4, BFD_RELOC_LO16, 2);
break; break;
case PE_ARCH_arm:
quick_reloc (abfd, 8, BFD_RELOC_32, 2);
break;
default: default:
abort (); abort ();
} }
@ -2048,7 +2074,7 @@ make_import_fixup_mark (arelent *rel)
return fixup_name; return fixup_name;
} }
/* .section .idata$3 /* .section .idata$2
.rva __nm_thnk_SYM (singleton thunk with name of func) .rva __nm_thnk_SYM (singleton thunk with name of func)
.long 0 .long 0
.long 0 .long 0
@ -2061,8 +2087,8 @@ make_import_fixup_entry (const char *name,
const char *dll_symname, const char *dll_symname,
bfd *parent) bfd *parent)
{ {
asection *id3; asection *id2;
unsigned char *d3; unsigned char *d2;
char *oname; char *oname;
bfd *abfd; bfd *abfd;
@ -2079,25 +2105,25 @@ make_import_fixup_entry (const char *name,
symptr = 0; symptr = 0;
symtab = xmalloc (6 * sizeof (asymbol *)); 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 ("_nm_thnk_"), name, "", UNDSEC, BSF_GLOBAL, 0);
quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0); quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0); quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
bfd_set_section_size (abfd, id3, 20); bfd_set_section_size (abfd, id2, 20);
d3 = xmalloc (20); d2 = xmalloc (20);
id3->contents = d3; id2->contents = d2;
memset (d3, 0, 20); memset (d2, 0, 20);
quick_reloc (abfd, 0, BFD_RELOC_RVA, 1); quick_reloc (abfd, 0, BFD_RELOC_RVA, 1);
quick_reloc (abfd, 12, BFD_RELOC_RVA, 2); quick_reloc (abfd, 12, BFD_RELOC_RVA, 2);
quick_reloc (abfd, 16, BFD_RELOC_RVA, 3); quick_reloc (abfd, 16, BFD_RELOC_RVA, 3);
save_relocs (id3); save_relocs (id2);
bfd_set_symtab (abfd, symtab, symptr); 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); bfd_make_readable (abfd);
return abfd; return abfd;

Loading…
Cancel
Save