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