mirror of
https://github.com/golang/go
synced 2024-11-25 01:08:02 -07:00
arm: fix build on android
R=kaib CC=golang-dev https://golang.org/cl/206059
This commit is contained in:
parent
fb94be55dc
commit
66cdc699b2
@ -232,10 +232,10 @@ enum as
|
|||||||
|
|
||||||
#define D_SHIFT (D_NONE+19)
|
#define D_SHIFT (D_NONE+19)
|
||||||
#define D_FPCR (D_NONE+20)
|
#define D_FPCR (D_NONE+20)
|
||||||
#define D_REGREG (D_NONE+21)
|
#define D_REGREG (D_NONE+21)
|
||||||
#define D_ADDR (D_NONE+22)
|
#define D_ADDR (D_NONE+22)
|
||||||
|
|
||||||
#define D_SBIG (D_NONE+23)
|
#define D_SBIG (D_NONE+23)
|
||||||
#define D_CONST2 (D_NONE+24)
|
#define D_CONST2 (D_NONE+24)
|
||||||
|
|
||||||
/* name */
|
/* name */
|
||||||
@ -244,6 +244,9 @@ enum as
|
|||||||
#define D_AUTO (D_NONE+5)
|
#define D_AUTO (D_NONE+5)
|
||||||
#define D_PARAM (D_NONE+6)
|
#define D_PARAM (D_NONE+6)
|
||||||
|
|
||||||
|
/* internal only */
|
||||||
|
#define D_SIZE (D_NONE+40)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this is the ranlib header
|
* this is the ranlib header
|
||||||
*/
|
*/
|
||||||
|
@ -9,6 +9,7 @@ TARG=\
|
|||||||
|
|
||||||
OFILES=\
|
OFILES=\
|
||||||
asm.$O\
|
asm.$O\
|
||||||
|
elf.$O\
|
||||||
enam.$O\
|
enam.$O\
|
||||||
lib.$O\
|
lib.$O\
|
||||||
list.$O\
|
list.$O\
|
||||||
@ -24,6 +25,7 @@ OFILES=\
|
|||||||
HFILES=\
|
HFILES=\
|
||||||
l.h\
|
l.h\
|
||||||
../5l/5.out.h\
|
../5l/5.out.h\
|
||||||
|
../ld/elf.h\
|
||||||
|
|
||||||
$(TARG): $(OFILES)
|
$(TARG): $(OFILES)
|
||||||
$(LD) -o $(TARG) -L"$(GOROOT)"/lib $(OFILES) -lbio -l9
|
$(LD) -o $(TARG) -L"$(GOROOT)"/lib $(OFILES) -lbio -l9
|
||||||
|
761
src/cmd/5l/asm.c
761
src/cmd/5l/asm.c
@ -30,11 +30,14 @@
|
|||||||
|
|
||||||
#include "l.h"
|
#include "l.h"
|
||||||
#include "../ld/lib.h"
|
#include "../ld/lib.h"
|
||||||
|
#include "../ld/elf.h"
|
||||||
|
|
||||||
int32 OFFSET;
|
int32 OFFSET;
|
||||||
|
|
||||||
static Prog *PP;
|
static Prog *PP;
|
||||||
|
|
||||||
|
char linuxdynld[] = "/lib/ld-linux.so.2";
|
||||||
|
|
||||||
int32
|
int32
|
||||||
entryvalue(void)
|
entryvalue(void)
|
||||||
{
|
{
|
||||||
@ -60,16 +63,310 @@ entryvalue(void)
|
|||||||
return s->value;
|
return s->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vlong
|
||||||
|
addstring(Sym *s, char *str)
|
||||||
|
{
|
||||||
|
int n, m;
|
||||||
|
vlong r;
|
||||||
|
Prog *p;
|
||||||
|
|
||||||
|
if(s->type == 0)
|
||||||
|
s->type = SDATA;
|
||||||
|
s->reachable = 1;
|
||||||
|
r = s->value;
|
||||||
|
n = strlen(str)+1;
|
||||||
|
while(n > 0) {
|
||||||
|
m = n;
|
||||||
|
if(m > NSNAME)
|
||||||
|
m = NSNAME;
|
||||||
|
p = newdata(s, s->value, m, D_EXTERN);
|
||||||
|
p->to.type = D_SCONST;
|
||||||
|
p->to.sval = mal(NSNAME);
|
||||||
|
memmove(p->to.sval, str, m);
|
||||||
|
s->value += m;
|
||||||
|
str += m;
|
||||||
|
n -= m;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
vlong
|
||||||
|
adduintxx(Sym *s, uint64 v, int wid)
|
||||||
|
{
|
||||||
|
vlong r;
|
||||||
|
Prog *p;
|
||||||
|
|
||||||
|
if(s->type == 0)
|
||||||
|
s->type = SDATA;
|
||||||
|
s->reachable = 1;
|
||||||
|
r = s->value;
|
||||||
|
p = newdata(s, s->value, wid, D_EXTERN);
|
||||||
|
s->value += wid;
|
||||||
|
p->to.type = D_CONST;
|
||||||
|
p->to.offset = v;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
vlong
|
||||||
|
adduint8(Sym *s, uint8 v)
|
||||||
|
{
|
||||||
|
return adduintxx(s, v, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
vlong
|
||||||
|
adduint16(Sym *s, uint16 v)
|
||||||
|
{
|
||||||
|
return adduintxx(s, v, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vlong
|
||||||
|
adduint32(Sym *s, uint32 v)
|
||||||
|
{
|
||||||
|
return adduintxx(s, v, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
vlong
|
||||||
|
adduint64(Sym *s, uint64 v)
|
||||||
|
{
|
||||||
|
return adduintxx(s, v, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
vlong
|
||||||
|
addaddr(Sym *s, Sym *t)
|
||||||
|
{
|
||||||
|
vlong r;
|
||||||
|
Prog *p;
|
||||||
|
enum { Ptrsize = 4 };
|
||||||
|
|
||||||
|
if(s->type == 0)
|
||||||
|
s->type = SDATA;
|
||||||
|
s->reachable = 1;
|
||||||
|
r = s->value;
|
||||||
|
p = newdata(s, s->value, Ptrsize, D_EXTERN);
|
||||||
|
s->value += Ptrsize;
|
||||||
|
p->to.type = D_ADDR;
|
||||||
|
p->to.index = D_EXTERN;
|
||||||
|
p->to.offset = 0;
|
||||||
|
p->to.sym = t;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
vlong
|
||||||
|
addsize(Sym *s, Sym *t)
|
||||||
|
{
|
||||||
|
vlong r;
|
||||||
|
Prog *p;
|
||||||
|
enum { Ptrsize = 4 };
|
||||||
|
|
||||||
|
if(s->type == 0)
|
||||||
|
s->type = SDATA;
|
||||||
|
s->reachable = 1;
|
||||||
|
r = s->value;
|
||||||
|
p = newdata(s, s->value, Ptrsize, D_EXTERN);
|
||||||
|
s->value += Ptrsize;
|
||||||
|
p->to.type = D_SIZE;
|
||||||
|
p->to.index = D_EXTERN;
|
||||||
|
p->to.offset = 0;
|
||||||
|
p->to.sym = t;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ElfStrEmpty,
|
||||||
|
ElfStrInterp,
|
||||||
|
ElfStrHash,
|
||||||
|
ElfStrGot,
|
||||||
|
ElfStrGotPlt,
|
||||||
|
ElfStrDynamic,
|
||||||
|
ElfStrDynsym,
|
||||||
|
ElfStrDynstr,
|
||||||
|
ElfStrRel,
|
||||||
|
ElfStrText,
|
||||||
|
ElfStrData,
|
||||||
|
ElfStrBss,
|
||||||
|
ElfStrGosymtab,
|
||||||
|
ElfStrGopclntab,
|
||||||
|
ElfStrShstrtab,
|
||||||
|
NElfStr
|
||||||
|
};
|
||||||
|
|
||||||
|
vlong elfstr[NElfStr];
|
||||||
|
|
||||||
|
void
|
||||||
|
doelf(void)
|
||||||
|
{
|
||||||
|
Sym *s, *shstrtab, *dynamic, *dynstr, *d;
|
||||||
|
int h, nsym, t;
|
||||||
|
|
||||||
|
if(!iself)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* predefine strings we need for section headers */
|
||||||
|
shstrtab = lookup(".shstrtab", 0);
|
||||||
|
shstrtab->reachable = 1;
|
||||||
|
elfstr[ElfStrEmpty] = addstring(shstrtab, "");
|
||||||
|
elfstr[ElfStrText] = addstring(shstrtab, ".text");
|
||||||
|
elfstr[ElfStrData] = addstring(shstrtab, ".data");
|
||||||
|
elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
|
||||||
|
if(!debug['s']) {
|
||||||
|
elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab");
|
||||||
|
elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab");
|
||||||
|
}
|
||||||
|
elfstr[ElfStrShstrtab] = addstring(shstrtab, ".shstrtab");
|
||||||
|
|
||||||
|
if(!debug['d']) { /* -d suppresses dynamic loader format */
|
||||||
|
elfstr[ElfStrInterp] = addstring(shstrtab, ".interp");
|
||||||
|
elfstr[ElfStrHash] = addstring(shstrtab, ".hash");
|
||||||
|
elfstr[ElfStrGot] = addstring(shstrtab, ".got");
|
||||||
|
elfstr[ElfStrGotPlt] = addstring(shstrtab, ".got.plt");
|
||||||
|
elfstr[ElfStrDynamic] = addstring(shstrtab, ".dynamic");
|
||||||
|
elfstr[ElfStrDynsym] = addstring(shstrtab, ".dynsym");
|
||||||
|
elfstr[ElfStrDynstr] = addstring(shstrtab, ".dynstr");
|
||||||
|
elfstr[ElfStrRel] = addstring(shstrtab, ".rel");
|
||||||
|
|
||||||
|
/* interpreter string */
|
||||||
|
s = lookup(".interp", 0);
|
||||||
|
s->reachable = 1;
|
||||||
|
s->type = SDATA; // TODO: rodata
|
||||||
|
|
||||||
|
/* dynamic symbol table - first entry all zeros */
|
||||||
|
s = lookup(".dynsym", 0);
|
||||||
|
s->type = SDATA;
|
||||||
|
s->reachable = 1;
|
||||||
|
s->value += ELF32SYMSIZE;
|
||||||
|
|
||||||
|
/* dynamic string table */
|
||||||
|
s = lookup(".dynstr", 0);
|
||||||
|
addstring(s, "");
|
||||||
|
dynstr = s;
|
||||||
|
|
||||||
|
/* relocation table */
|
||||||
|
s = lookup(".rel", 0);
|
||||||
|
s->reachable = 1;
|
||||||
|
s->type = SDATA;
|
||||||
|
|
||||||
|
/* global offset table */
|
||||||
|
s = lookup(".got", 0);
|
||||||
|
s->reachable = 1;
|
||||||
|
s->type = SDATA;
|
||||||
|
|
||||||
|
/* got.plt - ??? */
|
||||||
|
s = lookup(".got.plt", 0);
|
||||||
|
s->reachable = 1;
|
||||||
|
s->type = SDATA;
|
||||||
|
|
||||||
|
/* define dynamic elf table */
|
||||||
|
s = lookup(".dynamic", 0);
|
||||||
|
dynamic = s;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* relocation entries for dynld symbols
|
||||||
|
*/
|
||||||
|
nsym = 1; // sym 0 is reserved
|
||||||
|
for(h=0; h<NHASH; h++) {
|
||||||
|
for(s=hash[h]; s!=S; s=s->link) {
|
||||||
|
if(!s->reachable || (s->type != SDATA && s->type != SBSS) || s->dynldname == nil)
|
||||||
|
continue;
|
||||||
|
#if 0
|
||||||
|
d = lookup(".rel", 0);
|
||||||
|
addaddr(d, s);
|
||||||
|
adduint32(d, ELF32_R_INFO(nsym, R_386_32));
|
||||||
|
nsym++;
|
||||||
|
|
||||||
|
d = lookup(".dynsym", 0);
|
||||||
|
adduint32(d, addstring(lookup(".dynstr", 0), s->dynldname));
|
||||||
|
adduint32(d, 0); /* value */
|
||||||
|
adduint32(d, 0); /* size of object */
|
||||||
|
t = STB_GLOBAL << 4;
|
||||||
|
t |= STT_OBJECT; // works for func too, empirically
|
||||||
|
adduint8(d, t);
|
||||||
|
adduint8(d, 0); /* reserved */
|
||||||
|
adduint16(d, SHN_UNDEF); /* section where symbol is defined */
|
||||||
|
|
||||||
|
if(needlib(s->dynldlib))
|
||||||
|
elfwritedynent(dynamic, DT_NEEDED, addstring(dynstr, s->dynldlib));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hash table.
|
||||||
|
* only entries that other objects need to find when
|
||||||
|
* linking us need to be in the table. right now that is
|
||||||
|
* no entries.
|
||||||
|
*
|
||||||
|
* freebsd insists on having chains enough for all
|
||||||
|
* the local symbols, though. for now, we just lay
|
||||||
|
* down a trivial hash table with 1 bucket and a long chain,
|
||||||
|
* because no one is actually looking for our symbols.
|
||||||
|
*/
|
||||||
|
s = lookup(".hash", 0);
|
||||||
|
s->type = SDATA; // TODO: rodata
|
||||||
|
s->reachable = 1;
|
||||||
|
adduint32(s, 1); // nbucket
|
||||||
|
adduint32(s, nsym); // nchain
|
||||||
|
adduint32(s, nsym-1); // bucket 0
|
||||||
|
adduint32(s, 0); // chain 0
|
||||||
|
for(h=1; h<nsym; h++) // chain nsym-1 -> nsym-2 -> ... -> 2 -> 1 -> 0
|
||||||
|
adduint32(s, h-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* .dynamic table
|
||||||
|
*/
|
||||||
|
s = dynamic;
|
||||||
|
elfwritedynentsym(s, DT_HASH, lookup(".hash", 0));
|
||||||
|
elfwritedynentsym(s, DT_SYMTAB, lookup(".dynsym", 0));
|
||||||
|
elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE);
|
||||||
|
elfwritedynentsym(s, DT_STRTAB, lookup(".dynstr", 0));
|
||||||
|
elfwritedynentsymsize(s, DT_STRSZ, lookup(".dynstr", 0));
|
||||||
|
elfwritedynentsym(s, DT_REL, lookup(".rel", 0));
|
||||||
|
elfwritedynentsymsize(s, DT_RELSZ, lookup(".rel", 0));
|
||||||
|
elfwritedynent(s, DT_RELENT, ELF32RELSIZE);
|
||||||
|
elfwritedynent(s, DT_NULL, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vlong
|
||||||
|
datoff(vlong addr)
|
||||||
|
{
|
||||||
|
if(addr >= INITDAT)
|
||||||
|
return addr - INITDAT + rnd(HEADR+textsize, INITRND);
|
||||||
|
diag("datoff %#llx", addr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
shsym(Elf64_Shdr *sh, Sym *s)
|
||||||
|
{
|
||||||
|
sh->addr = s->value + INITDAT;
|
||||||
|
sh->off = datoff(sh->addr);
|
||||||
|
sh->size = s->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
phsh(Elf64_Phdr *ph, Elf64_Shdr *sh)
|
||||||
|
{
|
||||||
|
ph->vaddr = sh->addr;
|
||||||
|
ph->paddr = ph->vaddr;
|
||||||
|
ph->off = sh->off;
|
||||||
|
ph->filesz = sh->size;
|
||||||
|
ph->memsz = sh->size;
|
||||||
|
ph->align = sh->addralign;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
asmb(void)
|
asmb(void)
|
||||||
{
|
{
|
||||||
Prog *p;
|
Prog *p;
|
||||||
int32 t, etext;
|
int32 t, etext;
|
||||||
int np;
|
int a, dynsym;
|
||||||
vlong va, fo, w, symo;
|
uint32 va, fo, w, symo, startva;
|
||||||
int strtabsize;
|
int strtabsize;
|
||||||
vlong symdatva = SYMDATVA;
|
vlong symdatva = SYMDATVA;
|
||||||
Optab *o;
|
Optab *o;
|
||||||
|
ElfEhdr *eh;
|
||||||
|
ElfPhdr *ph, *pph;
|
||||||
|
ElfShdr *sh;
|
||||||
|
|
||||||
strtabsize = 0;
|
strtabsize = 0;
|
||||||
symo = 0;
|
symo = 0;
|
||||||
@ -135,11 +432,8 @@ asmb(void)
|
|||||||
seek(cout, OFFSET, 0);
|
seek(cout, OFFSET, 0);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
|
OFFSET = rnd(HEADR+textsize, INITRND);
|
||||||
strtabsize = linuxstrtable();
|
seek(cout, OFFSET, 0);
|
||||||
cflush();
|
|
||||||
t = rnd(HEADR+textsize, INITRND);
|
|
||||||
seek(cout, t, 0);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(dlm){
|
if(dlm){
|
||||||
@ -275,179 +569,242 @@ asmb(void)
|
|||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
/* elf arm */
|
/* elf arm */
|
||||||
strnput("\177ELF", 4); /* e_ident */
|
eh = getElfEhdr();
|
||||||
cput(1); /* class = 32 bit */
|
|
||||||
cput(1); /* data = LSB */
|
|
||||||
cput(1); /* version = CURRENT */
|
|
||||||
strnput("", 9);
|
|
||||||
|
|
||||||
wputl(2); /* type = EXEC */
|
|
||||||
wputl(40); /* machine = ARM */
|
|
||||||
lputl(1L); /* version = CURRENT */
|
|
||||||
lputl(entryvalue()); /* entry vaddr */
|
|
||||||
lputl(52L); /* offset to first phdr */
|
|
||||||
np = 3;
|
|
||||||
if(!debug['s'])
|
|
||||||
np++;
|
|
||||||
lputl(52L+32*np); /* offset to first shdr */
|
|
||||||
lputl(0L); /* processor specific flags */
|
|
||||||
wputl(52); /* Ehdr size */
|
|
||||||
wputl(32); /* Phdr size */
|
|
||||||
wputl(np); /* # of Phdrs */
|
|
||||||
wputl(40); /* Shdr size */
|
|
||||||
if (!debug['s'])
|
|
||||||
wputl(7); /* # of Shdrs */
|
|
||||||
else
|
|
||||||
wputl(5); /* # of Shdrs */
|
|
||||||
wputl(4); /* Shdr with strings */
|
|
||||||
|
|
||||||
fo = HEADR;
|
fo = HEADR;
|
||||||
va = rnd(INITTEXT, INITRND);
|
va = INITTEXT;
|
||||||
|
startva = INITTEXT - fo; /* va of byte 0 of file */
|
||||||
w = textsize;
|
w = textsize;
|
||||||
|
|
||||||
|
/* This null SHdr must appear before all others */
|
||||||
|
sh = newElfShdr(elfstr[ElfStrEmpty]);
|
||||||
|
|
||||||
linuxphdr(1, /* text - type = PT_LOAD */
|
/* program header info */
|
||||||
1L+4L, /* text - flags = PF_X+PF_R */
|
pph = newElfPhdr();
|
||||||
fo, /* file offset */
|
pph->type = PT_PHDR;
|
||||||
va, /* vaddr */
|
pph->flags = PF_R + PF_X;
|
||||||
va, /* paddr */
|
pph->off = eh->ehsize;
|
||||||
w, /* file size */
|
pph->vaddr = INITTEXT - HEADR + pph->off;
|
||||||
w, /* memory size */
|
pph->paddr = INITTEXT - HEADR + pph->off;
|
||||||
INITRND); /* alignment */
|
pph->align = INITRND;
|
||||||
|
|
||||||
fo = rnd(fo+w, INITRND);
|
if(!debug['d']) {
|
||||||
va = rnd(va+w, INITRND);
|
/* interpreter for dynamic linking */
|
||||||
w = datsize;
|
sh = newElfShdr(elfstr[ElfStrInterp]);
|
||||||
|
sh->type = SHT_PROGBITS;
|
||||||
|
sh->flags = SHF_ALLOC;
|
||||||
|
sh->addralign = 1;
|
||||||
|
elfinterp(sh, startva, linuxdynld);
|
||||||
|
|
||||||
linuxphdr(1, /* data - type = PT_LOAD */
|
ph = newElfPhdr();
|
||||||
2L+4L, /* data - flags = PF_W+PF_R */
|
ph->type = PT_INTERP;
|
||||||
fo, /* file offset */
|
ph->flags = PF_R;
|
||||||
va, /* vaddr */
|
phsh(ph, sh);
|
||||||
va, /* paddr */
|
|
||||||
w, /* file size */
|
|
||||||
w+bsssize, /* memory size */
|
|
||||||
INITRND); /* alignment */
|
|
||||||
|
|
||||||
if(!debug['s']) {
|
|
||||||
linuxphdr(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 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
linuxphdr(0x6474e551, /* gok - type = gok */
|
ph = newElfPhdr();
|
||||||
1L+2L+4L, /* gok - flags = PF_X+PF_W+PF_R */
|
ph->type = PT_LOAD;
|
||||||
0, /* file offset */
|
ph->flags = PF_X+PF_R;
|
||||||
0, /* vaddr */
|
ph->vaddr = va;
|
||||||
0, /* paddr */
|
ph->paddr = va;
|
||||||
0, /* file size */
|
ph->off = fo;
|
||||||
0, /* memory size */
|
ph->filesz = w;
|
||||||
8); /* alignment */
|
ph->memsz = w;
|
||||||
|
ph->align = INITRND;
|
||||||
linuxshdr(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 = rnd(INITTEXT, INITRND);
|
|
||||||
w = textsize;
|
|
||||||
|
|
||||||
linuxshdr(".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);
|
fo = rnd(fo+w, INITRND);
|
||||||
va = rnd(va+w, INITRND);
|
va = rnd(va+w, INITRND);
|
||||||
w = datsize;
|
w = datsize;
|
||||||
|
|
||||||
linuxshdr(".data", /* name */
|
ph = newElfPhdr();
|
||||||
1, /* type */
|
ph->type = PT_LOAD;
|
||||||
3, /* flags */
|
ph->flags = PF_W+PF_R;
|
||||||
va, /* addr */
|
ph->off = fo;
|
||||||
fo, /* off */
|
ph->vaddr = va;
|
||||||
w, /* size */
|
ph->paddr = va;
|
||||||
0, /* link */
|
ph->filesz = w;
|
||||||
0, /* info */
|
ph->memsz = w+bsssize;
|
||||||
8, /* align */
|
ph->align = INITRND;
|
||||||
0); /* entsize */
|
|
||||||
|
if(!debug['s']) {
|
||||||
|
ph = newElfPhdr();
|
||||||
|
ph->type = PT_LOAD;
|
||||||
|
ph->flags = PF_W+PF_R;
|
||||||
|
ph->off = symo;
|
||||||
|
ph->vaddr = symdatva;
|
||||||
|
ph->paddr = symdatva;
|
||||||
|
ph->filesz = 8+symsize+lcsize;
|
||||||
|
ph->memsz = 8+symsize+lcsize;
|
||||||
|
ph->align = INITRND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dynamic linking sections */
|
||||||
|
if (!debug['d']) { /* -d suppresses dynamic loader format */
|
||||||
|
/* S headers for dynamic linking */
|
||||||
|
sh = newElfShdr(elfstr[ElfStrGot]);
|
||||||
|
sh->type = SHT_PROGBITS;
|
||||||
|
sh->flags = SHF_ALLOC+SHF_WRITE;
|
||||||
|
sh->entsize = 4;
|
||||||
|
sh->addralign = 4;
|
||||||
|
shsym(sh, lookup(".got", 0));
|
||||||
|
|
||||||
|
sh = newElfShdr(elfstr[ElfStrGotPlt]);
|
||||||
|
sh->type = SHT_PROGBITS;
|
||||||
|
sh->flags = SHF_ALLOC+SHF_WRITE;
|
||||||
|
sh->entsize = 4;
|
||||||
|
sh->addralign = 4;
|
||||||
|
shsym(sh, lookup(".got.plt", 0));
|
||||||
|
|
||||||
|
dynsym = eh->shnum;
|
||||||
|
sh = newElfShdr(elfstr[ElfStrDynsym]);
|
||||||
|
sh->type = SHT_DYNSYM;
|
||||||
|
sh->flags = SHF_ALLOC;
|
||||||
|
sh->entsize = ELF32SYMSIZE;
|
||||||
|
sh->addralign = 4;
|
||||||
|
sh->link = dynsym+1; // dynstr
|
||||||
|
// sh->info = index of first non-local symbol (number of local symbols)
|
||||||
|
shsym(sh, lookup(".dynsym", 0));
|
||||||
|
|
||||||
|
sh = newElfShdr(elfstr[ElfStrDynstr]);
|
||||||
|
sh->type = SHT_STRTAB;
|
||||||
|
sh->flags = SHF_ALLOC;
|
||||||
|
sh->addralign = 1;
|
||||||
|
shsym(sh, lookup(".dynstr", 0));
|
||||||
|
|
||||||
|
sh = newElfShdr(elfstr[ElfStrHash]);
|
||||||
|
sh->type = SHT_HASH;
|
||||||
|
sh->flags = SHF_ALLOC;
|
||||||
|
sh->entsize = 4;
|
||||||
|
sh->addralign = 4;
|
||||||
|
sh->link = dynsym;
|
||||||
|
shsym(sh, lookup(".hash", 0));
|
||||||
|
|
||||||
|
sh = newElfShdr(elfstr[ElfStrRel]);
|
||||||
|
sh->type = SHT_REL;
|
||||||
|
sh->flags = SHF_ALLOC;
|
||||||
|
sh->entsize = ELF32RELSIZE;
|
||||||
|
sh->addralign = 4;
|
||||||
|
sh->link = dynsym;
|
||||||
|
shsym(sh, lookup(".rel", 0));
|
||||||
|
|
||||||
|
/* sh and PT_DYNAMIC for .dynamic section */
|
||||||
|
sh = newElfShdr(elfstr[ElfStrDynamic]);
|
||||||
|
sh->type = SHT_DYNAMIC;
|
||||||
|
sh->flags = SHF_ALLOC+SHF_WRITE;
|
||||||
|
sh->entsize = 8;
|
||||||
|
sh->addralign = 4;
|
||||||
|
sh->link = dynsym+1; // dynstr
|
||||||
|
shsym(sh, lookup(".dynamic", 0));
|
||||||
|
|
||||||
|
ph = newElfPhdr();
|
||||||
|
ph->type = PT_DYNAMIC;
|
||||||
|
ph->flags = PF_R + PF_W;
|
||||||
|
phsh(ph, sh);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Thread-local storage segment (really just size).
|
||||||
|
if(tlsoffset != 0) {
|
||||||
|
ph = newElfPhdr();
|
||||||
|
ph->type = PT_TLS;
|
||||||
|
ph->flags = PF_R;
|
||||||
|
ph->memsz = -tlsoffset;
|
||||||
|
ph->align = 4;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
ph = newElfPhdr();
|
||||||
|
ph->type = PT_GNU_STACK;
|
||||||
|
ph->flags = PF_W+PF_R;
|
||||||
|
ph->align = 4;
|
||||||
|
|
||||||
|
fo = ELFRESERVE;
|
||||||
|
va = startva + fo;
|
||||||
|
w = textsize;
|
||||||
|
|
||||||
|
sh = newElfShdr(elfstr[ElfStrText]);
|
||||||
|
sh->type = SHT_PROGBITS;
|
||||||
|
sh->flags = SHF_ALLOC+SHF_EXECINSTR;
|
||||||
|
sh->addr = va;
|
||||||
|
sh->off = fo;
|
||||||
|
sh->size = w;
|
||||||
|
sh->addralign = 4;
|
||||||
|
|
||||||
|
fo = rnd(fo+w, INITRND);
|
||||||
|
va = rnd(va+w, INITRND);
|
||||||
|
w = datsize;
|
||||||
|
|
||||||
|
sh = newElfShdr(elfstr[ElfStrData]);
|
||||||
|
sh->type = SHT_PROGBITS;
|
||||||
|
sh->flags = SHF_WRITE+SHF_ALLOC;
|
||||||
|
sh->addr = va;
|
||||||
|
sh->off = fo;
|
||||||
|
sh->size = w;
|
||||||
|
sh->addralign = 4;
|
||||||
|
|
||||||
fo += w;
|
fo += w;
|
||||||
va += w;
|
va += w;
|
||||||
w = bsssize;
|
w = bsssize;
|
||||||
|
|
||||||
linuxshdr(".bss", /* name */
|
sh = newElfShdr(elfstr[ElfStrBss]);
|
||||||
8, /* type */
|
sh->type = SHT_NOBITS;
|
||||||
3, /* flags */
|
sh->flags = SHF_WRITE+SHF_ALLOC;
|
||||||
va, /* addr */
|
sh->addr = va;
|
||||||
fo, /* off */
|
sh->off = fo;
|
||||||
w, /* size */
|
sh->size = w;
|
||||||
0, /* link */
|
sh->addralign = 4;
|
||||||
0, /* info */
|
|
||||||
8, /* align */
|
|
||||||
0); /* entsize */
|
|
||||||
|
|
||||||
w = strtabsize;
|
if (!debug['s']) {
|
||||||
|
fo = symo+8;
|
||||||
|
w = symsize;
|
||||||
|
|
||||||
linuxshdr(".shstrtab", /* name */
|
sh = newElfShdr(elfstr[ElfStrGosymtab]);
|
||||||
3, /* type */
|
sh->type = SHT_PROGBITS;
|
||||||
0, /* flags */
|
sh->off = fo;
|
||||||
0, /* addr */
|
sh->size = w;
|
||||||
fo, /* off */
|
sh->addralign = 1;
|
||||||
w, /* size */
|
|
||||||
0, /* link */
|
|
||||||
0, /* info */
|
|
||||||
1, /* align */
|
|
||||||
0); /* entsize */
|
|
||||||
|
|
||||||
if (debug['s'])
|
fo += w;
|
||||||
break;
|
w = lcsize;
|
||||||
|
|
||||||
fo = symo+8;
|
sh = newElfShdr(elfstr[ElfStrGopclntab]);
|
||||||
w = symsize;
|
sh->type = SHT_PROGBITS;
|
||||||
|
sh->off = fo;
|
||||||
|
sh->size = w;
|
||||||
|
sh->addralign = 1;
|
||||||
|
}
|
||||||
|
|
||||||
linuxshdr(".gosymtab", /* name */
|
sh = newElfShstrtab(elfstr[ElfStrShstrtab]);
|
||||||
1, /* type 1 = SHT_PROGBITS */
|
sh->type = SHT_STRTAB;
|
||||||
0, /* flags */
|
sh->addralign = 1;
|
||||||
0, /* addr */
|
shsym(sh, lookup(".shstrtab", 0));
|
||||||
fo, /* off */
|
|
||||||
w, /* size */
|
|
||||||
0, /* link */
|
|
||||||
0, /* info */
|
|
||||||
1, /* align */
|
|
||||||
24); /* entsize */
|
|
||||||
|
|
||||||
fo += w;
|
/* Main header */
|
||||||
w = lcsize;
|
eh->ident[EI_MAG0] = '\177';
|
||||||
|
eh->ident[EI_MAG1] = 'E';
|
||||||
|
eh->ident[EI_MAG2] = 'L';
|
||||||
|
eh->ident[EI_MAG3] = 'F';
|
||||||
|
eh->ident[EI_CLASS] = ELFCLASS32;
|
||||||
|
eh->ident[EI_DATA] = ELFDATA2LSB;
|
||||||
|
eh->ident[EI_VERSION] = EV_CURRENT;
|
||||||
|
|
||||||
linuxshdr(".gopclntab", /* name */
|
eh->type = ET_EXEC;
|
||||||
1, /* type 1 = SHT_PROGBITS*/
|
eh->machine = EM_ARM;
|
||||||
0, /* flags */
|
eh->version = EV_CURRENT;
|
||||||
0, /* addr */
|
eh->entry = entryvalue();
|
||||||
fo, /* off */
|
|
||||||
w, /* size */
|
if(pph != nil) {
|
||||||
0, /* link */
|
pph->filesz = eh->phnum * eh->phentsize;
|
||||||
0, /* info */
|
pph->memsz = pph->filesz;
|
||||||
1, /* align */
|
}
|
||||||
24); /* entsize */
|
|
||||||
|
seek(cout, 0, 0);
|
||||||
|
a = 0;
|
||||||
|
a += elfwritehdr();
|
||||||
|
a += elfwritephdrs();
|
||||||
|
a += elfwriteshdrs();
|
||||||
|
cflush();
|
||||||
|
if(a+elfwriteinterp() > ELFRESERVE)
|
||||||
|
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cflush();
|
cflush();
|
||||||
@ -920,7 +1277,10 @@ datblk(int32 s, int32 n, int str)
|
|||||||
break;
|
break;
|
||||||
case SDATA:
|
case SDATA:
|
||||||
case SBSS:
|
case SBSS:
|
||||||
d += v->value + INITDAT;
|
if(p->to.type == D_SIZE)
|
||||||
|
d += v->size;
|
||||||
|
else
|
||||||
|
d += v->value + INITDAT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(dlm)
|
if(dlm)
|
||||||
@ -2071,90 +2431,3 @@ chipfloat(Ieee *e)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
|
||||||
linuxheadr(void)
|
|
||||||
{
|
|
||||||
uint32 a;
|
|
||||||
|
|
||||||
a = 64; /* a.out header */
|
|
||||||
|
|
||||||
a += 56; /* page zero seg */
|
|
||||||
a += 56; /* text seg */
|
|
||||||
a += 56; /* stack seg */
|
|
||||||
|
|
||||||
a += 64; /* nil sect */
|
|
||||||
a += 64; /* .text sect */
|
|
||||||
a += 64; /* .data seg */
|
|
||||||
a += 64; /* .bss sect */
|
|
||||||
a += 64; /* .shstrtab sect - strings for headers */
|
|
||||||
if (!debug['s']) {
|
|
||||||
a += 56; /* symdat seg */
|
|
||||||
a += 64; /* .gosymtab sect */
|
|
||||||
a += 64; /* .gopclntab sect */
|
|
||||||
}
|
|
||||||
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
linuxphdr(int type, int flags, vlong foff,
|
|
||||||
vlong vaddr, vlong paddr,
|
|
||||||
vlong filesize, vlong memsize, vlong 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
|
|
||||||
linuxshdr(char *name, uint32 type, vlong flags, vlong addr, vlong off,
|
|
||||||
vlong size, uint32 link, uint32 info, vlong align, vlong 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
|
|
||||||
linuxstrtable(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;
|
|
||||||
}
|
|
||||||
|
@ -127,6 +127,7 @@ struct Sym
|
|||||||
uchar reachable;
|
uchar reachable;
|
||||||
int32 value;
|
int32 value;
|
||||||
int32 sig;
|
int32 sig;
|
||||||
|
int32 size;
|
||||||
uchar used;
|
uchar used;
|
||||||
uchar thumb; // thumb code
|
uchar thumb; // thumb code
|
||||||
uchar foreign; // called by arm if thumb, by thumb if arm
|
uchar foreign; // called by arm if thumb, by thumb if arm
|
||||||
@ -470,13 +471,20 @@ int fninc(Sym *);
|
|||||||
void thumbcount(void);
|
void thumbcount(void);
|
||||||
void reachable(void);
|
void reachable(void);
|
||||||
void fnptrs(void);
|
void fnptrs(void);
|
||||||
|
void doelf(void);
|
||||||
|
|
||||||
uint32 linuxheadr(void);
|
vlong addaddr(Sym *s, Sym *t);
|
||||||
void linuxphdr(int type, int flags, vlong foff,
|
vlong addsize(Sym *s, Sym *t);
|
||||||
vlong vaddr, vlong paddr,
|
vlong addstring(Sym *s, char *str);
|
||||||
vlong filesize, vlong memsize, vlong align);
|
vlong adduint16(Sym *s, uint16 v);
|
||||||
void linuxshdr(char *name, uint32 type, vlong flags, vlong addr, vlong off,
|
vlong adduint32(Sym *s, uint32 v);
|
||||||
vlong size, uint32 link, uint32 info, vlong align, vlong entsize);
|
vlong adduint64(Sym *s, uint64 v);
|
||||||
int linuxstrtable(void);
|
vlong adduint8(Sym *s, uint8 v);
|
||||||
|
vlong adduintxx(Sym *s, uint64 v, int wid);
|
||||||
|
|
||||||
|
/* Native is little-endian */
|
||||||
|
#define LPUT(a) lputl(a)
|
||||||
|
#define WPUT(a) wputl(a)
|
||||||
|
#define VPUT(a) abort()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#define EXTERN
|
#define EXTERN
|
||||||
#include "l.h"
|
#include "l.h"
|
||||||
#include "../ld/lib.h"
|
#include "../ld/lib.h"
|
||||||
|
#include "../ld/elf.h"
|
||||||
#include <ar.h>
|
#include <ar.h>
|
||||||
|
|
||||||
#ifndef DEFAULT
|
#ifndef DEFAULT
|
||||||
@ -223,9 +224,11 @@ main(int argc, char *argv[])
|
|||||||
INITRND = 1024;
|
INITRND = 1024;
|
||||||
break;
|
break;
|
||||||
case 6: /* arm elf */
|
case 6: /* arm elf */
|
||||||
HEADR = linuxheadr();
|
debug['d'] = 1; // no dynamic linking
|
||||||
|
elfinit();
|
||||||
|
HEADR = ELFRESERVE;
|
||||||
if(INITTEXT == -1)
|
if(INITTEXT == -1)
|
||||||
INITTEXT = 0x8000;
|
INITTEXT = 0x8000 + HEADR;
|
||||||
if(INITDAT == -1)
|
if(INITDAT == -1)
|
||||||
INITDAT = 0;
|
INITDAT = 0;
|
||||||
if(INITRND == -1)
|
if(INITRND == -1)
|
||||||
@ -300,12 +303,15 @@ main(int argc, char *argv[])
|
|||||||
doprof2();
|
doprof2();
|
||||||
if(debug['u'])
|
if(debug['u'])
|
||||||
reachable();
|
reachable();
|
||||||
|
doelf();
|
||||||
dodata();
|
dodata();
|
||||||
if(seenthumb && debug['f'])
|
if(seenthumb && debug['f'])
|
||||||
fnptrs();
|
fnptrs();
|
||||||
follow();
|
follow();
|
||||||
if(firstp == P)
|
if(firstp == P) {
|
||||||
goto out;
|
diag("no code");
|
||||||
|
errorexit();
|
||||||
|
}
|
||||||
softfloat();
|
softfloat();
|
||||||
noops();
|
noops();
|
||||||
span();
|
span();
|
||||||
|
@ -92,6 +92,7 @@ dodata(void)
|
|||||||
}
|
}
|
||||||
while(v & 3)
|
while(v & 3)
|
||||||
v++;
|
v++;
|
||||||
|
s->size = v;
|
||||||
s->value = v;
|
s->value = v;
|
||||||
if(v > MINSIZ)
|
if(v > MINSIZ)
|
||||||
continue;
|
continue;
|
||||||
@ -113,6 +114,7 @@ dodata(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
v = s->value;
|
v = s->value;
|
||||||
|
s->size = v;
|
||||||
s->value = orig;
|
s->value = orig;
|
||||||
orig += v;
|
orig += v;
|
||||||
}
|
}
|
||||||
@ -130,6 +132,7 @@ dodata(void)
|
|||||||
if(s->type != SBSS)
|
if(s->type != SBSS)
|
||||||
continue;
|
continue;
|
||||||
v = s->value;
|
v = s->value;
|
||||||
|
s->size = v;
|
||||||
s->value = orig;
|
s->value = orig;
|
||||||
orig += v;
|
orig += v;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#define SYS_exit (SYS_BASE + 1)
|
#define SYS_exit (SYS_BASE + 1)
|
||||||
#define SYS_write (SYS_BASE + 4)
|
#define SYS_write (SYS_BASE + 4)
|
||||||
|
#define SYS_gettimeofday (SYS_BASE + 78)
|
||||||
#define SYS_clone (SYS_BASE + 120)
|
#define SYS_clone (SYS_BASE + 120)
|
||||||
#define SYS_mmap2 (SYS_BASE + 192)
|
#define SYS_mmap2 (SYS_BASE + 192)
|
||||||
#define SYS_gettid (SYS_BASE + 224)
|
#define SYS_gettid (SYS_BASE + 224)
|
||||||
@ -60,6 +61,33 @@ TEXT ·mmap(SB),7,$0
|
|||||||
SWI $0
|
SWI $0
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
TEXT gettime(SB),7,$32
|
||||||
|
/* dummy version - return 0,0 */
|
||||||
|
MOVW $0, R1
|
||||||
|
MOVW 0(FP), R0
|
||||||
|
MOVW R1, 0(R0)
|
||||||
|
MOVW R1, 4(R0)
|
||||||
|
MOVW 4(FP), R0
|
||||||
|
MOVW R1, 0(R0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
attempt at real version - seg faults
|
||||||
|
|
||||||
|
MOVW $8(SP), R0
|
||||||
|
MOVW $0, R1
|
||||||
|
MOVW $SYS_gettimeofday, R7
|
||||||
|
SWI $0
|
||||||
|
|
||||||
|
MOVW 0(FP), R0 // sec
|
||||||
|
MOVW 8(SP), R1
|
||||||
|
MOVW R1, 0(R0)
|
||||||
|
|
||||||
|
MOVW 4(FP), R0 // usec
|
||||||
|
MOVW 12(SP), R1
|
||||||
|
MOVW R1, 0(R0)
|
||||||
|
*/
|
||||||
|
RET
|
||||||
|
|
||||||
// int32 futex(int32 *uaddr, int32 op, int32 val,
|
// int32 futex(int32 *uaddr, int32 op, int32 val,
|
||||||
// struct timespec *timeout, int32 *uaddr2, int32 val2);
|
// struct timespec *timeout, int32 *uaddr2, int32 val2);
|
||||||
TEXT futex(SB),7,$0
|
TEXT futex(SB),7,$0
|
||||||
|
@ -133,7 +133,6 @@ fixedbugs/bug120.go
|
|||||||
fixedbugs/bug121.go
|
fixedbugs/bug121.go
|
||||||
fixedbugs/bug122.go
|
fixedbugs/bug122.go
|
||||||
fixedbugs/bug123.go
|
fixedbugs/bug123.go
|
||||||
fixedbugs/bug125.go
|
|
||||||
fixedbugs/bug126.go
|
fixedbugs/bug126.go
|
||||||
fixedbugs/bug127.go
|
fixedbugs/bug127.go
|
||||||
fixedbugs/bug128.go
|
fixedbugs/bug128.go
|
||||||
@ -171,7 +170,6 @@ fixedbugs/bug161.go
|
|||||||
fixedbugs/bug163.go
|
fixedbugs/bug163.go
|
||||||
fixedbugs/bug164.go
|
fixedbugs/bug164.go
|
||||||
fixedbugs/bug165.go
|
fixedbugs/bug165.go
|
||||||
fixedbugs/bug166.go
|
|
||||||
fixedbugs/bug167.go
|
fixedbugs/bug167.go
|
||||||
fixedbugs/bug168.go
|
fixedbugs/bug168.go
|
||||||
fixedbugs/bug169.go
|
fixedbugs/bug169.go
|
||||||
@ -287,7 +285,6 @@ method3.go
|
|||||||
named1.go
|
named1.go
|
||||||
nil.go
|
nil.go
|
||||||
parentype.go
|
parentype.go
|
||||||
peano.go
|
|
||||||
printbig.go
|
printbig.go
|
||||||
range.go
|
range.go
|
||||||
rename1.go
|
rename1.go
|
||||||
@ -304,4 +301,3 @@ turing.go
|
|||||||
utf.go
|
utf.go
|
||||||
varinit.go
|
varinit.go
|
||||||
vectors.go
|
vectors.go
|
||||||
x.go
|
|
||||||
|
141
test/golden-arm.out
Normal file
141
test/golden-arm.out
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
|
||||||
|
=========== 64bit.go
|
||||||
|
BUG: 64bit
|
||||||
|
|
||||||
|
=========== chan/nonblock.go
|
||||||
|
PASS
|
||||||
|
|
||||||
|
=========== cmp2.go
|
||||||
|
comparing uncomparable type []int
|
||||||
|
throw: interface compare
|
||||||
|
|
||||||
|
panic PC=xxx
|
||||||
|
[1] Segmentation fault "${@}"
|
||||||
|
|
||||||
|
=========== cmp3.go
|
||||||
|
comparing uncomparable type []int
|
||||||
|
throw: interface compare
|
||||||
|
|
||||||
|
panic PC=xxx
|
||||||
|
[1] Segmentation fault "${@}"
|
||||||
|
|
||||||
|
=========== cmp4.go
|
||||||
|
hash of unhashable type []int
|
||||||
|
throw: interface hash
|
||||||
|
|
||||||
|
panic PC=xxx
|
||||||
|
[1] Segmentation fault "${@}"
|
||||||
|
|
||||||
|
=========== cmp5.go
|
||||||
|
hash of unhashable type []int
|
||||||
|
throw: interface hash
|
||||||
|
|
||||||
|
panic PC=xxx
|
||||||
|
[1] Segmentation fault "${@}"
|
||||||
|
|
||||||
|
=========== fixedbugs/bug016.go
|
||||||
|
fixedbugs/bug016.go:11: constant -3 overflows uint
|
||||||
|
|
||||||
|
=========== fixedbugs/bug027.go
|
||||||
|
hi
|
||||||
|
0 44444
|
||||||
|
1 3333
|
||||||
|
2 222
|
||||||
|
3 11
|
||||||
|
4 0
|
||||||
|
0 44444
|
||||||
|
1 3333
|
||||||
|
2 222
|
||||||
|
3 11
|
||||||
|
4 0
|
||||||
|
|
||||||
|
=========== fixedbugs/bug067.go
|
||||||
|
ok
|
||||||
|
|
||||||
|
=========== fixedbugs/bug070.go
|
||||||
|
outer loop top k 0
|
||||||
|
inner loop top i 0
|
||||||
|
do break
|
||||||
|
broke
|
||||||
|
|
||||||
|
=========== fixedbugs/bug081.go
|
||||||
|
fixedbugs/bug081.go:9: fatal error: typecheck loop
|
||||||
|
|
||||||
|
=========== fixedbugs/bug093.go
|
||||||
|
M
|
||||||
|
|
||||||
|
=========== fixedbugs/bug113.go
|
||||||
|
interface is int, not int32
|
||||||
|
throw: interface conversion
|
||||||
|
|
||||||
|
panic PC=xxx
|
||||||
|
[1] Segmentation fault "${@}"
|
||||||
|
|
||||||
|
=========== fixedbugs/bug120.go
|
||||||
|
Bad float64 const: 123.5 want 123.5 got %¤
|
||||||
|
[1] Segmentation fault "${@}"
|
||||||
|
BUG: bug120
|
||||||
|
|
||||||
|
=========== fixedbugs/bug148.go
|
||||||
|
2 3
|
||||||
|
interface is main.T, not main.T
|
||||||
|
throw: interface conversion
|
||||||
|
|
||||||
|
panic PC=xxx
|
||||||
|
[1] Segmentation fault "${@}"
|
||||||
|
|
||||||
|
=========== fixedbugs/bug154.go
|
||||||
|
??none??: $GOROOT/pkg/linux_arm/strconv.a: failed to load: os.ERANGE
|
||||||
|
BUG: should not panic
|
||||||
|
|
||||||
|
=========== fixedbugs/bug206.go
|
||||||
|
??none??: $GOROOT/pkg/linux_arm/strconv.a: failed to load: os.ERANGE
|
||||||
|
BUG: bug206
|
||||||
|
|
||||||
|
=========== helloworld.go
|
||||||
|
hello, world
|
||||||
|
|
||||||
|
=========== interface/fail.go
|
||||||
|
*main.S is not main.I: missing method Foo
|
||||||
|
throw: interface conversion
|
||||||
|
|
||||||
|
panic PC=xxx
|
||||||
|
[1] Segmentation fault "${@}"
|
||||||
|
|
||||||
|
=========== interface/returntype.go
|
||||||
|
*main.S is not main.I2: missing method Name
|
||||||
|
throw: interface conversion
|
||||||
|
|
||||||
|
panic PC=xxx
|
||||||
|
[1] Segmentation fault "${@}"
|
||||||
|
|
||||||
|
=========== ken/intervar.go
|
||||||
|
print 1 bio 2 file 3 -- abc
|
||||||
|
|
||||||
|
=========== ken/label.go
|
||||||
|
100
|
||||||
|
|
||||||
|
=========== ken/rob1.go
|
||||||
|
9876543210
|
||||||
|
|
||||||
|
=========== ken/rob2.go
|
||||||
|
(defn foo (add 12 34))
|
||||||
|
|
||||||
|
=========== ken/simpprint.go
|
||||||
|
hello world
|
||||||
|
|
||||||
|
=========== ken/simpswitch.go
|
||||||
|
0out01out12out2aout34out4fiveout56out6aout78out89out9
|
||||||
|
|
||||||
|
=========== ken/string.go
|
||||||
|
abcxyz-abcxyz-abcxyz-abcxyz-abcxyz-abcxyz-abcxyz
|
||||||
|
|
||||||
|
=========== printbig.go
|
||||||
|
-9223372036854775808
|
||||||
|
9223372036854775807
|
||||||
|
|
||||||
|
=========== sigchld.go
|
||||||
|
survived SIGCHLD
|
||||||
|
|
||||||
|
=========== turing.go
|
||||||
|
Hello World!
|
8
test/run
8
test/run
@ -89,10 +89,6 @@ done | # clean up some stack noise
|
|||||||
/^\$RUNFILE: line 1: PID Trace\/breakpoint trap/d
|
/^\$RUNFILE: line 1: PID Trace\/breakpoint trap/d
|
||||||
/^qemu: uncaught target signal 11 (Segmentation fault) - exiting/d' > run.out
|
/^qemu: uncaught target signal 11 (Segmentation fault) - exiting/d' > run.out
|
||||||
|
|
||||||
case $failed in
|
|
||||||
1)
|
|
||||||
echo FAIL
|
|
||||||
esac
|
|
||||||
rm -f $RUNFILE $TMP1FILE $TMP2FILE *.$A $A.out
|
rm -f $RUNFILE $TMP1FILE $TMP2FILE *.$A $A.out
|
||||||
diffmsg=""
|
diffmsg=""
|
||||||
if ! diff run.out golden.out
|
if ! diff run.out golden.out
|
||||||
@ -106,4 +102,8 @@ inbugs=$(sed '1,/^== bugs/d' run.out | grep -c '^BUG')
|
|||||||
|
|
||||||
echo 2>&1 $inbugs known bugs';' $notinbugs unexpected bugs$diffmsg
|
echo 2>&1 $inbugs known bugs';' $notinbugs unexpected bugs$diffmsg
|
||||||
|
|
||||||
|
if [ "$failed" != "0" ]; then
|
||||||
|
echo FAILED
|
||||||
|
fi
|
||||||
|
|
||||||
exit $failed
|
exit $failed
|
||||||
|
25
test/run-arm
25
test/run-arm
@ -13,7 +13,7 @@ X386)
|
|||||||
;;
|
;;
|
||||||
Xarm)
|
Xarm)
|
||||||
export A=5
|
export A=5
|
||||||
export E="qemu-arm -cpu cortex-a8 "
|
export E="${GORUN:-qemu-arm -cpu cortex-a8}"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo 1>&2 run: unsupported '$GOARCH'
|
echo 1>&2 run: unsupported '$GOARCH'
|
||||||
@ -42,20 +42,18 @@ do
|
|||||||
dir=$(dirname $i)
|
dir=$(dirname $i)
|
||||||
export D=$dir
|
export D=$dir
|
||||||
sed '/^\/\//!q' $i | sed 's@//@@; $d' |sed 's|./\$A.out|$E &|' >$RUNFILE
|
sed '/^\/\//!q' $i | sed 's@//@@; $d' |sed 's|./\$A.out|$E &|' >$RUNFILE
|
||||||
if ! sh $RUNFILE >$TMP1FILE 2>$TMP2FILE
|
if ! sh $RUNFILE >$TMP1FILE 2>&1
|
||||||
then
|
then
|
||||||
echo
|
echo
|
||||||
echo "===========" $i
|
echo "===========" $i
|
||||||
cat $TMP1FILE
|
cat $TMP1FILE
|
||||||
cat $TMP2FILE
|
|
||||||
echo >&2 fail: $i
|
echo >&2 fail: $i
|
||||||
touch $FAILEDFILE
|
touch $FAILEDFILE
|
||||||
elif test -s $TMP1FILE || test -s $TMP2FILE
|
elif test -s $TMP1FILE
|
||||||
then
|
then
|
||||||
echo
|
echo
|
||||||
echo "===========" $i
|
echo "===========" $i
|
||||||
cat $TMP1FILE
|
cat $TMP1FILE
|
||||||
cat $TMP2FILE
|
|
||||||
elif [ $dir = "bugs" ]
|
elif [ $dir = "bugs" ]
|
||||||
then
|
then
|
||||||
echo $i succeeded with no output.
|
echo $i succeeded with no output.
|
||||||
@ -68,16 +66,27 @@ done | # clean up some stack noise
|
|||||||
s/^pc: 0x[0-9a-f]*/pc: xxx/
|
s/^pc: 0x[0-9a-f]*/pc: xxx/
|
||||||
/^Trace\/breakpoint trap/d
|
/^Trace\/breakpoint trap/d
|
||||||
/^Trace\/BPT trap/d
|
/^Trace\/BPT trap/d
|
||||||
|
s!'$GOROOT'!$GOROOT!g
|
||||||
/RUNFILE/ s/line 1: *[0-9]*/line 1: PID/
|
/RUNFILE/ s/line 1: *[0-9]*/line 1: PID/
|
||||||
/^\$RUNFILE: line 1: PID Trace\/breakpoint trap/d
|
/^\$RUNFILE: line 1: PID Trace\/breakpoint trap/d
|
||||||
/^qemu: uncaught target signal 11 (Segmentation fault) - exiting/d' > run.out
|
/^qemu: uncaught target signal 11 (Segmentation fault) - exiting/d' > run.out
|
||||||
|
|
||||||
failed=0
|
failed=0
|
||||||
if test -f $FAILEDFILE; then
|
rm -f $RUNFILE $TMP1FILE $TMP2FILE *.$A $A.out
|
||||||
|
diffmsg=""
|
||||||
|
if ! diff run.out golden-arm.out
|
||||||
|
then
|
||||||
|
diffmsg="; test output differs"
|
||||||
failed=1
|
failed=1
|
||||||
rm -f $FAILEDFILE
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f $RUNFILE $TMP1FILE $TMP2FILE *.$A $A.out
|
notinbugs=$(sed '/^== bugs/q' run.out | grep -c '^BUG')
|
||||||
|
inbugs=$(sed '1,/^== bugs/d' run.out | grep -c '^BUG')
|
||||||
|
|
||||||
|
echo 2>&1 $inbugs known bugs';' $notinbugs unexpected bugs$diffmsg
|
||||||
|
|
||||||
|
if [ "$failed" != "0" ]; then
|
||||||
|
echo FAILED
|
||||||
|
fi
|
||||||
|
|
||||||
exit $failed
|
exit $failed
|
||||||
|
Loading…
Reference in New Issue
Block a user