This source file includes following definitions.
- formathdr
 
- dumpobj
 
- dumpglobls
 
- Bputname
 
- linksym
 
- duintxx
 
- duint8
 
- duint16
 
- duint32
 
- duint64
 
- duintptr
 
- stringsym
 
- slicebytes
 
#include <u.h>
#include <libc.h>
#include "go.h"
static  void    dumpglobls(void);
enum
{
        ArhdrSize = 60
};
static void
formathdr(char *arhdr, char *name, vlong size)
{
        snprint(arhdr, ArhdrSize, "%-16s%-12d%-6d%-6d%-8o%-10lld`",
                name, 0, 0, 0, 0644, size);
        arhdr[ArhdrSize-1] = '\n'; 
}
void
dumpobj(void)
{
        NodeList *externs, *tmp;
        char arhdr[ArhdrSize];
        vlong startobj, size;
        Sym *zero;
        bout = Bopen(outfile, OWRITE);
        if(bout == nil) {
                flusherrors();
                print("can't create %s: %r\n", outfile);
                errorexit();
        }
        startobj = 0;
        if(writearchive) {
                Bwrite(bout, "!<arch>\n", 8);
                memset(arhdr, 0, sizeof arhdr);
                Bwrite(bout, arhdr, sizeof arhdr);
                startobj = Boffset(bout);
        }
        Bprint(bout, "go object %s %s %s %s\n", getgoos(), getgoarch(), getgoversion(), expstring());
        dumpexport();
        
        if(writearchive) {
                Bflush(bout);
                size = Boffset(bout) - startobj;
                if(size&1)
                        Bputc(bout, 0);
                Bseek(bout, startobj - ArhdrSize, 0);
                formathdr(arhdr, "__.PKGDEF", size);
                Bwrite(bout, arhdr, ArhdrSize);
                Bflush(bout);
                Bseek(bout, startobj + size + (size&1), 0);
                memset(arhdr, 0, ArhdrSize);
                Bwrite(bout, arhdr, ArhdrSize);
                startobj = Boffset(bout);
                Bprint(bout, "go object %s %s %s %s\n", getgoos(), getgoarch(), getgoversion(), expstring());
        }
        Bprint(bout, "\n!\n");
        externs = nil;
        if(externdcl != nil)
                externs = externdcl->end;
        dumpglobls();
        dumptypestructs();
        
        tmp = externdcl;
        if(externs != nil)
                externdcl = externs->next;
        dumpglobls();
        externdcl = tmp;
        zero = pkglookup("zerovalue", runtimepkg);
        ggloblsym(zero, zerosize, 1, 1);
        dumpdata();
        writeobj(ctxt, bout);
        if(writearchive) {
                Bflush(bout);
                size = Boffset(bout) - startobj;
                if(size&1)
                        Bputc(bout, 0);
                Bseek(bout, startobj - ArhdrSize, 0);
                snprint(namebuf, sizeof namebuf, "_go_.%c", thechar);
                formathdr(arhdr, namebuf, size);
                Bwrite(bout, arhdr, ArhdrSize);
        }
        Bterm(bout);
}
static void
dumpglobls(void)
{
        Node *n;
        NodeList *l;
        
        for(l=externdcl; l; l=l->next) {
                n = l->n;
                if(n->op != ONAME)
                        continue;
                if(n->type == T)
                        fatal("external %N nil type\n", n);
                if(n->class == PFUNC)
                        continue;
                if(n->sym->pkg != localpkg)
                        continue;
                dowidth(n->type);
                ggloblnod(n);
        }
        
        for(l=funcsyms; l; l=l->next) {
                n = l->n;
                dsymptr(n->sym, 0, n->sym->def->shortname->sym, 0);
                ggloblsym(n->sym, widthptr, 1, 1);
        }
        
        
        funcsyms = nil;
}
void
Bputname(Biobuf *b, LSym *s)
{
        Bwrite(b, s->name, strlen(s->name)+1);
}
LSym*
linksym(Sym *s)
{
        char *p;
        if(s == nil)
                return nil;
        if(s->lsym != nil)
                return s->lsym;
        if(isblanksym(s))
                s->lsym = linklookup(ctxt, "_", 0);
        else {
                p = smprint("%s.%s", s->pkg->prefix, s->name);
                s->lsym = linklookup(ctxt, p, 0);
                free(p);
        }
        return s->lsym; 
}
int
duintxx(Sym *s, int off, uint64 v, int wid)
{
        
        
        
        off = rnd(off, wid);
        return setuintxx(ctxt, linksym(s), off, v, wid);
}
int
duint8(Sym *s, int off, uint8 v)
{
        return duintxx(s, off, v, 1);
}
int
duint16(Sym *s, int off, uint16 v)
{
        return duintxx(s, off, v, 2);
}
int
duint32(Sym *s, int off, uint32 v)
{
        return duintxx(s, off, v, 4);
}
int
duint64(Sym *s, int off, uint64 v)
{
        return duintxx(s, off, v, 8);
}
int
duintptr(Sym *s, int off, uint64 v)
{
        return duintxx(s, off, v, widthptr);
}
Sym*
stringsym(char *s, int len)
{
        static int gen;
        Sym *sym;
        int off, n, m;
        struct {
                Strlit lit;
                char buf[110];
        } tmp;
        Pkg *pkg;
        if(len > 100) {
                
                snprint(namebuf, sizeof(namebuf), ".gostring.%d", ++gen);
                pkg = localpkg;
        } else {
                
                
                
                tmp.lit.len = len;
                memmove(tmp.lit.s, s, len);
                tmp.lit.s[len] = '\0';
                snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp.lit);
                pkg = gostringpkg;
        }
        sym = pkglookup(namebuf, pkg);
        
        
        if(sym->flags & SymUniq)
                return sym;
        sym->flags |= SymUniq;
        sym->def = newname(sym);
        off = 0;
        
        
        off = dsymptr(sym, off, sym, widthptr+widthint);
        off = duintxx(sym, off, len, widthint);
        
        
        for(n=0; n<len; n+=m) {
                m = 8;
                if(m > len-n)
                        m = len-n;
                off = dsname(sym, off, s+n, m);
        }
        off = duint8(sym, off, 0);  
        off = (off+widthptr-1)&~(widthptr-1);  
        ggloblsym(sym, off, 1, 1);
        return sym;     
}
void
slicebytes(Node *nam, char *s, int len)
{
        int off, n, m;
        static int gen;
        Sym *sym;
        snprint(namebuf, sizeof(namebuf), ".gobytes.%d", ++gen);
        sym = pkglookup(namebuf, localpkg);
        sym->def = newname(sym);
        off = 0;
        for(n=0; n<len; n+=m) {
                m = 8;
                if(m > len-n)
                        m = len-n;
                off = dsname(sym, off, s+n, m);
        }
        ggloblsym(sym, off, 0, 0);
        
        if(nam->op != ONAME)
                fatal("slicebytes %N", nam);
        off = nam->xoffset;
        off = dsymptr(nam->sym, off, sym, 0);
        off = duintxx(nam->sym, off, len, widthint);
        duintxx(nam->sym, off, len, widthint);
}