mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-19 22:44:16 +08:00
Apply fixes to allow arm WinCE toolchain to produce working executables.
This commit is contained in:
parent
ad623ec6b4
commit
53baae4870
@ -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>
|
||||
|
||||
PR 2342
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
||||
* config/tc-mips.c (append_insn): Only warn about an out-of-range
|
||||
|
@ -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
|
||||
|
14
ld/ChangeLog
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>
|
||||
|
||||
* ld.texinfo: Document PowerPC and PowerPC64 options.
|
||||
|
@ -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
|
||||
|
52
ld/pe-dll.c
52
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 <dj@cygnus.com>
|
||||
|
||||
@ -95,7 +95,7 @@
|
||||
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
|
||||
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_<sym> 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;
|
||||
|
Loading…
Reference in New Issue
Block a user