Add support for WinCE based toolchains.

This commit is contained in:
Nick Clifton 2000-02-24 17:53:12 +00:00
parent cfcdbe9790
commit 344a211f99
13 changed files with 255 additions and 11 deletions

View file

@ -1,3 +1,29 @@
2000-02-24 Nick Clifton <nickc@cygnus.com>
* Makefile.am: Add rules to build emipspe.o and earmpe.o.
* Makefile.in: Regenerate.
* configure.tgt: Add targets for arm-wince, sh-pe and mips-pe.
* ldemul.h (ld_emulation_xfer_struct): Add new field:
find_potential_libraries.
* ldemul.c (ldemul_find_potential_libraries): New function.
* ldfile.c (ldfile_open_file_search): Allow function to be
exported.
(ldfile_open_file): Call ldemul_find_potential_libraries.
* ldfile.h: Add prototype for ldfile_open_file_search.
* pe-dll.c: Add support for ARM, MIPS and SH targets.
* emulparams/mipspe.sh: New file. Parameters for mips-pe target.
* emulparams/shpe.sh: New file. Parameters for sh-pe target.
* emultempl/pe.em: Add support for ARM, MIPS and SH DLLs.
(gld_X_find_potential_libraries): New function. Search for
libraries called "*.lib".
* scriptempl/pe.sc: Add .pdata section.
2000-02-23 Richard Henderson <rth@cygnus.com>
* scripttempl/elfd10v.sc: Remove dynamic linking hooks.

View file

@ -180,6 +180,7 @@ ALL_EMULATIONS = \
emipsidtl.o \
emipslit.o \
emipslnews.o \
emipspe.o \
enews.o \
epjelf.o \
epjlelf.o \
@ -194,6 +195,7 @@ ALL_EMULATIONS = \
eshelf.o \
eshlelf.o \
eshl.o \
eshpe.o \
esparcaout.o \
esparclinux.o \
esparclynx.o \
@ -548,6 +550,9 @@ emipslit.c: $(srcdir)/emulparams/mipslit.sh \
emipslnews.c: $(srcdir)/emulparams/mipslnews.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
${GENSCRIPTS} mipslnews
emipspe.c: $(srcdir)/emulparams/mipspe.sh \
$(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
${GENSCRIPTS} mipspe "$(tdir_mips)"
emn10300.c: $(srcdir)/emulparams/mn10300.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} mn10300 "$(tdir_mn10300)"
@ -596,6 +601,9 @@ eshlelf.c: $(srcdir)/emulparams/shlelf.sh \
eshl.c: $(srcdir)/emulparams/shl.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sh.sc ${GEN_DEPENDS}
${GENSCRIPTS} shl "$(tdir_shl)"
eshpe.c: $(srcdir)/emulparams/shpe.sh \
$(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
${GENSCRIPTS} shpe "$(tdir_shl)"
esparcaout.c: $(srcdir)/emulparams/sparcaout.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
${GENSCRIPTS} sparcaout "$(tdir_sparcaout)"

View file

@ -285,6 +285,7 @@ ALL_EMULATIONS = \
emipsidtl.o \
emipslit.o \
emipslnews.o \
emipspe.o \
enews.o \
epjelf.o \
epjlelf.o \
@ -299,6 +300,7 @@ ALL_EMULATIONS = \
eshelf.o \
eshlelf.o \
eshl.o \
eshpe.o \
esparcaout.o \
esparclinux.o \
esparclynx.o \
@ -1249,6 +1251,9 @@ emipslit.c: $(srcdir)/emulparams/mipslit.sh \
emipslnews.c: $(srcdir)/emulparams/mipslnews.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
${GENSCRIPTS} mipslnews
emipspe.c: $(srcdir)/emulparams/mipspe.sh \
$(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
${GENSCRIPTS} mipspe "$(tdir_mips)"
emn10300.c: $(srcdir)/emulparams/mn10300.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} mn10300 "$(tdir_mn10300)"
@ -1297,6 +1302,9 @@ eshlelf.c: $(srcdir)/emulparams/shlelf.sh \
eshl.c: $(srcdir)/emulparams/shl.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sh.sc ${GEN_DEPENDS}
${GENSCRIPTS} shl "$(tdir_shl)"
eshpe.c: $(srcdir)/emulparams/shpe.sh \
$(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
${GENSCRIPTS} shpe "$(tdir_shl)"
esparcaout.c: $(srcdir)/emulparams/sparcaout.sh \
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
${GENSCRIPTS} sparcaout "$(tdir_sparcaout)"

View file

@ -16,6 +16,8 @@ targ_extra_ofiles=
case "${targ}" in
arm-epoc-pe) targ_emul=arm_epoc_pe ;
targ_extra_ofiles="deffilep.o pe-dll.o" ;;
arm-*-wince) targ_emul=armpe ;
targ_extra_ofiles="deffilep.o pe-dll.o" ;;
arm-*-pe) targ_emul=armpe ;
targ_extra_ofiles="deffilep.o pe-dll.o" ;;
arc-*-elf*) targ_emul=arcelf ;;
@ -157,6 +159,8 @@ sh-*-elf* | sh-*-rtemself*)
targ_emul=shelf
targ_extra_emuls="shlelf sh shl"
;;
sh-*-pe) targ_emul=shpe ;
targ_extra_ofiles="deffilep.o pe-dll.o" ;;
sh-*-*|sh-*-rtems*) targ_emul=sh; targ_extra_emuls=shl ;;
m68k-sony-*) targ_emul=news ;;
m68k-hp-bsd*) targ_emul=hp300bsd ;;
@ -185,6 +189,8 @@ hppa*-*-linux-gnu*) targ_emul=hppaelf ;;
hppa*-*-lites*) targ_emul=hppaelf ;;
hppa*-*-rtems*) targ_emul=hppaelf ;;
vax-dec-ultrix* | vax-dec-bsd*) targ_emul=vax ;;
mips*-*-pe) targ_emul=mipspe ;
targ_extra_ofiles="deffilep.o pe-dll.o" ;;
mips*-dec-ultrix*) targ_emul=mipslit ;;
mips*-dec-osf*) targ_emul=mipslit ;;
mips*-sgi-irix5*) targ_emul=elf32bsmip ;;

6
ld/emulparams/mipspe.sh Normal file
View file

@ -0,0 +1,6 @@
ARCH=mips
SCRIPT_NAME=pe
OUTPUT_FORMAT="pei-mips"
OUTPUT_ARCH="mips"
RELOCATEABLE_OUTPUT_FORMAT="ecoff-littlemips"
TEMPLATE_NAME=pe

4
ld/emulparams/shpe.sh Normal file
View file

@ -0,0 +1,4 @@
ARCH=sh
SCRIPT_NAME=pe
OUTPUT_FORMAT="pei-shl"
TEMPLATE_NAME=pe

View file

@ -65,8 +65,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if defined(TARGET_IS_i386pe)
#define DLL_SUPPORT
#endif
#if defined(TARGET_IS_shpe) || defined(TARGET_IS_mipspe) || defined(TARGET_IS_armpe)
#define DLL_SUPPORT
#endif
#if defined(TARGET_IS_i386pe) || ! defined(DLL_SUPPORT)
#define PE_DEF_SUBSYSTEM 3
#else
#undef NT_EXE_IMAGE_BASE
#undef PE_DEF_SECTION_ALIGNMENT
#undef PE_DEF_FILE_ALIGNMENT
#define NT_EXE_IMAGE_BASE 0x00010000
#ifdef TARGET_IS_armpe
#define PE_DEF_SECTION_ALIGNMENT 0x00001000
#define PE_DEF_SUBSYSTEM 9
#else
#define PE_DEF_SECTION_ALIGNMENT 0x00000400
#define PE_DEF_SUBSYSTEM 2
#endif
#define PE_DEF_FILE_ALIGNMENT 0x00000200
#endif
#ifdef TARGET_IS_arm_epoc_pe
#define bfd_arm_pe_allocate_interworking_sections \
@ -109,6 +127,14 @@ gld_${EMULATION_NAME}_before_parse()
ldfile_output_architecture = bfd_arch_${ARCH};
#ifdef DLL_SUPPORT
config.has_shared = 1;
#if (PE_DEF_SUBSYSTEM == 9) || (PE_DEF_SUBSYSTEM == 2)
#if defined TARGET_IS_mipspe || defined TARGET_IS_armpe
lang_add_entry ("WinMainCRTStartup", 1);
#else
lang_add_entry ("_WinMainCRTStartup", 1);
#endif
#endif
#endif
}
@ -207,7 +233,11 @@ static definfo init[] =
D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
D(MajorImageVersion,"__major_image_version__", 1),
D(MinorImageVersion,"__minor_image_version__", 0),
#ifdef TARGET_IS_armpe
D(MajorSubsystemVersion,"__major_subsystem_version__", 2),
#else
D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
#endif
D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
D(Subsystem,"__subsystem__", ${SUBSYSTEM}),
D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x2000000),
@ -288,13 +318,18 @@ set_pe_subsystem ()
v[] =
{
{ "native", 1, "NtProcessStartup" },
#if defined TARGET_IS_mipspe || defined TARGET_IS_armpe
{ "windows", 2, "WinMainCRTStartup" },
#else
{ "windows", 2, "WinMainCRTStartup" },
#endif
{ "console", 3, "mainCRTStartup" },
#if 0
/* The Microsoft linker does not recognize this. */
{ "os2", 5, "" },
#endif
{ "posix", 7, "__PosixProcessStartup"},
{ "wince", 9, "_WinMainCRTStartup" },
{ 0, 0, 0 }
};
@ -692,6 +727,13 @@ gld_${EMULATION_NAME}_after_open ()
pe_process_import_defs(output_bfd, &link_info);
if (link_info.shared)
pe_dll_build_sections (output_bfd, &link_info);
#ifndef TARGET_IS_i386pe
#ifndef TARGET_IS_armpe
else
pe_exe_build_sections (output_bfd, &link_info);
#endif
#endif
#endif
#if defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe)
@ -930,6 +972,15 @@ gld_${EMULATION_NAME}_recognized_file(entry)
#ifdef DLL_SUPPORT
#ifdef TARGET_IS_i386pe
pe_dll_id_target ("pei-i386");
#endif
#ifdef TARGET_IS_shpe
pe_dll_id_target ("pei-shl");
#endif
#ifdef TARGET_IS_mipspe
pe_dll_id_target ("pei-mips");
#endif
#ifdef TARGET_IS_armpe
pe_dll_id_target ("pei-arm-little");
#endif
if (bfd_get_format (entry->the_bfd) == bfd_object)
{
@ -992,6 +1043,13 @@ gld_${EMULATION_NAME}_finish ()
if (pe_implib_filename)
pe_dll_generate_implib (pe_def_file, pe_implib_filename);
}
#if defined(TARGET_IS_shpe) || defined(TARGET_IS_mipspe)
else
{
pe_exe_fill_sections (output_bfd, &link_info);
}
#endif
if (pe_out_def_filename)
pe_dll_generate_def_file (pe_out_def_filename);
#endif
@ -1236,6 +1294,14 @@ gld${EMULATION_NAME}_place_section (s)
else if (strcmp (os->name, ".bss") == 0)
hold_bss = os;
}
static int
gld_${EMULATION_NAME}_find_potential_libraries (name, entry)
char * name;
lang_input_statement_type * entry;
{
return ldfile_open_file_search (name, entry, "", ".lib");
}
static char *
gld_${EMULATION_NAME}_get_script(isfile)
@ -1288,6 +1354,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
gld_${EMULATION_NAME}_parse_args,
gld_${EMULATION_NAME}_unrecognized_file,
gld_${EMULATION_NAME}_list_options,
gld_${EMULATION_NAME}_recognized_file
gld_${EMULATION_NAME}_recognized_file,
gld_${EMULATION_NAME}_find_potential_libraries
};
EOF

View file

@ -297,3 +297,14 @@ ldemul_list_emulation_options (f)
if (! options_found)
fprintf (f, _(" no emulation specific options.\n"));
}
int
ldemul_find_potential_libraries (name, entry)
char * name;
lang_input_statement_type * entry;
{
if (ld_emulation->find_potential_libraries)
return ld_emulation->find_potential_libraries (name, entry);
return 0;
}

View file

@ -1,5 +1,5 @@
/* ld-emul.h - Linker emulation header file
Copyright 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
Copyright 1991, 92, 93, 94, 95, 96, 97, 1998, 2000 Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
@ -55,6 +55,8 @@ extern void before_allocation_default PARAMS ((void));
extern void set_output_arch_default PARAMS ((void));
extern void syslib_default PARAMS ((char*));
extern void hll_default PARAMS ((char*));
extern int ldemul_find_potential_libraries
PARAMS ((char *, struct lang_input_statement_struct *));
typedef struct ld_emulation_xfer_struct
{
@ -135,6 +137,13 @@ typedef struct ld_emulation_xfer_struct
boolean (*recognized_file)
PARAMS ((struct lang_input_statement_struct *));
/* Called when looking for libraries in a directory specified
via a linker command line option or linker script option.
Files that match the pattern "lib*.a" have already been scanned.
(For VMS files matching ":lib*.a" have also been scanned). */
int (* find_potential_libraries)
PARAMS ((char *, struct lang_input_statement_struct *));
} ld_emulation_xfer_type;
typedef enum

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 92, 93, 94, 95, 98, 1999 Free Software Foundation, Inc.
/* Copyright (C) 1991, 92, 93, 94, 95, 98, 99, 2000 Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
@ -74,9 +74,6 @@ typedef struct search_arch
static search_arch_type *search_arch_head;
static search_arch_type **search_arch_tail_ptr = &search_arch_head;
static boolean ldfile_open_file_search
PARAMS ((const char *arch, lang_input_statement_type *,
const char *lib, const char *suffix));
static FILE *try_open PARAMS ((const char *name, const char *exten));
void
@ -150,7 +147,7 @@ ldfile_try_open_bfd (attempt, entry)
/* Search for and open the file specified by ENTRY. If it is an
archive, use ARCH, LIB and SUFFIX to modify the file name. */
static boolean
boolean
ldfile_open_file_search (arch, entry, lib, suffix)
const char *arch;
lang_input_statement_type *entry;
@ -247,6 +244,8 @@ ldfile_open_file (entry)
if (ldfile_open_file_search (arch->name, entry, ":lib", ".a"))
return;
#endif
if (ldemul_find_potential_libraries (arch->name, entry))
return;
}
einfo (_("%F%P: cannot find %s\n"), entry->local_sym_name);
}

View file

@ -51,3 +51,6 @@ extern boolean ldfile_try_open_bfd
extern FILE *ldfile_find_command_file
PARAMS ((const char *name, const char *extend));
extern void ldfile_set_output_arch PARAMS ((CONST char *));
extern boolean ldfile_open_file_search
PARAMS ((const char *arch, lang_input_statement_type *,
const char *lib, const char *suffix));

View file

@ -86,6 +86,9 @@ typedef struct {
} pe_details_type;
#define PE_ARCH_i386 1
#define PE_ARCH_sh 2
#define PE_ARCH_mips 3
#define PE_ARCH_arm 4
static pe_details_type pe_detail_list[] = {
{
@ -96,6 +99,30 @@ static pe_details_type pe_detail_list[] = {
bfd_arch_i386,
1
},
{
"pei-shl",
"pe-shl",
16 /* R_SH_IMAGEBASE */,
PE_ARCH_sh,
bfd_arch_sh,
1
},
{
"pei-mips",
"pe-mips",
34 /* MIPS_R_RVA */,
PE_ARCH_mips,
bfd_arch_mips,
0
},
{
"pei-arm-little",
"pe-arm-little",
11 /* ARM_RVA32 */,
PE_ARCH_arm,
bfd_arch_arm,
0
},
{ NULL, NULL, 0, 0, 0, 0 }
};
@ -403,7 +430,7 @@ process_def_file (abfd, info)
exported_symbol_sections[i] = blhe->u.def.section;
else
exported_symbol_sections[i] = blhe->u.c.p->section;
if (pe_def_file->exports[i].ordinal != -1)
{
if (max_ordinal < pe_def_file->exports[i].ordinal)
@ -776,13 +803,32 @@ generate_reloc (abfd, info)
+ sym->section->output_offset
+ sym->section->output_section->vma);
reloc_data[total_relocs].vma = sec_vma + relocs[i]->address;
switch (relocs[i]->howto->bitsize*1000
+ relocs[i]->howto->rightshift)
#define BITS_AND_SHIFT(bits, shift) (bits * 1000 | shift)
switch BITS_AND_SHIFT (relocs[i]->howto->bitsize,
relocs[i]->howto->rightshift)
{
case 32000:
case BITS_AND_SHIFT (32, 0):
reloc_data[total_relocs].type = 3;
total_relocs++;
break;
case BITS_AND_SHIFT (16, 0):
reloc_data[total_relocs].type = 2;
total_relocs++;
break;
case BITS_AND_SHIFT (16, 16):
reloc_data[total_relocs].type = 4;
/* FIXME: we can't know the symbol's right value yet,
but we probably can safely assume that CE will relocate
us in 64k blocks, so leaving it zero is safe. */
reloc_data[total_relocs].extra = 0;
total_relocs++;
break;
case BITS_AND_SHIFT (26, 2):
reloc_data[total_relocs].type = 5;
total_relocs++;
break;
default:
/* xgettext:c-format */
einfo (_("%XError: %d-bit reloc in dll\n"),
@ -807,13 +853,18 @@ generate_reloc (abfd, info)
for (i = 0; i < total_relocs; i++)
{
unsigned long this_page = (reloc_data[i].vma >> 12);
if (this_page != sec_page)
{
reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align */
reloc_sz += 8;
sec_page = this_page;
}
reloc_sz += 2;
if (reloc_data[i].type == 4)
reloc_sz += 2;
}
reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align */
@ -1319,6 +1370,31 @@ static unsigned char jmp_ix86_bytes[] = {
0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
};
/*
*_function:
* mov.l ip+8,r0
* mov.l @r0,r0
* jmp @r0
* nop
* .dw __imp_function
*/
static unsigned char jmp_sh_bytes[] = {
0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00
};
/*
*_function:
* lui $t0,<high:__imp_function>
* lw $t0,<low:__imp_function>
* jr $t0
* nop
*/
static unsigned char jmp_mips_bytes[] = {
0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d,
0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
};
static bfd *
make_one (exp, parent)
@ -1339,6 +1415,14 @@ make_one (exp, parent)
jmp_bytes = jmp_ix86_bytes;
jmp_byte_count = sizeof (jmp_ix86_bytes);
break;
case PE_ARCH_sh:
jmp_bytes = jmp_sh_bytes;
jmp_byte_count = sizeof (jmp_sh_bytes);
break;
case PE_ARCH_mips:
jmp_bytes = jmp_mips_bytes;
jmp_byte_count = sizeof (jmp_mips_bytes);
break;
}
oname = (char *) xmalloc (20);
@ -1376,6 +1460,14 @@ make_one (exp, parent)
case PE_ARCH_i386:
quick_reloc (abfd, 2, BFD_RELOC_32, 2);
break;
case PE_ARCH_sh:
quick_reloc (abfd, 8, BFD_RELOC_32, 2);
break;
case PE_ARCH_mips:
quick_reloc (abfd, 0, BFD_RELOC_HI16_S, 2);
quick_reloc (abfd, 0, BFD_RELOC_LO16, 0); /* MIPS_R_PAIR */
quick_reloc (abfd, 4, BFD_RELOC_LO16, 2);
break;
}
save_relocs (tx);

View file

@ -87,6 +87,11 @@ SECTIONS
*(.eh_frame)
}
.pdata ${RELOCATING+BLOCK(__section_alignment__)} :
{
*(.pdata)
}
.bss ${RELOCATING+BLOCK(__section_alignment__)} :
{
${RELOCATING+__bss_start__ = . ;}