]> Cypherpunks repositories - gostls13.git/commitdiff
count SHdrs and PHdrs and write them out as a unit
authorRob Pike <r@golang.org>
Fri, 17 Jul 2009 23:34:58 +0000 (16:34 -0700)
committerRob Pike <r@golang.org>
Fri, 17 Jul 2009 23:34:58 +0000 (16:34 -0700)
R=rsc
DELTA=181  (93 added, 63 deleted, 25 changed)
OCL=31802
CL=31812

src/cmd/6l/asm.c
src/cmd/ld/elf64.c
src/cmd/ld/elf64.h

index e6c499fbf34c6837ebb2ff118f02bc398558afa6..2fdae8b3c1e8028a6e22712df4be92e8ec398bf4 100644 (file)
@@ -122,16 +122,13 @@ asmb(void)
 {
        Prog *p;
        int32 v, magic;
-       int a, nl, np;
+       int a, nl;
        uchar *op1;
        vlong vl, va, fo, w, symo;
-       int strtabsize;
        vlong symdatva = 0x99LL<<32;
        Elf64PHdr *ph;
        Elf64SHdr *sh;
 
-       strtabsize = 0;
-
        if(debug['v'])
                Bprint(&bso, "%5.2f asmb\n", cputime());
        Bflush(&bso);
@@ -196,9 +193,6 @@ asmb(void)
 
        case 7:
                debug['8'] = 1; /* 64-bit addresses */
-               seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
-               strtabsize = elf64strtable();
-               cflush();
                v = rnd(HEADR+textsize, INITRND);
                seek(cout, v, 0);
                break;
@@ -241,7 +235,7 @@ asmb(void)
                        symo = rnd(HEADR+textsize, INITRND)+rnd(datsize, INITRND);
                        break;
                case 7:
-                       symo = rnd(HEADR+textsize, INITRND)+datsize+strtabsize;
+                       symo = rnd(HEADR+textsize, INITRND)+datsize+STRTABSIZE;
                        symo = rnd(symo, INITRND);
                        break;
                }
@@ -421,31 +415,6 @@ asmb(void)
                break;
        case 7:
                /* elf amd-64 */
-               strnput("\177ELF", 4);          /* e_ident */
-               cput(2);                        /* class = 64 bit */
-               cput(1);                        /* data = LSB */
-               cput(1);                        /* version = CURRENT */
-               strnput("", 9);
-
-               wputl(2);                       /* type = EXEC */
-               wputl(62);                      /* machine = AMD64 */
-               lputl(1L);                      /* version = CURRENT */
-               vputl(entryvalue());            /* entry vaddr */
-               vputl(64L);                     /* offset to first phdr */
-               np = 3;
-               if(!debug['s'])
-                       np++;
-               vputl(64L+56*np);               /* offset to first shdr */
-               lputl(0L);                      /* processor specific flags */
-               wputl(64);                      /* Ehdr size */
-               wputl(56);                      /* Phdr size */
-               wputl(np);                      /* # of Phdrs */
-               wputl(64);                      /* Shdr size */
-               if (!debug['s'])
-                       wputl(7);                       /* # of Shdrs */
-               else
-                       wputl(5);                       /* # of Shdrs */
-               wputl(4);                       /* Shdr with strings */
 
                fo = 0;
                va = INITTEXT & ~((vlong)INITRND - 1);
@@ -459,7 +428,6 @@ asmb(void)
                ph->filesz = w;
                ph->memsz = w;
                ph->align = INITRND;
-               elf64phdr(ph);
 
                fo = rnd(fo+w, INITRND);
                va = rnd(va+w, INITRND);
@@ -474,7 +442,6 @@ asmb(void)
                ph->filesz = w;
                ph->memsz = w+bsssize;
                ph->align = INITRND;
-               elf64phdr(ph);
 
                if(!debug['s']) {
                        ph = newElf64PHdr();
@@ -486,66 +453,59 @@ asmb(void)
                        ph->filesz = 8+symsize+lcsize;
                        ph->memsz = 8+symsize+lcsize;
                        ph->align = INITRND;
-                       elf64phdr(ph);
                }
 
                ph = newElf64PHdr();
                ph->type = 0x6474e551;  /* gok */
                ph->flags = PF_X+PF_W+PF_R;
                ph->align = 8;
-               elf64phdr(ph);
 
-               sh = newElf64SHdr();
-               elf64shdr(nil, sh);
+               sh = newElf64SHdr("");
 
                stroffset = 1;  /* 0 means no name, so start at 1 */
                fo = HEADR;
                va = (INITTEXT & ~((vlong)INITRND - 1)) + HEADR;
                w = textsize;
 
-               sh = newElf64SHdr();
+               sh = newElf64SHdr(".text");
                sh->type = SHT_PROGBITS;
                sh->flags = SHF_ALLOC+SHF_EXECINSTR;
                sh->addr = va;
                sh->off = fo;
                sh->size = w;
                sh->addralign = 8;
-               elf64shdr(".text", sh);
 
                fo = rnd(fo+w, INITRND);
                va = rnd(va+w, INITRND);
                w = datsize;
 
-               sh = newElf64SHdr();
+               sh = newElf64SHdr(".data");
                sh->type = SHT_PROGBITS;
                sh->flags = SHF_WRITE+SHF_ALLOC;
                sh->addr = va;
                sh->off = fo;
                sh->size = w;
                sh->addralign = 8;
-               elf64shdr(".data", sh);
 
                fo += w;
                va += w;
                w = bsssize;
 
-               sh = newElf64SHdr();
+               sh = newElf64SHdr(".bss");
                sh->type = SHT_NOBITS;
                sh->flags = SHF_WRITE+SHF_ALLOC;
                sh->addr = va;
                sh->off = fo;
                sh->size = w;
                sh->addralign = 8;
-               elf64shdr(".bss", sh);
 
-               w = strtabsize;
+               w = STRTABSIZE;
 
-               sh = newElf64SHdr();
+               sh = newElf64SHdr(".shstrtab");
                sh->type = SHT_STRTAB;
                sh->off = fo;
                sh->size = w;
                sh->addralign = 1;
-               elf64shdr(".shstrtab", sh);
 
                if (debug['s'])
                        break;
@@ -553,24 +513,52 @@ asmb(void)
                fo = symo+8;
                w = symsize;
 
-               sh = newElf64SHdr();
+               sh = newElf64SHdr(".gosymtab");
                sh->type = SHT_PROGBITS;
                sh->off = fo;
                sh->size = w;
                sh->addralign = 1;
                sh->entsize = 24;
-               elf64shdr(".gosymtab", sh);
 
                fo += w;
                w = lcsize;
 
-               sh = newElf64SHdr();
+               sh = newElf64SHdr(".gopclntab");
                sh->type = SHT_PROGBITS;
                sh->off = fo;
                sh->size = w;
                sh->addralign = 1;
                sh->entsize = 24;
-               elf64shdr(".gopclntab", sh);
+
+               // write out the main header */
+               strnput("\177ELF", 4);          /* e_ident */
+               cput(2);                        /* class = 64 bit */
+               cput(1);                        /* data = LSB */
+               cput(1);                        /* version = CURRENT */
+               strnput("", 9);
+
+               wputl(2);                       /* type = EXEC */
+               wputl(62);                      /* machine = AMD64 */
+               lputl(1L);                      /* version = CURRENT */
+               vputl(entryvalue());            /* entry vaddr */
+               vputl(64L);                     /* offset to first phdr */
+               vputl(64L+56*nume64phdr);               /* offset to first shdr */
+               lputl(0L);                      /* processor specific flags */
+               wputl(64);                      /* Ehdr size */
+               wputl(56);                      /* Phdr size */
+               wputl(nume64phdr);                      /* # of Phdrs */
+               wputl(64);                      /* Shdr size */
+               wputl(nume64shdr);                      /* # of Shdrs */
+               wputl(4);                       /* Shdr with strings */
+
+               elf64writephdrs();
+               elf64writeshdrs();
+               cflush();
+
+               /* string table */
+               seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
+               elf64writestrtable();
+               cflush();
 
                break;
        }
index ba30f655228ab566979f6308692becdb30b1a451..647becd97d291db71b3e4e6b602e6ca1d69e4618 100644 (file)
@@ -6,6 +6,15 @@
 
 #include "../ld/elf64.h"
 
+#define        NSECT   16
+int    nume64phdr;
+int    nume64shdr;
+int    nume64str;
+static Elf64PHdr       *phdr[NSECT];
+static Elf64SHdr       *shdr[NSECT];
+static char    *sname[NSECT];
+static char    *str[NSECT];
+
 void
 elf64phdr(Elf64PHdr *e)
 {
@@ -32,9 +41,6 @@ elf64shdr(char *name, Elf64SHdr *e)
        lputl(e->info);
        vputl(e->addralign);
        vputl(e->entsize);
-
-       if(name != nil)
-               stroffset += strlen(name)+1;
 }
 
 int
@@ -47,25 +53,29 @@ putelf64strtab(char* name)
        return w;
 }
 
-
-int
-elf64strtable(void)
+void
+elf64writestrtable(void)
 {
+       int i;
        int size;
 
        size = 0;
-       size += putelf64strtab("");
-       size += putelf64strtab(".text");
-       size += putelf64strtab(".data");
-       size += putelf64strtab(".bss");
-       size += putelf64strtab(".shstrtab");
-       if (!debug['s']) {
-               size += putelf64strtab(".gosymtab");
-               size += putelf64strtab(".gopclntab");
-       }
-       return size;
+       for (i = 0; i < nume64str; i++)
+               size += putelf64strtab(str[i]);
+       if (size > STRTABSIZE)
+               diag("elf64 string table overflow");
 }
 
+void
+e64addstr(char *name)
+{
+       if (nume64str >= NSECT) {
+               diag("too many elf strings");
+               return;
+       }
+       str[nume64str++] = strdup(name);
+       stroffset += strlen(name)+1;
+}
 
 uint32
 elf64headr(void)
@@ -74,6 +84,7 @@ elf64headr(void)
 
        a = 64;         /* a.out header */
 
+       /* TODO: calculate these byte counts properly */
        a += 56;        /* page zero seg */
        a += 56;        /* text seg */
        a += 56;        /* stack seg */
@@ -92,25 +103,51 @@ elf64headr(void)
        return a;
 }
 
-Elf64SHdr*
-newElf64SHdr()
+void
+elf64writeshdrs(void)
 {
-       Elf64SHdr *e;
+       int i;
 
-       e = malloc(sizeof *e);
-       memset(e, 0, sizeof *e);
-       e->name = stroffset;
-       return e;
+       for (i = 0; i < nume64shdr; i++)
+               elf64shdr(sname[i], shdr[i]);
 }
 
+void
+elf64writephdrs(void)
+{
+       int i;
+
+       for (i = 0; i < nume64phdr; i++)
+               elf64phdr(phdr[i]);
+}
 
 Elf64PHdr*
-newElf64PHdr()
+newElf64PHdr(void)
 {
        Elf64PHdr *e;
 
        e = malloc(sizeof *e);
        memset(e, 0, sizeof *e);
+       if (nume64phdr >= NSECT)
+               diag("too many phdrs");
+       else
+               phdr[nume64phdr++] = e;
        return e;
 }
 
+Elf64SHdr*
+newElf64SHdr(char *name)
+{
+       Elf64SHdr *e;
+
+       e = malloc(sizeof *e);
+       memset(e, 0, sizeof *e);
+       e->name = stroffset;
+       if (nume64shdr >= NSECT) {
+               diag("too many shdrs");
+       } else {
+               e64addstr(name);
+               shdr[nume64shdr++] = e;
+       }
+       return e;
+}
index 07d3cd68a6fed0a70ff8c2cb1b8c35a84d5be3b4..34348a1dbc80d8fa80baa4bc2e7ee17f3fe02d23 100644 (file)
@@ -132,9 +132,14 @@ struct Elf64SHdr
 #define        SHF_MASKOS      0x0F000000      /* Environment-specific use */
 #define        SHF_MASKPROC    0xF0000000      /* Processor-specific use */
 
-Elf64SHdr      *newElf64SHdr();
+Elf64SHdr      *newElf64SHdr(char*);
 Elf64PHdr      *newElf64PHdr();
 uint32 elf64headr(void);
-void   elf64phdr(Elf64PHdr*);
-void   elf64shdr(char*, Elf64SHdr*);
-int    elf64strtable(void);
+void   elf64writephdrs(void);
+void   elf64writeshdrs(void);
+void   elf64writestrtable(void);
+
+extern int     nume64phdr;
+extern int     nume64shdr;
+
+#define        STRTABSIZE      256