diff options
author | Ondřej Surý <ondrej@sury.org> | 2012-04-06 15:14:11 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2012-04-06 15:14:11 +0200 |
commit | 505c19580e0f43fe5224431459cacb7c21edd93d (patch) | |
tree | 79e2634c253d60afc0cc0b2f510dc7dcbb48497b /src/cmd/5l | |
parent | 1336a7c91e596c423a49d1194ea42d98bca0d958 (diff) | |
download | golang-505c19580e0f43fe5224431459cacb7c21edd93d.tar.gz |
Imported Upstream version 1upstream/1
Diffstat (limited to 'src/cmd/5l')
-rw-r--r-- | src/cmd/5l/5.out.h | 3 | ||||
-rw-r--r-- | src/cmd/5l/Makefile | 42 | ||||
-rw-r--r-- | src/cmd/5l/asm.c | 54 | ||||
-rw-r--r-- | src/cmd/5l/doc.go | 32 | ||||
-rw-r--r-- | src/cmd/5l/l.h | 1 | ||||
-rw-r--r-- | src/cmd/5l/list.c | 2 | ||||
-rw-r--r-- | src/cmd/5l/noop.c | 3 | ||||
-rw-r--r-- | src/cmd/5l/obj.c | 30 | ||||
-rw-r--r-- | src/cmd/5l/pass.c | 5 | ||||
-rw-r--r-- | src/cmd/5l/softfloat.c | 1 | ||||
-rw-r--r-- | src/cmd/5l/span.c | 2 |
11 files changed, 76 insertions, 99 deletions
diff --git a/src/cmd/5l/5.out.h b/src/cmd/5l/5.out.h index cf86ae48b..569536ebd 100644 --- a/src/cmd/5l/5.out.h +++ b/src/cmd/5l/5.out.h @@ -35,7 +35,8 @@ #define NOPROF (1<<0) #define DUPOK (1<<1) #define NOSPLIT (1<<2) -#define ALLTHUMBS (1<<3) +#define RODATA (1<<3) +#define NOPTR (1<<4) #define REGRET 0 /* -1 disables use of REGARG */ diff --git a/src/cmd/5l/Makefile b/src/cmd/5l/Makefile index 8489abc64..3f528d751 100644 --- a/src/cmd/5l/Makefile +++ b/src/cmd/5l/Makefile @@ -1,43 +1,5 @@ -# Copyright 2009 The Go Authors. All rights reserved. +# Copyright 2012 The Go Authors. All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. -include ../../Make.inc -O:=$(HOST_O) - -TARG=5l - -OFILES=\ - asm.$O\ - data.$O\ - elf.$O\ - enam.$O\ - ldelf.$O\ - ldmacho.$O\ - ldpe.$O\ - lib.$O\ - list.$O\ - noop.$O\ - obj.$O\ - optab.$O\ - pass.$O\ - prof.$O\ - softfloat.$O\ - span.$O\ - symtab.$O\ - go.$O\ - -HFILES=\ - l.h\ - 5.out.h\ - ../ld/elf.h\ - -include ../../Make.ccmd - -enam.c: 5.out.h - sh mkenam - -CLEANFILES+=enam.c - -%.$O: ../ld/%.c - $(HOST_CC) $(HOST_CFLAGS) -c -I. ../ld/$*.c +include ../../Make.dist diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c index 5b7f6f111..b36a982d1 100644 --- a/src/cmd/5l/asm.c +++ b/src/cmd/5l/asm.c @@ -73,6 +73,9 @@ enum { ElfStrShstrtab, ElfStrRelPlt, ElfStrPlt, + ElfStrNoteNetbsdIdent, + ElfStrNoPtrData, + ElfStrNoPtrBss, NElfStr }; @@ -90,6 +93,7 @@ needlib(char *name) /* reuse hash code in symbol table */ p = smprint(".dynlib.%s", name); s = lookup(p, 0); + free(p); if(s->type == 0) { s->type = 100; // avoid SDATA, etc. return 1; @@ -162,8 +166,12 @@ doelf(void) elfstr[ElfStrEmpty] = addstring(shstrtab, ""); elfstr[ElfStrText] = addstring(shstrtab, ".text"); + elfstr[ElfStrNoPtrData] = addstring(shstrtab, ".noptrdata"); elfstr[ElfStrData] = addstring(shstrtab, ".data"); elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); + elfstr[ElfStrNoPtrBss] = addstring(shstrtab, ".noptrbss"); + if(HEADTYPE == Hnetbsd) + elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident"); addstring(shstrtab, ".rodata"); addstring(shstrtab, ".gosymtab"); addstring(shstrtab, ".gopclntab"); @@ -232,7 +240,7 @@ doelf(void) /* define dynamic elf table */ s = lookup(".dynamic", 0); s->reachable = 1; - s->type = SELFROSECT; + s->type = SELFSECT; // writable /* * .dynamic table @@ -251,6 +259,7 @@ doelf(void) elfwritedynent(s, DT_PLTREL, DT_REL); elfwritedynentsymsize(s, DT_PLTRELSZ, lookup(".rel.plt", 0)); elfwritedynentsym(s, DT_JMPREL, lookup(".rel.plt", 0)); + elfwritedynent(s, DT_DEBUG, 0); elfwritedynent(s, DT_NULL, 0); } } @@ -293,7 +302,7 @@ asmb(void) { int32 t; int a, dynsym; - uint32 fo, symo, startva; + uint32 fo, symo, startva, resoff; ElfEhdr *eh; ElfPhdr *ph, *pph; ElfShdr *sh; @@ -321,11 +330,6 @@ asmb(void) cseek(segdata.fileoff); datblk(segdata.vaddr, segdata.filelen); - /* output read-only data in text segment */ - sect = segtext.sect->next; - cseek(sect->vaddr - segtext.vaddr + segtext.fileoff); - datblk(sect->vaddr, sect->len); - if(iself) { /* index of elf text section; needed by asmelfsym, double-checked below */ /* !debug['d'] causes extra sections before the .text section */ @@ -335,6 +339,8 @@ asmb(void) if(elfverneed) elftextsh += 2; } + if(HEADTYPE == Hnetbsd) + elftextsh += 1; } /* output symbol table */ @@ -370,7 +376,7 @@ asmb(void) cseek(symo); if(iself) { if(debug['v']) - Bprint(&bso, "%5.2f elfsym\n", cputime()); + Bprint(&bso, "%5.2f elfsym\n", cputime()); asmelfsym(); cflush(); cwrite(elfstrdat, elfstrsize); @@ -454,6 +460,7 @@ asmb(void) eh = getElfEhdr(); fo = HEADR; startva = INITTEXT - fo; /* va of byte 0 of file */ + resoff = ELFRESERVE; /* This null SHdr must appear before all others */ newElfShdr(elfstr[ElfStrEmpty]); @@ -486,7 +493,7 @@ asmb(void) sh->addralign = 1; if(interpreter == nil) interpreter = linuxdynld; - elfinterp(sh, startva, interpreter); + resoff -= elfinterp(sh, startva, resoff, interpreter); ph = newElfPhdr(); ph->type = PT_INTERP; @@ -494,11 +501,24 @@ asmb(void) phsh(ph, sh); } + if(HEADTYPE == Hnetbsd) { + sh = newElfShdr(elfstr[ElfStrNoteNetbsdIdent]); + sh->type = SHT_NOTE; + sh->flags = SHF_ALLOC; + sh->addralign = 4; + resoff -= elfnetbsdsig(sh, startva, resoff); + + ph = newElfPhdr(); + ph->type = PT_NOTE; + ph->flags = PF_R; + phsh(ph, sh); + } + elfphload(&segtext); elfphload(&segdata); /* Dynamic linking sections */ - if (!debug['d']) { /* -d suppresses dynamic loader format */ + if(!debug['d']) { /* -d suppresses dynamic loader format */ /* S headers for dynamic linking */ sh = newElfShdr(elfstr[ElfStrGot]); sh->type = SHT_PROGBITS; @@ -589,7 +609,7 @@ asmb(void) for(sect=segdata.sect; sect!=nil; sect=sect->next) elfshbits(sect); - if (!debug['s']) { + if(!debug['s']) { sh = newElfShdr(elfstr[ElfStrSymtab]); sh->type = SHT_SYMTAB; sh->off = symo; @@ -631,8 +651,10 @@ asmb(void) a += elfwritehdr(); a += elfwritephdrs(); a += elfwriteshdrs(); - cflush(); - if(a+elfwriteinterp() > ELFRESERVE) + a += elfwriteinterp(elfstr[ElfStrInterp]); + if(HEADTYPE == Hnetbsd) + a += elfwritenetbsdsig(elfstr[ElfStrNoteNetbsdIdent]); + if(a > ELFRESERVE) diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE); break; } @@ -1827,14 +1849,20 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*)) case STYPE: case SSTRING: case SGOSTRING: + case SNOPTRDATA: + case SSYMTAB: + case SPCLNTAB: if(!s->reachable) continue; put(s, s->name, 'D', s->value, s->size, s->version, s->gotype); continue; case SBSS: + case SNOPTRBSS: if(!s->reachable) continue; + if(s->np > 0) + diag("%s should not be bss (size=%d type=%d special=%d)", s->name, (int)s->np, s->type, s->special); put(s, s->name, 'B', s->value, s->size, s->version, s->gotype); continue; diff --git a/src/cmd/5l/doc.go b/src/cmd/5l/doc.go index aa7ccebfc..969f502a7 100644 --- a/src/cmd/5l/doc.go +++ b/src/cmd/5l/doc.go @@ -4,36 +4,10 @@ /* -5l is a modified version of the Plan 9 linker. The original is documented at +5l is the linker for the ARM. +The $GOARCH for these tools is arm. - http://plan9.bell-labs.com/magic/man2html/1/2l - -Its target architecture is the ARM, referred to by these tools as arm. -It reads files in .5 format generated by 5g, 5c, and 5a and emits -a binary called 5.out by default. - -Major changes include: - - support for segmented stacks (this feature is implemented here, not in the compilers). - - -Original options are listed in the link above. - -Options new in this version: - --F - Force use of software floating point. - Also implied by setting GOARM=5 in the environment. --Hlinux - Write Linux ELF binaries (default when $GOOS is linux) --I interpreter - Set the ELF dynamic linker to use. --L dir1 -L dir2 - Search for libraries (package files) in dir1, dir2, etc. - The default is the single location $GOROOT/pkg/$GOOS_arm. --r dir1:dir2:... - Set the dynamic linker search path when using ELF. --V - Print the linker version. +The flags are documented in ../ld/doc.go. */ package documentation diff --git a/src/cmd/5l/l.h b/src/cmd/5l/l.h index dabe93d37..b1a48ded8 100644 --- a/src/cmd/5l/l.h +++ b/src/cmd/5l/l.h @@ -143,6 +143,7 @@ struct Sym int32 value; int32 sig; int32 size; + int32 align; // if non-zero, required alignment in bytes uchar special; uchar fnptr; // used as fn ptr Sym* hash; // in hash table diff --git a/src/cmd/5l/list.c b/src/cmd/5l/list.c index fa838215b..7b623d78a 100644 --- a/src/cmd/5l/list.c +++ b/src/cmd/5l/list.c @@ -65,7 +65,7 @@ Pconv(Fmt *fp) switch(a) { default: fmtprint(fp, "(%d)", p->line); - if(p->reg == NREG) + if(p->reg == NREG && p->as != AGLOBL) fmtprint(fp, " %A%C %D,%D", a, p->scond, &p->from, &p->to); else diff --git a/src/cmd/5l/noop.c b/src/cmd/5l/noop.c index eb44344f4..004f9f2fa 100644 --- a/src/cmd/5l/noop.c +++ b/src/cmd/5l/noop.c @@ -226,8 +226,7 @@ noops(void) p->as = AMOVW; p->scond = C_SCOND_LO; p->from.type = D_CONST; - /* 160 comes from 3 calls (3*8) 4 safes (4*8) and 104 guard */ - p->from.offset = autosize+160; + p->from.offset = autosize; p->to.type = D_REG; p->to.reg = 1; diff --git a/src/cmd/5l/obj.c b/src/cmd/5l/obj.c index fc5806aac..a3f816160 100644 --- a/src/cmd/5l/obj.c +++ b/src/cmd/5l/obj.c @@ -81,7 +81,7 @@ void main(int argc, char *argv[]) { int c, i; - char *p; + char *p, *name, *val; Binit(&bso, 1, OWRITE); listinit(); @@ -92,6 +92,7 @@ main(int argc, char *argv[]) INITDAT = -1; INITRND = -1; INITENTRY = 0; + nuxiinit(); p = getenv("GOARM"); if(p != nil && strcmp(p, "5") == 0) @@ -136,6 +137,11 @@ main(int argc, char *argv[]) case 'V': print("%cl version %s\n", thechar, getgoversion()); errorexit(); + case 'X': + name = EARGF(usage()); + val = EARGF(usage()); + addstrdata(name, val); + break; } ARGEND USED(argc); @@ -235,7 +241,6 @@ main(int argc, char *argv[]) histgen = 0; pc = 0; dtype = 4; - nuxiinit(); version = 0; cbp = buf.cbuf; @@ -535,7 +540,7 @@ loop: s->type = SBSS; s->value = 0; } - if(s->type != SBSS) { + if(s->type != SBSS && s->type != SNOPTRBSS && !s->dupok) { diag("redefinition: %s\n%P", s->name, p); s->type = SBSS; s->value = 0; @@ -544,6 +549,10 @@ loop: s->size = p->to.offset; if(p->reg & DUPOK) s->dupok = 1; + if(p->reg & RODATA) + s->type = SRODATA; + else if(p->reg & NOPTR) + s->type = SNOPTRBSS; break; case ADATA: @@ -553,8 +562,8 @@ loop: // redefinitions. s = p->from.sym; if(s->dupok) { - if(debug['v']) - Bprint(&bso, "skipping %s in %s: dupok\n", s->name, pn); +// if(debug['v']) +// Bprint(&bso, "skipping %s in %s: dupok\n", s->name, pn); goto loop; } if(s->file == nil) @@ -585,6 +594,10 @@ loop: errorexit(); } cursym = s; + if(s->type != 0 && s->type != SXREF && (p->reg & DUPOK)) { + skip = 1; + goto casedef; + } if(ntext++ == 0 && s->type != 0 && s->type != SXREF) { /* redefinition, so file has probably been seen before */ if(debug['v']) @@ -592,13 +605,8 @@ loop: return; } skip = 0; - if(s->type != 0 && s->type != SXREF) { - if(p->reg & DUPOK) { - skip = 1; - goto casedef; - } + if(s->type != 0 && s->type != SXREF) diag("redefinition: %s\n%P", s->name, p); - } if(etextp) etextp->next = s; else diff --git a/src/cmd/5l/pass.c b/src/cmd/5l/pass.c index c43049459..0f2afbd85 100644 --- a/src/cmd/5l/pass.c +++ b/src/cmd/5l/pass.c @@ -213,6 +213,8 @@ patch(void) if((a == ABL || a == ABX || a == AB || a == ARET) && p->to.type != D_BRANCH && p->to.sym != S) { s = p->to.sym; + if(s->text == nil) + continue; switch(s->type) { default: diag("undefined: %s", s->name); @@ -222,7 +224,8 @@ patch(void) case STEXT: p->to.offset = s->value; p->to.type = D_BRANCH; - break; + p->cond = s->text; + continue; } } if(p->to.type != D_BRANCH) diff --git a/src/cmd/5l/softfloat.c b/src/cmd/5l/softfloat.c index 4f799d17e..401107178 100644 --- a/src/cmd/5l/softfloat.c +++ b/src/cmd/5l/softfloat.c @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -#define EXTERN #include "l.h" #include "../ld/lib.h" diff --git a/src/cmd/5l/span.c b/src/cmd/5l/span.c index 2e1232a1a..13e1848e1 100644 --- a/src/cmd/5l/span.c +++ b/src/cmd/5l/span.c @@ -421,6 +421,8 @@ symaddr(Sym *s) case SDATA: case SBSS: case SCONST: + case SNOPTRDATA: + case SNOPTRBSS: break; } return v; |