a.out.h for 64-bit Cygwin?

Ken Brown kbrown@cornell.edu
Mon Mar 11 16:14:00 GMT 2013


On 3/10/2013 4:52 PM, Corinna Vinschen wrote:
> On Mar 10 09:06, Ken Brown wrote:
>> On 3/10/2013 7:18 AM, Corinna Vinschen wrote:
>>> On Mar  9 22:43, Ken Brown wrote:
>>>> It may be too soon to expect this to work, but I'm trying to build
>>>> emacs for 64-bit Cygwin.  Part of the build process involves direct
>>>> manipulation of a .exe file, based on the structures defined in
>>>> /usr/include/a.out.h.  I'm wondering whether this file needs to be
>>>> updated before it will work with 64-bit .exe files.
>>>
>>> Yes, absolutely!
>>>
>>> It's not very tricky.  AFAIK only a single header part is different, the
>>> one called IMAGE_OPTIONAL_HEADER in MSDN.  Given the age of a.out.h,
>>> there are also a couple of defines missing, all of them are documented
>>> in MSDN and available in the Mingw headers.  Patches most welcome.
>>
>> OK, I'll work on this.  One question: Is it OK for a.out.h to
>> include windows.h so that I can use macros like WORD, DWORD,... as
>> in the Mingw headers?  Or is it better to just use standard types as
>> in the current a.out.h?
>
> No, we shouldn't include windows.h.  Some of the values are already
> defined using another name in a.out.h, see I386MAGIC, DOSMAGIC, or
> NT_SIGNATURE.
>
> I'm pretty open to add definitions for other values, as long as they
> either match the already used naimg scheme, or, if they are entirely
> new, are similar, but not exactly named like the original Windows
> definitions.  I don't think anything speaks against adding stuff like
>
>    #define AMD64MAGIC 0x8664
>    [...]
>    #define IMG_NT_OPTIONAL_HDR32_MAGIC 0x10b
>    [...]
>    #define IMG_SUBSYS_NATIVE 1

OK, my patch is attached.  I'm also attaching the program I used to test 
it, based on the emacs code I sent in my first post.  (And I'm able to 
build 64-bit emacs with this patch.)

It turned out that the most important thing I had to do was change most 
occurrences of "unsigned long" to "uint32_t" to keep DWORDs from 
becoming 64 bits wide on AMD64.

Ken

-------------- next part --------------
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <a.out.h>

typedef struct
{
  FILHDR file_header;
  PEAOUTHDR file_optional_header;
  SCNHDR section_header[32];
} exe_header_t;

static exe_header_t *
read_exe_header (int fd, exe_header_t * exe_header_buffer)
{
  int i;
  int ret;

  assert (exe_header_buffer != 0);

  ret = lseek (fd, 0L, SEEK_SET);
  assert (ret != -1);

  ret =
    read (fd, &exe_header_buffer->file_header,
	  sizeof (exe_header_buffer->file_header));
  assert (ret == sizeof (exe_header_buffer->file_header));

  assert (exe_header_buffer->file_header.e_magic == 0x5a4d);
  assert (exe_header_buffer->file_header.nt_signature == 0x4550);
#ifdef __x86_64__
  assert (exe_header_buffer->file_header.f_magic == 0x8664);
#else
  assert (exe_header_buffer->file_header.f_magic == 0x014c);
#endif
  assert (exe_header_buffer->file_header.f_nscns > 0);
  assert (exe_header_buffer->file_header.f_nscns <=
	  sizeof (exe_header_buffer->section_header) /
	  sizeof (exe_header_buffer->section_header[0]));
  assert (exe_header_buffer->file_header.f_opthdr > 0);

  ret =
    read (fd, &exe_header_buffer->file_optional_header,
	  sizeof (exe_header_buffer->file_optional_header));
  assert (ret == sizeof (exe_header_buffer->file_optional_header));

#ifdef __x86_64__
  assert (exe_header_buffer->file_optional_header.magic == 0x020b);
#else
  assert (exe_header_buffer->file_optional_header.magic == 0x010b);
#endif
  for (i = 0; i < exe_header_buffer->file_header.f_nscns; ++i)
    {
      ret =
	read (fd, &exe_header_buffer->section_header[i],
	      sizeof (exe_header_buffer->section_header[i]));
      assert (ret == sizeof (exe_header_buffer->section_header[i]));
    }

  return (exe_header_buffer);
}

int
main ()
{
  int fd;
  exe_header_t exe_header_buffer;

  printf ("Type PEAOUTHDR has size %u bytes.\n", sizeof (PEAOUTHDR));
  fd = open ("/bin/ls.exe", O_RDONLY);
  assert (fd >= 0);
  read_exe_header (fd, &exe_header_buffer);
}
-------------- next part --------------
--- a.out.h.orig	2013-03-11 05:25:59.339893700 -0400
+++ a.out.h	2013-03-11 12:03:48.509132100 -0400
@@ -1,6 +1,6 @@
 /* a.out.h
 
-   Copyright 1997, 1998, 1999, 2001 Red Hat, Inc.
+   Copyright 1997, 1998, 1999, 2001, 2013 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -14,10 +14,13 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+
+#include <stdint.h>
+
 #define COFF_IMAGE_WITH_PE
 #define COFF_LONG_SECTION_NAMES
 
-/*** coff information for Intel 386/486.  */
+/*** coff information for Intel 386/486 and AMD64.  */
 
 
 /********************** FILE HEADER **********************/
@@ -25,9 +28,9 @@
 struct external_filehdr {
   short f_magic;	/* magic number			*/
   short f_nscns;	/* number of sections		*/
-  unsigned long f_timdat;	/* time & date stamp		*/
-  unsigned long f_symptr;	/* file pointer to symtab	*/
-  unsigned long f_nsyms;	/* number of symtab entries	*/
+  uint32_t f_timdat;	/* time & date stamp		*/
+  uint32_t f_symptr;	/* file pointer to symtab	*/
+  uint32_t f_nsyms;	/* number of symtab entries	*/
   short f_opthdr;	/* sizeof(optional hdr)		*/
   short f_flags;	/* flags			*/
 };
@@ -50,6 +53,16 @@
 #define	I386MAGIC	0x14c
 #define I386PTXMAGIC	0x154
 #define I386AIXMAGIC	0x175
+#define IMAGE_FILE_MACHINE_I386 0x014c
+#define IMAGE_FILE_MACHINE_AMD64 0x8664
+#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
+#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
+#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28
+#define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224
+#define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240
+#define IMAGE_SUBSYSTEM_NATIVE 1
+#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2
+#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3
 
 /* This is Lynx's all-platform magic number for executables. */
 
@@ -72,12 +85,12 @@
 {
   unsigned short magic;		/* type of file				*/
   unsigned short vstamp;	/* version stamp			*/
-  unsigned long	tsize;		/* text size in bytes, padded to FW bdry*/
-  unsigned long	dsize;		/* initialized data "  "		*/
-  unsigned long	bsize;		/* uninitialized data "   "		*/
-  unsigned long	entry;		/* entry pt.				*/
-  unsigned long text_start;	/* base of text used for this file */
-  unsigned long data_start;	/* base of data used for this file=
+  uint32_t	tsize;		/* text size in bytes, padded to FW bdry*/
+  uint32_t	dsize;		/* initialized data "  "		*/
+  uint32_t	bsize;		/* uninitialized data "   "		*/
+  uint32_t	entry;		/* entry pt.				*/
+  uint32_t text_start;		/* base of text used for this file */
+  uint32_t data_start;		/* base of data used for this file=
  */
 }
 AOUTHDR;
@@ -103,16 +116,16 @@
 
 struct external_scnhdr {
   char		s_name[8];	/* section name			*/
-  unsigned long	s_paddr;	/* physical address, offset
+  uint32_t	s_paddr;	/* physical address, offset
 				   of last addr in scn */
-  unsigned long	s_vaddr;	/* virtual address		*/
-  unsigned long	s_size;		/* section size			*/
-  unsigned long	s_scnptr;	/* file ptr to raw data for section */
-  unsigned long	s_relptr;	/* file ptr to relocation	*/
-  unsigned long	s_lnnoptr;	/* file ptr to line numbers	*/
+  uint32_t	s_vaddr;	/* virtual address		*/
+  uint32_t	s_size;		/* section size			*/
+  uint32_t	s_scnptr;	/* file ptr to raw data for section */
+  uint32_t	s_relptr;	/* file ptr to relocation	*/
+  uint32_t	s_lnnoptr;	/* file ptr to line numbers	*/
   unsigned short s_nreloc;	/* number of relocation entries	*/
   unsigned short s_nlnno;	/* number of line number entries*/
-  unsigned long	s_flags;	/* flags			*/
+  uint32_t	s_flags;	/* flags			*/
 };
 
 #define	SCNHDR	struct external_scnhdr
@@ -136,8 +149,8 @@
  */
 struct external_lineno {
   union {
-    unsigned long l_symndx; /* function name symbol index, iff l_lnno 0 */
-    unsigned long l_paddr;	/* (physical) address of line number	*/
+    uint32_t l_symndx; 		/* function name symbol index, iff l_lnno 0 */
+    uint32_t l_paddr;		/* (physical) address of line number	*/
   } l_addr;
   unsigned short l_lnno;	/* line number		*/
 };
@@ -156,11 +169,11 @@
   union {
     char e_name[E_SYMNMLEN];
     struct {
-      unsigned long e_zeroes;
-      unsigned long e_offset;
+      uint32_t e_zeroes;
+      uint32_t e_offset;
     } e;
   } e;
-  unsigned long e_value;
+  uint32_t e_value;
   unsigned short e_scnum;
   unsigned short e_type;
   char e_sclass[1];
@@ -174,18 +187,18 @@
 
 union external_auxent {
   struct {
-    unsigned long x_tagndx;	/* str, un, or enum tag indx */
+    uint32_t x_tagndx;	/* str, un, or enum tag indx */
     union {
       struct {
 	unsigned short  x_lnno; /* declaration line number */
 	unsigned short  x_size; /* str/union/array size */
       } x_lnsz;
-      unsigned long x_fsize;	/* size of function */
+      uint32_t x_fsize;	/* size of function */
     } x_misc;
     union {
       struct {			/* if ISFCN, tag, or .bb */
-	unsigned long x_lnnoptr;/* ptr to fcn line # */
-	unsigned long x_endndx;	/* entry ndx past block end */
+	uint32_t x_lnnoptr;	/* ptr to fcn line # */
+	uint32_t x_endndx;	/* entry ndx past block end */
       } x_fcn;
       struct {			/* if ISARY, up to 4 dimen. */
 	char x_dimen[E_DIMNUM][2];
@@ -197,22 +210,22 @@
   union {
     char x_fname[E_FILNMLEN];
     struct {
-      unsigned long x_zeroes;
-      unsigned long x_offset;
+      uint32_t x_zeroes;
+      uint32_t x_offset;
     } x_n;
   } x_file;
 
   struct {
-    unsigned long x_scnlen;	/* section length */
+    uint32_t x_scnlen;		/* section length */
     unsigned short x_nreloc;	/* # relocation entries */
     unsigned short x_nlinno;	/* # line numbers */
-    unsigned long x_checksum;	/* section COMDAT checksum */
+    uint32_t x_checksum;	/* section COMDAT checksum */
     unsigned short x_associated;/* COMDAT associated section index */
     char x_comdat[1];		/* COMDAT selection number */
   } x_scn;
 
   struct {
-    unsigned long x_tvfill;	/* tv fill value */
+    uint32_t x_tvfill;		/* tv fill value */
     unsigned short x_tvlen;	/* length of .tv */
     char x_tvran[2][2];		/* tv range */
   } x_tv;	/* info about .tv section (in auxent of symbol .tv)) */
@@ -320,7 +333,7 @@
 
 
 #ifdef COFF_IMAGE_WITH_PE
-/* The filehdr is only weired in images */
+/* The filehdr is only weird in images */
 
 #undef FILHDR
 struct external_PE_filehdr
@@ -344,7 +357,7 @@
   unsigned short e_oemid;	/* OEM identifier (for e_oeminfo), 0x0 */
   unsigned short e_oeminfo;	/* OEM information; e_oemid specific, 0x0 */
   char e_res2[10][2];		/* Reserved words, all 0x0 */
-  unsigned long e_lfanew;	/* File address of new exe header, 0x80 */
+  uint32_t e_lfanew;		/* File address of new exe header, 0x80 */
   char dos_message[16][4];	/* other stuff, always follow DOS header */
   unsigned int nt_signature;	/* required NT signature, 0x4550 */
 
@@ -352,9 +365,9 @@
 
   unsigned short f_magic;	/* magic number			*/
   unsigned short f_nscns;	/* number of sections		*/
-  unsigned long f_timdat;	/* time & date stamp		*/
-  unsigned long f_symptr;	/* file pointer to symtab	*/
-  unsigned long f_nsyms;	/* number of symtab entries	*/
+  uint32_t f_timdat;		/* time & date stamp		*/
+  uint32_t f_symptr;		/* file pointer to symtab	*/
+  uint32_t f_nsyms;		/* number of symtab entries	*/
   unsigned short f_opthdr;	/* sizeof(optional hdr)		*/
   unsigned short f_flags;	/* flags			*/
 };
@@ -370,17 +383,19 @@
 {
   unsigned short magic;		/* type of file				*/
   unsigned short vstamp;	/* version stamp			*/
-  unsigned long	tsize;		/* text size in bytes, padded to FW bdry*/
-  unsigned long	dsize;		/* initialized data "  "		*/
-  unsigned long	bsize;		/* uninitialized data "   "		*/
-  unsigned long	entry;		/* entry pt.				*/
-  unsigned long text_start;	/* base of text used for this file */
-  unsigned long data_start;	/* base of all data used for this file */
+  uint32_t	tsize;		/* text size in bytes, padded to FW bdry*/
+  uint32_t	dsize;		/* initialized data "  "		*/
+  uint32_t	bsize;		/* uninitialized data "   "		*/
+  uint32_t	entry;		/* entry pt.				*/
+  uint32_t	text_start;	/* base of text used for this file */
+#ifndef __x86_64__
+  uint32_t	data_start;	/* base of all data used for this file */
+#endif
 
   /* NT extra fields; see internal.h for descriptions */
   unsigned long  ImageBase;
-  unsigned long  SectionAlignment;
-  unsigned long  FileAlignment;
+  uint32_t  SectionAlignment;
+  uint32_t  FileAlignment;
   unsigned short  MajorOperatingSystemVersion;
   unsigned short  MinorOperatingSystemVersion;
   unsigned short  MajorImageVersion;
@@ -388,17 +403,17 @@
   unsigned short  MajorSubsystemVersion;
   unsigned short  MinorSubsystemVersion;
   char  Reserved1[4];
-  unsigned long  SizeOfImage;
-  unsigned long  SizeOfHeaders;
-  unsigned long  CheckSum;
+  uint32_t  SizeOfImage;
+  uint32_t  SizeOfHeaders;
+  uint32_t  CheckSum;
   unsigned short Subsystem;
   unsigned short DllCharacteristics;
   unsigned long  SizeOfStackReserve;
   unsigned long  SizeOfStackCommit;
   unsigned long  SizeOfHeapReserve;
   unsigned long  SizeOfHeapCommit;
-  unsigned long  LoaderFlags;
-  unsigned long  NumberOfRvaAndSizes;
+  uint32_t  LoaderFlags;
+  uint32_t  NumberOfRvaAndSizes;
   /* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */
   char  DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars */
 
@@ -406,7 +421,11 @@
 
 
 #undef AOUTSZ
+#ifdef __x86_64__
+#define AOUTSZ (AOUTHDRSZ + 212)
+#else
 #define AOUTSZ (AOUTHDRSZ + 196)
+#endif
 
 #undef  E_FILNMLEN
 #define E_FILNMLEN	18	/* # characters in a file name		*/


More information about the Cygwin-apps mailing list