public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
@ 2009-03-06 19:25 Charles Wilson
  0 siblings, 0 replies; 36+ messages in thread
From: Charles Wilson @ 2009-03-06 19:25 UTC (permalink / raw)
  To: binutils; +Cc: cygwin

[oops. I replied to a non-existent list, so binutils never saw this and
cygwin will see it twice. Sorry about that]

Christopher Faylor wrote:
> I would like to see an objcopy option at some point.  I don't agree with
> the prevailing cygwin opinion that you need a separate binary to deal
> with this.  It seems silly to have objcopy able to do only some things
> to a PE and, if objcopy can do this, then I don't see why you need an
> extra program to manipulate this field.

I agree that objcopy should be able to manipulate this (these) field(s).
However, having a simple tool that does a simple thing is The Unix Way.
Having a giant do-everything tool is...not.  For that we have Perl. <g>

[The following gets OT for binutils; I've CC:ed the cygwin list. If you
wish to continue this subthread, please take it over there]

Seriously, with regards to cygwin though, there are a few important
reasons for the bit-twiddler program to be separate from  objcopy, even
if it duplicates some of its functionality.

1) we're going to recommend that -- until everything in the cygwin
   distro is rebuilt using a not-yet-available ld with new defaults --
   users (including lusers and n00bs) -- run a bit-twiddler tool on
   many, if not all, of the DLLs and EXEs in their installation. It
   would be bad if this tool was developer-centric, with lots of
   confusing (to the uninitiated) options that have the potential to
   seriously foul up the target object(s) in unrecoverable ways, if used
   incorrectly.  Like objcopy.  The bit-twiddler proggie, being so
   simple and limited in scope, can always revert any changes it makes.
   Even when used by a n00b.

2) Do we really want all users -- who might not be developers -- who
   happen to run in to a particular problem be forced to download and
   install all of binutils, just for objcopy?

3) We're dealing with an issue where EXEs will not operate at all if
   they do not have the correct DllCharacteristics bits.  Which exes
   suffer from this limitation is not immediately obvious, and we don't
   know what triggers the misbehavior (on WindowsTS, at least). So far
   we are "lucky" -- it appears that the binutils tools such as nm and
   objcopy are NOT affected by this issue, but we don't know why, nor if
   our "luck" will change in the future. In the end, we might be forced
   to distribute the bit-twiddler as a mingw app, not a cygwin one. I
   don't think we (cygwin) want to distribute a standalone version of
   i686-pc-mingw32-objcopy, nor as in #2 above, force all users (who
   happen to run in to ...) to download mingw-cross-binutils.

4) The behavior of a specific bit-twiddler program can be tweaked to
   better suit our intended purpose: to be called on a large list of
   files ONCE to perform similar operations on all of those files, thus
   avoiding lots of forks.  This is important not just for speed, but
   also because the dynbase issue is the solution to a problem that
   fails specifically when you're doing a lot of forks. (Granted, you
   could avoid this latter issue by ensuring that the bit-twiddler
   program -- be it objdump or peflags -- itself is only shipped with
   the dynbase flag preset). But AFAIK objdump is not meant to operate
   in a "SIMD" manner -- that is, do the same operation on an entire
   list of target objects. Rather, objcopy takes exactly two file names:
   one input and one optional output.  If the output file isn't
   specified, then the temporary modified version is renamed over the
   input (which is the behavior we'd want to exploit for a make-all-
   dynbase script -- or we'd do the rename manually IN that script,
   having given objcopy an explicit temporary name for its output).
   That's a lot of extra disk writes and data copying -- again, slow.
   peflags operates inplace.

5) Why does cygwin ship rebase? Technically objcopy could and should do
   this, too (even though that particular operation is a lot more
   complicated than just setting a value in the PE file's header). But
   #1 thru #4 above all also apply with regards to rebase.exe, even if
   objcopy had that capability.

--
Chuck

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-13  3:10                                     ` Dave Korn
@ 2009-03-13  8:33                                       ` Nick Clifton
  0 siblings, 0 replies; 36+ messages in thread
From: Nick Clifton @ 2009-03-13  8:33 UTC (permalink / raw)
  To: Dave Korn, Danny Smith; +Cc: NightStrike, binutils

Hi Dave, Hi Danny,

>   Cross-tested from i686-pc-linux-gnu to {arm-epoc-pe arm-wince-pe,
> i386-pc-netbsdpe, i386-pc-pe i586-pc-interix, i586-unknown-beospe,
> i686-pc-cygwin, i686-pc-mingw32, mcore-unknown-pe, powerpcle-unknown-pe,
> sh-unknown-pe, thumb-epoc-pe, x86_64-pc-freebsd, x86_64-pc-linux-gnu,
> x86_64-pc-mingw32} with no regressions.

Great - please consider this patch approved.

Cheers
   Nick



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-12 18:03                                   ` Dave Korn
@ 2009-03-13  3:10                                     ` Dave Korn
  2009-03-13  8:33                                       ` Nick Clifton
  0 siblings, 1 reply; 36+ messages in thread
From: Dave Korn @ 2009-03-13  3:10 UTC (permalink / raw)
  To: Dave Korn; +Cc: Nick Clifton, Danny Smith, NightStrike, binutils

Dave Korn wrote:
> Dave Korn wrote:
> 
>>   I suspect this is caused by a stray hunk in Danny's patch:
> 
>   Yep.  Now doing a full test run on this revised version, results in a few hours.

  Cross-tested from i686-pc-linux-gnu to {arm-epoc-pe arm-wince-pe,
i386-pc-netbsdpe, i386-pc-pe i586-pc-interix, i586-unknown-beospe,
i686-pc-cygwin, i686-pc-mingw32, mcore-unknown-pe, powerpcle-unknown-pe,
sh-unknown-pe, thumb-epoc-pe, x86_64-pc-freebsd, x86_64-pc-linux-gnu,
x86_64-pc-mingw32} with no regressions.  Haven't actually verified if it works
correctly yet.

    cheers,
      DaveK

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-12 17:28                                 ` Dave Korn
@ 2009-03-12 18:03                                   ` Dave Korn
  2009-03-13  3:10                                     ` Dave Korn
  0 siblings, 1 reply; 36+ messages in thread
From: Dave Korn @ 2009-03-12 18:03 UTC (permalink / raw)
  To: Dave Korn; +Cc: Nick Clifton, Danny Smith, NightStrike, binutils

[-- Attachment #1: Type: text/plain, Size: 190 bytes --]

Dave Korn wrote:

>   I suspect this is caused by a stray hunk in Danny's patch:

  Yep.  Now doing a full test run on this revised version, results in a few hours.

    cheers,
      DaveK

[-- Attachment #2: dll_characteristic_SEP-revised.diff --]
[-- Type: text/plain, Size: 13078 bytes --]

Index: include/coff/internal.h
===================================================================
RCS file: /cvs/src/src/include/coff/internal.h,v
retrieving revision 1.22
diff -p -u -r1.22 internal.h
--- include/coff/internal.h	12 Jul 2007 07:16:41 -0000	1.22
+++ include/coff/internal.h	12 Mar 2009 17:59:37 -0000
@@ -185,7 +185,7 @@ struct internal_extra_pe_aouthdr 
      3 - WINDOWS_CUI runs in Windows char sub. (console app)
      5 - OS2_CUI runs in OS/2 character subsystem
      7 - POSIX_CUI runs in Posix character subsystem */
-  short   DllCharacteristics;	/* flags for DLL init, use 0 */
+  unsigned short DllCharacteristics; /* flags for DLL init  */
   bfd_vma SizeOfStackReserve;	/* amount of memory to reserve  */
   bfd_vma SizeOfStackCommit;	/* amount of memory initially committed for 
 				   initial thread's stack, default is 0x1000 */
Index: include/coff/pe.h
===================================================================
RCS file: /cvs/src/src/include/coff/pe.h,v
retrieving revision 1.18
diff -p -u -r1.18 pe.h
--- include/coff/pe.h	4 Nov 2007 23:49:08 -0000	1.18
+++ include/coff/pe.h	12 Mar 2009 17:59:37 -0000
@@ -38,6 +38,17 @@
 #define IMAGE_FILE_UP_SYSTEM_ONLY            0x4000
 #define IMAGE_FILE_BYTES_REVERSED_HI         0x8000
 
+/* DllCharacteristics flag bits.  The inconsistent naming may seem
+   odd, but that is how they are defined in the PE specification.  */
+#define IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE          0x0040
+#define IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY       0x0080
+#define IMAGE_DLL_CHARACTERISTICS_NX_COMPAT             0x0100
+#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION           0x0200
+#define IMAGE_DLLCHARACTERISTICS_NO_SEH                 0x0400
+#define IMAGE_DLLCHARACTERISTICS_NO_BIND                0x0800
+#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER             0x2000
+#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE  0x8000
+
 /* Additional flags to be set for section headers to allow the NT loader to
    read and write to the section data (to replace the addresses of data in
    dlls for one thing); also to execute the section in .text's case.  */
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.235
diff -p -u -r1.235 ld.texinfo
--- ld/ld.texinfo	3 Mar 2009 18:22:10 -0000	1.235
+++ ld/ld.texinfo	12 Mar 2009 17:59:39 -0000
@@ -2488,6 +2488,46 @@ the subsystem version also.  Numeric val
 @var{which}.
 [This option is specific to the i386 PE targeted port of the linker]
 
+The following options set flags in the @code{DllCharacteristics} field
+of the PE file header:
+[These options are specific to PE targeted ports of the linker]
+
+@kindex --dynamicbase
+@item --dynamicbase
+The image base address may be relocated using address space layout
+randomization (ASLR).  This feature was introduced with MS Windows
+Vista for i386 PE targets.
+
+@kindex --forceinteg
+@item --forceinteg
+Code integrity checks are enforced.
+
+@kindex --nxcompat
+@item --nxcompat
+The image is compatible with the Data Execution Prevention.
+This feature was introduced with MS Windows XP SP2 for i386 PE targets.
+
+@kindex --no-isolation
+@item --no-isolation
+Although the image understands isolation, do not isolate the image.
+
+@kindex --no-seh
+@item --no-seh
+The image does not use SEH. No SE handler may be called from
+this image.
+
+@kindex --no-bind
+@item --no-bind
+Do not bind this image.
+
+@kindex --wdmdriver
+@item --wdmdriver
+The driver uses the MS Windows Driver Model.
+ 
+@kindex --tsaware
+@item --tsaware
+The image is Terminal Server aware.
+
 @end table
 
 @c man end
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.146
diff -p -u -r1.146 pe.em
--- ld/emultempl/pe.em	3 Mar 2009 18:22:11 -0000	1.146
+++ ld/emultempl/pe.em	12 Mar 2009 17:59:40 -0000
@@ -126,6 +126,7 @@ static flagword real_flags = 0;
 static int support_old_code = 0;
 static char * thumb_entry_symbol = NULL;
 static lang_assignment_statement_type *image_base_statement = 0;
+static unsigned short pe_dll_characteristics = 0;
 
 #ifdef DLL_SUPPORT
 static int pe_enable_stdcall_fixup = -1; /* 0=disable 1=enable.  */
@@ -229,6 +230,15 @@ fragment <<EOF
 					(OPTION_USE_NUL_PREFIXED_IMPORT_TABLES + 1)
 #define OPTION_DISABLE_LONG_SECTION_NAMES \
 					(OPTION_ENABLE_LONG_SECTION_NAMES + 1)
+/* DLLCharacteristics flags */
+#define OPTION_DYNAMIC_BASE		(OPTION_DISABLE_LONG_SECTION_NAMES + 1)
+#define OPTION_FORCE_INTEGRITY		(OPTION_DYNAMIC_BASE + 1)
+#define OPTION_NX_COMPAT		(OPTION_FORCE_INTEGRITY + 1)
+#define OPTION_NO_ISOLATION		(OPTION_NX_COMPAT + 1) 
+#define OPTION_NO_SEH			(OPTION_NO_ISOLATION + 1)
+#define OPTION_NO_BIND			(OPTION_NO_SEH + 1)
+#define OPTION_WDM_DRIVER		(OPTION_NO_BIND + 1)
+#define OPTION_TERMINAL_SERVER_AWARE	(OPTION_WDM_DRIVER + 1)
 
 static void
 gld${EMULATION_NAME}_add_options
@@ -290,6 +300,14 @@ gld${EMULATION_NAME}_add_options
     {"large-address-aware", no_argument, NULL, OPTION_LARGE_ADDRESS_AWARE},
     {"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
     {"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
+    {"dynamicbase",no_argument, NULL, OPTION_DYNAMIC_BASE},
+    {"forceinteg", no_argument, NULL, OPTION_FORCE_INTEGRITY},
+    {"nxcompat", no_argument, NULL, OPTION_NX_COMPAT},
+    {"no-isolation", no_argument, NULL, OPTION_NO_ISOLATION},
+    {"no-seh", no_argument, NULL, OPTION_NO_SEH},
+    {"no-bind", no_argument, NULL, OPTION_NO_BIND},
+    {"wdmdriver", no_argument, NULL, OPTION_WDM_DRIVER},
+    {"tsaware", no_argument, NULL, OPTION_TERMINAL_SERVER_AWARE},
     {NULL, no_argument, NULL, 0}
   };
 
@@ -339,6 +357,7 @@ static definfo init[] =
   D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
   D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
   D(LoaderFlags,"__loader_flags__", 0x0),
+  D(DllCharacteristics, "__dll_characteristics__", 0x0), 
   { NULL, 0, 0, NULL, 0 }
 };
 
@@ -401,6 +420,16 @@ gld_${EMULATION_NAME}_list_options (FILE
                                        executable image files\n"));
   fprintf (file, _("  --disable-long-section-names       Never use long COFF section names, even\n\
                                        in object files\n"));
+  fprintf (file, _("  --dynamicbase			 Image base address may be relocated using\n\
+				       address space layout randomization (ASLR)\n"));
+  fprintf (file, _("  --forceinteg		 Code integrity checks are enforced\n"));
+  fprintf (file, _("  --nxcompat		 Image is compatible with data execution prevention\n"));
+  fprintf (file, _("  --no-isolation		 Image understands isolation but do not isolate the image\n"));
+  fprintf (file, _("  --no-seh			 Image does not use SEH. No SE handler may\n\
+				       be called in this image\n"));
+  fprintf (file, _("  --no-bind			 Do not bind this image\n"));
+  fprintf (file, _("  --wdmdriver		 Driver uses the WDM model\n"));
+  fprintf (file, _("  --tsaware       		 Image is Terminal Server aware\n"));
 }
 
 
@@ -707,7 +736,36 @@ gld${EMULATION_NAME}_handle_option (int 
     case OPTION_DISABLE_LONG_SECTION_NAMES:
       pe_use_coff_long_section_names = 0;
       break;
+/*  Get DLLCharacteristics bits  */
+    case OPTION_DYNAMIC_BASE:
+      pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
+      break;
+    case OPTION_FORCE_INTEGRITY:
+      pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
+      break;
+    case OPTION_NX_COMPAT:
+      pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
+      break;
+    case OPTION_NO_ISOLATION:
+      pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_ISOLATION;
+      break;
+    case OPTION_NO_SEH:
+      pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_SEH;
+      break;
+    case OPTION_NO_BIND:
+      pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_BIND;
+      break;
+    case OPTION_WDM_DRIVER:
+      pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_WDM_DRIVER;
+      break;
+    case OPTION_TERMINAL_SERVER_AWARE:
+      pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
+      break;
     }
+
+  /*  Set DLLCharacteristics bits  */
+  set_pe_name ("__dll_characteristics__", pe_dll_characteristics);
+
   return TRUE;
 }
 \f
Index: ld/emultempl/pep.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pep.em,v
retrieving revision 1.23
diff -p -u -r1.23 pep.em
--- ld/emultempl/pep.em	3 Mar 2009 18:22:11 -0000	1.23
+++ ld/emultempl/pep.em	12 Mar 2009 17:59:40 -0000
@@ -104,6 +104,7 @@ static int dll;
 static flagword real_flags = IMAGE_FILE_LARGE_ADDRESS_AWARE;
 static int support_old_code = 0;
 static lang_assignment_statement_type *image_base_statement = 0;
+static unsigned short pe_dll_characteristics = 0;
 
 #ifdef DLL_SUPPORT
 static int    pep_enable_stdcall_fixup = 1; /* 0=disable 1=enable (default).  */
@@ -179,7 +180,15 @@ enum options
   OPTION_EXCLUDE_MODULES_FOR_IMPLIB,
   OPTION_USE_NUL_PREFIXED_IMPORT_TABLES,
   OPTION_ENABLE_LONG_SECTION_NAMES,
-  OPTION_DISABLE_LONG_SECTION_NAMES
+  OPTION_DISABLE_LONG_SECTION_NAMES,
+  OPTION_DYNAMIC_BASE,
+  OPTION_FORCE_INTEGRITY,
+  OPTION_NX_COMPAT,
+  OPTION_NO_ISOLATION,
+  OPTION_NO_SEH,
+  OPTION_NO_BIND,
+  OPTION_WDM_DRIVER,
+  OPTION_TERMINAL_SERVER_AWARE
 };
 
 static void
@@ -244,7 +253,14 @@ gld${EMULATION_NAME}_add_options
 #endif
     {"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
     {"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
-    {NULL, no_argument, NULL, 0}
+    {"dynamicbase",no_argument, NULL, OPTION_DYNAMIC_BASE},
+    {"forceinteg", no_argument, NULL, OPTION_FORCE_INTEGRITY},
+    {"nxcompat", no_argument, NULL, OPTION_NX_COMPAT},
+    {"no-isolation", no_argument, NULL, OPTION_NO_ISOLATION},
+    {"no-seh", no_argument, NULL, OPTION_NO_SEH},
+    {"no-bind", no_argument, NULL, OPTION_NO_BIND},
+    {"wdmdriver", no_argument, NULL, OPTION_WDM_DRIVER},
+    {"tsaware", no_argument, NULL, OPTION_TERMINAL_SERVER_AWARE},    {NULL, no_argument, NULL, 0}
   };
 
   *longopts = xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
@@ -288,6 +304,7 @@ static definfo init[] =
   D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
   D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
   D(LoaderFlags,"__loader_flags__", 0x0),
+  D(DllCharacteristics, "__dll_characteristics__", 0x0), 
   { NULL, 0, 0, NULL, 0 }
 };
 
@@ -346,6 +363,16 @@ gld_${EMULATION_NAME}_list_options (FILE
                                        executable image files\n"));
   fprintf (file, _("  --disable-long-section-names       Never use long COFF section names, even\n\
                                        in object files\n"));
+  fprintf (file, _("  --dynamicbase			 Image base address may be relocated using\n\
+				       address space layout randomization (ASLR)\n"));
+  fprintf (file, _("  --forceinteg		 Code integrity checks are enforced\n"));
+  fprintf (file, _("  --nxcompat		 Image is compatible with data execution prevention\n"));
+  fprintf (file, _("  --no-isolation		 Image understands isolation but do not isolate the image\n"));
+  fprintf (file, _("  --no-seh			 Image does not use SEH. No SE handler may\n\
+				       be called in this image\n"));
+  fprintf (file, _("  --no-bind		 	 Do not bind this image\n"));
+  fprintf (file, _("  --wdmdriver		 Driver uses the WDM model\n"));
+  fprintf (file, _("  --tsaware       		 Image is Terminal Server aware\n"));
 #endif
 }
 
@@ -647,7 +674,36 @@ gld${EMULATION_NAME}_handle_option (int 
     case OPTION_DISABLE_LONG_SECTION_NAMES:
       pep_use_coff_long_section_names = 0;
       break;
+    /*  Get DLLCharacteristics bits  */
+    case OPTION_DYNAMIC_BASE:
+      pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
+      break;
+    case OPTION_FORCE_INTEGRITY:
+      pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
+      break;
+    case OPTION_NX_COMPAT:
+      pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
+      break;
+    case OPTION_NO_ISOLATION:
+      pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_ISOLATION;
+      break;
+    case OPTION_NO_SEH:
+      pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_SEH;
+      break;
+    case OPTION_NO_BIND:
+      pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_BIND;
+      break;
+    case OPTION_WDM_DRIVER:
+      pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_WDM_DRIVER;
+      break;
+    case OPTION_TERMINAL_SERVER_AWARE:
+      pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
+      break;
     }
+
+  /*  Set DLLCharacteristics bits  */
+  set_pep_name ("__dll_characteristics__", pe_dll_characteristics);
+ 
   return TRUE;
 }
 \f

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-12 13:59                               ` Dave Korn
@ 2009-03-12 17:28                                 ` Dave Korn
  2009-03-12 18:03                                   ` Dave Korn
  0 siblings, 1 reply; 36+ messages in thread
From: Dave Korn @ 2009-03-12 17:28 UTC (permalink / raw)
  To: Dave Korn; +Cc: Nick Clifton, Danny Smith, NightStrike, binutils

Dave Korn wrote:
> Nick Clifton wrote:

>> All of these fail because of an internal error in the linker.  For example the
>> i686-pc-cygwin target reports:
>>
>> internal error: aborting at ei386pe.c line 400 in set_pe_name
> 
>   Hadn't got to the rebuild yet, but I see it now.  Danny, there's a mismatch
> between the init[] entry
> 
> +   D(DllCharacteristics, "__dll_characteristics__", 0x0),
> 
> and the call to set_pe_name:
> 
> +   set_pe_name ("__dllcharacteristics__", pe_dll_characteristics);
> 
>   I'll test the obvious fix.

  Still not there yet.  Now I'm getting these (cross-testing from linux):

[davek@ubique binutils]$ diff -pu unpatched-results.log patched-results.log |
grep '^[+-]'
--- unpatched-results.log	2009-03-12 16:48:23.000000000 +0000
+++ patched-results.log	2009-03-12 16:48:31.000000000 +0000
-x86_64-pc-mingw32.log:PASS: check sections 1
+x86_64-pc-mingw32.log:FAIL: check sections 1
-x86_64-pc-mingw32.log:PASS: ld (fastcall symbols)
-x86_64-pc-mingw32.log:PASS: -l: test (preparation)
-x86_64-pc-mingw32.log:PASS: -l: test
-x86_64-pc-mingw32.log:PASS: PE-COFF Long section names (default)
-x86_64-pc-mingw32.log:PASS: PE-COFF Long section names (disabled)
-x86_64-pc-mingw32.log:PASS: PE-COFF Long section names (enabled)
-x86_64-pc-mingw32.log:PASS: PE-COFF Long section names in objects (default)
-x86_64-pc-mingw32.log:PASS: PE-COFF Long section names in objects (disabled)
-x86_64-pc-mingw32.log:PASS: PE-COFF Long section names in objects (enabled)
-x86_64-pc-mingw32.log:PASS: .secrel32
-x86_64-pc-mingw32.log:PASS: align1
-x86_64-pc-mingw32.log:PASS: ld-scripts/align2a
-x86_64-pc-mingw32.log:PASS: ld-scripts/align2b
+x86_64-pc-mingw32.log:FAIL: ld (fastcall symbols)
+x86_64-pc-mingw32.log:FAIL: -l: test (preparation)
+x86_64-pc-mingw32.log:FAIL: -l: test
+x86_64-pc-mingw32.log:FAIL: PE-COFF Long section names (default)
+x86_64-pc-mingw32.log:FAIL: PE-COFF Long section names (disabled)
+x86_64-pc-mingw32.log:FAIL: PE-COFF Long section names (enabled)
+x86_64-pc-mingw32.log:FAIL: PE-COFF Long section names in objects (default)
+x86_64-pc-mingw32.log:FAIL: PE-COFF Long section names in objects (disabled)
+x86_64-pc-mingw32.log:FAIL: PE-COFF Long section names in objects (enabled)
+x86_64-pc-mingw32.log:FAIL: .secrel32
+x86_64-pc-mingw32.log:FAIL: align1
+x86_64-pc-mingw32.log:FAIL: ld-scripts/align2a
+x86_64-pc-mingw32.log:FAIL: ld-scripts/align2b
-x86_64-pc-mingw32.log:PASS: ALIGNOF
-x86_64-pc-mingw32.log:PASS: ASSERT
-x86_64-pc-mingw32.log:PASS: ld-scripts/data
-x86_64-pc-mingw32.log:PASS: ld-scripts/default-script1
-x86_64-pc-mingw32.log:PASS: ld-scripts/default-script2
-x86_64-pc-mingw32.log:PASS: ld-scripts/default-script3
-x86_64-pc-mingw32.log:PASS: ld-scripts/default-script4
-x86_64-pc-mingw32.log:PASS: DEFINED (PRMS 5699)
-x86_64-pc-mingw32.log:PASS: ld-scripts/defined2
-x86_64-pc-mingw32.log:PASS: ld-scripts/defined3
+x86_64-pc-mingw32.log:FAIL: ALIGNOF
+x86_64-pc-mingw32.log:FAIL: ASSERT
+x86_64-pc-mingw32.log:FAIL: ld-scripts/data
+x86_64-pc-mingw32.log:FAIL: ld-scripts/default-script1
+x86_64-pc-mingw32.log:FAIL: ld-scripts/default-script2
+x86_64-pc-mingw32.log:FAIL: ld-scripts/default-script3
+x86_64-pc-mingw32.log:FAIL: ld-scripts/default-script4
+x86_64-pc-mingw32.log:FAIL: DEFINED (PRMS 5699)
+x86_64-pc-mingw32.log:FAIL: ld-scripts/defined2
+x86_64-pc-mingw32.log:FAIL: ld-scripts/defined3
-x86_64-pc-mingw32.log:PASS: EXTERN
+x86_64-pc-mingw32.log:FAIL: EXTERN
-x86_64-pc-mingw32.log:PASS: map addresses
-x86_64-pc-mingw32.log:PASS: ld-scripts/provide-1
-x86_64-pc-mingw32.log:PASS: ld-scripts/provide-2
-x86_64-pc-mingw32.log:PASS: script
-x86_64-pc-mingw32.log:PASS: MRI script
-x86_64-pc-mingw32.log:PASS: MEMORY
-x86_64-pc-mingw32.log:PASS: ld-scripts/size-1
-x86_64-pc-mingw32.log:PASS: SIZEOF
-x86_64-pc-mingw32.log:PASS: weak undefined symbols
+x86_64-pc-mingw32.log:FAIL: map addresses
+x86_64-pc-mingw32.log:FAIL: ld-scripts/provide-1
+x86_64-pc-mingw32.log:FAIL: ld-scripts/provide-2
+x86_64-pc-mingw32.log:FAIL: script
+x86_64-pc-mingw32.log:FAIL: MRI script
+x86_64-pc-mingw32.log:FAIL: MEMORY
+x86_64-pc-mingw32.log:FAIL: ld-scripts/size-1
+x86_64-pc-mingw32.log:FAIL: SIZEOF
+x86_64-pc-mingw32.log:FAIL: weak undefined symbols
[davek@ubique binutils]$

  All the failures are caused by errors like:

/gnu/binutils/obj31708-x86_64-pc-mingw32/ld/ld-new: i386:x86-64 architecture
of input file `tmpdir/asm.o' is incompatible with i386 output

  I suspect this is caused by a stray hunk in Danny's patch:

Index: ld/emultempl/pep.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pep.em,v
retrieving revision 1.23
diff -c -3 -p -r1.23 pep.em
*** ld/emultempl/pep.em	3 Mar 2009 18:22:11 -0000	1.23
--- ld/emultempl/pep.em	12 Mar 2009 07:25:31 -0000
***************
*** 2,8 ****
  # It does some substitutions.
  test -z "${ENTRY}" && ENTRY="_mainCRTStartup"
  if [ -z "$MACHINE" ]; then
!   OUTPUT_ARCH=${ARCH}
  else
    OUTPUT_ARCH=${ARCH}:${MACHINE}
  fi
--- 2,8 ----
  # It does some substitutions.
  test -z "${ENTRY}" && ENTRY="_mainCRTStartup"
  if [ -z "$MACHINE" ]; then
!   OUTPUT_ARCH=${ARCH}00
  else
    OUTPUT_ARCH=${ARCH}:${MACHINE}
  fi


... so I'll retest after removing it.

    cheers,
      DaveK


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-12  7:42                         ` Danny Smith
  2009-03-12  8:12                           ` Dave Korn
@ 2009-03-12 14:00                           ` Christopher Faylor
  1 sibling, 0 replies; 36+ messages in thread
From: Christopher Faylor @ 2009-03-12 14:00 UTC (permalink / raw)
  To: binutils

On Thu, Mar 12, 2009 at 08:41:55PM +1300, Danny Smith wrote:
>>>
>>> Does this mean the patch won't go in, simply because of seemingly
>>> unimportant arguments over the option name?
>>
>> ?No, it just means it's SEP now.
>>
>Hello,
>
>The following implements Dave's patch as per Chris's suggestions. Chris
>argued that you should be able to "figure out how to turn on the tsaware
>flag without reading the texinfo documentation". That convinced me that
>a separate switch for each flag was not only simpler to implement but
>also simpler for the user.

Thanks, Danny.

I really appreciate your modifying Dave's patch.  And, of course, I
appreciate the effort that Dave put into the patch initially.

cgf

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-12 13:51                             ` Nick Clifton
@ 2009-03-12 13:59                               ` Dave Korn
  2009-03-12 17:28                                 ` Dave Korn
  0 siblings, 1 reply; 36+ messages in thread
From: Dave Korn @ 2009-03-12 13:59 UTC (permalink / raw)
  To: Nick Clifton; +Cc: Dave Korn, Danny Smith, NightStrike, binutils

Nick Clifton wrote:
> Hi Dave, Hi Danny,

  'lo Nick!

>>> The following implements Dave's patch as per Chris's suggestions.
> 
> Well I consider this patch to be good but not quite ready for prime time.  This
> is because of ...
> 
>> Thanks a bunch for picking this up, Danny.  I'll take your patch for a spin 
>> through my autotester and let you know if anything crops up.
> 
> My regression tester shows the following new linker testsuite failures

  I was just collating a list of the same failures to post here when you posted!

> All of these fail because of an internal error in the linker.  For example the
> i686-pc-cygwin target reports:
> 
> internal error: aborting at ei386pe.c line 400 in set_pe_name

  Hadn't got to the rebuild yet, but I see it now.  Danny, there's a mismatch
between the init[] entry

+   D(DllCharacteristics, "__dll_characteristics__", 0x0),

and the call to set_pe_name:

+   set_pe_name ("__dllcharacteristics__", pe_dll_characteristics);

  I'll test the obvious fix.

    cheers,
      DaveK

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-12  8:12                           ` Dave Korn
@ 2009-03-12 13:51                             ` Nick Clifton
  2009-03-12 13:59                               ` Dave Korn
  0 siblings, 1 reply; 36+ messages in thread
From: Nick Clifton @ 2009-03-12 13:51 UTC (permalink / raw)
  To: Dave Korn, Danny Smith; +Cc: NightStrike, binutils

Hi Dave, Hi Danny,

>> The following implements Dave's patch as per Chris's suggestions. 

Well I consider this patch to be good but not quite ready for prime 
time.  This is because of ...

> Thanks a bunch for picking this up, Danny.  I'll take your patch for a spin
> through my autotester and let you know if anything crops up.

My regression tester shows the following new linker testsuite failures 
for the arm-epoc-pe, arm-wince-pe, i686-pc-cygwin, i686-pc-mingw2, 
mcore-pe and mingw32-pe:

   PE-COFF Long section names (disabled)
   PE-COFF Long section names (enabled)
   PE-COFF Long section names in objects (disabled)
   PE-COFF Long section names in objects (enabled)
   script      [from ld-script/script.exp]
   MRI script  [from ld-script/script.exp]
   MEMORY      [from ld-script/script.exp]

Also the i686-pc-cygwin target shows:

   .secrel32              [from ld-pe/pe.exp]
   weak undefined symbols [from ld-undefined/weak-undef.exp]


All of these fail because of an internal error in the linker.  For 
example the i686-pc-cygwin target reports:

  internal error: aborting at ei386pe.c line 400 in set_pe_name

This really needs to be fixed before the patch can be approved.

Cheers
   Nick

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-12  7:42                         ` Danny Smith
@ 2009-03-12  8:12                           ` Dave Korn
  2009-03-12 13:51                             ` Nick Clifton
  2009-03-12 14:00                           ` Christopher Faylor
  1 sibling, 1 reply; 36+ messages in thread
From: Dave Korn @ 2009-03-12  8:12 UTC (permalink / raw)
  To: Danny Smith; +Cc: Dave Korn, NightStrike, binutils

Danny Smith wrote:
>>> Does this mean the patch won't go in, simply because of seemingly
>>> unimportant arguments over the option name?
>>  No, it just means it's SEP now.
>>
> Hello,
> 
> The following implements Dave's patch as per Chris's suggestions. 

  Thanks a bunch for picking this up, Danny.  I'll take your patch for a spin
through my autotester and let you know if anything crops up.

    cheers,
      DaveK

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-09 17:24                       ` Dave Korn
@ 2009-03-12  7:42                         ` Danny Smith
  2009-03-12  8:12                           ` Dave Korn
  2009-03-12 14:00                           ` Christopher Faylor
  0 siblings, 2 replies; 36+ messages in thread
From: Danny Smith @ 2009-03-12  7:42 UTC (permalink / raw)
  To: Dave Korn; +Cc: NightStrike, binutils

[-- Attachment #1: Type: text/plain, Size: 2748 bytes --]

>>
>> Does this mean the patch won't go in, simply because of seemingly
>> unimportant arguments over the option name?
>
>  No, it just means it's SEP now.
>
Hello,

The following implements Dave's patch as per Chris's suggestions. Chris
argued that you should be able to "figure out how to turn on the tsaware
flag without reading the texinfo documentation". That convinced me that
a separate switch for each flag was not only simpler to implement but
also simpler for the user.

The MS linker uses /ALLOWBIND:NO  to set the
IMAGE_DLLCHARACTERISTICS_NO_BIND bit.  It may be better to rename the
--no-bind option to --no-allowbind.

Tested on i686-mingw32 and x64-mingw32

include/ChangeLog
2009-03-12  Dave Korn  <dave.korn.cygwin@gmail.com>

	* coff/internal.h (struct internal_extra_pe_aouthdr):  Correct type
	of DllCharacteristics flags field to unsigned.
	* coff/pe.h (IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE,
	IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE,
	IMAGE_DLL_CHARACTERISTICS_NX_COMPAT,
	IMAGE_DLLCHARACTERISTICS_NO_ISOLATION,
	IMAGE_DLLCHARACTERISTICS_NO_SEH,
	IMAGE_DLLCHARACTERISTICS_NO_BIND,
	IMAGE_DLLCHARACTERISTICS_WDM_DRIVER,
	IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE):  New macros to
	define flag bit values for DllCharacteristics field of PEAOUTHDR,
	PEPAOUTHDR.

ld/ChangeLog
2009-03-12  Dave Korn  <dave.korn.cygwin@gmail.com>
            Danny Smith  <dannysmith@users.sourceforge.net>

	* emultmpl/pe.em (pe_dll_characteristics): New variable.
	(OPTION_DYNAMIC_BASE, OPTION_FORCE_INTEGRITY, OPTION_NX_COMPAT,
	OPTION_NO_ISOLATION. OPTION_NO_SEH, OPTION_NO_BIND,
	OPTION_WDM_DRIVER, OPTION_TERMINAL_SERVER_AWARE):
	New macros for options to set DllCharacteristics flag bits.
	(gld${EMULATION_NAME}_add_options): Add dynamicbase, forceinteg,
	nxcompat, no-isolation, no-seh, no-bind, wdmdriver, tsaware options.
	(init): Add DllCharacteristics field.
	(gld_${EMULATION_NAME}_list_options): List new options.
	(gld${EMULATION_NAME}_handle_option): Handle new options.
	* emultmpl/pep.em (pe_dll_characteristics): New variable.
	(OPTION_DYNAMIC_BASE, OPTION_FORCE_INTEGRITY, OPTION_NX_COMPAT,
	OPTION_NO_ISOLATION. OPTION_NO_SEH, OPTION_NO_BIND,
	OPTION_WDM_DRIVER, OPTION_TERMINAL_SERVER_AWARE):
	New macros for options to set DllCharacteristics flags.
	(gld${EMULATION_NAME}_add_options): Add dynamicbase, forceinteg,
	nxcompat,no-isolation, no-seh, no-bind, wdmdriver, tsaware options.
	(init): Add DllCharacteristics field.
	(gld_${EMULATION_NAME}_list_options): List new options.
	(gld${EMULATION_NAME}_handle_option): Handle new options.
	* ldtexinfo : Document dynamicbase, forceinteg,	nxcompat,
	no-isolation, no-seh, no-bind, wdmdriver, tsaware options.

[-- Attachment #2: dll_characteristic_SEP.diff --]
[-- Type: application/octet-stream, Size: 14999 bytes --]

Index: include/coff/internal.h
===================================================================
RCS file: /cvs/src/src/include/coff/internal.h,v
retrieving revision 1.22
diff -c -3 -p -r1.22 internal.h
*** include/coff/internal.h	12 Jul 2007 07:16:41 -0000	1.22
--- include/coff/internal.h	12 Mar 2009 07:25:24 -0000
*************** struct internal_extra_pe_aouthdr 
*** 185,191 ****
       3 - WINDOWS_CUI runs in Windows char sub. (console app)
       5 - OS2_CUI runs in OS/2 character subsystem
       7 - POSIX_CUI runs in Posix character subsystem */
!   short   DllCharacteristics;	/* flags for DLL init, use 0 */
    bfd_vma SizeOfStackReserve;	/* amount of memory to reserve  */
    bfd_vma SizeOfStackCommit;	/* amount of memory initially committed for 
  				   initial thread's stack, default is 0x1000 */
--- 185,191 ----
       3 - WINDOWS_CUI runs in Windows char sub. (console app)
       5 - OS2_CUI runs in OS/2 character subsystem
       7 - POSIX_CUI runs in Posix character subsystem */
!   unsigned short DllCharacteristics; /* flags for DLL init  */
    bfd_vma SizeOfStackReserve;	/* amount of memory to reserve  */
    bfd_vma SizeOfStackCommit;	/* amount of memory initially committed for 
  				   initial thread's stack, default is 0x1000 */
Index: include/coff/pe.h
===================================================================
RCS file: /cvs/src/src/include/coff/pe.h,v
retrieving revision 1.18
diff -c -3 -p -r1.18 pe.h
*** include/coff/pe.h	4 Nov 2007 23:49:08 -0000	1.18
--- include/coff/pe.h	12 Mar 2009 07:25:24 -0000
***************
*** 38,43 ****
--- 38,54 ----
  #define IMAGE_FILE_UP_SYSTEM_ONLY            0x4000
  #define IMAGE_FILE_BYTES_REVERSED_HI         0x8000
  
+ /* DllCharacteristics flag bits.  The inconsistent naming may seem
+    odd, but that is how they are defined in the PE specification.  */
+ #define IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE          0x0040
+ #define IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY       0x0080
+ #define IMAGE_DLL_CHARACTERISTICS_NX_COMPAT             0x0100
+ #define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION           0x0200
+ #define IMAGE_DLLCHARACTERISTICS_NO_SEH                 0x0400
+ #define IMAGE_DLLCHARACTERISTICS_NO_BIND                0x0800
+ #define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER             0x2000
+ #define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE  0x8000
+ 
  /* Additional flags to be set for section headers to allow the NT loader to
     read and write to the section data (to replace the addresses of data in
     dlls for one thing); also to execute the section in .text's case.  */
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.235
diff -c -3 -p -r1.235 ld.texinfo
*** ld/ld.texinfo	3 Mar 2009 18:22:10 -0000	1.235
--- ld/ld.texinfo	12 Mar 2009 07:25:29 -0000
*************** the subsystem version also.  Numeric val
*** 2488,2493 ****
--- 2488,2533 ----
  @var{which}.
  [This option is specific to the i386 PE targeted port of the linker]
  
+ The following options set flags in the @code{DllCharacteristics} field
+ of the PE file header:
+ [These options are specific to PE targeted ports of the linker]
+ 
+ @kindex --dynamicbase
+ @item --dynamicbase
+ The image base address may be relocated using address space layout
+ randomization (ASLR).  This feature was introduced with MS Windows
+ Vista for i386 PE targets.
+ 
+ @kindex --forceinteg
+ @item --forceinteg
+ Code integrity checks are enforced.
+ 
+ @kindex --nxcompat
+ @item --nxcompat
+ The image is compatible with the Data Execution Prevention.
+ This feature was introduced with MS Windows XP SP2 for i386 PE targets.
+ 
+ @kindex --no-isolation
+ @item --no-isolation
+ Although the image understands isolation, do not isolate the image.
+ 
+ @kindex --no-seh
+ @item --no-seh
+ The image does not use SEH. No SE handler may be called from
+ this image.
+ 
+ @kindex --no-bind
+ @item --no-bind
+ Do not bind this image.
+ 
+ @kindex --wdmdriver
+ @item --wdmdriver
+ The driver uses the MS Windows Driver Model.
+  
+ @kindex --tsaware
+ @item --tsaware
+ The image is Terminal Server aware.
+ 
  @end table
  
  @c man end
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.146
diff -c -3 -p -r1.146 pe.em
*** ld/emultempl/pe.em	3 Mar 2009 18:22:11 -0000	1.146
--- ld/emultempl/pe.em	12 Mar 2009 07:25:30 -0000
*************** static flagword real_flags = 0;
*** 126,131 ****
--- 126,132 ----
  static int support_old_code = 0;
  static char * thumb_entry_symbol = NULL;
  static lang_assignment_statement_type *image_base_statement = 0;
+ static unsigned short pe_dll_characteristics = 0;
  
  #ifdef DLL_SUPPORT
  static int pe_enable_stdcall_fixup = -1; /* 0=disable 1=enable.  */
*************** fragment <<EOF
*** 229,234 ****
--- 230,244 ----
  					(OPTION_USE_NUL_PREFIXED_IMPORT_TABLES + 1)
  #define OPTION_DISABLE_LONG_SECTION_NAMES \
  					(OPTION_ENABLE_LONG_SECTION_NAMES + 1)
+ /* DLLCharacteristics flags */
+ #define OPTION_DYNAMIC_BASE		(OPTION_DISABLE_LONG_SECTION_NAMES + 1)
+ #define OPTION_FORCE_INTEGRITY		(OPTION_DYNAMIC_BASE + 1)
+ #define OPTION_NX_COMPAT		(OPTION_FORCE_INTEGRITY + 1)
+ #define OPTION_NO_ISOLATION		(OPTION_NX_COMPAT + 1) 
+ #define OPTION_NO_SEH			(OPTION_NO_ISOLATION + 1)
+ #define OPTION_NO_BIND			(OPTION_NO_SEH + 1)
+ #define OPTION_WDM_DRIVER		(OPTION_NO_BIND + 1)
+ #define OPTION_TERMINAL_SERVER_AWARE	(OPTION_WDM_DRIVER + 1)
  
  static void
  gld${EMULATION_NAME}_add_options
*************** gld${EMULATION_NAME}_add_options
*** 290,295 ****
--- 300,313 ----
      {"large-address-aware", no_argument, NULL, OPTION_LARGE_ADDRESS_AWARE},
      {"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
      {"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
+     {"dynamicbase",no_argument, NULL, OPTION_DYNAMIC_BASE},
+     {"forceinteg", no_argument, NULL, OPTION_FORCE_INTEGRITY},
+     {"nxcompat", no_argument, NULL, OPTION_NX_COMPAT},
+     {"no-isolation", no_argument, NULL, OPTION_NO_ISOLATION},
+     {"no-seh", no_argument, NULL, OPTION_NO_SEH},
+     {"no-bind", no_argument, NULL, OPTION_NO_BIND},
+     {"wdmdriver", no_argument, NULL, OPTION_WDM_DRIVER},
+     {"tsaware", no_argument, NULL, OPTION_TERMINAL_SERVER_AWARE},
      {NULL, no_argument, NULL, 0}
    };
  
*************** static definfo init[] =
*** 339,344 ****
--- 357,363 ----
    D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
    D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
    D(LoaderFlags,"__loader_flags__", 0x0),
+   D(DllCharacteristics, "__dll_characteristics__", 0x0), 
    { NULL, 0, 0, NULL, 0 }
  };
  
*************** gld_${EMULATION_NAME}_list_options (FILE
*** 401,406 ****
--- 420,435 ----
                                         executable image files\n"));
    fprintf (file, _("  --disable-long-section-names       Never use long COFF section names, even\n\
                                         in object files\n"));
+   fprintf (file, _("  --dynamicbase			 Image base address may be relocated using\n\
+ 				       address space layout randomization (ASLR)\n"));
+   fprintf (file, _("  --forceinteg		 Code integrity checks are enforced\n"));
+   fprintf (file, _("  --nxcompat		 Image is compatible with data execution prevention\n"));
+   fprintf (file, _("  --no-isolation		 Image understands isolation but do not isolate the image\n"));
+   fprintf (file, _("  --no-seh			 Image does not use SEH. No SE handler may\n\
+ 				       be called in this image\n"));
+   fprintf (file, _("  --no-bind			 Do not bind this image\n"));
+   fprintf (file, _("  --wdmdriver		 Driver uses the WDM model\n"));
+   fprintf (file, _("  --tsaware       		 Image is Terminal Server aware\n"));
  }
  
  
*************** gld${EMULATION_NAME}_handle_option (int 
*** 707,713 ****
--- 736,771 ----
      case OPTION_DISABLE_LONG_SECTION_NAMES:
        pe_use_coff_long_section_names = 0;
        break;
+ /*  Get DLLCharacteristics bits  */
+     case OPTION_DYNAMIC_BASE:
+       pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
+       break;
+     case OPTION_FORCE_INTEGRITY:
+       pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
+       break;
+     case OPTION_NX_COMPAT:
+       pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
+       break;
+     case OPTION_NO_ISOLATION:
+       pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_ISOLATION;
+       break;
+     case OPTION_NO_SEH:
+       pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_SEH;
+       break;
+     case OPTION_NO_BIND:
+       pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_BIND;
+       break;
+     case OPTION_WDM_DRIVER:
+       pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_WDM_DRIVER;
+       break;
+     case OPTION_TERMINAL_SERVER_AWARE:
+       pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
+       break;
      }
+ 
+   /*  Set DLLCharacteristics bits  */
+   set_pe_name ("__dllcharacteristics__", pe_dll_characteristics);
+ 
    return TRUE;
  }
  \f
Index: ld/emultempl/pep.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pep.em,v
retrieving revision 1.23
diff -c -3 -p -r1.23 pep.em
*** ld/emultempl/pep.em	3 Mar 2009 18:22:11 -0000	1.23
--- ld/emultempl/pep.em	12 Mar 2009 07:25:31 -0000
***************
*** 2,8 ****
  # It does some substitutions.
  test -z "${ENTRY}" && ENTRY="_mainCRTStartup"
  if [ -z "$MACHINE" ]; then
!   OUTPUT_ARCH=${ARCH}
  else
    OUTPUT_ARCH=${ARCH}:${MACHINE}
  fi
--- 2,8 ----
  # It does some substitutions.
  test -z "${ENTRY}" && ENTRY="_mainCRTStartup"
  if [ -z "$MACHINE" ]; then
!   OUTPUT_ARCH=${ARCH}00
  else
    OUTPUT_ARCH=${ARCH}:${MACHINE}
  fi
*************** static int dll;
*** 104,109 ****
--- 104,110 ----
  static flagword real_flags = IMAGE_FILE_LARGE_ADDRESS_AWARE;
  static int support_old_code = 0;
  static lang_assignment_statement_type *image_base_statement = 0;
+ static unsigned short pe_dll_characteristics = 0;
  
  #ifdef DLL_SUPPORT
  static int    pep_enable_stdcall_fixup = 1; /* 0=disable 1=enable (default).  */
*************** enum options
*** 179,185 ****
    OPTION_EXCLUDE_MODULES_FOR_IMPLIB,
    OPTION_USE_NUL_PREFIXED_IMPORT_TABLES,
    OPTION_ENABLE_LONG_SECTION_NAMES,
!   OPTION_DISABLE_LONG_SECTION_NAMES
  };
  
  static void
--- 180,194 ----
    OPTION_EXCLUDE_MODULES_FOR_IMPLIB,
    OPTION_USE_NUL_PREFIXED_IMPORT_TABLES,
    OPTION_ENABLE_LONG_SECTION_NAMES,
!   OPTION_DISABLE_LONG_SECTION_NAMES,
!   OPTION_DYNAMIC_BASE,
!   OPTION_FORCE_INTEGRITY,
!   OPTION_NX_COMPAT,
!   OPTION_NO_ISOLATION,
!   OPTION_NO_SEH,
!   OPTION_NO_BIND,
!   OPTION_WDM_DRIVER,
!   OPTION_TERMINAL_SERVER_AWARE
  };
  
  static void
*************** gld${EMULATION_NAME}_add_options
*** 244,250 ****
  #endif
      {"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
      {"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
!     {NULL, no_argument, NULL, 0}
    };
  
    *longopts = xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
--- 253,266 ----
  #endif
      {"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
      {"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
!     {"dynamicbase",no_argument, NULL, OPTION_DYNAMIC_BASE},
!     {"forceinteg", no_argument, NULL, OPTION_FORCE_INTEGRITY},
!     {"nxcompat", no_argument, NULL, OPTION_NX_COMPAT},
!     {"no-isolation", no_argument, NULL, OPTION_NO_ISOLATION},
!     {"no-seh", no_argument, NULL, OPTION_NO_SEH},
!     {"no-bind", no_argument, NULL, OPTION_NO_BIND},
!     {"wdmdriver", no_argument, NULL, OPTION_WDM_DRIVER},
!     {"tsaware", no_argument, NULL, OPTION_TERMINAL_SERVER_AWARE},    {NULL, no_argument, NULL, 0}
    };
  
    *longopts = xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
*************** static definfo init[] =
*** 288,293 ****
--- 304,310 ----
    D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
    D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
    D(LoaderFlags,"__loader_flags__", 0x0),
+   D(DllCharacteristics, "__dll_characteristics__", 0x0), 
    { NULL, 0, 0, NULL, 0 }
  };
  
*************** gld_${EMULATION_NAME}_list_options (FILE
*** 346,351 ****
--- 363,378 ----
                                         executable image files\n"));
    fprintf (file, _("  --disable-long-section-names       Never use long COFF section names, even\n\
                                         in object files\n"));
+   fprintf (file, _("  --dynamicbase			 Image base address may be relocated using\n\
+ 				       address space layout randomization (ASLR)\n"));
+   fprintf (file, _("  --forceinteg		 Code integrity checks are enforced\n"));
+   fprintf (file, _("  --nxcompat		 Image is compatible with data execution prevention\n"));
+   fprintf (file, _("  --no-isolation		 Image understands isolation but do not isolate the image\n"));
+   fprintf (file, _("  --no-seh			 Image does not use SEH. No SE handler may\n\
+ 				       be called in this image\n"));
+   fprintf (file, _("  --no-bind		 	 Do not bind this image\n"));
+   fprintf (file, _("  --wdmdriver		 Driver uses the WDM model\n"));
+   fprintf (file, _("  --tsaware       		 Image is Terminal Server aware\n"));
  #endif
  }
  
*************** gld${EMULATION_NAME}_handle_option (int 
*** 647,653 ****
--- 674,709 ----
      case OPTION_DISABLE_LONG_SECTION_NAMES:
        pep_use_coff_long_section_names = 0;
        break;
+     /*  Get DLLCharacteristics bits  */
+     case OPTION_DYNAMIC_BASE:
+       pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
+       break;
+     case OPTION_FORCE_INTEGRITY:
+       pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
+       break;
+     case OPTION_NX_COMPAT:
+       pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
+       break;
+     case OPTION_NO_ISOLATION:
+       pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_ISOLATION;
+       break;
+     case OPTION_NO_SEH:
+       pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_SEH;
+       break;
+     case OPTION_NO_BIND:
+       pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_BIND;
+       break;
+     case OPTION_WDM_DRIVER:
+       pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_WDM_DRIVER;
+       break;
+     case OPTION_TERMINAL_SERVER_AWARE:
+       pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
+       break;
      }
+ 
+   /*  Set DLLCharacteristics bits  */
+   set_pep_name ("__dllcharacteristics__", pe_dll_characteristics);
+  
    return TRUE;
  }
  \f

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-09 17:17                     ` NightStrike
  2009-03-09 17:23                       ` Christopher Faylor
@ 2009-03-09 17:24                       ` Dave Korn
  2009-03-12  7:42                         ` Danny Smith
  1 sibling, 1 reply; 36+ messages in thread
From: Dave Korn @ 2009-03-09 17:24 UTC (permalink / raw)
  To: NightStrike; +Cc: Dave Korn, binutils

NightStrike wrote:
> On Mon, Mar 9, 2009 at 12:16 PM, Dave Korn
> <dave.korn.cygwin@googlemail.com> wrote:
>> Christopher Faylor wrote:
>>
>>> I wasn't referring to the comma.  I was referring to the requirement of
>>> parsing suboptions.  Are you saying there are other ld options which
>>> take keywords like this?
>>  Nope, I just misread you, I thought you /were/ referring to the list nature
>> of the syntax.
>>
>>> I think I'm done arguing now because I seem to be repeating myself.
>>  Yes, me too.  I've way overrun the amount of time I want to spend on such a
>> trivial matter.  Patch withdrawn.
> 
> Does this mean the patch won't go in, simply because of seemingly
> unimportant arguments over the option name?  

  No, it just means it's SEP now.

    cheers,
      DaveK

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-09 17:17                     ` NightStrike
@ 2009-03-09 17:23                       ` Christopher Faylor
  2009-03-09 17:24                       ` Dave Korn
  1 sibling, 0 replies; 36+ messages in thread
From: Christopher Faylor @ 2009-03-09 17:23 UTC (permalink / raw)
  To: binutils

On Mon, Mar 09, 2009 at 01:17:44PM -0400, NightStrike wrote:
>On Mon, Mar 9, 2009 at 12:16 PM, Dave Korn
><dave.korn.cygwin@googlemail.com> wrote:
>>Christopher Faylor wrote:
>>>I wasn't referring to the comma.  I was referring to the requirement of
>>>parsing suboptions.  Are you saying there are other ld options which
>>>take keywords like this?
>>
>>Nope, I just misread you, I thought you /were/ referring to the list
>>nature of the syntax.
>>
>>>I think I'm done arguing now because I seem to be repeating myself.
>>
>>Yes, me too.  I've way overrun the amount of time I want to spend on
>>such a trivial matter.  Patch withdrawn.
>
>Does this mean the patch won't go in, simply because of seemingly
>unimportant arguments over the option name?  Surely it's more important
>that the option itself gets in.

I disagree that UI issues are unimportant.  YMMV.

cgf

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-09 16:06                   ` Dave Korn
@ 2009-03-09 17:17                     ` NightStrike
  2009-03-09 17:23                       ` Christopher Faylor
  2009-03-09 17:24                       ` Dave Korn
  0 siblings, 2 replies; 36+ messages in thread
From: NightStrike @ 2009-03-09 17:17 UTC (permalink / raw)
  To: Dave Korn; +Cc: binutils

On Mon, Mar 9, 2009 at 12:16 PM, Dave Korn
<dave.korn.cygwin@googlemail.com> wrote:
> Christopher Faylor wrote:
>
>> I wasn't referring to the comma.  I was referring to the requirement of
>> parsing suboptions.  Are you saying there are other ld options which
>> take keywords like this?
>
>  Nope, I just misread you, I thought you /were/ referring to the list nature
> of the syntax.
>
>> I think I'm done arguing now because I seem to be repeating myself.
>
>  Yes, me too.  I've way overrun the amount of time I want to spend on such a
> trivial matter.  Patch withdrawn.

Does this mean the patch won't go in, simply because of seemingly
unimportant arguments over the option name?  Surely it's more
important that the option itself gets in.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-09 17:02   ` Daniel Jacobowitz
@ 2009-03-09 17:09     ` Christopher Faylor
  0 siblings, 0 replies; 36+ messages in thread
From: Christopher Faylor @ 2009-03-09 17:09 UTC (permalink / raw)
  To: binutils, Charles Wilson

On Mon, Mar 09, 2009 at 01:02:25PM -0400, Daniel Jacobowitz wrote:
>On Mon, Mar 09, 2009 at 12:48:56PM -0400, Christopher Faylor wrote:
>> And, perhaps I'm wrong, but I don't think any other ld (or ultimately
>> objcopy) option takes a list of arbitrary keywords like this.  The
>> result of doing things this way means that (in Dave's original patch at
>> least) you can't figure out how to turn on the tsaware flag without
>> reading the texinfo documentation.  I don't see any reason for that.
>
>--set-section-flags and --rename-section, fwiw.

Ah, yes.  I should have known to look in the objcopy help before
expressing a general opinion.

cgf

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-09 16:49 ` Christopher Faylor
@ 2009-03-09 17:02   ` Daniel Jacobowitz
  2009-03-09 17:09     ` Christopher Faylor
  0 siblings, 1 reply; 36+ messages in thread
From: Daniel Jacobowitz @ 2009-03-09 17:02 UTC (permalink / raw)
  To: binutils, Charles Wilson

On Mon, Mar 09, 2009 at 12:48:56PM -0400, Christopher Faylor wrote:
> And, perhaps I'm wrong, but I don't think any other ld (or ultimately
> objcopy) option takes a list of arbitrary keywords like this.  The
> result of doing things this way means that (in Dave's original patch at
> least) you can't figure out how to turn on the tsaware flag without
> reading the texinfo documentation.  I don't see any reason for that.

--set-section-flags and --rename-section, fwiw.

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-09 15:58 Charles Wilson
@ 2009-03-09 16:49 ` Christopher Faylor
  2009-03-09 17:02   ` Daniel Jacobowitz
  0 siblings, 1 reply; 36+ messages in thread
From: Christopher Faylor @ 2009-03-09 16:49 UTC (permalink / raw)
  To: binutils, Charles Wilson

On Mon, Mar 09, 2009 at 11:58:00AM -0400, Charles Wilson wrote:
>> The ld option would not represent a mask.  It is just an arbitrary collection
>> of keyworeds.  You are grouping suboptions together only because Microsoft 
>> decided to have disparate behavior controlled by one unsigned short field
>> in the PE header.
>
>Ah. I see what the problem is.
>
>Dave and I are thinking: "There is an important field in the EXE/DLL
>header.  We need a way to conveniently set the value of this field. 
>Since the field is composed of various flags, one obvious convenient
>mechanism is to allow setting those flags in the field symbolically.  Or
>also numerically, all at once.  But, the operation is one atomic
>transaction: set the field."
>
>This naturally leads to a single command line option (for the field),
>with parseable suboptions (for each flag).
>
>You're thinking: "There are a number of flags that are important in the
>EXE/DLL header.  We should be able to set those flags.  These flags are
>each independent logical entities -- regardless of how Microsoft
>implemented them in the PE header itself, as bit-members of a single
>field, multiple fields, whatever.  The ld user doesn't care -- he just
>needs to be able to set each flag."
>
>This naturally leads to multiple command line options -- one for each
>flag. 
>
>I can see the argument for both.  Can't we have both?

Given the code complexity of implementing "your" way, I don't see any
reason to add two ways to binutils.  It's hard for me to imagine that
anyone who needed to use one of these options would find
"--pe-dll-characteristics tsaware" easier to use or remember than
"--tsaware".  Especially since you are assuming that someone who wanted
to use this option would know that they come from DllCharacteristics.  I
know with great certainty that I would have to look this up the next
time I wanted to use it.  I would possibly remember --tsaware but
"--dll-characteristics tsaware" is not something that would naturally
stick.

And, perhaps I'm wrong, but I don't think any other ld (or ultimately
objcopy) option takes a list of arbitrary keywords like this.  The
result of doing things this way means that (in Dave's original patch at
least) you can't figure out how to turn on the tsaware flag without
reading the texinfo documentation.  I don't see any reason for that.

I know that these options would show up if you implemented them both
ways but, like I said, I really don't see the need to do it two ways.

cgf

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-09 15:37                 ` Christopher Faylor
@ 2009-03-09 16:06                   ` Dave Korn
  2009-03-09 17:17                     ` NightStrike
  0 siblings, 1 reply; 36+ messages in thread
From: Dave Korn @ 2009-03-09 16:06 UTC (permalink / raw)
  To: binutils, Dave Korn

Christopher Faylor wrote:

> I wasn't referring to the comma.  I was referring to the requirement of
> parsing suboptions.  Are you saying there are other ld options which
> take keywords like this?

  Nope, I just misread you, I thought you /were/ referring to the list nature
of the syntax.

> I think I'm done arguing now because I seem to be repeating myself.

  Yes, me too.  I've way overrun the amount of time I want to spend on such a
trivial matter.  Patch withdrawn.

    cheers,
      DaveK

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
@ 2009-03-09 15:58 Charles Wilson
  2009-03-09 16:49 ` Christopher Faylor
  0 siblings, 1 reply; 36+ messages in thread
From: Charles Wilson @ 2009-03-09 15:58 UTC (permalink / raw)
  To: binutils

> The ld option would not represent a mask.  It is just an arbitrary collection
> of keyworeds.  You are grouping suboptions together only because Microsoft 
> decided to have disparate behavior controlled by one unsigned short field
> in the PE header.

Ah. I see what the problem is.

Dave and I are thinking: "There is an important field in the EXE/DLL
header.  We need a way to conveniently set the value of this field. 
Since the field is composed of various flags, one obvious convenient
mechanism is to allow setting those flags in the field symbolically.  Or
also numerically, all at once.  But, the operation is one atomic
transaction: set the field."

This naturally leads to a single command line option (for the field),
with parseable suboptions (for each flag).

You're thinking: "There are a number of flags that are important in the
EXE/DLL header.  We should be able to set those flags.  These flags are
each independent logical entities -- regardless of how Microsoft
implemented them in the PE header itself, as bit-members of a single
field, multiple fields, whatever.  The ld user doesn't care -- he just
needs to be able to set each flag."

This naturally leads to multiple command line options -- one for each
flag. 

I can see the argument for both.  Can't we have both?

--
Chuck

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-09  6:14               ` Dave Korn
@ 2009-03-09 15:37                 ` Christopher Faylor
  2009-03-09 16:06                   ` Dave Korn
  0 siblings, 1 reply; 36+ messages in thread
From: Christopher Faylor @ 2009-03-09 15:37 UTC (permalink / raw)
  To: binutils, Dave Korn

On Mon, Mar 09, 2009 at 06:24:01AM +0000, Dave Korn wrote:
>Christopher Faylor wrote:
>>I don't see any reason for a user to have to remember two things
>>(--dll-characteristics something) when they could just use --something.
>>If implemented as a simple option, you could get useful information
>>from --help, and you wouldn't have to invent a new way of parsing
>>options.
>
>The syntax isn't unprecedented, there are three other options that take
>an comma-separated list for the argument.

I wasn't referring to the comma.  I was referring to the requirement of
parsing suboptions.  Are you saying there are other ld options which
take keywords like this?


>(I added a couple of other separators that made sense because there may
>be integers present.  I also took as an example the strace --mask
>syntax.)

Nevertheless, you added a non-trivial amount of code to deal with
parsing these things as suboptions.

The Cygwin strace option is for a mask which controls what strace
outputs.  The ld option would not represent a mask.  It is just an
arbitrary collection of keyworeds.  You are grouping suboptions together
only because Microsoft decided to have disparate behavior controlled by
one unsigned short field in the PE header.

I think I'm done arguing now because I seem to be repeating myself.

cgf

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-09  1:13         ` Dave Korn
  2009-03-09  5:47           ` Dave Korn
@ 2009-03-09  9:35           ` Vincent R.
  1 sibling, 0 replies; 36+ messages in thread
From: Vincent R. @ 2009-03-09  9:35 UTC (permalink / raw)
  To: binutils

On Mon, 09 Mar 2009 01:22:35 +0000, Dave Korn
<dave.korn.cygwin@googlemail.com> wrote:
> Dave Korn wrote:
>> Christopher Faylor wrote:
> 
>>> or --pe-characteristics.
> 
> 
>   Attached, generated by running "sed -e's/-dll-/-/g' over the last
patch.
> Retested with same results as before.
> 
>     cheers,
>       DaveK

You mean that now --pe-characteristics refers to the DllCharacteristics
flag ? 
If that's tue this is very stupid to remove the dll part because now
everytime I see this option I think about 
the characteritics flag which is different from dllcharacteristics.



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-09  5:24             ` Christopher Faylor
@ 2009-03-09  6:14               ` Dave Korn
  2009-03-09 15:37                 ` Christopher Faylor
  0 siblings, 1 reply; 36+ messages in thread
From: Dave Korn @ 2009-03-09  6:14 UTC (permalink / raw)
  To: binutils, Dave Korn

Christopher Faylor wrote:

> I don't see any reason for a user to have to remember two things
> (--dll-characteristics something) when they could just use --something.
> If implemented as a simple option, you could get useful information from
> --help, and you wouldn't have to invent a new way of parsing options.

  The syntax isn't unprecedented, there are three other options that take an
comma-separated list for the argument.  (I added a couple of other separators
that made sense because there may be integers present.  I also took as an
example the strace --mask syntax.)

> And, if we name the options similarly to Microsoft's link command (and
> there is certainly precedent for ld accommodating other linker's
> arguments) we might even make it slightly easier for people who are
> familiar with Microsoft's tools to use ours.

  Well, a follow-on patch could add a bunch of synonyms very easily: make them
non-argument options, call into set_pe_value_from_flags with optarg still
pointing at the option name itself, add matching entries to dllchrctnames[],
and make the operation of set_pe_value_from_flags cumulative by changing the
last line:

-  set_pe_name (name,  flags);
+  set_pe_name (name,  flags | (init->inited ? init->value : 0));

    cheers,
      DaveK

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-09  1:13         ` Dave Korn
@ 2009-03-09  5:47           ` Dave Korn
  2009-03-09  9:35           ` Vincent R.
  1 sibling, 0 replies; 36+ messages in thread
From: Dave Korn @ 2009-03-09  5:47 UTC (permalink / raw)
  To: Dave Korn; +Cc: binutils

[-- Attachment #1: Type: text/plain, Size: 406 bytes --]

Dave Korn wrote:
> Dave Korn wrote:
>> Christopher Faylor wrote:
> 
>>> or --pe-characteristics.
> 
> 
>   Attached, generated by running "sed -e's/-dll-/-/g' over the last patch.
> Retested with same results as before.
> 

  Now with even the getopts long option enumeratied values renamed.  This
time, only tested on cygwin x {cygwin, mingw32, x64-mingw), still no regressions.

    cheers,
      DaveK


[-- Attachment #2: pe-characteristics-patch.diff --]
[-- Type: text/plain, Size: 28773 bytes --]

Index: include/coff/internal.h
===================================================================
RCS file: /cvs/src/src/include/coff/internal.h,v
retrieving revision 1.22
diff -p -u -r1.22 internal.h
--- include/coff/internal.h	12 Jul 2007 07:16:41 -0000	1.22
+++ include/coff/internal.h	9 Mar 2009 05:45:57 -0000
@@ -185,7 +185,7 @@ struct internal_extra_pe_aouthdr 
      3 - WINDOWS_CUI runs in Windows char sub. (console app)
      5 - OS2_CUI runs in OS/2 character subsystem
      7 - POSIX_CUI runs in Posix character subsystem */
-  short   DllCharacteristics;	/* flags for DLL init, use 0 */
+  unsigned short DllCharacteristics;	/* flags for DLL init, use 0 */
   bfd_vma SizeOfStackReserve;	/* amount of memory to reserve  */
   bfd_vma SizeOfStackCommit;	/* amount of memory initially committed for 
 				   initial thread's stack, default is 0x1000 */
Index: include/coff/pe.h
===================================================================
RCS file: /cvs/src/src/include/coff/pe.h,v
retrieving revision 1.18
diff -p -u -r1.18 pe.h
--- include/coff/pe.h	4 Nov 2007 23:49:08 -0000	1.18
+++ include/coff/pe.h	9 Mar 2009 05:45:57 -0000
@@ -38,6 +38,17 @@
 #define IMAGE_FILE_UP_SYSTEM_ONLY            0x4000
 #define IMAGE_FILE_BYTES_REVERSED_HI         0x8000
 
+/* DllCharacteristics flag bits.  The inconsistent naming may seem
+   odd, but that is how they are defined in the PE specification.  */
+#define IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE          0x0040
+#define IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY       0x0080
+#define IMAGE_DLL_CHARACTERISTICS_NX_COMPAT             0x0100
+#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION           0x0200
+#define IMAGE_DLLCHARACTERISTICS_NO_SEH                 0x0400
+#define IMAGE_DLLCHARACTERISTICS_NO_BIND                0x0800
+#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER             0x2000
+#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE  0x8000
+
 /* Additional flags to be set for section headers to allow the NT loader to
    read and write to the section data (to replace the addresses of data in
    dlls for one thing); also to execute the section in .text's case.  */
Index: ld/NEWS
===================================================================
RCS file: /cvs/src/src/ld/NEWS,v
retrieving revision 1.100
diff -p -u -r1.100 NEWS
--- ld/NEWS	3 Mar 2009 18:22:10 -0000	1.100
+++ ld/NEWS	9 Mar 2009 05:45:57 -0000
@@ -1,5 +1,9 @@
 -*- text -*-
 
+* A new command-line flag '--pe-characteristics' allows PE targets
+  to set the value of the PE file header's DllCharacteristics field,
+  using a flexible combination of numeric and symbolic names.
+
 * New script function REGION_ALIAS to add alias names to memory regions.
 
 * PE targets no longer make use of the long section names PE extension to
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.235
diff -p -u -r1.235 ld.texinfo
--- ld/ld.texinfo	3 Mar 2009 18:22:10 -0000	1.235
+++ ld/ld.texinfo	9 Mar 2009 05:45:58 -0000
@@ -2257,6 +2257,57 @@ Sets the minor number of the ``os versio
 Sets the minor number of the ``subsystem version''.  Defaults to 0.
 [This option is specific to the i386 PE targeted port of the linker]
 
+@kindex --pe-characteristics
+@item --pe-characteristics (@var{name}|@var{integer})@*@	@w{@	}@	@w{@	}@	@w{@	}@	@w{@	}[(',' | '|' | '+' | ':')(@var{name}|@var{integer})[...]]
+Sets the value of the DllCharacteristics field in the PE header.  The
+value can be specified by using hexadecimal or decimal integers, or the
+symbolic names of the various bits, optionally combined by any combination
+of @samp{|}, @samp{+}, @samp{:} or @samp{,} characters.  The following
+short symbolic names are recognized, shown with the full name of the flag
+(as given in the MS PE specification) to which they correspond, which is
+also accepted:
+
+@table @samp
+@item dynbase
+@samp{IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE}
+
+@item forceinteg
+@samp{IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY}
+
+@item nxcompat
+@samp{IMAGE_DLL_CHARACTERISTICS_NX_COMPAT}
+
+@item noisolation
+@samp{IMAGE_DLLCHARACTERISTICS_NO_ISOLATION}
+
+@item noseh
+@samp{IMAGE_DLLCHARACTERISTICS_NO_SEH}
+
+@item nobind
+@samp{IMAGE_DLLCHARACTERISTICS_NO_BIND}
+
+@item wdmdriver
+@samp{IMAGE_DLLCHARACTERISTICS_WDM_DRIVER}
+
+@item tsaware
+@samp{IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE}
+
+@end table
+These options and separators can be combined with almost total
+flexibility; for example, valid uses of this option include:
+
+@smallexample
+--pe-characteristics=0x0400|0x0100
+@end smallexample
+@smallexample
+--pe-characteristics=1+128+1024,noseh,nobind
+@end smallexample
+@smallexample
+--pe-characteristics noseh:nobind:tsaware
+@end smallexample
+
+[This option is valid for all PE targeted ports of the linker]
+
 @cindex DEF files, creating
 @cindex DLLs, creating
 @kindex --output-def
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.146
diff -p -u -r1.146 pe.em
--- ld/emultempl/pe.em	3 Mar 2009 18:22:11 -0000	1.146
+++ ld/emultempl/pe.em	9 Mar 2009 05:45:59 -0000
@@ -229,6 +229,8 @@ fragment <<EOF
 					(OPTION_USE_NUL_PREFIXED_IMPORT_TABLES + 1)
 #define OPTION_DISABLE_LONG_SECTION_NAMES \
 					(OPTION_ENABLE_LONG_SECTION_NAMES + 1)
+#define OPTION_PE_CHARACTERISTICS \
+					(OPTION_DISABLE_LONG_SECTION_NAMES + 1)
 
 static void
 gld${EMULATION_NAME}_add_options
@@ -290,6 +292,7 @@ gld${EMULATION_NAME}_add_options
     {"large-address-aware", no_argument, NULL, OPTION_LARGE_ADDRESS_AWARE},
     {"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
     {"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
+    {"pe-characteristics", required_argument, NULL, OPTION_PE_CHARACTERISTICS},
     {NULL, no_argument, NULL, 0}
   };
 
@@ -303,14 +306,47 @@ gld${EMULATION_NAME}_add_options
 
 typedef struct
 {
+  const char *name;
+  int len;
+  int value;
+} definfoflag;
+
+#define C(name)       { #name, sizeof(#name) - 1, name }
+#define CF(name,flag) { #name, sizeof(#name) - 1, flag }
+static const definfoflag dllchrctnames[] =
+{
+  /* Accept a few handy abbreviations.  */
+  CF(dynbase,     IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE),
+  CF(forceinteg,  IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY),
+  CF(nxcompat,    IMAGE_DLL_CHARACTERISTICS_NX_COMPAT),
+  CF(noisolation, IMAGE_DLLCHARACTERISTICS_NO_ISOLATION),
+  CF(noseh,       IMAGE_DLLCHARACTERISTICS_NO_SEH),
+  CF(nobind,      IMAGE_DLLCHARACTERISTICS_NO_BIND),
+  CF(wdmdriver,   IMAGE_DLLCHARACTERISTICS_WDM_DRIVER),
+  CF(tsaware,     IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE),
+  /* And the full names as defined in the PE specification.  */
+  C(IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE),
+  C(IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY),
+  C(IMAGE_DLL_CHARACTERISTICS_NX_COMPAT),
+  C(IMAGE_DLLCHARACTERISTICS_NO_ISOLATION),
+  C(IMAGE_DLLCHARACTERISTICS_NO_SEH),
+  C(IMAGE_DLLCHARACTERISTICS_WDM_DRIVER),
+  C(IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE),
+  { 0, 0, 0 },
+};
+
+typedef struct
+{
   void *ptr;
   int size;
   int value;
   char *symbol;
   int inited;
+  const definfoflag *flagnames;
 } definfo;
 
-#define D(field,symbol,def)  {&pe.field,sizeof(pe.field), def, symbol,0}
+#define D(field,symbol,def)         {&pe.field,sizeof(pe.field), def, symbol, 0, 0}
+#define DF(field,symbol,def,flags)  {&pe.field,sizeof(pe.field), def, symbol, 0, flags}
 
 static definfo init[] =
 {
@@ -318,7 +354,7 @@ static definfo init[] =
 #define IMAGEBASEOFF 0
   D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
 #define DLLOFF 1
-  {&dll, sizeof(dll), 0, "__dll__", 0},
+  {&dll, sizeof(dll), 0, "__dll__", 0, 0},
 #define MSIMAGEBASEOFF	2
   D(ImageBase, U ("__ImageBase"), NT_EXE_IMAGE_BASE),
   D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
@@ -339,10 +375,10 @@ static definfo init[] =
   D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
   D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
   D(LoaderFlags,"__loader_flags__", 0x0),
-  { NULL, 0, 0, NULL, 0 }
+  DF(DllCharacteristics, "__dll_characteristics__", 0x0, dllchrctnames),
+  { NULL, 0, 0, NULL, 0, 0 }
 };
 
-
 static void
 gld_${EMULATION_NAME}_list_options (FILE *file)
 {
@@ -401,29 +437,48 @@ gld_${EMULATION_NAME}_list_options (FILE
                                        executable image files\n"));
   fprintf (file, _("  --disable-long-section-names       Never use long COFF section names, even\n\
                                        in object files\n"));
+  fprintf (file, _("  --pe-characteristics <name|int>[<,|+:><name|int>[...]]\n\
+                                     Sets PE header DllCharacteristics field.\n"));
 }
 
+static const definfoflag *
+find_pe_flag_name (char *name, const definfoflag *flagnames)
+{
+  int i;
 
-static void
-set_pe_name (char *name, long val)
+  /* Look for the name, return pointer to definfoflag if found.  */
+  if (flagnames)
+    for (i = 0; flagnames[i].name; i++)
+      if (strncmp (name, flagnames[i].name, flagnames[i].len) == 0)
+	return &flagnames[i];
+  /* Unknown name could be an integer, so not an error here.  */
+  return 0;
+}
+
+static definfo *
+find_pe_name (char *name)
 {
   int i;
 
-  /* Find the name and set it.  */
+  /* Look for the name, return pointer to definfo.  */
   for (i = 0; init[i].ptr; i++)
-    {
-      if (strcmp (name, init[i].symbol) == 0)
-	{
-	  init[i].value = val;
-	  init[i].inited = 1;
-	  if (strcmp (name,"__image_base__") == 0)
-	    set_pe_name (U ("__ImageBase"), val);
-	  return;
-	}
-    }
+    if (strcmp (name, init[i].symbol) == 0)
+      return &init[i];
+  /* Unknown name is a serious internal coding error, so don't
+     bother to diagnose or return error indication, just bail.  */
   abort ();
 }
 
+static void
+set_pe_name (char *name, long val)
+{
+  /* Find the name and set it.  */
+  definfo *init = find_pe_name (name);
+  init->value = val;
+  init->inited = 1;
+  if (strcmp (name,"__image_base__") == 0)
+    set_pe_name (U ("__ImageBase"), val);
+}
 
 static void
 set_pe_subsystem (void)
@@ -543,6 +598,62 @@ set_pe_value (char *name)
   optarg = end;
 }
 
+static char
+is_flag_sep (char x)
+{
+  return x == '+' || x == '|' || x == ':' || x == ',';
+}
+
+static void
+set_pe_value_from_flags (char *name)
+{
+  long flags = 0;
+  definfo *init;
+
+  /* Look up the symbolic flag names.  Even if there aren't any we
+     will still parse multiple integers combined by separators.  */
+  init = find_pe_name (name);
+
+  /* Parse the flags out of optarg.  We accept any combination of
+     symbolic abbreviations and strtoul-parseable integers, separated
+     by any combination of '+', '|', ':' and ',' characters.  */
+  while (*optarg)
+    {
+      const definfoflag *flag;
+
+      /* Deliberately allow multiple conjoined separators.  */
+      while (is_flag_sep (*optarg))
+	optarg++;
+
+      /* Even trailing at the end.  */
+      if (!*optarg)
+	break;
+
+      flag = find_pe_flag_name (optarg, init->flagnames);
+      if (flag)
+	{
+	  flags |= flag->value;
+	  optarg += flag->len;
+	}
+      else
+	{
+	  char *end;
+	  long value;
+	  value = strtoul (optarg, &end, 0);
+	  if (end == optarg)
+	    einfo (_("%P%F: unrecognised integer/flag '%s' for PE parameter '%s'\n"),
+		optarg, name);
+	  flags |= value;
+	  optarg = end;
+	}
+      /* If there's any more, we do insist on at least one separator.  */
+      if (*optarg && !is_flag_sep (*optarg))
+	einfo (_("%P%F: unparseable at '%s' for PE parameter '%s'\n"),
+	  optarg, name);
+    }
+
+  set_pe_name (name,  flags);
+}
 
 static void
 set_pe_stack_heap (char *resname, char *comname)
@@ -707,6 +818,9 @@ gld${EMULATION_NAME}_handle_option (int 
     case OPTION_DISABLE_LONG_SECTION_NAMES:
       pe_use_coff_long_section_names = 0;
       break;
+    case OPTION_PE_CHARACTERISTICS:
+      set_pe_value_from_flags ("__dll_characteristics__");
+      break;
     }
   return TRUE;
 }
Index: ld/emultempl/pep.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pep.em,v
retrieving revision 1.23
diff -p -u -r1.23 pep.em
--- ld/emultempl/pep.em	3 Mar 2009 18:22:11 -0000	1.23
+++ ld/emultempl/pep.em	9 Mar 2009 05:45:59 -0000
@@ -179,7 +179,8 @@ enum options
   OPTION_EXCLUDE_MODULES_FOR_IMPLIB,
   OPTION_USE_NUL_PREFIXED_IMPORT_TABLES,
   OPTION_ENABLE_LONG_SECTION_NAMES,
-  OPTION_DISABLE_LONG_SECTION_NAMES
+  OPTION_DISABLE_LONG_SECTION_NAMES,
+  OPTION_PE_CHARACTERISTICS
 };
 
 static void
@@ -244,6 +245,7 @@ gld${EMULATION_NAME}_add_options
 #endif
     {"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
     {"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
+    {"pe-characteristics", required_argument, NULL, OPTION_PE_CHARACTERISTICS},
     {NULL, no_argument, NULL, 0}
   };
 
@@ -256,14 +258,47 @@ gld${EMULATION_NAME}_add_options
 
 typedef struct
 {
+  const char *name;
+  int len;
+  int value;
+} definfoflag;
+
+#define C(name)       { #name, sizeof(#name) - 1, name }
+#define CF(name,flag) { #name, sizeof(#name) - 1, flag }
+static const definfoflag dllchrctnames[] =
+{
+  /* Accept a few handy abbreviations.  */
+  CF(dynbase,     IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE),
+  CF(forceinteg,  IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY),
+  CF(nxcompat,    IMAGE_DLL_CHARACTERISTICS_NX_COMPAT),
+  CF(noisolation, IMAGE_DLLCHARACTERISTICS_NO_ISOLATION),
+  CF(noseh,       IMAGE_DLLCHARACTERISTICS_NO_SEH),
+  CF(nobind,      IMAGE_DLLCHARACTERISTICS_NO_BIND),
+  CF(wdmdriver,   IMAGE_DLLCHARACTERISTICS_WDM_DRIVER),
+  CF(tsaware,     IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE),
+  /* And the full names as defined in the PE specification.  */
+  C(IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE),
+  C(IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY),
+  C(IMAGE_DLL_CHARACTERISTICS_NX_COMPAT),
+  C(IMAGE_DLLCHARACTERISTICS_NO_ISOLATION),
+  C(IMAGE_DLLCHARACTERISTICS_NO_SEH),
+  C(IMAGE_DLLCHARACTERISTICS_WDM_DRIVER),
+  C(IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE),
+  { 0, 0, 0 },
+};
+
+typedef struct
+{
   void *ptr;
   int size;
   bfd_vma value;
   char *symbol;
   int inited;
+  const definfoflag *flagnames;
 } definfo;
 
-#define D(field,symbol,def)  {&pep.field,sizeof(pep.field), def, symbol,0}
+#define D(field,symbol,def)         {&pep.field,sizeof(pep.field), def, symbol, 0, 0}
+#define DF(field,symbol,def,flags)  {&pep.field,sizeof(pep.field), def, symbol, 0, flags}
 
 static definfo init[] =
 {
@@ -271,7 +306,7 @@ static definfo init[] =
 #define IMAGEBASEOFF 0
   D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
 #define DLLOFF 1
-  {&dll, sizeof(dll), 0, "__dll__", 0},
+  {&dll, sizeof(dll), 0, "__dll__", 0, 0},
 #define MSIMAGEBASEOFF	2
   D(ImageBase,"___ImageBase", NT_EXE_IMAGE_BASE),
   D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
@@ -288,7 +323,8 @@ static definfo init[] =
   D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
   D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
   D(LoaderFlags,"__loader_flags__", 0x0),
-  { NULL, 0, 0, NULL, 0 }
+  DF(DllCharacteristics, "__dll_characteristics__", 0x0, dllchrctnames),
+  { NULL, 0, 0, NULL, 0, 0 }
 };
 
 
@@ -346,30 +382,49 @@ gld_${EMULATION_NAME}_list_options (FILE
                                        executable image files\n"));
   fprintf (file, _("  --disable-long-section-names       Never use long COFF section names, even\n\
                                        in object files\n"));
+  fprintf (file, _("  --pe-characteristics <name|int>[<,|+:><name|int>[...]]\n\
+                                     Sets PE header DllCharacteristics field.\n"));
 #endif
 }
 
+static const definfoflag *
+find_pep_flag_name (char *name, const definfoflag *flagnames)
+{
+  int i;
 
-static void
-set_pep_name (char *name, bfd_vma val)
+  /* Look for the name, return pointer to definfoflag if found.  */
+  if (flagnames)
+    for (i = 0; flagnames[i].name; i++)
+      if (strncmp (name, flagnames[i].name, flagnames[i].len) == 0)
+	return &flagnames[i];
+  /* Unknown name could be an integer, so not an error here.  */
+  return 0;
+}
+
+static definfo *
+find_pep_name (char *name)
 {
   int i;
 
-  /* Find the name and set it.  */
+  /* Look for the name, return pointer to definfo.  */
   for (i = 0; init[i].ptr; i++)
-    {
-      if (strcmp (name, init[i].symbol) == 0)
-	{
-	  init[i].value = val;
-	  init[i].inited = 1;
-	  if (strcmp (name,"__image_base__") == 0)
-	    set_pep_name ("___ImageBase", val);
-	  return;
-	}
-    }
+    if (strcmp (name, init[i].symbol) == 0)
+      return &init[i];
+  /* Unknown name is a serious internal coding error, so don't
+     bother to diagnose or return error indication, just bail.  */
   abort ();
 }
 
+static void
+set_pep_name (char *name, long val)
+{
+  /* Find the name and set it.  */
+  definfo *init = find_pep_name (name);
+  init->value = val;
+  init->inited = 1;
+  if (strcmp (name,"__image_base__") == 0)
+    set_pep_name ("___ImageBase", val);
+}
 
 static void
 set_pep_subsystem (void)
@@ -489,6 +544,62 @@ set_pep_value (char *name)
   optarg = end;
 }
 
+static char
+is_flag_sep (char x)
+{
+  return x == '+' || x == '|' || x == ':' || x == ',';
+}
+
+static void
+set_pep_value_from_flags (char *name)
+{
+  long flags = 0;
+  definfo *init;
+
+  /* Look up the symbolic flag names.  Even if there aren't any we
+     will still parse multiple integers combined by separators.  */
+  init = find_pep_name (name);
+
+  /* Parse the flags out of optarg.  We accept any combination of
+     symbolic abbreviations and strtoul-parseable integers, separated
+     by any combination of '+', '|', ':' and ',' characters.  */
+  while (*optarg)
+    {
+      const definfoflag *flag;
+
+      /* Deliberately allow multiple conjoined separators.  */
+      while (is_flag_sep (*optarg))
+	optarg++;
+
+      /* Even trailing at the end.  */
+      if (!*optarg)
+	break;
+
+      flag = find_pep_flag_name (optarg, init->flagnames);
+      if (flag)
+	{
+	  flags |= flag->value;
+	  optarg += flag->len;
+	}
+      else
+	{
+	  char *end;
+	  long value;
+	  value = strtoul (optarg, &end, 0);
+	  if (end == optarg)
+	    einfo (_("%P%F: unrecognised integer/flag '%s' for PE parameter '%s'\n"),
+		optarg, name);
+	  flags |= value;
+	  optarg = end;
+	}
+      /* If there's any more, we do insist on at least one separator.  */
+      if (*optarg && !is_flag_sep (*optarg))
+	einfo (_("%P%F: unparseable at '%s' for PE parameter '%s'\n"),
+	  optarg, name);
+    }
+
+  set_pep_name (name,  flags);
+}
 
 static void
 set_pep_stack_heap (char *resname, char *comname)
@@ -647,6 +758,9 @@ gld${EMULATION_NAME}_handle_option (int 
     case OPTION_DISABLE_LONG_SECTION_NAMES:
       pep_use_coff_long_section_names = 0;
       break;
+    case OPTION_PE_CHARACTERISTICS:
+      set_pep_value_from_flags ("__dll_characteristics__");
+      break;
     }
   return TRUE;
 }
Index: ld/testsuite/ld-pe/dllcharact-1.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-1.d
diff -N ld/testsuite/ld-pe/dllcharact-1.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-1.d	9 Mar 2009 05:45:59 -0000
@@ -0,0 +1,7 @@
+#name: pe-characteristics-1
+#ld:  --pe-characteristics=1+128+512:nxcompat\\|wdmdriver\\|forceinteg
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00002381
Index: ld/testsuite/ld-pe/dllcharact-2.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-2.d
diff -N ld/testsuite/ld-pe/dllcharact-2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-2.d	9 Mar 2009 05:45:59 -0000
@@ -0,0 +1,7 @@
+#name: pe-characteristics-2
+#ld: --pe-characteristics=0x1234
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00001234
Index: ld/testsuite/ld-pe/dllcharact-3.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-3.d
diff -N ld/testsuite/ld-pe/dllcharact-3.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-3.d	9 Mar 2009 05:45:59 -0000
@@ -0,0 +1,7 @@
+#name: pe-characteristics-3
+#ld:  --pe-characteristics noseh:nobind:tsaware
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00008c00
Index: ld/testsuite/ld-pe/dllcharact-4.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-4.d
diff -N ld/testsuite/ld-pe/dllcharact-4.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-4.d	9 Mar 2009 05:45:59 -0000
@@ -0,0 +1,7 @@
+#name: pe-characteristics-4
+#ld:  --pe-characteristics=0x0400\\|0x0100
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00000500
Index: ld/testsuite/ld-pe/dllcharact-5.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-5.d
diff -N ld/testsuite/ld-pe/dllcharact-5.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-5.d	9 Mar 2009 05:45:59 -0000
@@ -0,0 +1,7 @@
+#name: pe-characteristics-5
+#ld:  --pe-characteristics=1+128+1024,noseh,nobind
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00000c81
Index: ld/testsuite/ld-pe/dllcharact-fail-1.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-fail-1.d
diff -N ld/testsuite/ld-pe/dllcharact-fail-1.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-fail-1.d	9 Mar 2009 05:45:59 -0000
@@ -0,0 +1,4 @@
+#name: pe-characteristics-fail-1
+#ld:  --pe-characteristics=1+0xf00:+badname+
+#error: .*unrecognised integer/flag.*
+#source: empty.s
Index: ld/testsuite/ld-pe/dllcharact-fail-2.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-fail-2.d
diff -N ld/testsuite/ld-pe/dllcharact-fail-2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-fail-2.d	9 Mar 2009 05:45:59 -0000
@@ -0,0 +1,9 @@
+#name: pe-characteristics-fail-2
+#ld:  --pe-characteristics=0xGoWrong:noseh
+#error: .*(unrecognised integer/flag '0xGoWrong:noseh'|unparseable at 'xGoWrong:noseh').*
+#source: empty.s
+
+## This one was interesting.  Different libc strtoul implementations appear to
+## behave differently: newlib regards '0x' as a hex prefix followed by an invalid
+## hex number, GNU libc parses it as an integer zero followed by an 'x'.  This
+## could well be a bug in newlib.
Index: ld/testsuite/ld-pe/dllcharact-fail-3.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-fail-3.d
diff -N ld/testsuite/ld-pe/dllcharact-fail-3.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-fail-3.d	9 Mar 2009 05:45:59 -0000
@@ -0,0 +1,4 @@
+#name: pe-characteristics-fail-3
+#ld:  --pe-characteristics 0x3DFG
+#error: .*unparseable at.*
+#source: empty.s
Index: ld/testsuite/ld-pe/dllcharact-fail-4.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-fail-4.d
diff -N ld/testsuite/ld-pe/dllcharact-fail-4.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-fail-4.d	9 Mar 2009 05:45:59 -0000
@@ -0,0 +1,4 @@
+#name: pe-characteristics-fail-4
+#ld:  --pe-characteristics 1+noseh+0x3DFnobind
+#error: .*unparseable at.*
+#source: empty.s
Index: ld/testsuite/ld-pe/dllcharact.exp
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact.exp
diff -N ld/testsuite/ld-pe/dllcharact.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact.exp	9 Mar 2009 05:45:59 -0000
@@ -0,0 +1,43 @@
+# Expect script for --pe-characteristics command-line option tests.
+#   Copyright 2009
+#   Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+ 
+# This test can only be run on PE/COFF platforms.
+if {![is_pecoff_format]} {
+    return
+}
+
+# Now we repeatedly re-link it with different args, 
+# and check that the field gets set correctly.
+
+run_dump_test "dllcharact-1"
+run_dump_test "dllcharact-2"
+run_dump_test "dllcharact-3"
+run_dump_test "dllcharact-4"
+run_dump_test "dllcharact-5"
+
+run_dump_test "dllcharact-fail-1"
+run_dump_test "dllcharact-fail-2"
+run_dump_test "dllcharact-fail-3"
+run_dump_test "dllcharact-fail-4"
+
+
+
Index: ld/testsuite/ld-pe/empty.s
===================================================================
RCS file: ld/testsuite/ld-pe/empty.s
diff -N ld/testsuite/ld-pe/empty.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/empty.s	9 Mar 2009 05:45:59 -0000
@@ -0,0 +1,7 @@
+	.text
+	.global _start
+	.global _mainCRTStartup
+_start:
+_mainCRTStartup:
+	.end
+
Index: ld/testsuite/lib/ld-lib.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/lib/ld-lib.exp,v
retrieving revision 1.59
diff -p -u -r1.59 ld-lib.exp
--- ld/testsuite/lib/ld-lib.exp	6 Feb 2009 16:56:12 -0000	1.59
+++ ld/testsuite/lib/ld-lib.exp	9 Mar 2009 05:45:59 -0000
@@ -582,11 +582,17 @@ proc simple_diff { file_1 file_2 } {
 #   objdump: FLAGS
 #   nm: FLAGS
 #   objcopy: FLAGS
+#   readelf: FLAGS
 #	Use the specified program to analyze the assembler or linker
 #       output file, and pass it FLAGS, in addition to the output name.
 #	Note that they are run with LC_ALL=C in the environment to give
 #	consistent sorting of symbols.
 #
+#   sed: FLAGS
+#       Run SED with the specified flags on the analyzer output dump
+#       file to perform custom post-processing, before attempting to
+#       match it against the pattern lines.
+#
 #   source: SOURCE [FLAGS]
 #	Assemble the file SOURCE.s using the flags in the "as" directive
 #       and the (optional) FLAGS.  If omitted, the source defaults to
@@ -661,6 +667,7 @@ proc run_dump_test { name } {
     set opts(nm) {}
     set opts(objcopy) {}
     set opts(readelf) {}
+    set opts(sed) {}
     set opts(name) {}
     set opts(PROG) {}
     set opts(source) {}
@@ -917,20 +924,31 @@ proc run_dump_test { name } {
     if { $progopts1 == "" } { set $progopts1 "-r" }
     verbose "running $binary $progopts $progopts1" 3
 
-    # Objcopy, unlike the other two, won't send its output to stdout,
-    # so we have to run it specially.
-    set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
-    if { $program == "objcopy" } {
-	set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
+    # Must be ready to post-process the dumpfile, if need be.  Objcopy,
+    # unlike the other two, won't send its output to stdout, so we have
+    # to run it specially.
+    if { $opts(sed) != "" } {
+	set cmdoutput "| sed $opts(sed) > $dumpfile"
+	if { $program == "objcopy" } {
+	    set cmdoutput "$dumpfile.1 && sed $opts(sed) < $dumpfile.1 > $dumpfile"
+	}
+    } else {
+	set cmdoutput "> $dumpfile"
+	if { $program == "objcopy" } {
+	    set cmdoutput "$dumpfile"
+	}
     }
 
+    # Generate the main command line, minus redirects.
+    set cmd "$binary $progopts $progopts1 $objfile"
+
     # Ensure consistent sorting of symbols
     if {[info exists env(LC_ALL)]} {
 	set old_lc_all $env(LC_ALL)
     }
     set env(LC_ALL) "C"
     send_log "$cmd\n"
-    set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
+    set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp $cmdoutput"]] "" "/dev/null"]
     remote_upload host "ld.tmp"
     set comp_output [prune_warnings [file_contents "ld.tmp"]]
     remote_file host delete "ld.tmp"

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-07  5:00           ` Dave Korn
@ 2009-03-09  5:24             ` Christopher Faylor
  2009-03-09  6:14               ` Dave Korn
  0 siblings, 1 reply; 36+ messages in thread
From: Christopher Faylor @ 2009-03-09  5:24 UTC (permalink / raw)
  To: binutils, Dave Korn

On Sat, Mar 07, 2009 at 05:10:02AM +0000, Dave Korn wrote:
>Christopher Faylor wrote:
>> On Fri, Mar 06, 2009 at 04:42:20PM +0000, Dave Korn wrote:
>>>Can you enlarge on how you would see the name "--dll-characteristics"
>>>causing confusion?  [ ...  ] I'm really not grasping the problem that
>>>you think could arise.
>>
>>Since you are talking about things like "documented name"s, why not
>>just make each of these an option like the Microsoft linker does?
>
>Because I'm not working to implement their linker spec, I'm working to
>implement their object file format spec, so details of their linker
>syntax are outside the scope of the work I am doing and not relevant to
>me.

I don't see any reason for a user to have to remember two things
(--dll-characteristics something) when they could just use --something.
If implemented as a simple option, you could get useful information from
--help, and you wouldn't have to invent a new way of parsing options.
And, if we name the options similarly to Microsoft's link command (and
there is certainly precedent for ld accommodating other linker's
arguments) we might even make it slightly easier for people who are
familiar with Microsoft's tools to use ours.

cgf

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-06 16:33       ` Dave Korn
  2009-03-06 23:40         ` Christopher Faylor
@ 2009-03-09  1:13         ` Dave Korn
  2009-03-09  5:47           ` Dave Korn
  2009-03-09  9:35           ` Vincent R.
  1 sibling, 2 replies; 36+ messages in thread
From: Dave Korn @ 2009-03-09  1:13 UTC (permalink / raw)
  To: Dave Korn; +Cc: binutils

[-- Attachment #1: Type: text/plain, Size: 214 bytes --]

Dave Korn wrote:
> Christopher Faylor wrote:

>> or --pe-characteristics.


  Attached, generated by running "sed -e's/-dll-/-/g' over the last patch.
Retested with same results as before.

    cheers,
      DaveK

[-- Attachment #2: pe-characteristics-patch.diff --]
[-- Type: text/plain, Size: 28797 bytes --]

Index: include/coff/internal.h
===================================================================
RCS file: /cvs/src/src/include/coff/internal.h,v
retrieving revision 1.22
diff -p -u -r1.22 internal.h
--- include/coff/internal.h	12 Jul 2007 07:16:41 -0000	1.22
+++ include/coff/internal.h	8 Mar 2009 04:01:20 -0000
@@ -185,7 +185,7 @@ struct internal_extra_pe_aouthdr 
      3 - WINDOWS_CUI runs in Windows char sub. (console app)
      5 - OS2_CUI runs in OS/2 character subsystem
      7 - POSIX_CUI runs in Posix character subsystem */
-  short   DllCharacteristics;	/* flags for DLL init, use 0 */
+  unsigned short DllCharacteristics;	/* flags for DLL init, use 0 */
   bfd_vma SizeOfStackReserve;	/* amount of memory to reserve  */
   bfd_vma SizeOfStackCommit;	/* amount of memory initially committed for 
 				   initial thread's stack, default is 0x1000 */
Index: include/coff/pe.h
===================================================================
RCS file: /cvs/src/src/include/coff/pe.h,v
retrieving revision 1.18
diff -p -u -r1.18 pe.h
--- include/coff/pe.h	4 Nov 2007 23:49:08 -0000	1.18
+++ include/coff/pe.h	8 Mar 2009 04:01:21 -0000
@@ -38,6 +38,17 @@
 #define IMAGE_FILE_UP_SYSTEM_ONLY            0x4000
 #define IMAGE_FILE_BYTES_REVERSED_HI         0x8000
 
+/* DllCharacteristics flag bits.  The inconsistent naming may seem
+   odd, but that is how they are defined in the PE specification.  */
+#define IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE          0x0040
+#define IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY       0x0080
+#define IMAGE_DLL_CHARACTERISTICS_NX_COMPAT             0x0100
+#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION           0x0200
+#define IMAGE_DLLCHARACTERISTICS_NO_SEH                 0x0400
+#define IMAGE_DLLCHARACTERISTICS_NO_BIND                0x0800
+#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER             0x2000
+#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE  0x8000
+
 /* Additional flags to be set for section headers to allow the NT loader to
    read and write to the section data (to replace the addresses of data in
    dlls for one thing); also to execute the section in .text's case.  */
Index: ld/NEWS
===================================================================
RCS file: /cvs/src/src/ld/NEWS,v
retrieving revision 1.100
diff -p -u -r1.100 NEWS
--- ld/NEWS	3 Mar 2009 18:22:10 -0000	1.100
+++ ld/NEWS	8 Mar 2009 04:01:21 -0000
@@ -1,5 +1,9 @@
 -*- text -*-
 
+* A new command-line flag '--pe-characteristics' allows PE targets
+  to set the value of the PE file header's DllCharacteristics field,
+  using a flexible combination of numeric and symbolic names.
+
 * New script function REGION_ALIAS to add alias names to memory regions.
 
 * PE targets no longer make use of the long section names PE extension to
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.235
diff -p -u -r1.235 ld.texinfo
--- ld/ld.texinfo	3 Mar 2009 18:22:10 -0000	1.235
+++ ld/ld.texinfo	8 Mar 2009 04:01:23 -0000
@@ -2257,6 +2257,57 @@ Sets the minor number of the ``os versio
 Sets the minor number of the ``subsystem version''.  Defaults to 0.
 [This option is specific to the i386 PE targeted port of the linker]
 
+@kindex --pe-characteristics
+@item --pe-characteristics (@var{name}|@var{integer})@*@	@w{@	}@	@w{@	}@	@w{@	}@	@w{@	}[(',' | '|' | '+' | ':')(@var{name}|@var{integer})[...]]
+Sets the value of the DllCharacteristics field in the PE header.  The
+value can be specified by using hexadecimal or decimal integers, or the
+symbolic names of the various bits, optionally combined by any combination
+of @samp{|}, @samp{+}, @samp{:} or @samp{,} characters.  The following
+short symbolic names are recognized, shown with the full name of the flag
+(as given in the MS PE specification) to which they correspond, which is
+also accepted:
+
+@table @samp
+@item dynbase
+@samp{IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE}
+
+@item forceinteg
+@samp{IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY}
+
+@item nxcompat
+@samp{IMAGE_DLL_CHARACTERISTICS_NX_COMPAT}
+
+@item noisolation
+@samp{IMAGE_DLLCHARACTERISTICS_NO_ISOLATION}
+
+@item noseh
+@samp{IMAGE_DLLCHARACTERISTICS_NO_SEH}
+
+@item nobind
+@samp{IMAGE_DLLCHARACTERISTICS_NO_BIND}
+
+@item wdmdriver
+@samp{IMAGE_DLLCHARACTERISTICS_WDM_DRIVER}
+
+@item tsaware
+@samp{IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE}
+
+@end table
+These options and separators can be combined with almost total
+flexibility; for example, valid uses of this option include:
+
+@smallexample
+--pe-characteristics=0x0400|0x0100
+@end smallexample
+@smallexample
+--pe-characteristics=1+128+1024,noseh,nobind
+@end smallexample
+@smallexample
+--pe-characteristics noseh:nobind:tsaware
+@end smallexample
+
+[This option is valid for all PE targeted ports of the linker]
+
 @cindex DEF files, creating
 @cindex DLLs, creating
 @kindex --output-def
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.146
diff -p -u -r1.146 pe.em
--- ld/emultempl/pe.em	3 Mar 2009 18:22:11 -0000	1.146
+++ ld/emultempl/pe.em	8 Mar 2009 04:01:24 -0000
@@ -229,6 +229,8 @@ fragment <<EOF
 					(OPTION_USE_NUL_PREFIXED_IMPORT_TABLES + 1)
 #define OPTION_DISABLE_LONG_SECTION_NAMES \
 					(OPTION_ENABLE_LONG_SECTION_NAMES + 1)
+#define OPTION_PE_DLL_CHARACTERISTICS \
+					(OPTION_DISABLE_LONG_SECTION_NAMES + 1)
 
 static void
 gld${EMULATION_NAME}_add_options
@@ -290,6 +292,7 @@ gld${EMULATION_NAME}_add_options
     {"large-address-aware", no_argument, NULL, OPTION_LARGE_ADDRESS_AWARE},
     {"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
     {"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
+    {"pe-characteristics", required_argument, NULL, OPTION_PE_DLL_CHARACTERISTICS},
     {NULL, no_argument, NULL, 0}
   };
 
@@ -303,14 +306,47 @@ gld${EMULATION_NAME}_add_options
 
 typedef struct
 {
+  const char *name;
+  int len;
+  int value;
+} definfoflag;
+
+#define C(name)       { #name, sizeof(#name) - 1, name }
+#define CF(name,flag) { #name, sizeof(#name) - 1, flag }
+static const definfoflag dllchrctnames[] =
+{
+  /* Accept a few handy abbreviations.  */
+  CF(dynbase,     IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE),
+  CF(forceinteg,  IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY),
+  CF(nxcompat,    IMAGE_DLL_CHARACTERISTICS_NX_COMPAT),
+  CF(noisolation, IMAGE_DLLCHARACTERISTICS_NO_ISOLATION),
+  CF(noseh,       IMAGE_DLLCHARACTERISTICS_NO_SEH),
+  CF(nobind,      IMAGE_DLLCHARACTERISTICS_NO_BIND),
+  CF(wdmdriver,   IMAGE_DLLCHARACTERISTICS_WDM_DRIVER),
+  CF(tsaware,     IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE),
+  /* And the full names as defined in the PE specification.  */
+  C(IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE),
+  C(IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY),
+  C(IMAGE_DLL_CHARACTERISTICS_NX_COMPAT),
+  C(IMAGE_DLLCHARACTERISTICS_NO_ISOLATION),
+  C(IMAGE_DLLCHARACTERISTICS_NO_SEH),
+  C(IMAGE_DLLCHARACTERISTICS_WDM_DRIVER),
+  C(IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE),
+  { 0, 0, 0 },
+};
+
+typedef struct
+{
   void *ptr;
   int size;
   int value;
   char *symbol;
   int inited;
+  const definfoflag *flagnames;
 } definfo;
 
-#define D(field,symbol,def)  {&pe.field,sizeof(pe.field), def, symbol,0}
+#define D(field,symbol,def)         {&pe.field,sizeof(pe.field), def, symbol, 0, 0}
+#define DF(field,symbol,def,flags)  {&pe.field,sizeof(pe.field), def, symbol, 0, flags}
 
 static definfo init[] =
 {
@@ -318,7 +354,7 @@ static definfo init[] =
 #define IMAGEBASEOFF 0
   D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
 #define DLLOFF 1
-  {&dll, sizeof(dll), 0, "__dll__", 0},
+  {&dll, sizeof(dll), 0, "__dll__", 0, 0},
 #define MSIMAGEBASEOFF	2
   D(ImageBase, U ("__ImageBase"), NT_EXE_IMAGE_BASE),
   D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
@@ -339,10 +375,10 @@ static definfo init[] =
   D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
   D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
   D(LoaderFlags,"__loader_flags__", 0x0),
-  { NULL, 0, 0, NULL, 0 }
+  DF(DllCharacteristics, "__dll_characteristics__", 0x0, dllchrctnames),
+  { NULL, 0, 0, NULL, 0, 0 }
 };
 
-
 static void
 gld_${EMULATION_NAME}_list_options (FILE *file)
 {
@@ -401,29 +437,48 @@ gld_${EMULATION_NAME}_list_options (FILE
                                        executable image files\n"));
   fprintf (file, _("  --disable-long-section-names       Never use long COFF section names, even\n\
                                        in object files\n"));
+  fprintf (file, _("  --pe-characteristics <name|int>[<,|+:><name|int>[...]]\n\
+                                     Sets PE header DllCharacteristics field.\n"));
 }
 
+static const definfoflag *
+find_pe_flag_name (char *name, const definfoflag *flagnames)
+{
+  int i;
 
-static void
-set_pe_name (char *name, long val)
+  /* Look for the name, return pointer to definfoflag if found.  */
+  if (flagnames)
+    for (i = 0; flagnames[i].name; i++)
+      if (strncmp (name, flagnames[i].name, flagnames[i].len) == 0)
+	return &flagnames[i];
+  /* Unknown name could be an integer, so not an error here.  */
+  return 0;
+}
+
+static definfo *
+find_pe_name (char *name)
 {
   int i;
 
-  /* Find the name and set it.  */
+  /* Look for the name, return pointer to definfo.  */
   for (i = 0; init[i].ptr; i++)
-    {
-      if (strcmp (name, init[i].symbol) == 0)
-	{
-	  init[i].value = val;
-	  init[i].inited = 1;
-	  if (strcmp (name,"__image_base__") == 0)
-	    set_pe_name (U ("__ImageBase"), val);
-	  return;
-	}
-    }
+    if (strcmp (name, init[i].symbol) == 0)
+      return &init[i];
+  /* Unknown name is a serious internal coding error, so don't
+     bother to diagnose or return error indication, just bail.  */
   abort ();
 }
 
+static void
+set_pe_name (char *name, long val)
+{
+  /* Find the name and set it.  */
+  definfo *init = find_pe_name (name);
+  init->value = val;
+  init->inited = 1;
+  if (strcmp (name,"__image_base__") == 0)
+    set_pe_name (U ("__ImageBase"), val);
+}
 
 static void
 set_pe_subsystem (void)
@@ -543,6 +598,62 @@ set_pe_value (char *name)
   optarg = end;
 }
 
+static char
+is_flag_sep (char x)
+{
+  return x == '+' || x == '|' || x == ':' || x == ',';
+}
+
+static void
+set_pe_value_from_flags (char *name)
+{
+  long flags = 0;
+  definfo *init;
+
+  /* Look up the symbolic flag names.  Even if there aren't any we
+     will still parse multiple integers combined by separators.  */
+  init = find_pe_name (name);
+
+  /* Parse the flags out of optarg.  We accept any combination of
+     symbolic abbreviations and strtoul-parseable integers, separated
+     by any combination of '+', '|', ':' and ',' characters.  */
+  while (*optarg)
+    {
+      const definfoflag *flag;
+
+      /* Deliberately allow multiple conjoined separators.  */
+      while (is_flag_sep (*optarg))
+	optarg++;
+
+      /* Even trailing at the end.  */
+      if (!*optarg)
+	break;
+
+      flag = find_pe_flag_name (optarg, init->flagnames);
+      if (flag)
+	{
+	  flags |= flag->value;
+	  optarg += flag->len;
+	}
+      else
+	{
+	  char *end;
+	  long value;
+	  value = strtoul (optarg, &end, 0);
+	  if (end == optarg)
+	    einfo (_("%P%F: unrecognised integer/flag '%s' for PE parameter '%s'\n"),
+		optarg, name);
+	  flags |= value;
+	  optarg = end;
+	}
+      /* If there's any more, we do insist on at least one separator.  */
+      if (*optarg && !is_flag_sep (*optarg))
+	einfo (_("%P%F: unparseable at '%s' for PE parameter '%s'\n"),
+	  optarg, name);
+    }
+
+  set_pe_name (name,  flags);
+}
 
 static void
 set_pe_stack_heap (char *resname, char *comname)
@@ -707,6 +818,9 @@ gld${EMULATION_NAME}_handle_option (int 
     case OPTION_DISABLE_LONG_SECTION_NAMES:
       pe_use_coff_long_section_names = 0;
       break;
+    case OPTION_PE_DLL_CHARACTERISTICS:
+      set_pe_value_from_flags ("__dll_characteristics__");
+      break;
     }
   return TRUE;
 }
Index: ld/emultempl/pep.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pep.em,v
retrieving revision 1.23
diff -p -u -r1.23 pep.em
--- ld/emultempl/pep.em	3 Mar 2009 18:22:11 -0000	1.23
+++ ld/emultempl/pep.em	8 Mar 2009 04:01:24 -0000
@@ -179,7 +179,8 @@ enum options
   OPTION_EXCLUDE_MODULES_FOR_IMPLIB,
   OPTION_USE_NUL_PREFIXED_IMPORT_TABLES,
   OPTION_ENABLE_LONG_SECTION_NAMES,
-  OPTION_DISABLE_LONG_SECTION_NAMES
+  OPTION_DISABLE_LONG_SECTION_NAMES,
+  OPTION_PE_DLL_CHARACTERISTICS
 };
 
 static void
@@ -244,6 +245,7 @@ gld${EMULATION_NAME}_add_options
 #endif
     {"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
     {"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
+    {"pe-characteristics", required_argument, NULL, OPTION_PE_DLL_CHARACTERISTICS},
     {NULL, no_argument, NULL, 0}
   };
 
@@ -256,14 +258,47 @@ gld${EMULATION_NAME}_add_options
 
 typedef struct
 {
+  const char *name;
+  int len;
+  int value;
+} definfoflag;
+
+#define C(name)       { #name, sizeof(#name) - 1, name }
+#define CF(name,flag) { #name, sizeof(#name) - 1, flag }
+static const definfoflag dllchrctnames[] =
+{
+  /* Accept a few handy abbreviations.  */
+  CF(dynbase,     IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE),
+  CF(forceinteg,  IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY),
+  CF(nxcompat,    IMAGE_DLL_CHARACTERISTICS_NX_COMPAT),
+  CF(noisolation, IMAGE_DLLCHARACTERISTICS_NO_ISOLATION),
+  CF(noseh,       IMAGE_DLLCHARACTERISTICS_NO_SEH),
+  CF(nobind,      IMAGE_DLLCHARACTERISTICS_NO_BIND),
+  CF(wdmdriver,   IMAGE_DLLCHARACTERISTICS_WDM_DRIVER),
+  CF(tsaware,     IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE),
+  /* And the full names as defined in the PE specification.  */
+  C(IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE),
+  C(IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY),
+  C(IMAGE_DLL_CHARACTERISTICS_NX_COMPAT),
+  C(IMAGE_DLLCHARACTERISTICS_NO_ISOLATION),
+  C(IMAGE_DLLCHARACTERISTICS_NO_SEH),
+  C(IMAGE_DLLCHARACTERISTICS_WDM_DRIVER),
+  C(IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE),
+  { 0, 0, 0 },
+};
+
+typedef struct
+{
   void *ptr;
   int size;
   bfd_vma value;
   char *symbol;
   int inited;
+  const definfoflag *flagnames;
 } definfo;
 
-#define D(field,symbol,def)  {&pep.field,sizeof(pep.field), def, symbol,0}
+#define D(field,symbol,def)         {&pep.field,sizeof(pep.field), def, symbol, 0, 0}
+#define DF(field,symbol,def,flags)  {&pep.field,sizeof(pep.field), def, symbol, 0, flags}
 
 static definfo init[] =
 {
@@ -271,7 +306,7 @@ static definfo init[] =
 #define IMAGEBASEOFF 0
   D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
 #define DLLOFF 1
-  {&dll, sizeof(dll), 0, "__dll__", 0},
+  {&dll, sizeof(dll), 0, "__dll__", 0, 0},
 #define MSIMAGEBASEOFF	2
   D(ImageBase,"___ImageBase", NT_EXE_IMAGE_BASE),
   D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
@@ -288,7 +323,8 @@ static definfo init[] =
   D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
   D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
   D(LoaderFlags,"__loader_flags__", 0x0),
-  { NULL, 0, 0, NULL, 0 }
+  DF(DllCharacteristics, "__dll_characteristics__", 0x0, dllchrctnames),
+  { NULL, 0, 0, NULL, 0, 0 }
 };
 
 
@@ -346,30 +382,49 @@ gld_${EMULATION_NAME}_list_options (FILE
                                        executable image files\n"));
   fprintf (file, _("  --disable-long-section-names       Never use long COFF section names, even\n\
                                        in object files\n"));
+  fprintf (file, _("  --pe-characteristics <name|int>[<,|+:><name|int>[...]]\n\
+                                     Sets PE header DllCharacteristics field.\n"));
 #endif
 }
 
+static const definfoflag *
+find_pep_flag_name (char *name, const definfoflag *flagnames)
+{
+  int i;
 
-static void
-set_pep_name (char *name, bfd_vma val)
+  /* Look for the name, return pointer to definfoflag if found.  */
+  if (flagnames)
+    for (i = 0; flagnames[i].name; i++)
+      if (strncmp (name, flagnames[i].name, flagnames[i].len) == 0)
+	return &flagnames[i];
+  /* Unknown name could be an integer, so not an error here.  */
+  return 0;
+}
+
+static definfo *
+find_pep_name (char *name)
 {
   int i;
 
-  /* Find the name and set it.  */
+  /* Look for the name, return pointer to definfo.  */
   for (i = 0; init[i].ptr; i++)
-    {
-      if (strcmp (name, init[i].symbol) == 0)
-	{
-	  init[i].value = val;
-	  init[i].inited = 1;
-	  if (strcmp (name,"__image_base__") == 0)
-	    set_pep_name ("___ImageBase", val);
-	  return;
-	}
-    }
+    if (strcmp (name, init[i].symbol) == 0)
+      return &init[i];
+  /* Unknown name is a serious internal coding error, so don't
+     bother to diagnose or return error indication, just bail.  */
   abort ();
 }
 
+static void
+set_pep_name (char *name, long val)
+{
+  /* Find the name and set it.  */
+  definfo *init = find_pep_name (name);
+  init->value = val;
+  init->inited = 1;
+  if (strcmp (name,"__image_base__") == 0)
+    set_pep_name ("___ImageBase", val);
+}
 
 static void
 set_pep_subsystem (void)
@@ -489,6 +544,62 @@ set_pep_value (char *name)
   optarg = end;
 }
 
+static char
+is_flag_sep (char x)
+{
+  return x == '+' || x == '|' || x == ':' || x == ',';
+}
+
+static void
+set_pep_value_from_flags (char *name)
+{
+  long flags = 0;
+  definfo *init;
+
+  /* Look up the symbolic flag names.  Even if there aren't any we
+     will still parse multiple integers combined by separators.  */
+  init = find_pep_name (name);
+
+  /* Parse the flags out of optarg.  We accept any combination of
+     symbolic abbreviations and strtoul-parseable integers, separated
+     by any combination of '+', '|', ':' and ',' characters.  */
+  while (*optarg)
+    {
+      const definfoflag *flag;
+
+      /* Deliberately allow multiple conjoined separators.  */
+      while (is_flag_sep (*optarg))
+	optarg++;
+
+      /* Even trailing at the end.  */
+      if (!*optarg)
+	break;
+
+      flag = find_pep_flag_name (optarg, init->flagnames);
+      if (flag)
+	{
+	  flags |= flag->value;
+	  optarg += flag->len;
+	}
+      else
+	{
+	  char *end;
+	  long value;
+	  value = strtoul (optarg, &end, 0);
+	  if (end == optarg)
+	    einfo (_("%P%F: unrecognised integer/flag '%s' for PE parameter '%s'\n"),
+		optarg, name);
+	  flags |= value;
+	  optarg = end;
+	}
+      /* If there's any more, we do insist on at least one separator.  */
+      if (*optarg && !is_flag_sep (*optarg))
+	einfo (_("%P%F: unparseable at '%s' for PE parameter '%s'\n"),
+	  optarg, name);
+    }
+
+  set_pep_name (name,  flags);
+}
 
 static void
 set_pep_stack_heap (char *resname, char *comname)
@@ -647,6 +758,9 @@ gld${EMULATION_NAME}_handle_option (int 
     case OPTION_DISABLE_LONG_SECTION_NAMES:
       pep_use_coff_long_section_names = 0;
       break;
+    case OPTION_PE_DLL_CHARACTERISTICS:
+      set_pep_value_from_flags ("__dll_characteristics__");
+      break;
     }
   return TRUE;
 }
Index: ld/testsuite/ld-pe/dllcharact-1.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-1.d
diff -N ld/testsuite/ld-pe/dllcharact-1.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-1.d	8 Mar 2009 04:01:26 -0000
@@ -0,0 +1,7 @@
+#name: pe-characteristics-1
+#ld:  --pe-characteristics=1+128+512:nxcompat\\|wdmdriver\\|forceinteg
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00002381
Index: ld/testsuite/ld-pe/dllcharact-2.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-2.d
diff -N ld/testsuite/ld-pe/dllcharact-2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-2.d	8 Mar 2009 04:01:26 -0000
@@ -0,0 +1,7 @@
+#name: pe-characteristics-2
+#ld: --pe-characteristics=0x1234
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00001234
Index: ld/testsuite/ld-pe/dllcharact-3.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-3.d
diff -N ld/testsuite/ld-pe/dllcharact-3.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-3.d	8 Mar 2009 04:01:26 -0000
@@ -0,0 +1,7 @@
+#name: pe-characteristics-3
+#ld:  --pe-characteristics noseh:nobind:tsaware
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00008c00
Index: ld/testsuite/ld-pe/dllcharact-4.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-4.d
diff -N ld/testsuite/ld-pe/dllcharact-4.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-4.d	8 Mar 2009 04:01:26 -0000
@@ -0,0 +1,7 @@
+#name: pe-characteristics-4
+#ld:  --pe-characteristics=0x0400\\|0x0100
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00000500
Index: ld/testsuite/ld-pe/dllcharact-5.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-5.d
diff -N ld/testsuite/ld-pe/dllcharact-5.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-5.d	8 Mar 2009 04:01:26 -0000
@@ -0,0 +1,7 @@
+#name: pe-characteristics-5
+#ld:  --pe-characteristics=1+128+1024,noseh,nobind
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00000c81
Index: ld/testsuite/ld-pe/dllcharact-fail-1.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-fail-1.d
diff -N ld/testsuite/ld-pe/dllcharact-fail-1.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-fail-1.d	8 Mar 2009 04:01:26 -0000
@@ -0,0 +1,4 @@
+#name: pe-characteristics-fail-1
+#ld:  --pe-characteristics=1+0xf00:+badname+
+#error: .*unrecognised integer/flag.*
+#source: empty.s
Index: ld/testsuite/ld-pe/dllcharact-fail-2.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-fail-2.d
diff -N ld/testsuite/ld-pe/dllcharact-fail-2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-fail-2.d	8 Mar 2009 04:01:26 -0000
@@ -0,0 +1,9 @@
+#name: pe-characteristics-fail-2
+#ld:  --pe-characteristics=0xGoWrong:noseh
+#error: .*(unrecognised integer/flag '0xGoWrong:noseh'|unparseable at 'xGoWrong:noseh').*
+#source: empty.s
+
+## This one was interesting.  Different libc strtoul implementations appear to
+## behave differently: newlib regards '0x' as a hex prefix followed by an invalid
+## hex number, GNU libc parses it as an integer zero followed by an 'x'.  This
+## could well be a bug in newlib.
Index: ld/testsuite/ld-pe/dllcharact-fail-3.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-fail-3.d
diff -N ld/testsuite/ld-pe/dllcharact-fail-3.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-fail-3.d	8 Mar 2009 04:01:26 -0000
@@ -0,0 +1,4 @@
+#name: pe-characteristics-fail-3
+#ld:  --pe-characteristics 0x3DFG
+#error: .*unparseable at.*
+#source: empty.s
Index: ld/testsuite/ld-pe/dllcharact-fail-4.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-fail-4.d
diff -N ld/testsuite/ld-pe/dllcharact-fail-4.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-fail-4.d	8 Mar 2009 04:01:26 -0000
@@ -0,0 +1,4 @@
+#name: pe-characteristics-fail-4
+#ld:  --pe-characteristics 1+noseh+0x3DFnobind
+#error: .*unparseable at.*
+#source: empty.s
Index: ld/testsuite/ld-pe/dllcharact.exp
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact.exp
diff -N ld/testsuite/ld-pe/dllcharact.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact.exp	8 Mar 2009 04:01:26 -0000
@@ -0,0 +1,43 @@
+# Expect script for --pe-characteristics command-line option tests.
+#   Copyright 2009
+#   Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+ 
+# This test can only be run on PE/COFF platforms.
+if {![is_pecoff_format]} {
+    return
+}
+
+# Now we repeatedly re-link it with different args, 
+# and check that the field gets set correctly.
+
+run_dump_test "dllcharact-1"
+run_dump_test "dllcharact-2"
+run_dump_test "dllcharact-3"
+run_dump_test "dllcharact-4"
+run_dump_test "dllcharact-5"
+
+run_dump_test "dllcharact-fail-1"
+run_dump_test "dllcharact-fail-2"
+run_dump_test "dllcharact-fail-3"
+run_dump_test "dllcharact-fail-4"
+
+
+
Index: ld/testsuite/ld-pe/empty.s
===================================================================
RCS file: ld/testsuite/ld-pe/empty.s
diff -N ld/testsuite/ld-pe/empty.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/empty.s	8 Mar 2009 04:01:26 -0000
@@ -0,0 +1,7 @@
+	.text
+	.global _start
+	.global _mainCRTStartup
+_start:
+_mainCRTStartup:
+	.end
+
Index: ld/testsuite/lib/ld-lib.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/lib/ld-lib.exp,v
retrieving revision 1.59
diff -p -u -r1.59 ld-lib.exp
--- ld/testsuite/lib/ld-lib.exp	6 Feb 2009 16:56:12 -0000	1.59
+++ ld/testsuite/lib/ld-lib.exp	8 Mar 2009 04:01:26 -0000
@@ -582,11 +582,17 @@ proc simple_diff { file_1 file_2 } {
 #   objdump: FLAGS
 #   nm: FLAGS
 #   objcopy: FLAGS
+#   readelf: FLAGS
 #	Use the specified program to analyze the assembler or linker
 #       output file, and pass it FLAGS, in addition to the output name.
 #	Note that they are run with LC_ALL=C in the environment to give
 #	consistent sorting of symbols.
 #
+#   sed: FLAGS
+#       Run SED with the specified flags on the analyzer output dump
+#       file to perform custom post-processing, before attempting to
+#       match it against the pattern lines.
+#
 #   source: SOURCE [FLAGS]
 #	Assemble the file SOURCE.s using the flags in the "as" directive
 #       and the (optional) FLAGS.  If omitted, the source defaults to
@@ -661,6 +667,7 @@ proc run_dump_test { name } {
     set opts(nm) {}
     set opts(objcopy) {}
     set opts(readelf) {}
+    set opts(sed) {}
     set opts(name) {}
     set opts(PROG) {}
     set opts(source) {}
@@ -917,20 +924,31 @@ proc run_dump_test { name } {
     if { $progopts1 == "" } { set $progopts1 "-r" }
     verbose "running $binary $progopts $progopts1" 3
 
-    # Objcopy, unlike the other two, won't send its output to stdout,
-    # so we have to run it specially.
-    set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
-    if { $program == "objcopy" } {
-	set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
+    # Must be ready to post-process the dumpfile, if need be.  Objcopy,
+    # unlike the other two, won't send its output to stdout, so we have
+    # to run it specially.
+    if { $opts(sed) != "" } {
+	set cmdoutput "| sed $opts(sed) > $dumpfile"
+	if { $program == "objcopy" } {
+	    set cmdoutput "$dumpfile.1 && sed $opts(sed) < $dumpfile.1 > $dumpfile"
+	}
+    } else {
+	set cmdoutput "> $dumpfile"
+	if { $program == "objcopy" } {
+	    set cmdoutput "$dumpfile"
+	}
     }
 
+    # Generate the main command line, minus redirects.
+    set cmd "$binary $progopts $progopts1 $objfile"
+
     # Ensure consistent sorting of symbols
     if {[info exists env(LC_ALL)]} {
 	set old_lc_all $env(LC_ALL)
     }
     set env(LC_ALL) "C"
     send_log "$cmd\n"
-    set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
+    set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp $cmdoutput"]] "" "/dev/null"]
     remote_upload host "ld.tmp"
     set comp_output [prune_warnings [file_contents "ld.tmp"]]
     remote_file host delete "ld.tmp"

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
@ 2009-03-08 22:21 Charles Wilson
  0 siblings, 0 replies; 36+ messages in thread
From: Charles Wilson @ 2009-03-08 22:21 UTC (permalink / raw)
  To: binutils

Dave Korn wrote:
> Christopher Faylor wrote: 
>> or --pe-characteristics.
> 
>   I could live with this, because it's part of the optional PE header, and the
> Characteristics field is part of the base COFF header, so could in theory be
> denoted by "--coff-characteristics".

FWIW, I like this suggestion.  Using

   --pe-characteristics
	manipulate flags in the DllCharacteristics field of the
	output object's "optional" PE header. When MS defined
	the PE format and decided to name this field, they picked
	a poor name: it really isn't DLL specific at all.  This
	field is really a PE extension to the base COFF
	characteristics...

This would leave room later for

    --coff-characteristics
	manipulate flags in the Characteristics field of the output
	object's base COFF header. (I think just plain
	"--characteristics" is way too ambiguous, for either field).

--
Chuck

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-06 23:40         ` Christopher Faylor
@ 2009-03-07  5:00           ` Dave Korn
  2009-03-09  5:24             ` Christopher Faylor
  0 siblings, 1 reply; 36+ messages in thread
From: Dave Korn @ 2009-03-07  5:00 UTC (permalink / raw)
  To: binutils

Christopher Faylor wrote:
> On Fri, Mar 06, 2009 at 04:42:20PM +0000, Dave Korn wrote:

>>  Can you enlarge on how you would see the name "--dll-characteristics"
>> causing confusion?   [ ... ]  I'm really
>> not grasping the problem that you think could arise.
> 
> Since you are talking about things like "documented name"s, why not just
> make each of these an option like the Microsoft linker does?  

  Because I'm not working to implement their linker spec, I'm working to
implement their object file format spec, so details of their linker syntax are
outside the scope of the work I am doing and not relevant to me.

    cheers,
      DaveK

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-06 16:33       ` Dave Korn
@ 2009-03-06 23:40         ` Christopher Faylor
  2009-03-07  5:00           ` Dave Korn
  2009-03-09  1:13         ` Dave Korn
  1 sibling, 1 reply; 36+ messages in thread
From: Christopher Faylor @ 2009-03-06 23:40 UTC (permalink / raw)
  To: binutils, Dave Korn

On Fri, Mar 06, 2009 at 04:42:20PM +0000, Dave Korn wrote:
>Christopher Faylor wrote:
>> On Fri, Mar 06, 2009 at 06:48:09AM +0000, Dave Korn wrote:
>>> It's only the extra debug option that mentions pe by name.  So if it
>>> was my choice I'd now want to call the flag "--dll-characteristics".
>>> Do you or any of the other regular maintainers have any suggestions?
>
>> --characteristics 
>
>  This removes the only part of the name that distinguishes whether it refers
>to the "Characteristics" field or the "DllCharacteristics".

Yes, I mentioned this my other message in response to Danny.

>> or --pe-characteristics.
>
>  I could live with this, because it's part of the optional PE header, and the
>Characteristics field is part of the base COFF header, so could in theory be
>denoted by "--coff-characteristics".
>
>  Can you enlarge on how you would see the name "--dll-characteristics"
>causing confusion?  I think it's an odd kind of end-user who'd know enough to
>have a reason to be looking to set these bits, yet somehow be surprised by
>what the option was called.  Most people who end up using it will, I think, be
>either (most common) non-developer-end-users who want to build packages from
>source and will run into problems which someone will answer by saying "Add
>-dll-characteristics=tsaware to the linker flags", and they'll just cut and
>paste it without caring what it means, or (less common) developers fully aware
>of the PE format who will know exactly what the name DllCharacteristics means
>and not be confused by its applicability to more than DLLs alone (and
>conceivably be surprised to find the option named differently).  I'm really
>not grasping the problem that you think could arise.

Since you are talking about things like "documented name"s, why not just
make each of these an option like the Microsoft linker does?  If we're
trying to catch people who are used to these facilities, it seems like
we should be trying to be consistent with the way the entity who created
these flags dealt with them.

So, I'd propose that all of the suboptions just become first-class
options and, if it is really required, --dll-characteristics take an
integer argument to provide pinpoint control over what gets set.

cgf

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-06 16:13     ` Christopher Faylor
@ 2009-03-06 16:33       ` Dave Korn
  2009-03-06 23:40         ` Christopher Faylor
  2009-03-09  1:13         ` Dave Korn
  0 siblings, 2 replies; 36+ messages in thread
From: Dave Korn @ 2009-03-06 16:33 UTC (permalink / raw)
  To: binutils

Christopher Faylor wrote:
> On Fri, Mar 06, 2009 at 06:48:09AM +0000, Dave Korn wrote:
>> It's only the extra debug option that mentions pe by name.  So if it
>> was my choice I'd now want to call the flag "--dll-characteristics".
>> Do you or any of the other regular maintainers have any suggestions?

> --characteristics 

  This removes the only part of the name that distinguishes whether it refers
to the "Characteristics" field or the "DllCharacteristics".

> or --pe-characteristics.

  I could live with this, because it's part of the optional PE header, and the
Characteristics field is part of the base COFF header, so could in theory be
denoted by "--coff-characteristics".

  Can you enlarge on how you would see the name "--dll-characteristics"
causing confusion?  I think it's an odd kind of end-user who'd know enough to
have a reason to be looking to set these bits, yet somehow be surprised by
what the option was called.  Most people who end up using it will, I think, be
either (most common) non-developer-end-users who want to build packages from
source and will run into problems which someone will answer by saying "Add
-dll-characteristics=tsaware to the linker flags", and they'll just cut and
paste it without caring what it means, or (less common) developers fully aware
of the PE format who will know exactly what the name DllCharacteristics means
and not be confused by its applicability to more than DLLs alone (and
conceivably be surprised to find the option named differently).  I'm really
not grasping the problem that you think could arise.

    cheers,
      DaveK

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-06  8:17     ` Danny Smith
@ 2009-03-06 16:24       ` Christopher Faylor
  0 siblings, 0 replies; 36+ messages in thread
From: Christopher Faylor @ 2009-03-06 16:24 UTC (permalink / raw)
  To: binutils

On Fri, Mar 06, 2009 at 09:17:03PM +1300, Danny Smith wrote:
>On Fri, Mar 6, 2009 at 7:48 PM, Dave Korn  wrote:
>>Christopher Faylor wrote:
>>>On Thu, Mar 05, 2009 at 12:58:39PM +0000, Dave Korn wrote:
>>>>The PE header in executables contains a field called
>>>>"DllCharacteristics", which contains various flags that inform the OS
>>>>dynamic loader about the status of the executable w.r.t.  ?runtime
>>>>factors such as NX/DEP, ASLR, dynamic rebasing, etc.  ?(Despite the
>>>>name, it applies to executables of all kinds, not just DLLs, but that's
>>>>what MS calls it so that's what I call it).
>>>
>I agree with Dave on the naming of the options.
>
>The PE Coff spec defines the meaning of these flags in a section called
>"DLL Characteristics".  dumpbin / header foo.exe | grep "DLL
>characteristics" tells us value of the field.
>
>It makes perfect sense to me to name the option after the the header
>field that it sets.

Not all of the other options used by ld reflect the "published name" that
you see from "dumpbin".

If you are going to quote Microsoft sources as definitive then we should
be unrolling each of the settings into a separate option, like editbin.

However, dumpbin does illustrate one thing that I forgot:
"characteristics" would be an overloaded term for PE's.

I suspect that the "DLL" part of the "DLL Characteristics" reflects the
history of the field in the PE header rather than its current
functionality.  I don't see any reason to promulgate it.

cgf

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-06  6:38   ` Dave Korn
  2009-03-06  8:17     ` Danny Smith
  2009-03-06 13:11     ` Vincent R.
@ 2009-03-06 16:13     ` Christopher Faylor
  2009-03-06 16:33       ` Dave Korn
  2 siblings, 1 reply; 36+ messages in thread
From: Christopher Faylor @ 2009-03-06 16:13 UTC (permalink / raw)
  To: binutils

On Fri, Mar 06, 2009 at 06:48:09AM +0000, Dave Korn wrote:
>It's only the extra debug option that mentions pe by name.  So if it
>was my choice I'd now want to call the flag "--dll-characteristics".
>Do you or any of the other regular maintainers have any suggestions?

--characteristics or --pe-characteristics.

cgf

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-06 13:11     ` Vincent R.
@ 2009-03-06 13:31       ` Kai Tietz
  0 siblings, 0 replies; 36+ messages in thread
From: Kai Tietz @ 2009-03-06 13:31 UTC (permalink / raw)
  To: binutils

2009/3/6 Vincent R. <forumer@smartmobili.com>:
> And while you play with PE format, I have noticed that binutils has a
> different way
> of considering Import Table size in DLLs.
> Indeed if you take the same source code, for instance linpng and you
> compile one with MS Visual
> and the other with gcc/binutils and look at code generated you will see
> that in Data directories
> size of Import Table is only equal to Import Directory Table(IDT) with MS
> Visual and is equal to
> IDT + ILT +DLLName with gcc.
> I think ktietz already knows that and has a patch for it that also fix some
> other minor issues.
>
>

Yes, I have a patch for it to paper-bag it, but this patch has some
problems when used with pseudo-relocation version 1. For this version
the IAT can't be calculated proper, because the IAT-entries are put
everywhere in code/data/etc . For version 2, where the IAT is a
continoues block, it works.
At the moment I work on a patch to add some of the missing issues in
for idata, NO_LOAD, and weak externals as the pe-coff spec describes
them.

Cheers,
Kai


-- 
|  (\_/) This is Bunny. Copy and paste
| (='.'=) Bunny into your signature to help
| (")_(") him gain world domination

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-06  6:38   ` Dave Korn
  2009-03-06  8:17     ` Danny Smith
@ 2009-03-06 13:11     ` Vincent R.
  2009-03-06 13:31       ` Kai Tietz
  2009-03-06 16:13     ` Christopher Faylor
  2 siblings, 1 reply; 36+ messages in thread
From: Vincent R. @ 2009-03-06 13:11 UTC (permalink / raw)
  To: binutils

And while you play with PE format, I have noticed that binutils has a
different way
of considering Import Table size in DLLs.
Indeed if you take the same source code, for instance linpng and you
compile one with MS Visual
and the other with gcc/binutils and look at code generated you will see
that in Data directories
size of Import Table is only equal to Import Directory Table(IDT) with MS
Visual and is equal to 
IDT + ILT +DLLName with gcc.
I think ktietz already knows that and has a patch for it that also fix some
other minor issues.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-06  6:38   ` Dave Korn
@ 2009-03-06  8:17     ` Danny Smith
  2009-03-06 16:24       ` Christopher Faylor
  2009-03-06 13:11     ` Vincent R.
  2009-03-06 16:13     ` Christopher Faylor
  2 siblings, 1 reply; 36+ messages in thread
From: Danny Smith @ 2009-03-06  8:17 UTC (permalink / raw)
  To: binutils

On Fri, Mar 6, 2009 at 7:48 PM, Dave Korn  wrote:
> Christopher Faylor wrote:
>> On Thu, Mar 05, 2009 at 12:58:39PM +0000, Dave Korn wrote:
>>> The PE header in executables contains a field called
>>> "DllCharacteristics", which contains various flags that inform the OS
>>> dynamic loader about the status of the executable w.r.t.  runtime
>>> factors such as NX/DEP, ASLR, dynamic rebasing, etc.  (Despite the
>>> name, it applies to executables of all kinds, not just DLLs, but that's
>>> what MS calls it so that's what I call it).
>>
I agree with Dave on the naming of the options.

The PE Coff spec defines the meaning of these flags in a section called
"DLL Characteristics".
 dumpbin / header foo.exe | grep "DLL characteristics" tells us value
of the field.

It makes perfect sense to me to name the option after the the header
field that it sets.
Danny

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-06  5:47 ` Christopher Faylor
@ 2009-03-06  6:38   ` Dave Korn
  2009-03-06  8:17     ` Danny Smith
                       ` (2 more replies)
  0 siblings, 3 replies; 36+ messages in thread
From: Dave Korn @ 2009-03-06  6:38 UTC (permalink / raw)
  To: binutils

Christopher Faylor wrote:
> On Thu, Mar 05, 2009 at 12:58:39PM +0000, Dave Korn wrote:
>> The PE header in executables contains a field called
>> "DllCharacteristics", which contains various flags that inform the OS
>> dynamic loader about the status of the executable w.r.t.  runtime
>> factors such as NX/DEP, ASLR, dynamic rebasing, etc.  (Despite the
>> name, it applies to executables of all kinds, not just DLLs, but that's
>> what MS calls it so that's what I call it).
> 
> And, as I mentioned in the Cygwin mailing list, "despite the name", I
> don't think the option should mention "dll".  The name of the option
> doesn't have to mirror an internal define.

  Well, whatever alternative suggestion you can come up with is probably
something I'd grudgingly accept, but it has to avoid any confusion with the
"Characteristics" field that also exists in PE file headers.  And I remain
allergic to making up new names for things that already have existing standard
names on general principle.  I don't think it's entirely correct to call it an
"internal define": it's a documented name in an open standard.

> I wonder if the name "pe-" is even TMI for this option but at least
> there is some precedent for that.

  Actually looking at the other header-related options convinces me that it is.

`--major-image-version VALUE'
`--major-os-version VALUE'
`--major-subsystem-version VALUE'
`--minor-image-version VALUE'
`--minor-os-version VALUE'
`--minor-subsystem-version VALUE'
`--stack RESERVE'
`--stack RESERVE,COMMIT'
`--subsystem WHICH'
`--subsystem WHICH:MAJOR'
`--subsystem WHICH:MAJOR.MINOR'
`--heap RESERVE'
`--heap RESERVE,COMMIT'
`--image-base VALUE'

  It's only the extra debug option that mentions pe by name.  So if it was my
choice I'd now want to call the flag "--dll-characteristics".  Do you or any
of the other regular maintainers have any suggestions?

> I would like to see an objcopy option at some point.  

  Yes, I'm totally going to do that sometime after gcc-4.3.2-2.

    cheers,
      DaveK

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH] New --pe-dll-characteristcs switch for PE ld.
  2009-03-05 12:49 Dave Korn
@ 2009-03-06  5:47 ` Christopher Faylor
  2009-03-06  6:38   ` Dave Korn
  0 siblings, 1 reply; 36+ messages in thread
From: Christopher Faylor @ 2009-03-06  5:47 UTC (permalink / raw)
  To: binutils, Dave Korn

On Thu, Mar 05, 2009 at 12:58:39PM +0000, Dave Korn wrote:
>The PE header in executables contains a field called
>"DllCharacteristics", which contains various flags that inform the OS
>dynamic loader about the status of the executable w.r.t.  runtime
>factors such as NX/DEP, ASLR, dynamic rebasing, etc.  (Despite the
>name, it applies to executables of all kinds, not just DLLs, but that's
>what MS calls it so that's what I call it).

And, as I mentioned in the Cygwin mailing list, "despite the name", I
don't think the option should mention "dll".  The name of the option
doesn't have to mirror an internal define.

I wonder if the name "pe-" is even TMI for this option but at least
there is some precedent for that.

>The attached patch adds a new linker option to allow setting the value
>of this field.  As the default for this field is zero, and as there is
>no other source for these flags in any of the input BFDs, I haven't
>provided a mechanism to clear any of these flags; that would make a
>suitable follow-on patch for objcopy, but first things first.

I would like to see an objcopy option at some point.  I don't agree with
the prevailing cygwin opinion that you need a separate binary to deal
with this.  It seems silly to have objcopy able to do only some things
to a PE and, if objcopy can do this, then I don't see why you need an
extra program to manipulate this field.

But, I digress.

Other than the option name (and, if the option name is renamed a few
variables), I think this would be a fine addition to ld.

cgf

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH] New --pe-dll-characteristcs switch for PE ld.
@ 2009-03-05 12:49 Dave Korn
  2009-03-06  5:47 ` Christopher Faylor
  0 siblings, 1 reply; 36+ messages in thread
From: Dave Korn @ 2009-03-05 12:49 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 5557 bytes --]


    Hi team,

  The PE header in executables contains a field called "DllCharacteristics",
which contains various flags that inform the OS dynamic loader about the
status of the executable w.r.t. runtime factors such as NX/DEP, ASLR, dynamic
rebasing, etc.  (Despite the name, it applies to executables of all kinds, not
just DLLs, but that's what MS calls it so that's what I call it).

  Until now, BFD and LD have done nothing with this field, and it is zero in
all binutils-generated PE executables to date.  However the Cygwin project now
has a need to use these flags to ensure compatibility of our applications on
post-Vista versions of Windows; we've had a number of reports lately of
crashes that can be resolved by applying various of the flags in this bitfield.

  The attached patch adds a new linker option to allow setting the value of
this field.  As the default for this field is zero, and as there is no other
source for these flags in any of the input BFDs, I haven't provided a
mechanism to clear any of these flags; that would make a suitable follow-on
patch for objcopy, but first things first.

  You'll notice I've changed the type of the DllCharacteristics field from
short to unsigned short.  This fixes a minor bug that was causing the output
routines in bfd/peXXigen.c#_bfd_XX_print_private_bfd_data_common() (and hence
objdump) to display the tsaware flag as '0xffff8000' owing to sign extension.
 There shouldn't be any significant back-compat problems with this but it
would cause a change in output if using objdump to examine an executable that
was compiled with native tools that had set that flag.  I think it's worth the
minor pain; apologies in advance to anyone who has to fix a test script.  (Not
that we have any in our sources, but somone somewhere might just).

  Tested on {i686-pc-cygwin, i686-pc-linux-gnu} x {arm-epoc-pe, arm-wince-pe,
i386-pc-netbsdpe, i386-pc-pe, i586-pc-interix, i586-unknown-beospe,
i686-pc-cygwin, i686-pc-mingw32, mcore-unknown-pe, powerpcle-unknown-pe,
sh-unknown-pe, thumb-epoc-pe, x86_64-pc-freebsd, x86_64-pc-linux-gnu,
x86_64-pc-mingw32}, no regressions and all new tests pass on all PE platforms
tested.  Docs, NEWS and testcases included.  Ok for HEAD?

include/ChangeLog

	* coff/internal.h (struct internal_extra_pe_aouthdr):  Correct type
	of DllCharacteristics flags field to unsigned.
	* coff/pe.h (IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE,
	IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE,	
	IMAGE_DLL_CHARACTERISTICS_NX_COMPAT,
	IMAGE_DLLCHARACTERISTICS_NO_ISOLATION,
	IMAGE_DLLCHARACTERISTICS_NO_SEH,
	IMAGE_DLLCHARACTERISTICS_NO_BIND,
	IMAGE_DLLCHARACTERISTICS_WDM_DRIVER,
	IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE):  New macros define
	flag bit values for DllCharacteristics field of PEAOUTHDR, PEPAOUTHDR.
	
ld/ChangeLog

	* NEWS:  Mention new '--pe-dll-characteristics' option.
	* ld/ld.texinfo:  Document new '--pe-dll-characteristics' option.
	* emultempl/pe.em (OPTION_PE_DLL_CHARACTERISTICS):  New getopts flag.
	(gld${EMULATION_NAME}_add_options):  Add --pe-dll-characteristics
	to array of switches.
	(definfoflag):  Add new struct definition.
	(C, CF):  Add new helper macros.
	(dllchrctnames[]):  Add new array of DllCharacteristics flag names.
	(definfo):  Add new flagnames member pointing to definfoflag array.
	(D):  Adjust macro to zero-init new flagnames field.
	(DF):  Add new macro like D but allows setting flagnames.
	(init[]):  Add zero-initialised flagnames members where needed, and
	new entry for new __dll_characteristics__ PE value.
	(gld_${EMULATION_NAME}_list_options):  Document new option.
	(find_pe_flag_name):  New helper to search definfoflag arrays.
	(find_pe_name):  New helper broken out from set_pe_name.
	(set_pe_name):  Use it.
	(is_flag_sep):  New helper function to test separator characters.
	(set_pe_value_from_flags):  New function parses mixed flagnames and
	integers format to set a PE value.
	(gld${EMULATION_NAME}_handle_option):  Call it to handle new
	OPTION_PE_DLL_CHARACTERISTICS option.
	* emultempl/pep.em (enum options):  Add OPTION_PE_DLL_CHARACTERISTICS.
	(gld${EMULATION_NAME}_add_options):  Add --pe-dll-characteristics
	to array of switches.
	(definfoflag):  Add new struct definition.
	(C, CF):  Add new helper macros.
	(dllchrctnames[]):  Add new array of DllCharacteristics flag names.
	(definfo):  Add new flagnames member pointing to definfoflag array.
	(D):  Adjust macro to zero-init new flagnames field.
	(DF):  Add new macro like D but allows setting flagnames.
	(init[]):  Add zero-initialised flagnames members where needed, and
	new entry for new __dll_characteristics__ PE value.
	(gld_${EMULATION_NAME}_list_options):  Document new option.
	(find_pep_flag_name):  New helper to search definfoflag arrays.
	(find_pep_name):  New helper broken out from set_pe_name.
	(set_pep_name):  Use it.
	(is_flag_sep):  New helper function to test separator characters.
	(set_pep_value_from_flags):  New function parses mixed flagnames and
	integers format to set a PE value.
	(gld${EMULATION_NAME}_handle_option):  Call it to handle new
	OPTION_PE_DLL_CHARACTERISTICS option.

ld/testsuite/ChangeLog

	* lib/ld-lib.exp (run_dump_test):  Allow new 'sed'
	option in .d files for post-processing output dump file.
	* ld-pe/dllcharact-1.d, ld-pe/dllcharact-2.d, ld-pe/dllcharact-3.d,
	ld-pe/dllcharact-4.d, ld-pe/dllcharact-5.d, ld-pe/dllcharact-fail-1.d
	ld-pe/dllcharact-fail-2.d, ld-pe/dllcharact-fail-3.d, ld-pe/empty.s,
	ld-pe/dllcharact-fail-4.d, ld-pe/dllcharact.exp:  New test files.

    cheers,
      DaveK


[-- Attachment #2: pe-dll-characteristics-patch.diff --]
[-- Type: text/plain, Size: 28913 bytes --]

Index: include/coff/internal.h
===================================================================
RCS file: /cvs/src/src/include/coff/internal.h,v
retrieving revision 1.22
diff -p -u -r1.22 internal.h
--- include/coff/internal.h	12 Jul 2007 07:16:41 -0000	1.22
+++ include/coff/internal.h	5 Mar 2009 12:30:04 -0000
@@ -185,7 +185,7 @@ struct internal_extra_pe_aouthdr 
      3 - WINDOWS_CUI runs in Windows char sub. (console app)
      5 - OS2_CUI runs in OS/2 character subsystem
      7 - POSIX_CUI runs in Posix character subsystem */
-  short   DllCharacteristics;	/* flags for DLL init, use 0 */
+  unsigned short DllCharacteristics;	/* flags for DLL init, use 0 */
   bfd_vma SizeOfStackReserve;	/* amount of memory to reserve  */
   bfd_vma SizeOfStackCommit;	/* amount of memory initially committed for 
 				   initial thread's stack, default is 0x1000 */
Index: include/coff/pe.h
===================================================================
RCS file: /cvs/src/src/include/coff/pe.h,v
retrieving revision 1.18
diff -p -u -r1.18 pe.h
--- include/coff/pe.h	4 Nov 2007 23:49:08 -0000	1.18
+++ include/coff/pe.h	5 Mar 2009 12:30:04 -0000
@@ -38,6 +38,17 @@
 #define IMAGE_FILE_UP_SYSTEM_ONLY            0x4000
 #define IMAGE_FILE_BYTES_REVERSED_HI         0x8000
 
+/* DllCharacteristics flag bits.  The inconsistent naming may seem
+   odd, but that is how they are defined in the PE specification.  */
+#define IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE          0x0040
+#define IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY       0x0080
+#define IMAGE_DLL_CHARACTERISTICS_NX_COMPAT             0x0100
+#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION           0x0200
+#define IMAGE_DLLCHARACTERISTICS_NO_SEH                 0x0400
+#define IMAGE_DLLCHARACTERISTICS_NO_BIND                0x0800
+#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER             0x2000
+#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE  0x8000
+
 /* Additional flags to be set for section headers to allow the NT loader to
    read and write to the section data (to replace the addresses of data in
    dlls for one thing); also to execute the section in .text's case.  */
Index: ld/NEWS
===================================================================
RCS file: /cvs/src/src/ld/NEWS,v
retrieving revision 1.100
diff -p -u -r1.100 NEWS
--- ld/NEWS	3 Mar 2009 18:22:10 -0000	1.100
+++ ld/NEWS	5 Mar 2009 12:30:04 -0000
@@ -1,5 +1,9 @@
 -*- text -*-
 
+* A new command-line flag '--pe-dll-characteristics' allows PE targets
+  to set the value of the PE file header's DllCharacteristics field,
+  using a flexible combination of numeric and symbolic names.
+
 * New script function REGION_ALIAS to add alias names to memory regions.
 
 * PE targets no longer make use of the long section names PE extension to
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.235
diff -p -u -r1.235 ld.texinfo
--- ld/ld.texinfo	3 Mar 2009 18:22:10 -0000	1.235
+++ ld/ld.texinfo	5 Mar 2009 12:30:06 -0000
@@ -2257,6 +2257,57 @@ Sets the minor number of the ``os versio
 Sets the minor number of the ``subsystem version''.  Defaults to 0.
 [This option is specific to the i386 PE targeted port of the linker]
 
+@kindex --pe-dll-characteristics
+@item --pe-dll-characteristics (@var{name}|@var{integer})@*@	@w{@	}@	@w{@	}@	@w{@	}@	@w{@	}[(',' | '|' | '+' | ':')(@var{name}|@var{integer})[...]]
+Sets the value of the DllCharacteristics field in the PE header.  The
+value can be specified by using hexadecimal or decimal integers, or the
+symbolic names of the various bits, optionally combined by any combination
+of @samp{|}, @samp{+}, @samp{:} or @samp{,} characters.  The following
+short symbolic names are recognized, shown with the full name of the flag
+(as given in the MS PE specification) to which they correspond, which is
+also accepted:
+
+@table @samp
+@item dynbase
+@samp{IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE}
+
+@item forceinteg
+@samp{IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY}
+
+@item nxcompat
+@samp{IMAGE_DLL_CHARACTERISTICS_NX_COMPAT}
+
+@item noisolation
+@samp{IMAGE_DLLCHARACTERISTICS_NO_ISOLATION}
+
+@item noseh
+@samp{IMAGE_DLLCHARACTERISTICS_NO_SEH}
+
+@item nobind
+@samp{IMAGE_DLLCHARACTERISTICS_NO_BIND}
+
+@item wdmdriver
+@samp{IMAGE_DLLCHARACTERISTICS_WDM_DRIVER}
+
+@item tsaware
+@samp{IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE}
+
+@end table
+These options and separators can be combined with almost total
+flexibility; for example, valid uses of this option include:
+
+@smallexample
+--pe-dll-characteristics=0x0400|0x0100
+@end smallexample
+@smallexample
+--pe-dll-characteristics=1+128+1024,noseh,nobind
+@end smallexample
+@smallexample
+--pe-dll-characteristics noseh:nobind:tsaware
+@end smallexample
+
+[This option is valid for all PE targeted ports of the linker]
+
 @cindex DEF files, creating
 @cindex DLLs, creating
 @kindex --output-def
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.146
diff -p -u -r1.146 pe.em
--- ld/emultempl/pe.em	3 Mar 2009 18:22:11 -0000	1.146
+++ ld/emultempl/pe.em	5 Mar 2009 12:30:06 -0000
@@ -229,6 +229,8 @@ fragment <<EOF
 					(OPTION_USE_NUL_PREFIXED_IMPORT_TABLES + 1)
 #define OPTION_DISABLE_LONG_SECTION_NAMES \
 					(OPTION_ENABLE_LONG_SECTION_NAMES + 1)
+#define OPTION_PE_DLL_CHARACTERISTICS \
+					(OPTION_DISABLE_LONG_SECTION_NAMES + 1)
 
 static void
 gld${EMULATION_NAME}_add_options
@@ -290,6 +292,7 @@ gld${EMULATION_NAME}_add_options
     {"large-address-aware", no_argument, NULL, OPTION_LARGE_ADDRESS_AWARE},
     {"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
     {"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
+    {"pe-dll-characteristics", required_argument, NULL, OPTION_PE_DLL_CHARACTERISTICS},
     {NULL, no_argument, NULL, 0}
   };
 
@@ -303,14 +306,47 @@ gld${EMULATION_NAME}_add_options
 
 typedef struct
 {
+  const char *name;
+  int len;
+  int value;
+} definfoflag;
+
+#define C(name)       { #name, sizeof(#name) - 1, name }
+#define CF(name,flag) { #name, sizeof(#name) - 1, flag }
+static const definfoflag dllchrctnames[] =
+{
+  /* Accept a few handy abbreviations.  */
+  CF(dynbase,     IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE),
+  CF(forceinteg,  IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY),
+  CF(nxcompat,    IMAGE_DLL_CHARACTERISTICS_NX_COMPAT),
+  CF(noisolation, IMAGE_DLLCHARACTERISTICS_NO_ISOLATION),
+  CF(noseh,       IMAGE_DLLCHARACTERISTICS_NO_SEH),
+  CF(nobind,      IMAGE_DLLCHARACTERISTICS_NO_BIND),
+  CF(wdmdriver,   IMAGE_DLLCHARACTERISTICS_WDM_DRIVER),
+  CF(tsaware,     IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE),
+  /* And the full names as defined in the PE specification.  */
+  C(IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE),
+  C(IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY),
+  C(IMAGE_DLL_CHARACTERISTICS_NX_COMPAT),
+  C(IMAGE_DLLCHARACTERISTICS_NO_ISOLATION),
+  C(IMAGE_DLLCHARACTERISTICS_NO_SEH),
+  C(IMAGE_DLLCHARACTERISTICS_WDM_DRIVER),
+  C(IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE),
+  { 0, 0, 0 },
+};
+
+typedef struct
+{
   void *ptr;
   int size;
   int value;
   char *symbol;
   int inited;
+  const definfoflag *flagnames;
 } definfo;
 
-#define D(field,symbol,def)  {&pe.field,sizeof(pe.field), def, symbol,0}
+#define D(field,symbol,def)         {&pe.field,sizeof(pe.field), def, symbol, 0, 0}
+#define DF(field,symbol,def,flags)  {&pe.field,sizeof(pe.field), def, symbol, 0, flags}
 
 static definfo init[] =
 {
@@ -318,7 +354,7 @@ static definfo init[] =
 #define IMAGEBASEOFF 0
   D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
 #define DLLOFF 1
-  {&dll, sizeof(dll), 0, "__dll__", 0},
+  {&dll, sizeof(dll), 0, "__dll__", 0, 0},
 #define MSIMAGEBASEOFF	2
   D(ImageBase, U ("__ImageBase"), NT_EXE_IMAGE_BASE),
   D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
@@ -339,10 +375,10 @@ static definfo init[] =
   D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
   D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
   D(LoaderFlags,"__loader_flags__", 0x0),
-  { NULL, 0, 0, NULL, 0 }
+  DF(DllCharacteristics, "__dll_characteristics__", 0x0, dllchrctnames),
+  { NULL, 0, 0, NULL, 0, 0 }
 };
 
-
 static void
 gld_${EMULATION_NAME}_list_options (FILE *file)
 {
@@ -401,29 +437,48 @@ gld_${EMULATION_NAME}_list_options (FILE
                                        executable image files\n"));
   fprintf (file, _("  --disable-long-section-names       Never use long COFF section names, even\n\
                                        in object files\n"));
+  fprintf (file, _("  --pe-dll-characteristics <name|int>[<,|+:><name|int>[...]]\n\
+                                     Sets PE header DllCharacteristics field.\n"));
 }
 
+static const definfoflag *
+find_pe_flag_name (char *name, const definfoflag *flagnames)
+{
+  int i;
 
-static void
-set_pe_name (char *name, long val)
+  /* Look for the name, return pointer to definfoflag if found.  */
+  if (flagnames)
+    for (i = 0; flagnames[i].name; i++)
+      if (strncmp (name, flagnames[i].name, flagnames[i].len) == 0)
+	return &flagnames[i];
+  /* Unknown name could be an integer, so not an error here.  */
+  return 0;
+}
+
+static definfo *
+find_pe_name (char *name)
 {
   int i;
 
-  /* Find the name and set it.  */
+  /* Look for the name, return pointer to definfo.  */
   for (i = 0; init[i].ptr; i++)
-    {
-      if (strcmp (name, init[i].symbol) == 0)
-	{
-	  init[i].value = val;
-	  init[i].inited = 1;
-	  if (strcmp (name,"__image_base__") == 0)
-	    set_pe_name (U ("__ImageBase"), val);
-	  return;
-	}
-    }
+    if (strcmp (name, init[i].symbol) == 0)
+      return &init[i];
+  /* Unknown name is a serious internal coding error, so don't
+     bother to diagnose or return error indication, just bail.  */
   abort ();
 }
 
+static void
+set_pe_name (char *name, long val)
+{
+  /* Find the name and set it.  */
+  definfo *init = find_pe_name (name);
+  init->value = val;
+  init->inited = 1;
+  if (strcmp (name,"__image_base__") == 0)
+    set_pe_name (U ("__ImageBase"), val);
+}
 
 static void
 set_pe_subsystem (void)
@@ -543,6 +598,62 @@ set_pe_value (char *name)
   optarg = end;
 }
 
+static char
+is_flag_sep (char x)
+{
+  return x == '+' || x == '|' || x == ':' || x == ',';
+}
+
+static void
+set_pe_value_from_flags (char *name)
+{
+  long flags = 0;
+  definfo *init;
+
+  /* Look up the symbolic flag names.  Even if there aren't any we
+     will still parse multiple integers combined by separators.  */
+  init = find_pe_name (name);
+
+  /* Parse the flags out of optarg.  We accept any combination of
+     symbolic abbreviations and strtoul-parseable integers, separated
+     by any combination of '+', '|', ':' and ',' characters.  */
+  while (*optarg)
+    {
+      const definfoflag *flag;
+
+      /* Deliberately allow multiple conjoined separators.  */
+      while (is_flag_sep (*optarg))
+	optarg++;
+
+      /* Even trailing at the end.  */
+      if (!*optarg)
+	break;
+
+      flag = find_pe_flag_name (optarg, init->flagnames);
+      if (flag)
+	{
+	  flags |= flag->value;
+	  optarg += flag->len;
+	}
+      else
+	{
+	  char *end;
+	  long value;
+	  value = strtoul (optarg, &end, 0);
+	  if (end == optarg)
+	    einfo (_("%P%F: unrecognised integer/flag '%s' for PE parameter '%s'\n"),
+		optarg, name);
+	  flags |= value;
+	  optarg = end;
+	}
+      /* If there's any more, we do insist on at least one separator.  */
+      if (*optarg && !is_flag_sep (*optarg))
+	einfo (_("%P%F: unparseable at '%s' for PE parameter '%s'\n"),
+	  optarg, name);
+    }
+
+  set_pe_name (name,  flags);
+}
 
 static void
 set_pe_stack_heap (char *resname, char *comname)
@@ -707,6 +818,9 @@ gld${EMULATION_NAME}_handle_option (int 
     case OPTION_DISABLE_LONG_SECTION_NAMES:
       pe_use_coff_long_section_names = 0;
       break;
+    case OPTION_PE_DLL_CHARACTERISTICS:
+      set_pe_value_from_flags ("__dll_characteristics__");
+      break;
     }
   return TRUE;
 }
Index: ld/emultempl/pep.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pep.em,v
retrieving revision 1.23
diff -p -u -r1.23 pep.em
--- ld/emultempl/pep.em	3 Mar 2009 18:22:11 -0000	1.23
+++ ld/emultempl/pep.em	5 Mar 2009 12:30:07 -0000
@@ -179,7 +179,8 @@ enum options
   OPTION_EXCLUDE_MODULES_FOR_IMPLIB,
   OPTION_USE_NUL_PREFIXED_IMPORT_TABLES,
   OPTION_ENABLE_LONG_SECTION_NAMES,
-  OPTION_DISABLE_LONG_SECTION_NAMES
+  OPTION_DISABLE_LONG_SECTION_NAMES,
+  OPTION_PE_DLL_CHARACTERISTICS
 };
 
 static void
@@ -244,6 +245,7 @@ gld${EMULATION_NAME}_add_options
 #endif
     {"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
     {"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
+    {"pe-dll-characteristics", required_argument, NULL, OPTION_PE_DLL_CHARACTERISTICS},
     {NULL, no_argument, NULL, 0}
   };
 
@@ -256,14 +258,47 @@ gld${EMULATION_NAME}_add_options
 
 typedef struct
 {
+  const char *name;
+  int len;
+  int value;
+} definfoflag;
+
+#define C(name)       { #name, sizeof(#name) - 1, name }
+#define CF(name,flag) { #name, sizeof(#name) - 1, flag }
+static const definfoflag dllchrctnames[] =
+{
+  /* Accept a few handy abbreviations.  */
+  CF(dynbase,     IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE),
+  CF(forceinteg,  IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY),
+  CF(nxcompat,    IMAGE_DLL_CHARACTERISTICS_NX_COMPAT),
+  CF(noisolation, IMAGE_DLLCHARACTERISTICS_NO_ISOLATION),
+  CF(noseh,       IMAGE_DLLCHARACTERISTICS_NO_SEH),
+  CF(nobind,      IMAGE_DLLCHARACTERISTICS_NO_BIND),
+  CF(wdmdriver,   IMAGE_DLLCHARACTERISTICS_WDM_DRIVER),
+  CF(tsaware,     IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE),
+  /* And the full names as defined in the PE specification.  */
+  C(IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE),
+  C(IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY),
+  C(IMAGE_DLL_CHARACTERISTICS_NX_COMPAT),
+  C(IMAGE_DLLCHARACTERISTICS_NO_ISOLATION),
+  C(IMAGE_DLLCHARACTERISTICS_NO_SEH),
+  C(IMAGE_DLLCHARACTERISTICS_WDM_DRIVER),
+  C(IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE),
+  { 0, 0, 0 },
+};
+
+typedef struct
+{
   void *ptr;
   int size;
   bfd_vma value;
   char *symbol;
   int inited;
+  const definfoflag *flagnames;
 } definfo;
 
-#define D(field,symbol,def)  {&pep.field,sizeof(pep.field), def, symbol,0}
+#define D(field,symbol,def)         {&pep.field,sizeof(pep.field), def, symbol, 0, 0}
+#define DF(field,symbol,def,flags)  {&pep.field,sizeof(pep.field), def, symbol, 0, flags}
 
 static definfo init[] =
 {
@@ -271,7 +306,7 @@ static definfo init[] =
 #define IMAGEBASEOFF 0
   D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
 #define DLLOFF 1
-  {&dll, sizeof(dll), 0, "__dll__", 0},
+  {&dll, sizeof(dll), 0, "__dll__", 0, 0},
 #define MSIMAGEBASEOFF	2
   D(ImageBase,"___ImageBase", NT_EXE_IMAGE_BASE),
   D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
@@ -288,7 +323,8 @@ static definfo init[] =
   D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
   D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
   D(LoaderFlags,"__loader_flags__", 0x0),
-  { NULL, 0, 0, NULL, 0 }
+  DF(DllCharacteristics, "__dll_characteristics__", 0x0, dllchrctnames),
+  { NULL, 0, 0, NULL, 0, 0 }
 };
 
 
@@ -346,30 +382,49 @@ gld_${EMULATION_NAME}_list_options (FILE
                                        executable image files\n"));
   fprintf (file, _("  --disable-long-section-names       Never use long COFF section names, even\n\
                                        in object files\n"));
+  fprintf (file, _("  --pe-dll-characteristics <name|int>[<,|+:><name|int>[...]]\n\
+                                     Sets PE header DllCharacteristics field.\n"));
 #endif
 }
 
+static const definfoflag *
+find_pep_flag_name (char *name, const definfoflag *flagnames)
+{
+  int i;
 
-static void
-set_pep_name (char *name, bfd_vma val)
+  /* Look for the name, return pointer to definfoflag if found.  */
+  if (flagnames)
+    for (i = 0; flagnames[i].name; i++)
+      if (strncmp (name, flagnames[i].name, flagnames[i].len) == 0)
+	return &flagnames[i];
+  /* Unknown name could be an integer, so not an error here.  */
+  return 0;
+}
+
+static definfo *
+find_pep_name (char *name)
 {
   int i;
 
-  /* Find the name and set it.  */
+  /* Look for the name, return pointer to definfo.  */
   for (i = 0; init[i].ptr; i++)
-    {
-      if (strcmp (name, init[i].symbol) == 0)
-	{
-	  init[i].value = val;
-	  init[i].inited = 1;
-	  if (strcmp (name,"__image_base__") == 0)
-	    set_pep_name ("___ImageBase", val);
-	  return;
-	}
-    }
+    if (strcmp (name, init[i].symbol) == 0)
+      return &init[i];
+  /* Unknown name is a serious internal coding error, so don't
+     bother to diagnose or return error indication, just bail.  */
   abort ();
 }
 
+static void
+set_pep_name (char *name, long val)
+{
+  /* Find the name and set it.  */
+  definfo *init = find_pep_name (name);
+  init->value = val;
+  init->inited = 1;
+  if (strcmp (name,"__image_base__") == 0)
+    set_pep_name ("___ImageBase", val);
+}
 
 static void
 set_pep_subsystem (void)
@@ -489,6 +544,62 @@ set_pep_value (char *name)
   optarg = end;
 }
 
+static char
+is_flag_sep (char x)
+{
+  return x == '+' || x == '|' || x == ':' || x == ',';
+}
+
+static void
+set_pep_value_from_flags (char *name)
+{
+  long flags = 0;
+  definfo *init;
+
+  /* Look up the symbolic flag names.  Even if there aren't any we
+     will still parse multiple integers combined by separators.  */
+  init = find_pep_name (name);
+
+  /* Parse the flags out of optarg.  We accept any combination of
+     symbolic abbreviations and strtoul-parseable integers, separated
+     by any combination of '+', '|', ':' and ',' characters.  */
+  while (*optarg)
+    {
+      const definfoflag *flag;
+
+      /* Deliberately allow multiple conjoined separators.  */
+      while (is_flag_sep (*optarg))
+	optarg++;
+
+      /* Even trailing at the end.  */
+      if (!*optarg)
+	break;
+
+      flag = find_pep_flag_name (optarg, init->flagnames);
+      if (flag)
+	{
+	  flags |= flag->value;
+	  optarg += flag->len;
+	}
+      else
+	{
+	  char *end;
+	  long value;
+	  value = strtoul (optarg, &end, 0);
+	  if (end == optarg)
+	    einfo (_("%P%F: unrecognised integer/flag '%s' for PE parameter '%s'\n"),
+		optarg, name);
+	  flags |= value;
+	  optarg = end;
+	}
+      /* If there's any more, we do insist on at least one separator.  */
+      if (*optarg && !is_flag_sep (*optarg))
+	einfo (_("%P%F: unparseable at '%s' for PE parameter '%s'\n"),
+	  optarg, name);
+    }
+
+  set_pep_name (name,  flags);
+}
 
 static void
 set_pep_stack_heap (char *resname, char *comname)
@@ -647,6 +758,9 @@ gld${EMULATION_NAME}_handle_option (int 
     case OPTION_DISABLE_LONG_SECTION_NAMES:
       pep_use_coff_long_section_names = 0;
       break;
+    case OPTION_PE_DLL_CHARACTERISTICS:
+      set_pep_value_from_flags ("__dll_characteristics__");
+      break;
     }
   return TRUE;
 }
Index: ld/testsuite/ld-pe/dllcharact-1.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-1.d
diff -N ld/testsuite/ld-pe/dllcharact-1.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-1.d	5 Mar 2009 12:30:07 -0000
@@ -0,0 +1,7 @@
+#name: pe-dll-characteristics-1
+#ld:  --pe-dll-characteristics=1+128+512:nxcompat\\|wdmdriver\\|forceinteg
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00002381
Index: ld/testsuite/ld-pe/dllcharact-2.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-2.d
diff -N ld/testsuite/ld-pe/dllcharact-2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-2.d	5 Mar 2009 12:30:07 -0000
@@ -0,0 +1,7 @@
+#name: pe-dll-characteristics-2
+#ld: --pe-dll-characteristics=0x1234
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00001234
Index: ld/testsuite/ld-pe/dllcharact-3.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-3.d
diff -N ld/testsuite/ld-pe/dllcharact-3.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-3.d	5 Mar 2009 12:30:07 -0000
@@ -0,0 +1,7 @@
+#name: pe-dll-characteristics-3
+#ld:  --pe-dll-characteristics noseh:nobind:tsaware
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00008c00
Index: ld/testsuite/ld-pe/dllcharact-4.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-4.d
diff -N ld/testsuite/ld-pe/dllcharact-4.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-4.d	5 Mar 2009 12:30:07 -0000
@@ -0,0 +1,7 @@
+#name: pe-dll-characteristics-4
+#ld:  --pe-dll-characteristics=0x0400\\|0x0100
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00000500
Index: ld/testsuite/ld-pe/dllcharact-5.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-5.d
diff -N ld/testsuite/ld-pe/dllcharact-5.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-5.d	5 Mar 2009 12:30:07 -0000
@@ -0,0 +1,7 @@
+#name: pe-dll-characteristics-5
+#ld:  --pe-dll-characteristics=1+128+1024,noseh,nobind
+#objdump: -p
+#sed: -e '/^DllCharacteristics/!d'
+#source: empty.s
+
+DllCharacteristics[ \t]*00000c81
Index: ld/testsuite/ld-pe/dllcharact-fail-1.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-fail-1.d
diff -N ld/testsuite/ld-pe/dllcharact-fail-1.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-fail-1.d	5 Mar 2009 12:30:07 -0000
@@ -0,0 +1,4 @@
+#name: pe-dll-characteristics-fail-1
+#ld:  --pe-dll-characteristics=1+0xf00:+badname+
+#error: .*unrecognised integer/flag.*
+#source: empty.s
Index: ld/testsuite/ld-pe/dllcharact-fail-2.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-fail-2.d
diff -N ld/testsuite/ld-pe/dllcharact-fail-2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-fail-2.d	5 Mar 2009 12:30:07 -0000
@@ -0,0 +1,9 @@
+#name: pe-dll-characteristics-fail-2
+#ld:  --pe-dll-characteristics=0xGoWrong:noseh
+#error: .*(unrecognised integer/flag '0xGoWrong:noseh'|unparseable at 'xGoWrong:noseh').*
+#source: empty.s
+
+## This one was interesting.  Different libc strtoul implementations appear to
+## behave differently: newlib regards '0x' as a hex prefix followed by an invalid
+## hex number, GNU libc parses it as an integer zero followed by an 'x'.  This
+## could well be a bug in newlib.
Index: ld/testsuite/ld-pe/dllcharact-fail-3.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-fail-3.d
diff -N ld/testsuite/ld-pe/dllcharact-fail-3.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-fail-3.d	5 Mar 2009 12:30:07 -0000
@@ -0,0 +1,4 @@
+#name: pe-dll-characteristics-fail-3
+#ld:  --pe-dll-characteristics 0x3DFG
+#error: .*unparseable at.*
+#source: empty.s
Index: ld/testsuite/ld-pe/dllcharact-fail-4.d
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact-fail-4.d
diff -N ld/testsuite/ld-pe/dllcharact-fail-4.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact-fail-4.d	5 Mar 2009 12:30:07 -0000
@@ -0,0 +1,4 @@
+#name: pe-dll-characteristics-fail-4
+#ld:  --pe-dll-characteristics 1+noseh+0x3DFnobind
+#error: .*unparseable at.*
+#source: empty.s
Index: ld/testsuite/ld-pe/dllcharact.exp
===================================================================
RCS file: ld/testsuite/ld-pe/dllcharact.exp
diff -N ld/testsuite/ld-pe/dllcharact.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/dllcharact.exp	5 Mar 2009 12:30:07 -0000
@@ -0,0 +1,43 @@
+# Expect script for --pe-dll-characteristics command-line option tests.
+#   Copyright 2009
+#   Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+ 
+# This test can only be run on PE/COFF platforms.
+if {![is_pecoff_format]} {
+    return
+}
+
+# Now we repeatedly re-link it with different args, 
+# and check that the field gets set correctly.
+
+run_dump_test "dllcharact-1"
+run_dump_test "dllcharact-2"
+run_dump_test "dllcharact-3"
+run_dump_test "dllcharact-4"
+run_dump_test "dllcharact-5"
+
+run_dump_test "dllcharact-fail-1"
+run_dump_test "dllcharact-fail-2"
+run_dump_test "dllcharact-fail-3"
+run_dump_test "dllcharact-fail-4"
+
+
+
Index: ld/testsuite/ld-pe/empty.s
===================================================================
RCS file: ld/testsuite/ld-pe/empty.s
diff -N ld/testsuite/ld-pe/empty.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-pe/empty.s	5 Mar 2009 12:30:07 -0000
@@ -0,0 +1,7 @@
+	.text
+	.global _start
+	.global _mainCRTStartup
+_start:
+_mainCRTStartup:
+	.end
+
Index: ld/testsuite/lib/ld-lib.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/lib/ld-lib.exp,v
retrieving revision 1.59
diff -p -u -r1.59 ld-lib.exp
--- ld/testsuite/lib/ld-lib.exp	6 Feb 2009 16:56:12 -0000	1.59
+++ ld/testsuite/lib/ld-lib.exp	5 Mar 2009 12:30:07 -0000
@@ -582,11 +582,17 @@ proc simple_diff { file_1 file_2 } {
 #   objdump: FLAGS
 #   nm: FLAGS
 #   objcopy: FLAGS
+#   readelf: FLAGS
 #	Use the specified program to analyze the assembler or linker
 #       output file, and pass it FLAGS, in addition to the output name.
 #	Note that they are run with LC_ALL=C in the environment to give
 #	consistent sorting of symbols.
 #
+#   sed: FLAGS
+#       Run SED with the specified flags on the analyzer output dump
+#       file to perform custom post-processing, before attempting to
+#       match it against the pattern lines.
+#
 #   source: SOURCE [FLAGS]
 #	Assemble the file SOURCE.s using the flags in the "as" directive
 #       and the (optional) FLAGS.  If omitted, the source defaults to
@@ -661,6 +667,7 @@ proc run_dump_test { name } {
     set opts(nm) {}
     set opts(objcopy) {}
     set opts(readelf) {}
+    set opts(sed) {}
     set opts(name) {}
     set opts(PROG) {}
     set opts(source) {}
@@ -917,20 +924,31 @@ proc run_dump_test { name } {
     if { $progopts1 == "" } { set $progopts1 "-r" }
     verbose "running $binary $progopts $progopts1" 3
 
-    # Objcopy, unlike the other two, won't send its output to stdout,
-    # so we have to run it specially.
-    set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
-    if { $program == "objcopy" } {
-	set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
+    # Must be ready to post-process the dumpfile, if need be.  Objcopy,
+    # unlike the other two, won't send its output to stdout, so we have
+    # to run it specially.
+    if { $opts(sed) != "" } {
+	set cmdoutput "| sed $opts(sed) > $dumpfile"
+	if { $program == "objcopy" } {
+	    set cmdoutput "$dumpfile.1 && sed $opts(sed) < $dumpfile.1 > $dumpfile"
+	}
+    } else {
+	set cmdoutput "> $dumpfile"
+	if { $program == "objcopy" } {
+	    set cmdoutput "$dumpfile"
+	}
     }
 
+    # Generate the main command line, minus redirects.
+    set cmd "$binary $progopts $progopts1 $objfile"
+
     # Ensure consistent sorting of symbols
     if {[info exists env(LC_ALL)]} {
 	set old_lc_all $env(LC_ALL)
     }
     set env(LC_ALL) "C"
     send_log "$cmd\n"
-    set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
+    set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp $cmdoutput"]] "" "/dev/null"]
     remote_upload host "ld.tmp"
     set comp_output [prune_warnings [file_contents "ld.tmp"]]
     remote_file host delete "ld.tmp"

^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2009-03-13  8:33 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-06 19:25 [PATCH] New --pe-dll-characteristcs switch for PE ld Charles Wilson
  -- strict thread matches above, loose matches on Subject: below --
2009-03-09 15:58 Charles Wilson
2009-03-09 16:49 ` Christopher Faylor
2009-03-09 17:02   ` Daniel Jacobowitz
2009-03-09 17:09     ` Christopher Faylor
2009-03-08 22:21 Charles Wilson
2009-03-05 12:49 Dave Korn
2009-03-06  5:47 ` Christopher Faylor
2009-03-06  6:38   ` Dave Korn
2009-03-06  8:17     ` Danny Smith
2009-03-06 16:24       ` Christopher Faylor
2009-03-06 13:11     ` Vincent R.
2009-03-06 13:31       ` Kai Tietz
2009-03-06 16:13     ` Christopher Faylor
2009-03-06 16:33       ` Dave Korn
2009-03-06 23:40         ` Christopher Faylor
2009-03-07  5:00           ` Dave Korn
2009-03-09  5:24             ` Christopher Faylor
2009-03-09  6:14               ` Dave Korn
2009-03-09 15:37                 ` Christopher Faylor
2009-03-09 16:06                   ` Dave Korn
2009-03-09 17:17                     ` NightStrike
2009-03-09 17:23                       ` Christopher Faylor
2009-03-09 17:24                       ` Dave Korn
2009-03-12  7:42                         ` Danny Smith
2009-03-12  8:12                           ` Dave Korn
2009-03-12 13:51                             ` Nick Clifton
2009-03-12 13:59                               ` Dave Korn
2009-03-12 17:28                                 ` Dave Korn
2009-03-12 18:03                                   ` Dave Korn
2009-03-13  3:10                                     ` Dave Korn
2009-03-13  8:33                                       ` Nick Clifton
2009-03-12 14:00                           ` Christopher Faylor
2009-03-09  1:13         ` Dave Korn
2009-03-09  5:47           ` Dave Korn
2009-03-09  9:35           ` Vincent R.

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).