]> Cypherpunks repositories - gostls13.git/commitdiff
8l: emit resources (.rsrc) in Windows PE.
authorWei Guangjing <vcc.163@gmail.com>
Wed, 25 May 2011 11:53:00 +0000 (07:53 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 25 May 2011 11:53:00 +0000 (07:53 -0400)
R=alex.brainman, rsc
CC=golang-dev, vcc.163
https://golang.org/cl/4516055

src/cmd/ld/ldpe.c
src/cmd/ld/pe.c
src/cmd/ld/pe.h

index d8b0a6fc2373b1e26bb20f663a0e4a909e3eadb7..d6aa267c4e2c8ffb48cc57119d7df410d5e08305 100644 (file)
@@ -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
index 1c0c6653832b16c6b5b1d0b45ef9989dc049349a..91e15d343cc7d7a79e5b857206036b6b90a18f76 100644 (file)
@@ -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;
 
@@ -458,6 +460,48 @@ addsymtable(void)
        cflush();
 }
 
+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)
 {
@@ -492,7 +536,9 @@ asmbpe(void)
        addexports(nextfileoff);
        
        addsymtable();
-               
+       
+       addpersrc();
+       
        fh.NumberOfSections = nsect;
        fh.TimeDateStamp = time(0);
        fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED|
index 2180fb88cb79d98871066be1487ea8ade40aa25a..7aa938829367a9c577a2dbcfb74dfa0272263ad6 100644 (file)
@@ -175,3 +175,5 @@ typedef struct {
        uint32 NumberOfRvaAndSizes;
        IMAGE_DATA_DIRECTORY DataDirectory[16];
 } PE64_IMAGE_OPTIONAL_HEADER;
+
+void setpersrc(Sym *sym);