diff options
| author | Wei Guangjing <vcc.163@gmail.com> | 2011-05-25 07:53:00 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2011-05-25 07:53:00 -0400 |
| commit | 2ad58d48fb88d84989e0e6bf5844cd31fb7beb9d (patch) | |
| tree | cad355e0fdc4e9e3ed8180b82e681d4ca1d9744b /src/cmd/ld | |
| parent | 7b03f2a9901785fdf4dd4177682c4673c0d48f97 (diff) | |
| download | go-2ad58d48fb88d84989e0e6bf5844cd31fb7beb9d.tar.xz | |
8l: emit resources (.rsrc) in Windows PE.
R=alex.brainman, rsc
CC=golang-dev, vcc.163
https://golang.org/cl/4516055
Diffstat (limited to 'src/cmd/ld')
| -rw-r--r-- | src/cmd/ld/ldpe.c | 5 | ||||
| -rw-r--r-- | src/cmd/ld/pe.c | 48 | ||||
| -rw-r--r-- | src/cmd/ld/pe.h | 2 |
3 files changed, 53 insertions, 2 deletions
diff --git a/src/cmd/ld/ldpe.c b/src/cmd/ld/ldpe.c index d8b0a6fc23..d6aa267c4e 100644 --- a/src/cmd/ld/ldpe.c +++ b/src/cmd/ld/ldpe.c @@ -147,7 +147,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn) goto bad; obj->sect[i].size = obj->sect[i].sh.SizeOfRawData; obj->sect[i].name = (char*)obj->sect[i].sh.Name; - // TODO return error if found .cormeta .rsrc + // TODO return error if found .cormeta } // load string table Bseek(f, base+obj->fh.PointerToSymbolTable+18*obj->fh.NumberOfSymbols, 0); @@ -222,6 +222,8 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn) etextp = s; } sect->sym = s; + if(strcmp(sect->name, ".rsrc") == 0) + setpersrc(sect->sym); } // load relocations @@ -259,6 +261,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn) rp->type = D_PCREL; rp->add = 0; break; + case IMAGE_REL_I386_DIR32NB: case IMAGE_REL_I386_DIR32: rp->type = D_ADDR; // load addend from image diff --git a/src/cmd/ld/pe.c b/src/cmd/ld/pe.c index 1c0c665383..91e15d343c 100644 --- a/src/cmd/ld/pe.c +++ b/src/cmd/ld/pe.c @@ -34,6 +34,8 @@ static char dosstub[] = 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static Sym *rsrcsym; + static char symnames[256]; static int nextsymoff; @@ -459,6 +461,48 @@ addsymtable(void) } void +setpersrc(Sym *sym) +{ + if(rsrcsym != nil) + diag("too many .rsrc sections"); + + rsrcsym = sym; +} + +void +addpersrc(void) +{ + IMAGE_SECTION_HEADER *h; + uchar *p; + uint32 val; + Reloc *r; + + if(rsrcsym == nil) + return; + + h = addpesection(".rsrc", rsrcsym->size, rsrcsym->size, 0); + h->Characteristics = IMAGE_SCN_MEM_READ| + IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA; + // relocation + for(r=rsrcsym->r; r<rsrcsym->r+rsrcsym->nr; r++) { + p = rsrcsym->p + r->off; + val = h->VirtualAddress + r->add; + // 32-bit little-endian + p[0] = val; + p[1] = val>>8; + p[2] = val>>16; + p[3] = val>>24; + } + ewrite(cout, rsrcsym->p, rsrcsym->size); + strnput("", h->SizeOfRawData - rsrcsym->size); + cflush(); + + // update data directory + dd[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = h->VirtualAddress; + dd[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = h->VirtualSize; +} + +void asmbpe(void) { IMAGE_SECTION_HEADER *t, *d; @@ -492,7 +536,9 @@ asmbpe(void) addexports(nextfileoff); addsymtable(); - + + addpersrc(); + fh.NumberOfSections = nsect; fh.TimeDateStamp = time(0); fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED| diff --git a/src/cmd/ld/pe.h b/src/cmd/ld/pe.h index 2180fb88cb..7aa9388293 100644 --- a/src/cmd/ld/pe.h +++ b/src/cmd/ld/pe.h @@ -175,3 +175,5 @@ typedef struct { uint32 NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[16]; } PE64_IMAGE_OPTIONAL_HEADER; + +void setpersrc(Sym *sym); |
