diff options
author | Michael Stapelberg <stapelberg@debian.org> | 2013-03-04 21:27:36 +0100 |
---|---|---|
committer | Michael Stapelberg <michael@stapelberg.de> | 2013-03-04 21:27:36 +0100 |
commit | 04b08da9af0c450d645ab7389d1467308cfc2db8 (patch) | |
tree | db247935fa4f2f94408edc3acd5d0d4f997aa0d8 /src/libmach/executable.c | |
parent | 917c5fb8ec48e22459d77e3849e6d388f93d3260 (diff) | |
download | golang-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.c | 42 |
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; } |