]> Cypherpunks repositories - gostls13.git/commitdiff
make 8l generate Darwin Mach-O and Linux ELF binaries
authorRuss Cox <rsc@golang.org>
Fri, 20 Mar 2009 21:22:59 +0000 (14:22 -0700)
committerRuss Cox <rsc@golang.org>
Fri, 20 Mar 2009 21:22:59 +0000 (14:22 -0700)
R=ken
OCL=26584
CL=26589

src/cmd/8l/asm.c
src/cmd/8l/l.h
src/cmd/8l/obj.c
src/cmd/8l/span.c

index ecf84b7bd98a748dfc26bcee4c604e6549724586..8dd444afa5cfa70605adf9ba5edb81d02676d1de 100644 (file)
 
 #define        Dbufslop        100
 
+uint32 symdatva = 0x99<<24;
+uint32 stroffset;
+uint32 strtabsize;
+
+uint32 machheadr(void);
+uint32         elfheadr(void);
+void           elfphdr(int type, int flags, uint32 foff, uint32 vaddr, uint32 paddr, uint32 filesize, uint32 memsize, uint32 align);
+void           elfshdr(char *name, uint32 type, uint32 flags, uint32 addr, uint32 off, uint32 size, uint32 link, uint32 info, uint32 align, uint32 entsize);
+int            elfstrtable(void);
+void           machdylink(void);
+uint32         machheadr(void);
+void           machsect(char *name, char *seg, vlong addr, vlong size, uint32 off, uint32 align, uint32 reloc, uint32 nreloc, uint32 flag);
+void           machseg(char *name, uint32 vaddr, uint32 vsize, uint32 foff, uint32 fsize, uint32 prot1, uint32 prot2, uint32 nsect, uint32 flag);
+void           machstack(vlong e);
+void           machsymseg(uint32 foffset, uint32 fsize);
+
 int32
 entryvalue(void)
 {
@@ -57,25 +73,64 @@ entryvalue(void)
 }
 
 void
-wput(ushort w)
+wputl(ushort w)
 {
        cput(w);
        cput(w>>8);
 }
 
 void
-wputb(ushort w)
+wput(ushort w)
 {
        cput(w>>8);
        cput(w);
 }
 
+void
+lput(int32 l)
+{
+       cput(l>>24);
+       cput(l>>16);
+       cput(l>>8);
+       cput(l);
+}
+
+void
+lputl(int32 l)
+{
+       cput(l);
+       cput(l>>8);
+       cput(l>>16);
+       cput(l>>24);
+}
+
+void
+vputl(uvlong l)
+{
+       lputl(l >> 32);
+       lputl(l);
+}
+
+void
+strnput(char *s, int n)
+{
+       for(; *s && n > 0; s++) {
+               cput(*s);
+               n--;
+       }
+       while(n > 0) {
+               cput(0);
+               n--;
+       }
+}
+
 void
 asmb(void)
 {
        Prog *p;
        int32 v, magic;
-       int a;
+       int a, np, nl, ns;
+       uint32 va, fo, w, symo;
        uchar *op1;
 
        if(debug['v'])
@@ -134,6 +189,23 @@ asmb(void)
        case 4:
                seek(cout, HEADR+rnd(textsize, INITRND), 0);
                break;
+       case 6:
+               v = HEADR+textsize;
+               seek(cout, v, 0);
+               v = rnd(v, 4096) - v;
+               while(v > 0) {
+                       cput(0);
+                       v--;
+               }
+               cflush();
+               break;
+       case 7:
+               seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
+               strtabsize = elfstrtable();
+               cflush();
+               v = rnd(HEADR+textsize, INITRND);
+               seek(cout, v, 0);
+               break;
        }
 
        if(debug['v'])
@@ -157,6 +229,7 @@ asmb(void)
        symsize = 0;
        spsize = 0;
        lcsize = 0;
+       symo = 0;
        if(!debug['s']) {
                if(debug['v'])
                        Bprint(&bso, "%5.2f sym\n", cputime());
@@ -175,8 +248,17 @@ asmb(void)
                case 3:
                case 4:
                        debug['s'] = 1;
+                       symo = HEADR+textsize+datsize;
+                       break;
+               case 6:
+                       symo = rnd(HEADR+textsize, INITRND)+rnd(datsize, INITRND);
+                       break;
+               case 7:
+                       symo = rnd(HEADR+textsize, INITRND)+datsize+strtabsize;
+                       symo = rnd(symo, INITRND);
                        break;
                }
+               seek(cout, symo+8, 0);
                if(!debug['s'])
                        asmsym();
                if(debug['v'])
@@ -190,6 +272,10 @@ asmb(void)
                if(dlm)
                        asmdyn();
                cflush();
+               seek(cout, symo, 0);
+               lputl(symsize);
+               lputl(lcsize);
+               cflush();
        }
        else if(dlm){
                seek(cout, HEADR+textsize+datsize, 0);
@@ -311,45 +397,272 @@ asmb(void)
        case 4:
                /* fake MS-DOS .EXE */
                v = rnd(HEADR+textsize, INITRND)+datsize;
-               wput(0x5A4D);                   /* 'MZ' */
-               wput(v % 512);                  /* bytes in last page */
-               wput(rnd(v, 512)/512);          /* total number of pages */
-               wput(0x0000);                   /* number of reloc items */
+               wputl(0x5A4D);                  /* 'MZ' */
+               wputl(v % 512);                 /* bytes in last page */
+               wputl(rnd(v, 512)/512);         /* total number of pages */
+               wputl(0x0000);                  /* number of reloc items */
                v = rnd(HEADR-(INITTEXT & 0xFFFF), 16);
-               wput(v/16);                     /* size of header */
-               wput(0x0000);                   /* minimum allocation */
-               wput(0xFFFF);                   /* maximum allocation */
-               wput(0x0000);                   /* initial ss value */
-               wput(0x0100);                   /* initial sp value */
-               wput(0x0000);                   /* complemented checksum */
+               wputl(v/16);                    /* size of header */
+               wputl(0x0000);                  /* minimum allocation */
+               wputl(0xFFFF);                  /* maximum allocation */
+               wputl(0x0000);                  /* initial ss value */
+               wputl(0x0100);                  /* initial sp value */
+               wputl(0x0000);                  /* complemented checksum */
                v = entryvalue();
-               wput(v);                        /* initial ip value (!) */
-               wput(0x0000);                   /* initial cs value */
-               wput(0x0000);
-               wput(0x0000);
-               wput(0x003E);                   /* reloc table offset */
-               wput(0x0000);                   /* overlay number */
+               wputl(v);                       /* initial ip value (!) */
+               wputl(0x0000);                  /* initial cs value */
+               wputl(0x0000);
+               wputl(0x0000);
+               wputl(0x003E);                  /* reloc table offset */
+               wputl(0x0000);                  /* overlay number */
                break;
-       }
-       cflush();
-}
+       
+       case 6:
+               /* apple MACH */
+               va = 4096;
 
-void
-lput(int32 l)
-{
-       cput(l>>24);
-       cput(l>>16);
-       cput(l>>8);
-       cput(l);
-}
+               lputl(0xfeedface);              /* 32-bit */
+               lputl(7);               /* cputype - x86 */
+               lputl(3);                       /* subtype - x86 */
+               lputl(2);                       /* file type - mach executable */
+               nl = 4;
+               if (!debug['s'])
+                       nl += 3;
+               if (!debug['d'])        // -d = turn off "dynamic loader"
+                       nl += 3;
+               lputl(nl);                      /* number of loads */
+               lputl(machheadr()-28);          /* size of loads */
+               lputl(1);                       /* flags - no undefines */
 
-void
-lputl(int32 l)
-{
-       cput(l);
-       cput(l>>8);
-       cput(l>>16);
-       cput(l>>24);
+               machseg("__PAGEZERO",
+                       0,va,                   /* vaddr vsize */
+                       0,0,                    /* fileoffset filesize */
+                       0,0,                    /* protects */
+                       0,0);                   /* sections flags */
+
+               v = rnd(HEADR+textsize, INITRND);
+               machseg("__TEXT",
+                       va,                     /* vaddr */
+                       v,                      /* vsize */
+                       0,v,                    /* fileoffset filesize */
+                       7,5,                    /* protects */
+                       1,0);                   /* sections flags */
+               machsect("__text", "__TEXT",
+                       va+HEADR,v-HEADR,       /* addr size */
+                       HEADR,0,0,0,            /* offset align reloc nreloc */
+                       0|0x400);               /* flag - some instructions */
+
+               w = datsize+bsssize;
+               machseg("__DATA",
+                       va+v,                   /* vaddr */
+                       w,                      /* vsize */
+                       v,datsize,              /* fileoffset filesize */
+                       7,3,                    /* protects */
+                       2,0);                   /* sections flags */
+               machsect("__data", "__DATA",
+                       va+v,datsize,           /* addr size */
+                       v,0,0,0,                /* offset align reloc nreloc */
+                       0);                     /* flag */
+               machsect("__bss", "__DATA",
+                       va+v+datsize,bsssize,   /* addr size */
+                       0,0,0,0,                /* offset align reloc nreloc */
+                       1);                     /* flag - zero fill */
+
+               machdylink();
+               machstack(entryvalue());
+
+               if (!debug['s']) {
+                       machseg("__SYMDAT",
+                               symdatva,               /* vaddr */
+                               8+symsize+lcsize,               /* vsize */
+                               symo, 8+symsize+lcsize, /* fileoffset filesize */
+                               7, 5,                   /* protects */
+                               0, 0);                  /* sections flags */
+
+                       machsymseg(symo+8,symsize);     /* fileoffset,filesize */
+                       machsymseg(symo+8+symsize,lcsize);      /* fileoffset,filesize */
+               }
+               break;
+
+       case 7:
+               np = 3;
+               ns = 5;
+               if(!debug['s']) {
+                       np++;
+                       ns += 2;
+               }
+
+               /* ELF header */
+               strnput("\177ELF", 4);          /* e_ident */
+               cput(1);                        /* class = 32 bit */
+               cput(1);                        /* data = LSB */
+               cput(1);                        /* version = CURRENT */
+               strnput("", 9);
+               wputl(2);                       /* type = EXEC */
+               wputl(3);                       /* machine = AMD64 */
+               lputl(1L);                      /* version = CURRENT */
+               lputl(entryvalue());            /* entry vaddr */
+               lputl(52L);                     /* offset to first phdr */
+               lputl(52L+32L*np);              /* offset to first shdr */
+               lputl(0L);                      /* processor specific flags */
+               wputl(52L);                     /* Ehdr size */
+               wputl(32L);                     /* Phdr size */
+               wputl(np);                      /* # of Phdrs */
+               wputl(40L);                     /* Shdr size */
+               wputl(ns);                      /* # of Shdrs */
+               wputl(4);                       /* Shdr with strings */
+
+               /* prog headers */
+               fo = 0;
+               va = INITTEXT & ~((vlong)INITRND - 1);
+               w = HEADR+textsize;
+
+               elfphdr(1,                      /* text - type = PT_LOAD */
+                       1L+4L,                  /* text - flags = PF_X+PF_R */
+                       0,                      /* file offset */
+                       va,                     /* vaddr */
+                       va,                     /* paddr */
+                       w,                      /* file size */
+                       w,                      /* memory size */
+                       INITRND);               /* alignment */
+
+               fo = rnd(fo+w, INITRND);
+               va = rnd(va+w, INITRND);
+               w = datsize;
+
+               elfphdr(1,                      /* data - type = PT_LOAD */
+                       2L+4L,                  /* data - flags = PF_W+PF_R */
+                       fo,                     /* file offset */
+                       va,                     /* vaddr */
+                       va,                     /* paddr */
+                       w,                      /* file size */
+                       w+bsssize,              /* memory size */
+                       INITRND);               /* alignment */
+
+               if(!debug['s']) {
+                       elfphdr(1,                      /* data - type = PT_LOAD */
+                               2L+4L,                  /* data - flags = PF_W+PF_R */
+                               symo,           /* file offset */
+                               symdatva,                       /* vaddr */
+                               symdatva,                       /* paddr */
+                               8+symsize+lcsize,                       /* file size */
+                               8+symsize+lcsize,               /* memory size */
+                               INITRND);               /* alignment */
+               }
+
+               elfphdr(0x6474e551,             /* gok - type = gok */
+                       1L+2L+4L,               /* gok - flags = PF_X+PF_W+PF_R */
+                       0,                      /* file offset */
+                       0,                      /* vaddr */
+                       0,                      /* paddr */
+                       0,                      /* file size */
+                       0,                      /* memory size */
+                       8);                     /* alignment */
+
+               /* segment headers */
+               elfshdr(nil,                    /* name */
+                       0,                      /* type */
+                       0,                      /* flags */
+                       0,                      /* addr */
+                       0,                      /* off */
+                       0,                      /* size */
+                       0,                      /* link */
+                       0,                      /* info */
+                       0,                      /* align */
+                       0);                     /* entsize */
+
+               stroffset = 1;  /* 0 means no name, so start at 1 */
+               fo = HEADR;
+               va = (INITTEXT & ~((vlong)INITRND - 1)) + HEADR;
+               w = textsize;
+
+               elfshdr(".text",                /* name */
+                       1,                      /* type */
+                       6,                      /* flags */
+                       va,                     /* addr */
+                       fo,                     /* off */
+                       w,                      /* size */
+                       0,                      /* link */
+                       0,                      /* info */
+                       8,                      /* align */
+                       0);                     /* entsize */
+
+               fo = rnd(fo+w, INITRND);
+               va = rnd(va+w, INITRND);
+               w = datsize;
+
+               elfshdr(".data",                /* name */
+                       1,                      /* type */
+                       3,                      /* flags */
+                       va,                     /* addr */
+                       fo,                     /* off */
+                       w,                      /* size */
+                       0,                      /* link */
+                       0,                      /* info */
+                       8,                      /* align */
+                       0);                     /* entsize */
+
+               fo += w;
+               va += w;
+               w = bsssize;
+
+               elfshdr(".bss",         /* name */
+                       8,                      /* type */
+                       3,                      /* flags */
+                       va,                     /* addr */
+                       fo,                     /* off */
+                       w,                      /* size */
+                       0,                      /* link */
+                       0,                      /* info */
+                       8,                      /* align */
+                       0);                     /* entsize */
+
+               w = strtabsize;
+
+               elfshdr(".shstrtab",            /* name */
+                       3,                      /* type */
+                       0,                      /* flags */
+                       0,                      /* addr */
+                       fo,                     /* off */
+                       w,                      /* size */
+                       0,                      /* link */
+                       0,                      /* info */
+                       1,                      /* align */
+                       0);                     /* entsize */
+
+               if (debug['s'])
+                       break;
+
+               fo = symo+8;
+               w = symsize;
+
+               elfshdr(".gosymtab",            /* name */
+                       1,                      /* type 1 = SHT_PROGBITS */
+                       0,                      /* flags */
+                       0,                      /* addr */
+                       fo,                     /* off */
+                       w,                      /* size */
+                       0,                      /* link */
+                       0,                      /* info */
+                       1,                      /* align */
+                       24);                    /* entsize */
+
+               fo += w;
+               w = lcsize;
+
+               elfshdr(".gopclntab",           /* name */
+                       1,                      /* type 1 = SHT_PROGBITS*/
+                       0,                      /* flags */
+                       0,                      /* addr */
+                       fo,                     /* off */
+                       w,                      /* size */
+                       0,                      /* link */
+                       0,                      /* info */
+                       1,                      /* align */
+                       24);                    /* entsize */
+               break;
+       }
+       cflush();
 }
 
 void
@@ -530,3 +843,218 @@ rnd(int32 v, int32 r)
        v -= c;
        return v;
 }
+
+void
+machseg(char *name, uint32 vaddr, uint32 vsize, uint32 foff, uint32 fsize,
+       uint32 prot1, uint32 prot2, uint32 nsect, uint32 flag)
+{
+       lputl(1);       /* segment 32 */
+       lputl(56 + 68*nsect);
+       strnput(name, 16);
+       lputl(vaddr);
+       lputl(vsize);
+       lputl(foff);
+       lputl(fsize);
+       lputl(prot1);
+       lputl(prot2);
+       lputl(nsect);
+       lputl(flag);
+}
+
+void
+machsymseg(uint32 foffset, uint32 fsize)
+{
+       lputl(3);       /* obsolete gdb debug info */
+       lputl(16);      /* size of symseg command */
+       lputl(foffset);
+       lputl(fsize);
+}
+
+void
+machsect(char *name, char *seg, vlong addr, vlong size, uint32 off,
+       uint32 align, uint32 reloc, uint32 nreloc, uint32 flag)
+{
+       strnput(name, 16);
+       strnput(seg, 16);
+       lputl(addr);
+       lputl(size);
+       lputl(off);
+       lputl(align);
+       lputl(reloc);
+       lputl(nreloc);
+       lputl(flag);
+       lputl(0);       /* reserved */
+       lputl(0);       /* reserved */
+}
+
+// Emit a section requesting the dynamic loader
+// but giving it no work to do (an empty dynamic symbol table).
+// This is enough to make the Apple tracing programs (like dtrace)
+// accept the binary, so that one can run dtruss on an 8.out.
+void
+machdylink(void)
+{
+       int i;
+
+       if(debug['d'])
+               return;
+
+       lputl(2);       /* LC_SYMTAB */
+       lputl(24);      /* byte count - 6 words*/
+       for(i=0; i<4; i++)
+               lputl(0);
+
+       lputl(11);      /* LC_DYSYMTAB */
+       lputl(80);      /* byte count - 20 words */
+       for(i=0; i<18; i++)
+               lputl(0);
+
+       lputl(14);      /* LC_LOAD_DYLINKER */
+       lputl(32);      /* byte count */
+       lputl(12);      /* offset to string */
+       strnput("/usr/lib/dyld", 32-12);
+}
+
+void
+machstack(vlong e)
+{
+       int i;
+
+       lputl(5);                       /* unix thread */
+       lputl((16+4)*4);                /* total byte count */
+
+       lputl(1);                       /* thread type - x86_THREAD_STATE32 */
+       lputl(16);                      /* word count */
+
+       for(i=0; i<16; i++)     /* initial register set */
+               if(i == 10)
+                       lputl(e);
+               else
+                       lputl(0);
+}
+
+uint32
+machheadr(void)
+{
+       uint32 a;
+       enum {
+               Header = 28,
+               Seg = 56,
+               Sect = 68,
+               Symtab = 24,
+               Dysymtab = 80,
+               LoadDylinker = 32,
+               Stack = 80,
+               Symseg = 16,
+       };
+
+       a = Header;             /* a.out header */
+       a += Seg;       /* page zero seg */
+       a += Seg;       /* text seg */
+       a += Sect;      /* text sect */
+       a += Seg;       /* data seg */
+       a += Sect;      /* data sect */
+       a += Sect;      /* bss sect */
+       if (!debug['d']) {
+               a += Symtab;    /* symtab */
+               a += Dysymtab;  /* dysymtab */
+               a += LoadDylinker;      /* load dylinker */
+       }
+       a += Stack;     /* stack sect */
+       if (!debug['s']) {
+               a += Seg;       /* symdat seg */
+               a += Symseg;    /* symtab seg */
+               a += Symseg;    /* lctab seg */
+       }
+
+       return a;
+}
+
+uint32
+elfheadr(void)
+{
+       uint32 a;
+
+       a = 52;         /* elf header */
+
+       a += 32;        /* page zero seg */
+       a += 32;        /* text seg */
+       a += 32;        /* stack seg */
+
+       a += 40;        /* nil sect */
+       a += 40;        /* .text sect */
+       a += 40;        /* .data seg */
+       a += 40;        /* .bss sect */
+       a += 40;        /* .shstrtab sect - strings for headers */
+       if (!debug['s']) {
+               a += 32;        /* symdat seg */
+               a += 40;        /* .gosymtab sect */
+               a += 40;        /* .gopclntab sect */
+       }
+
+       return a;
+}
+
+
+void
+elfphdr(int type, int flags, uint32 foff,
+       uint32 vaddr, uint32 paddr,
+       uint32 filesize, uint32 memsize, uint32 align)
+{
+
+       lputl(type);                    /* text - type = PT_LOAD */
+       lputl(foff);                    /* file offset */
+       lputl(vaddr);                   /* vaddr */
+       lputl(paddr);                   /* paddr */
+       lputl(filesize);                /* file size */
+       lputl(memsize);         /* memory size */
+       lputl(flags);                   /* text - flags = PF_X+PF_R */
+       lputl(align);                   /* alignment */
+}
+
+void
+elfshdr(char *name, uint32 type, uint32 flags, uint32 addr, uint32 off,
+       uint32 size, uint32 link, uint32 info, uint32 align, uint32 entsize)
+{
+       lputl(stroffset);
+       lputl(type);
+       lputl(flags);
+       lputl(addr);
+       lputl(off);
+       lputl(size);
+       lputl(link);
+       lputl(info);
+       lputl(align);
+       lputl(entsize);
+
+       if(name != nil)
+               stroffset += strlen(name)+1;
+}
+
+int
+putstrtab(char* name)
+{
+       int w;
+
+       w = strlen(name)+1;
+       strnput(name, w);
+       return w;
+}
+
+int
+elfstrtable(void)
+{
+       int size;
+
+       size = 0;
+       size += putstrtab("");
+       size += putstrtab(".text");
+       size += putstrtab(".data");
+       size += putstrtab(".bss");
+       size += putstrtab(".shstrtab");
+       if (!debug['s']) {
+               size += putstrtab(".gosymtab");
+               size += putstrtab(".gopclntab");
+       }
+       return size;
+}
index ed752125b3a89946c1ecf297d47ed4bd34e26de5..fabf8903417580bbcc351de7000b265e8c164dde 100644 (file)
@@ -365,11 +365,19 @@ void      span(void);
 void   undef(void);
 void   undefsym(Sym*);
 int32  vaddr(Adr*);
-void   wputb(ushort);
+void   wput(ushort);
 void   xdefine(char*, int, int32);
 void   xfol(Prog*);
 int    zaddr(uchar*, Adr*, Sym*[]);
 void   zerosig(char*);
+uint32 machheadr(void);
+uint32 elfheadr(void);
+void   whatsys(void);
+
+/* set by call to whatsys() */
+extern char*   goroot;
+extern char*   goarch;
+extern char*   goos;
 
 #pragma        varargck        type    "D"     Adr*
 #pragma        varargck        type    "P"     Prog*
index 388c300975d6c6f4de55213b0ec1f14b70c2ebcb..a1d14318dda4f0c7b1183cce6b97b92b9d2f9f63 100644 (file)
@@ -139,16 +139,22 @@ main(int argc, char *argv[])
                diag("usage: 8l [-options] objects");
                errorexit();
        }
-       if(!debug['9'] && !debug['U'] && !debug['B'])
-               debug[DEFAULT] = 1;
+
+       whatsys();      // get goroot, goarch, goos
+       if(strcmp(goarch, thestring) != 0)
+               print("goarch is not known: %s\n", goarch);
+
        if(HEADTYPE == -1) {
-               if(debug['U'])
-                       HEADTYPE = 1;
-               if(debug['B'])
-                       HEADTYPE = 2;
-               if(debug['9'])
-                       HEADTYPE = 2;
+               HEADTYPE = 2;
+               if(strcmp(goos, "linux") == 0)
+                       HEADTYPE = 7;
+               else
+               if(strcmp(goos, "darwin") == 0)
+                       HEADTYPE = 6;
+               else
+                       print("goos is not known: %sn", goos);
        }
+
        switch(HEADTYPE) {
        default:
                diag("unknown -H option");
@@ -202,6 +208,24 @@ main(int argc, char *argv[])
                if(debug['v'])
                        Bprint(&bso, "HEADR = 0x%ld\n", HEADR);
                break;
+       case 6: /* apple MACH */
+               HEADR = machheadr();
+               if(INITTEXT == -1)
+                       INITTEXT = 4096+HEADR;
+               if(INITDAT == -1)
+                       INITDAT = 0;
+               if(INITRND == -1)
+                       INITRND = 4096;
+               break;
+       case 7: /* elf32 executable */
+               HEADR = elfheadr();
+               if(INITTEXT == -1)
+                       INITTEXT = 0x08048000+HEADR;
+               if(INITDAT == -1)
+                       INITDAT = 0;
+               if(INITRND == -1)
+                       INITRND = 4096;
+               break;
        }
        if(INITDAT != 0 && INITRND != 0)
                print("warning: -D0x%lux is ignored because of -R0x%lux\n",
@@ -294,19 +318,27 @@ main(int argc, char *argv[])
        firstp = prg();
        lastp = firstp;
 
-       if(INITENTRY == 0) {
-               INITENTRY = "_main";
-               if(debug['p'])
-                       INITENTRY = "_mainp";
-               if(!debug['l'])
-                       lookup(INITENTRY, 0)->type = SXREF;
-       } else
-               lookup(INITENTRY, 0)->type = SXREF;
+       if(INITENTRY == nil) {
+               INITENTRY = mal(strlen(goarch)+strlen(goos)+10);
+               sprint(INITENTRY, "_rt0_%s_%s", goarch, goos);
+       }
+       lookup(INITENTRY, 0)->type = SXREF;
+
+       if(!debug['l']) {
+               a = mal(strlen(goroot)+strlen(goarch)+strlen(goos)+20);
+               sprint(a, "%s/lib/rt0_%s_%s.%c", goroot, goarch, goos, thechar);
+               objfile(a);
+       }
 
        while(*argv)
                objfile(*argv++);
-       if(!debug['l'])
+
+       if(!debug['l']) {
                loadlib();
+               a = mal(strlen(goroot)+strlen(goarch)+strlen(goos)+20);
+               sprint(a, "%s/lib/lib_%s_%s.a", goroot, goarch, goos);
+               objfile(a);
+       }
        firstp = firstp->link;
        if(firstp == P)
                errorexit();
index 4b1cc6b459bfda7e80a44f1f9ddc2c6558ff015c..b524c735f7a8bd88dc688ab5a5d7b8f0a225bd44 100644 (file)
@@ -1396,7 +1396,7 @@ asmdyn()
                        t++;
                }
                else if(c == 1){
-                       wputb(ra);
+                       wput(ra);
                        t += 2;
                }
                else{