1
0
mirror of https://github.com/golang/go synced 2024-11-23 05:20:11 -07:00

libmach: fix amd64 pe handling

Fixes #4841.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7475046
This commit is contained in:
Alex Brainman 2013-03-06 15:14:07 -05:00 committed by Russ Cox
parent 77deeda717
commit e44f42e056

View File

@ -1335,13 +1335,45 @@ typedef struct {
IMAGE_DATA_DIRECTORY DataDirectory[16]; IMAGE_DATA_DIRECTORY DataDirectory[16];
} IMAGE_OPTIONAL_HEADER; } IMAGE_OPTIONAL_HEADER;
typedef struct {
uint16 Magic;
uint8 MajorLinkerVersion;
uint8 MinorLinkerVersion;
uint32 SizeOfCode;
uint32 SizeOfInitializedData;
uint32 SizeOfUninitializedData;
uint32 AddressOfEntryPoint;
uint32 BaseOfCode;
uint64 ImageBase;
uint32 SectionAlignment;
uint32 FileAlignment;
uint16 MajorOperatingSystemVersion;
uint16 MinorOperatingSystemVersion;
uint16 MajorImageVersion;
uint16 MinorImageVersion;
uint16 MajorSubsystemVersion;
uint16 MinorSubsystemVersion;
uint32 Win32VersionValue;
uint32 SizeOfImage;
uint32 SizeOfHeaders;
uint32 CheckSum;
uint16 Subsystem;
uint16 DllCharacteristics;
uint64 SizeOfStackReserve;
uint64 SizeOfStackCommit;
uint64 SizeOfHeapReserve;
uint64 SizeOfHeapCommit;
uint32 LoaderFlags;
uint32 NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[16];
} PE64_IMAGE_OPTIONAL_HEADER;
static int static int
match8(void *buf, char *cmp) match8(void *buf, char *cmp)
{ {
return strncmp((char*)buf, cmp, 8) == 0; return strncmp((char*)buf, cmp, 8) == 0;
} }
/* TODO(czaplinski): 64b windows? */
/* /*
* Read from Windows PE/COFF .exe file image. * Read from Windows PE/COFF .exe file image.
*/ */
@ -1353,9 +1385,10 @@ pedotout(int fd, Fhdr *fp, ExecHdr *hp)
IMAGE_FILE_HEADER fh; IMAGE_FILE_HEADER fh;
IMAGE_SECTION_HEADER sh; IMAGE_SECTION_HEADER sh;
IMAGE_OPTIONAL_HEADER oh; IMAGE_OPTIONAL_HEADER oh;
PE64_IMAGE_OPTIONAL_HEADER oh64;
uint8 sym[18]; uint8 sym[18];
uint32 *valp, ib; uint32 *valp, ib, entry;
int i; int i, ohoffset;
USED(hp); USED(hp);
seek(fd, 0x3c, 0); seek(fd, 0x3c, 0);
@ -1384,6 +1417,7 @@ pedotout(int fd, Fhdr *fp, ExecHdr *hp)
return 0; return 0;
} }
ohoffset = seek(fd, 0, 1);
if (readn(fd, &oh, sizeof(oh)) != sizeof(oh)) { if (readn(fd, &oh, sizeof(oh)) != sizeof(oh)) {
werrstr("crippled PE Optional Header"); werrstr("crippled PE Optional Header");
return 0; return 0;
@ -1392,17 +1426,24 @@ pedotout(int fd, Fhdr *fp, ExecHdr *hp)
switch(oh.Magic) { switch(oh.Magic) {
case 0x10b: // PE32 case 0x10b: // PE32
fp->type = FI386; fp->type = FI386;
ib = leswal(oh.ImageBase);
entry = leswal(oh.AddressOfEntryPoint);
break; break;
case 0x20b: // PE32+ case 0x20b: // PE32+
fp->type = FAMD64; fp->type = FAMD64;
seek(fd, ohoffset, 0);
if (readn(fd, &oh64, sizeof(oh64)) != sizeof(oh64)) {
werrstr("crippled PE32+ Optional Header");
return 0;
}
ib = leswal(oh64.ImageBase);
entry = leswal(oh64.AddressOfEntryPoint);
break; break;
default: default:
werrstr("invalid PE Optional magic number"); werrstr("invalid PE Optional Header magic number");
return 0; return 0;
} }
ib=leswal(oh.ImageBase);
seek(fd, start+sizeof(magic)+sizeof(fh)+leswab(fh.SizeOfOptionalHeader), 0);
fp->txtaddr = 0; fp->txtaddr = 0;
fp->dataddr = 0; fp->dataddr = 0;
for (i=0; i<leswab(fh.NumberOfSections); i++) { for (i=0; i<leswab(fh.NumberOfSections); i++) {
@ -1411,7 +1452,7 @@ pedotout(int fd, Fhdr *fp, ExecHdr *hp)
return 0; return 0;
} }
if (match8(sh.Name, ".text")) if (match8(sh.Name, ".text"))
settext(fp, ib+leswal(oh.AddressOfEntryPoint), ib+leswal(sh.VirtualAddress), leswal(sh.VirtualSize), leswal(sh.PointerToRawData)); settext(fp, ib+entry, ib+leswal(sh.VirtualAddress), leswal(sh.VirtualSize), leswal(sh.PointerToRawData));
if (match8(sh.Name, ".data")) if (match8(sh.Name, ".data"))
setdata(fp, ib+leswal(sh.VirtualAddress), leswal(sh.SizeOfRawData), leswal(sh.PointerToRawData), leswal(sh.VirtualSize)-leswal(sh.SizeOfRawData)); setdata(fp, ib+leswal(sh.VirtualAddress), leswal(sh.SizeOfRawData), leswal(sh.PointerToRawData), leswal(sh.VirtualSize)-leswal(sh.SizeOfRawData));
} }