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

#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);
}
--- 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          */

Reply via email to