summaryrefslogtreecommitdiff
path: root/src/libmach/executable.c
diff options
context:
space:
mode:
authorMichael Stapelberg <stapelberg@debian.org>2013-03-04 21:27:36 +0100
committerMichael Stapelberg <michael@stapelberg.de>2013-03-04 21:27:36 +0100
commit04b08da9af0c450d645ab7389d1467308cfc2db8 (patch)
treedb247935fa4f2f94408edc3acd5d0d4f997aa0d8 /src/libmach/executable.c
parent917c5fb8ec48e22459d77e3849e6d388f93d3260 (diff)
downloadgolang-upstream/1.1_hg20130304.tar.gz
Imported Upstream version 1.1~hg20130304upstream/1.1_hg20130304
Diffstat (limited to 'src/libmach/executable.c')
-rw-r--r--src/libmach/executable.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/src/libmach/executable.c b/src/libmach/executable.c
index 3db3e7da4..a93a8c268 100644
--- a/src/libmach/executable.c
+++ b/src/libmach/executable.c
@@ -1091,12 +1091,21 @@ machdotout(int fd, Fhdr *fp, ExecHdr *hp)
}
cmdbuf = malloc(mp->sizeofcmds);
+ if(!cmdbuf) {
+ werrstr("out of memory");
+ return 0;
+ }
seek(fd, hdrsize, 0);
if(read(fd, cmdbuf, mp->sizeofcmds) != mp->sizeofcmds) {
free(cmdbuf);
return 0;
}
cmd = malloc(mp->ncmds * sizeof(MachCmd*));
+ if(!cmd) {
+ free(cmdbuf);
+ werrstr("out of memory");
+ return 0;
+ }
cmdp = cmdbuf;
textva = 0;
textoff = 0;
@@ -1340,12 +1349,12 @@ static int
pedotout(int fd, Fhdr *fp, ExecHdr *hp)
{
uint32 start, magic;
- uint32 symtab, esymtab;
+ uint32 symtab, esymtab, pclntab, epclntab;
IMAGE_FILE_HEADER fh;
IMAGE_SECTION_HEADER sh;
IMAGE_OPTIONAL_HEADER oh;
uint8 sym[18];
- uint32 *valp;
+ uint32 *valp, ib;
int i;
USED(hp);
@@ -1380,6 +1389,19 @@ pedotout(int fd, Fhdr *fp, ExecHdr *hp)
return 0;
}
+ switch(oh.Magic) {
+ case 0x10b: // PE32
+ fp->type = FI386;
+ break;
+ case 0x20b: // PE32+
+ fp->type = FAMD64;
+ break;
+ default:
+ werrstr("invalid PE Optional magic number");
+ return 0;
+ }
+
+ ib=leswal(oh.ImageBase);
seek(fd, start+sizeof(magic)+sizeof(fh)+leswab(fh.SizeOfOptionalHeader), 0);
fp->txtaddr = 0;
fp->dataddr = 0;
@@ -1389,9 +1411,9 @@ pedotout(int fd, Fhdr *fp, ExecHdr *hp)
return 0;
}
if (match8(sh.Name, ".text"))
- settext(fp, leswal(sh.VirtualAddress), leswal(oh.AddressOfEntryPoint), leswal(sh.VirtualSize), leswal(sh.PointerToRawData));
+ settext(fp, ib+leswal(oh.AddressOfEntryPoint), ib+leswal(sh.VirtualAddress), leswal(sh.VirtualSize), leswal(sh.PointerToRawData));
if (match8(sh.Name, ".data"))
- setdata(fp, 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));
}
if (fp->txtaddr==0 || fp->dataddr==0) {
werrstr("no .text or .data");
@@ -1399,7 +1421,7 @@ pedotout(int fd, Fhdr *fp, ExecHdr *hp)
}
seek(fd, leswal(fh.PointerToSymbolTable), 0);
- symtab = esymtab = 0;
+ symtab = esymtab = pclntab = epclntab = 0;
for (i=0; i<leswal(fh.NumberOfSymbols); i++) {
if (readn(fd, sym, sizeof(sym)) != sizeof(sym)) {
werrstr("crippled COFF symbol %d", i);
@@ -1410,12 +1432,16 @@ pedotout(int fd, Fhdr *fp, ExecHdr *hp)
symtab = leswal(*valp);
if (match8(sym, "esymtab"))
esymtab = leswal(*valp);
+ if (match8(sym, "pclntab"))
+ pclntab = leswal(*valp);
+ if (match8(sym, "epclntab"))
+ epclntab = leswal(*valp);
}
- if (symtab==0 || esymtab==0) {
- werrstr("no symtab or esymtab in COFF symbol table");
+ if (symtab==0 || esymtab==0 || pclntab==0 || epclntab==0) {
+ werrstr("no symtab or esymtab or pclntab or epclntab in COFF symbol table");
return 0;
}
- setsym(fp, symtab, esymtab-symtab, 0, 0, 0, 0);
+ setsym(fp, symtab, esymtab-symtab, 0, 0, pclntab, epclntab-pclntab);
return 1;
}