Skip to content

Commit

Permalink
libmach: many pe handling fixes
Browse files Browse the repository at this point in the history
- implement windows pread;
- set correct Fhdr.type;
- add ImageBase to all pe "virtual" addresses;
- correct settext parameter order;
- use pclntab/epclntab to find line numbers.

Fixes #4841.
Fixes #4926.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7405050
  • Loading branch information
alexbrainman committed Mar 1, 2013
1 parent 211589a commit e72d1a9
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 10 deletions.
33 changes: 25 additions & 8 deletions src/libmach/executable.c
Expand Up @@ -1349,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);
Expand Down Expand Up @@ -1389,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;
Expand All @@ -1398,17 +1411,17 @@ 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");
return 0;
}

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);
Expand All @@ -1419,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;
}
Expand Down
8 changes: 6 additions & 2 deletions src/libmach/windows.c
Expand Up @@ -48,8 +48,12 @@ procthreadpids(int pid, int *p, int np)
int
pread(int fd, void *buf, int count, int offset)
{
sysfatal("pread unimplemented in Windows");
return -1;
int oldoffset, n;

oldoffset = seek(fd, offset, 0);
n = read(fd, buf, count);
seek(fd, oldoffset, 0);
return n;
}

int
Expand Down

0 comments on commit e72d1a9

Please sign in to comment.