]> Cypherpunks repositories - gostls13.git/commitdiff
FFI step 2: can ask for libc.so.6.
authorRuss Cox <rsc@golang.org>
Thu, 20 Aug 2009 23:09:38 +0000 (16:09 -0700)
committerRuss Cox <rsc@golang.org>
Thu, 20 Aug 2009 23:09:38 +0000 (16:09 -0700)
introduced explicit "data" symbol instead of etext
to mark beginning of data, so that using larger
alignment (i.e. 4MB like GNU loader) doesn't
confuse garbage collector.

split dodata into dodata and dobss in preparation
for putting the dynamic data + headers in the data
segment instead of stuffed at the beginning of the binary.

R=r
DELTA=52  (37 added, 3 deleted, 12 changed)
OCL=33610
CL=33618

src/cmd/6l/asm.c
src/cmd/6l/l.h
src/cmd/6l/obj.c
src/cmd/6l/pass.c
src/cmd/ld/elf64.c
src/cmd/ld/elf64.h
src/pkg/runtime/mgc0.c

index 7e0bd9191d85532c5b104a14fc1970fdf2c07811..5acaaae5f1d392f09f1d3d6dafa7dfce785cd73f 100644 (file)
@@ -128,7 +128,7 @@ asmb(void)
        int32 v, magic;
        int a, nl;
        uchar *op1;
-       vlong vl, va, startva, fo, w, symo, hashoff;
+       vlong vl, va, startva, fo, w, symo, hashoff, dstrtab, off;
        vlong symdatva = 0x99LL<<32;
        Elf64Hdr *eh;
        Elf64PHdr *ph, *pph;
@@ -431,6 +431,7 @@ asmb(void)
                sh = newElf64SHdr("");
 
                pph = nil;      /* silence compiler */
+               dstrtab = 0;
 
                /* Dynamic linking sections */
                if (!debug['d']) {      /* -d suppresses dynamic loader format */
@@ -443,7 +444,7 @@ asmb(void)
                        pph->off = ELF64HDRSIZE;
                        pph->vaddr = startva + pph->off;
                        pph->paddr = startva + pph->off;
-                       pph->align = 8;
+                       pph->align = INITRND;
 
                        /* interpreter */
                        ph = newElf64PHdr();
@@ -503,13 +504,19 @@ asmb(void)
                        sh->addr = startva + sh->off;
                        sh->off = startelf();
                        elf64writedynent(DT_HASH, startva+hashoff);
-                       elf64writedynent(DT_STRTAB, startva+ELF64FULLHDRSIZE-STRTABSIZE);
                        elf64writedynent(DT_SYMTAB, startva);
                        elf64writedynent(DT_RELA, startva);
                        elf64writedynent(DT_RELASZ, 0); // size of the whole rela in bytes
                        elf64writedynent(DT_RELAENT, ELF64RELASIZE);
-                       elf64writedynent(DT_STRSZ, STRTABSIZE);
                        elf64writedynent(DT_SYMENT, 0);
+//                     elf64writedynent(DT_NEEDED, elf64addstr("libc.so.6"));
+
+                       /* make space for these now but fill them in later */
+                       cflush();
+                       dstrtab = seek(cout, 0, 1);
+                       elf64writedynent(DT_STRTAB, -1);
+                       elf64writedynent(DT_STRSZ, -1);
+
                        elf64writedynent(DT_NULL, 0);
                        sh->size = endelf() - sh->off;
                        sh->addralign = 8;
@@ -534,7 +541,7 @@ asmb(void)
                        ph->paddr = startva + ph->off;
                        ph->filesz = sh->off + sh->size - ph->off;
                        ph->memsz = ph->filesz;
-                       ph->align = 8;
+                       ph->align = INITRND;
                }
 
                ph = newElf64PHdr();
@@ -644,6 +651,17 @@ asmb(void)
                elf64writestrtable();
                sh->size = endelf() - sh->off;
 
+               if(dstrtab != 0) {
+                       // update DT_STRTAB entry
+                       cflush();
+                       off = seek(cout, 0, 1);
+                       seek(cout, dstrtab, 0);
+                       elf64writedynent(DT_STRTAB, sh->addr);
+                       elf64writedynent(DT_STRSZ, sh->size);
+                       cflush();
+                       seek(cout, off, 0);
+               }
+
                /* Main header */
                eh = getElf64Hdr();
                eh->ident[EI_MAG0] = '\177';
index 8f72812bcca0df57f10f5412b5a99790b7c8b651..0490bc1db1038690b77019935b887b6c81a26479 100644 (file)
@@ -390,6 +390,7 @@ double      cputime(void);
 void   datblk(int32, int32);
 void   deadcode(void);
 void   diag(char*, ...);
+void   dobss(void);
 void   dodata(void);
 void   doinit(void);
 void   doprof1(void);
index d9630fe33359bcb269ed575234e29138476cd4db..98318d94b15ff3fb2e31dbd13397afbc911c11c0 100644 (file)
@@ -390,6 +390,7 @@ main(int argc, char *argv[])
        patch();
        follow();
        dodata();
+       dobss();
        dostkoff();
        paramspace = "SP";      /* (FP) now (SP) on output */
        if(debug['p'])
index 3917ac5423128b0a2473c30adeb78f8e6d574cbe..540063568fe28f38f25f2a2fe3ca48633fda4963 100644 (file)
@@ -124,6 +124,14 @@ dodata(void)
                }
                datsize += u;
        }
+}
+
+void
+dobss(void)
+{
+       int i;
+       Sym *s;
+       int32 t;
 
        /* now the bss */
        bsssize = 0;
@@ -137,6 +145,7 @@ dodata(void)
                s->value = bsssize + datsize;
                bsssize += t;
        }
+       xdefine("data", SBSS, 0);
        xdefine("edata", SBSS, datsize);
        xdefine("end", SBSS, bsssize + datsize);
 }
index dc9f4196b1d99be9aa9ee715cd8bdb8d60e71209..d6a2f7f3c284de42777839e798bf8912ab8f0ffe 100644 (file)
@@ -13,7 +13,7 @@ static        Elf64Hdr        hdr;
 static Elf64PHdr       *phdr[NSECT];
 static Elf64SHdr       *shdr[NSECT];
 static char    *sname[NSECT];
-static char    *str[NSECT];
+static char    *str[20];
 
 /*
  Initialize the global variable that describes the ELF header. It will be updated as
@@ -80,15 +80,19 @@ elf64writestrtable(void)
                diag("elf64 string table overflow");
 }
 
-void
-e64addstr(char *name)
+uint32
+elf64addstr(char *name)
 {
-       if (numstr >= NSECT) {
+       int r;
+
+       if (numstr >= nelem(str)) {
                diag("too many elf strings");
-               return;
+               return 0;
        }
        str[numstr++] = strdup(name);
+       r = stroffset;
        stroffset += strlen(name)+1;
+       return r;
 }
 
 uint32
@@ -135,11 +139,10 @@ newElf64SHdr(char *name)
                hdr.shstrndx = hdr.shnum;
        e = malloc(sizeof *e);
        memset(e, 0, sizeof *e);
-       e->name = stroffset;
+       e->name = elf64addstr(name);
        if (hdr.shnum >= NSECT) {
                diag("too many shdrs");
        } else {
-               e64addstr(name);
                shdr[hdr.shnum++] = e;
        }
        return e;
@@ -152,7 +155,7 @@ getElf64Hdr(void)
 }
 
 uint32
-elf64writehdr()
+elf64writehdr(void)
 {
        int i;
 
index 55d0ca3098c6a6e2735231a1092d92857e34329c..bde6376783dfd8c8e3f9fdc5a43b464065ed32d1 100644 (file)
@@ -274,6 +274,7 @@ Elf64PHdr   *newElf64PHdr();
 uint32 elf64writehdr(void);
 uint32 elf64writephdrs(void);
 uint32 elf64writeshdrs(void);
+uint32 elf64addstr(char*);
 void   elf64writestrtable(void);
 void   elf64writedynent(int, uint64);
 uint32 elf64_hash(uchar*);
index d27c186f412327ee83eee410aabe26f68bc9259b..b5b2b48a3ed3a45901acce3c5dc815b04052f039 100644 (file)
@@ -19,6 +19,7 @@ enum {
        Debug = 0
 };
 
+extern byte data[];
 extern byte etext[];
 extern byte end[];
 
@@ -84,7 +85,7 @@ mark(void)
        G *gp;
 
        // mark data+bss
-       scanblock(0, etext, end - etext);
+       scanblock(0, data, end - data);
 
        // mark stacks
        for(gp=allg; gp!=nil; gp=gp->alllink) {