WinCE support in LD

Nick Clifton nickc@cygnus.com
Wed Feb 23 15:47:00 GMT 2000


Hi Guys,

  Unless anyone has any objections I would like ot apply the following
  patch.  It adds support to LD for toolchains targeted at Microsoft's
  Windows CE operating system.  At the moment these targets are
  mips-pe, sh-pe and arm-wince. 

  Note - the ARM target used to be called arm-wince-pe, but it has
  been pointed out to me that this is wrong, and that it ought to be
  arm-wince instead.  I will be fixing the patches for the other parts
  of the toolchain that I have already sent out.

  Patches for other parts of binutils will follow.

Cheers
	Nick

2000-02-23  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.

	* ldfile.c (ldfile_open_file): Add library search of *.lib
	files.

	* 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.

	* scriptempl/pe.sc: Add .pdata section.

Index: Makefile.am
===================================================================
RCS file: /cvs/src//src/ld/Makefile.am,v
retrieving revision 1.19
diff -p -w -r1.19 Makefile.am
*** Makefile.am	1999/12/02 11:49:19	1.19
--- Makefile.am	2000/02/23 23:40:13
*************** ALL_EMULATIONS = \
*** 179,184 ****
--- 179,185 ----
  	emipsidtl.o \
  	emipslit.o \
  	emipslnews.o \
+ 	emipspe.o \
  	enews.o \
  	epjelf.o \
  	epjlelf.o \
*************** ALL_EMULATIONS = \
*** 193,198 ****
--- 194,200 ----
  	eshelf.o \
  	eshlelf.o \
  	eshl.o \
+ 	eshpe.o \
  	esparcaout.o \
  	esparclinux.o \
  	esparclynx.o \
*************** emipslit.c:  $(srcdir)/emulparams/mipsli
*** 544,549 ****
--- 546,554 ----
  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)"
*************** eshlelf.c: $(srcdir)/emulparams/shlelf.s
*** 592,597 ****
--- 597,605 ----
  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)"

Index: Makefile.in
===================================================================
RCS file: /cvs/src//src/ld/Makefile.in,v
retrieving revision 1.20
diff -p -w -r1.20 Makefile.in
*** Makefile.in	1999/12/02 11:49:19	1.20
--- Makefile.in	2000/02/23 23:40:13
*************** ALL_EMULATIONS = \
*** 284,289 ****
--- 284,290 ----
  	emipsidtl.o \
  	emipslit.o \
  	emipslnews.o \
+ 	emipspe.o \
  	enews.o \
  	epjelf.o \
  	epjlelf.o \
*************** ALL_EMULATIONS = \
*** 298,303 ****
--- 299,305 ----
  	eshelf.o \
  	eshlelf.o \
  	eshl.o \
+ 	eshpe.o \
  	esparcaout.o \
  	esparclinux.o \
  	esparclynx.o \
*************** emipslit.c:  $(srcdir)/emulparams/mipsli
*** 1245,1250 ****
--- 1247,1255 ----
  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)"
*************** eshlelf.c: $(srcdir)/emulparams/shlelf.s
*** 1293,1298 ****
--- 1298,1306 ----
  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)"

Index: configure.tgt
===================================================================
RCS file: /cvs/src//src/ld/configure.tgt,v
retrieving revision 1.18
diff -p -w -r1.18 configure.tgt
*** configure.tgt	2000/01/10 19:46:19	1.18
--- configure.tgt	2000/02/23 23:40:13
*************** targ_extra_ofiles=
*** 16,21 ****
--- 16,23 ----
  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 ;;
*************** sh-*-elf* | sh-*-rtemself*)
*** 155,160 ****
--- 157,164 ----
  			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 ;;
*************** hppa*-*-linux-gnu*)	targ_emul=hppaelf ;;
*** 183,188 ****
--- 187,194 ----
  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 ;;

Index: ldfile.c
===================================================================
RCS file: /cvs/src//src/ld/ldfile.c,v
retrieving revision 1.3
diff -p -w -r1.3 ldfile.c
*** ldfile.c	1999/07/09 22:52:05	1.3
--- ldfile.c	2000/02/23 23:40:13
*************** ldfile_open_file (entry)
*** 247,252 ****
--- 247,254 ----
  	  if (ldfile_open_file_search (arch->name, entry, ":lib", ".a"))
  	    return;
  #endif
+ 	  if (ldfile_open_file_search (arch->name, entry, "", ".lib"))
+ 	    return;
  	}
        einfo (_("%F%P: cannot find %s\n"), entry->local_sym_name);
      }

Index: pe-dll.c
===================================================================
RCS file: /cvs/src//src/ld/pe-dll.c,v
retrieving revision 1.8
diff -p -w -r1.8 pe-dll.c
*** pe-dll.c	2000/01/04 23:44:03	1.8
--- pe-dll.c	2000/02/23 23:40:14
*************** typedef struct {
*** 86,91 ****
--- 86,94 ----
  } 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[] = {
    {
*************** static pe_details_type pe_detail_list[] 
*** 96,101 ****
--- 99,128 ----
      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 }
  };
  
*************** generate_reloc (abfd, info)
*** 783,788 ****
--- 810,831 ----
  		      reloc_data[total_relocs].type = 3;
  		      total_relocs++;
  		      break;
+ 		    case 16000:
+ 		      reloc_data[total_relocs].type = 2;
+ 		      total_relocs++;
+ 		      break;
+ 		    case 16016:
+ 		      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 26002:
+ 		      reloc_data[total_relocs].type = 5;
+ 		      total_relocs++;
+ 		      break;
  		    default:
  		      /* xgettext:c-format */
  		      einfo (_("%XError: %d-bit reloc in dll\n"),
*************** generate_reloc (abfd, info)
*** 807,819 ****
--- 850,867 ----
    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 */
  
*************** static unsigned char jmp_ix86_bytes[] = 
*** 1319,1324 ****
--- 1367,1397 ----
    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)
*************** make_one (exp, parent)
*** 1339,1344 ****
--- 1412,1425 ----
        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);
*************** make_one (exp, parent)
*** 1375,1380 ****
--- 1456,1469 ----
      {
      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);

Index: emulparams/mipspe.sh
===================================================================
RCS file: mipspe.sh
diff -N mipspe.sh
*** /dev/null	Tue May  5 13:32:27 1998
--- mipspe.sh	Wed Feb 23 15:40:14 2000
***************
*** 0 ****
--- 1,6 ----
+ ARCH=mips
+ SCRIPT_NAME=pe
+ OUTPUT_FORMAT="pei-mips"
+ OUTPUT_ARCH="mips"
+ RELOCATEABLE_OUTPUT_FORMAT="ecoff-littlemips"
+ TEMPLATE_NAME=pe

Index: emulparams/shpe.sh
===================================================================
RCS file: shpe.sh
diff -N shpe.sh
*** /dev/null	Tue May  5 13:32:27 1998
--- shpe.sh	Wed Feb 23 15:40:14 2000
***************
*** 0 ****
--- 1,4 ----
+ ARCH=sh
+ SCRIPT_NAME=pe
+ OUTPUT_FORMAT="pei-shl"
+ TEMPLATE_NAME=pe

Index: emultempl/pe.em
===================================================================
RCS file: /cvs/src//src/ld/emultempl/pe.em,v
retrieving revision 1.18
diff -p -w -r1.18 pe.em
*** pe.em	2000/02/16 18:53:32	1.18
--- pe.em	2000/02/23 23:40:15
*************** Foundation, Inc., 59 Temple Place - Suit
*** 65,72 ****
--- 65,90 ----
  #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 \
*************** gld_${EMULATION_NAME}_before_parse()
*** 109,114 ****
--- 127,140 ----
    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
  }
  
*************** static definfo init[] =
*** 207,213 ****
--- 233,243 ----
    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),
*************** set_pe_subsystem ()
*** 288,300 ****
--- 318,335 ----
    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 }
      };
  
*************** gld_${EMULATION_NAME}_after_open ()
*** 692,698 ****
--- 727,740 ----
    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)
    if (strstr (bfd_get_target (output_bfd), "arm") == NULL)
*************** gld_${EMULATION_NAME}_recognized_file(en
*** 931,936 ****
--- 973,987 ----
  #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)
      {
        const char *ext = entry->filename + strlen (entry->filename) - 4;
*************** gld_${EMULATION_NAME}_finish ()
*** 992,997 ****
--- 1043,1055 ----
        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

Index: scripttempl/pe.sc
===================================================================
RCS file: /cvs/src//src/ld/scripttempl/pe.sc,v
retrieving revision 1.3
diff -p -w -r1.3 pe.sc
*** pe.sc	1999/09/12 16:48:02	1.3
--- pe.sc	2000/02/23 23:40:15
*************** SECTIONS
*** 87,92 ****
--- 87,97 ----
      *(.eh_frame)
    }
  
+   .pdata ${RELOCATING+BLOCK(__section_alignment__)} :
+   {
+     *(.pdata)
+   }
+ 
    .bss ${RELOCATING+BLOCK(__section_alignment__)} :
    {
      ${RELOCATING+__bss_start__ = . ;}


More information about the Binutils mailing list