From c14c4e55e00ff06b83063cc2117444a2d75a3b0d Mon Sep 17 00:00:00 2001 From: Yuval Pavel Zholkover Date: Fri, 4 Feb 2011 14:33:21 -0500 Subject: [PATCH] 8l: fix crash writing Plan 9 binaries Was crashing with GOOS=plan9 unless -s was passed. Add symbols and line numbers to Plan 9 a.out. R=rsc CC=golang-dev https://golang.org/cl/4080050 --- src/cmd/8l/asm.c | 88 +++++++++++++++++++++++++++------------------ src/cmd/8l/l.h | 2 +- src/cmd/ld/lib.h | 1 + src/cmd/ld/symtab.c | 56 +++++++++++++++++++++++++++++ 4 files changed, 111 insertions(+), 36 deletions(-) diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c index 6e83d8deaa..1518dc5dbf 100644 --- a/src/cmd/8l/asm.c +++ b/src/cmd/8l/asm.c @@ -67,14 +67,14 @@ wputl(ushort w) } void -wput(ushort w) +wputb(ushort w) { cput(w>>8); cput(w); } void -lput(int32 l) +lputb(int32 l) { cput(l>>24); cput(l>>16); @@ -688,6 +688,8 @@ asmb(void) ElfPhdr *ph, *pph; ElfShdr *sh; Section *sect; + Sym *sym; + int i; if(debug['v']) Bprint(&bso, "%5.2f asmb\n", cputime()); @@ -741,7 +743,7 @@ asmb(void) seek(cout, rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen, 0); break; case 2: - seek(cout, HEADR+segtext.filelen+segdata.filelen, 0); + symo = HEADR+segtext.filelen+segdata.filelen; break; case 3: case 4: @@ -761,11 +763,27 @@ asmb(void) symo = rnd(symo, PEFILEALIGN); break; } - if(HEADTYPE != 10 && !debug['s']) { + if(!debug['s']) { seek(cout, symo, 0); - if(debug['v']) - Bprint(&bso, "%5.2f dwarf\n", cputime()); - dwarfemitdebugsections(); + + if(HEADTYPE == 2) { + asmplan9sym(); + cflush(); + + sym = lookup("pclntab", 0); + if(sym != nil) { + lcsize = sym->np; + for(i=0; i < lcsize; i++) + cput(sym->p[i]); + + cflush(); + } + + } else if(HEADTYPE != 10) { + if(debug['v']) + Bprint(&bso, "%5.2f dwarf\n", cputime()); + dwarfemitdebugsections(); + } } } if(debug['v']) @@ -777,25 +795,25 @@ asmb(void) if(iself) goto Elfput; case 0: /* garbage */ - lput(0x160L<<16); /* magic and sections */ - lput(0L); /* time and date */ - lput(rnd(HEADR+segtext.filelen, 4096)+segdata.filelen); - lput(symsize); /* nsyms */ - lput((0x38L<<16)|7L); /* size of optional hdr and flags */ - lput((0413<<16)|0437L); /* magic and version */ - lput(rnd(HEADR+segtext.filelen, 4096)); /* sizes */ - lput(segdata.filelen); - lput(segdata.len - segdata.filelen); - lput(entryvalue()); /* va of entry */ - lput(INITTEXT-HEADR); /* va of base of text */ - lput(segdata.vaddr); /* va of base of data */ - lput(segdata.vaddr+segdata.filelen); /* va of base of bss */ - lput(~0L); /* gp reg mask */ - lput(0L); - lput(0L); - lput(0L); - lput(0L); - lput(~0L); /* gp value ?? */ + lputb(0x160L<<16); /* magic and sections */ + lputb(0L); /* time and date */ + lputb(rnd(HEADR+segtext.filelen, 4096)+segdata.filelen); + lputb(symsize); /* nsyms */ + lputb((0x38L<<16)|7L); /* size of optional hdr and flags */ + lputb((0413<<16)|0437L); /* magic and version */ + lputb(rnd(HEADR+segtext.filelen, 4096)); /* sizes */ + lputb(segdata.filelen); + lputb(segdata.len - segdata.filelen); + lputb(entryvalue()); /* va of entry */ + lputb(INITTEXT-HEADR); /* va of base of text */ + lputb(segdata.vaddr); /* va of base of data */ + lputb(segdata.vaddr+segdata.filelen); /* va of base of bss */ + lputb(~0L); /* gp reg mask */ + lputb(0L); + lputb(0L); + lputb(0L); + lputb(0L); + lputb(~0L); /* gp value ?? */ break; lputl(0); /* x */ case 1: /* unix coff */ @@ -814,7 +832,7 @@ asmb(void) lputl(rnd(segtext.filelen, INITRND)); /* text sizes */ lputl(segdata.filelen); /* data sizes */ lputl(segdata.len - segdata.filelen); /* bss sizes */ - lput(entryvalue()); /* va of entry */ + lputb(entryvalue()); /* va of entry */ lputl(INITTEXT); /* text start */ lputl(segdata.vaddr); /* data start */ /* @@ -868,14 +886,14 @@ asmb(void) break; case 2: /* plan9 */ magic = 4*11*11+7; - lput(magic); /* magic */ - lput(segtext.filelen); /* sizes */ - lput(segdata.filelen); - lput(segdata.len - segdata.filelen); - lput(symsize); /* nsyms */ - lput(entryvalue()); /* va of entry */ - lput(spsize); /* sp offsets */ - lput(lcsize); /* line offsets */ + lputb(magic); /* magic */ + lputb(segtext.filelen); /* sizes */ + lputb(segdata.filelen); + lputb(segdata.len - segdata.filelen); + lputb(symsize); /* nsyms */ + lputb(entryvalue()); /* va of entry */ + lputb(spsize); /* sp offsets */ + lputb(lcsize); /* line offsets */ break; case 3: /* MS-DOS .COM */ diff --git a/src/cmd/8l/l.h b/src/cmd/8l/l.h index e0746fc758..7cd97deaf3 100644 --- a/src/cmd/8l/l.h +++ b/src/cmd/8l/l.h @@ -363,7 +363,7 @@ void follow(void); void instinit(void); void listinit(void); Sym* lookup(char*, int); -void lput(int32); +void lputb(int32); void lputl(int32); void vputl(uvlong); void strnput(char*, int); diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h index 4ac5d37f98..16dfb0dc30 100644 --- a/src/cmd/ld/lib.h +++ b/src/cmd/ld/lib.h @@ -156,6 +156,7 @@ vlong adduint8(Sym*, uint8); vlong adduint16(Sym*, uint16); void asmsym(void); void asmelfsym64(void); +void asmplan9sym(void); void strnput(char*, int); void dodata(void); void address(void); diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c index 26e4def648..eba0589c2a 100644 --- a/src/cmd/ld/symtab.c +++ b/src/cmd/ld/symtab.c @@ -136,6 +136,62 @@ asmelfsym32(void) genasmsym(putelfsym32); } +void +putplan9sym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go) +{ + int i; + + switch(t) { + case 'T': + case 't': + case 'L': + case 'l': + case 'D': + case 'd': + case 'B': + case 'b': + case 'a': + case 'p': + + case 'f': + case 'z': + case 'Z': + + case 'm': + lputb(addr); + cput(t+0x80); /* 0x80 is variable length */ + + if(t == 'z' || t == 'Z') { + cput(0); + for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) { + cput(s[i]); + cput(s[i+1]); + } + cput(0); + cput(0); + i++; + } else { + /* skip the '<' in filenames */ + if(t=='f') + s++; + + for(i=0; s[i]; i++) + cput(s[i]); + cput(0); + } + + symsize += 4 + 1 + i + 1; + break; + default: + return; + }; +} + +void +asmplan9sym(void) +{ + genasmsym(putplan9sym); +} static Sym *symt;