diff options
Diffstat (limited to 'src/cmd/5l')
-rw-r--r-- | src/cmd/5l/asm.c | 57 | ||||
-rw-r--r-- | src/cmd/5l/l.h | 8 | ||||
-rw-r--r-- | src/cmd/5l/obj.c | 11 |
3 files changed, 48 insertions, 28 deletions
diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c index 04f2a9c6c..a1220a38e 100644 --- a/src/cmd/5l/asm.c +++ b/src/cmd/5l/asm.c @@ -125,7 +125,7 @@ adddynrel(Sym *s, Reloc *r) // Handle relocations found in ELF object files. case 256 + R_ARM_PLT32: r->type = D_CALL; - if(targ->dynimpname != nil && !targ->dynexport) { + if(targ->type == SDYNIMPORT) { addpltsym(targ); r->sym = lookup(".plt", 0); r->add = braddoff(r->add, targ->plt / 4); @@ -138,7 +138,7 @@ adddynrel(Sym *s, Reloc *r) return; case 256 + R_ARM_GOT32: // R_ARM_GOT_BREL - if(targ->dynimpname == nil || targ->dynexport) { + if(targ->type != SDYNIMPORT) { addgotsyminternal(targ); } else { addgotsym(targ); @@ -149,7 +149,7 @@ adddynrel(Sym *s, Reloc *r) return; case 256 + R_ARM_GOT_PREL: // GOT(S) + A - P - if(targ->dynimpname == nil || targ->dynexport) { + if(targ->type != SDYNIMPORT) { addgotsyminternal(targ); } else { addgotsym(targ); @@ -171,7 +171,7 @@ adddynrel(Sym *s, Reloc *r) case 256 + R_ARM_CALL: r->type = D_CALL; - if(targ->dynimpname != nil && !targ->dynexport) { + if(targ->type == SDYNIMPORT) { addpltsym(targ); r->sym = lookup(".plt", 0); r->add = braddoff(r->add, targ->plt / 4); @@ -184,7 +184,7 @@ adddynrel(Sym *s, Reloc *r) return; case 256 + R_ARM_ABS32: - if(targ->dynimpname != nil && !targ->dynexport) + if(targ->type == SDYNIMPORT) diag("unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ->name); r->type = D_ADDR; return; @@ -201,7 +201,7 @@ adddynrel(Sym *s, Reloc *r) case 256 + R_ARM_PC24: case 256 + R_ARM_JUMP24: r->type = D_CALL; - if(targ->dynimpname != nil && !targ->dynexport) { + if(targ->type == SDYNIMPORT) { addpltsym(targ); r->sym = lookup(".plt", 0); r->add = braddoff(r->add, targ->plt / 4); @@ -210,7 +210,7 @@ adddynrel(Sym *s, Reloc *r) } // Handle references to ELF symbols from our own object files. - if(targ->dynimpname == nil || targ->dynexport) + if(targ->type != SDYNIMPORT) return; switch(r->type) { @@ -240,12 +240,13 @@ adddynrel(Sym *s, Reloc *r) } int -elfreloc1(Reloc *r, vlong off, int32 elfsym, vlong add) +elfreloc1(Reloc *r, vlong sectoff) { - USED(add); // written to obj file by ../ld/data.c's reloc - - LPUT(off); + int32 elfsym; + + LPUT(sectoff); + elfsym = r->xsym->elfsym; switch(r->type) { default: return -1; @@ -295,6 +296,16 @@ elfsetupplt(void) } int +machoreloc1(Reloc *r, vlong sectoff) +{ + USED(r); + USED(sectoff); + + return -1; +} + + +int archreloc(Reloc *r, Sym *s, vlong *val) { switch(r->type) { @@ -324,15 +335,16 @@ archreloc(Reloc *r, Sym *s, vlong *val) *val = braddoff((0xff000000U & (uint32)r->add), (0xffffff & (uint32) ((symaddr(r->sym) + ((uint32)r->add) * 4 - (s->value + r->off)) / 4))); - return 0; -} -return -1; + return 0; + } + return -1; } static Reloc * addpltreloc(Sym *plt, Sym *got, Sym *sym, int typ) { -Reloc *r; + Reloc *r; + r = addrel(plt); r->sym = got; r->off = plt->size; @@ -437,20 +449,13 @@ adddynsym(Sym *s) if(s->dynid >= 0) return; - if(s->dynimpname == nil) { - s->dynimpname = s->name; - //diag("adddynsym: no dynamic name for %s", s->name); - } - if(iself) { s->dynid = nelfsym++; d = lookup(".dynsym", 0); /* name */ - name = s->dynimpname; - if(name == nil) - name = s->name; + name = s->extname; adduint32(d, addstring(lookup(".dynstr", 0), name)); /* value */ @@ -464,7 +469,7 @@ adddynsym(Sym *s) /* type */ t = STB_GLOBAL << 4; - if(s->dynexport && (s->type&SMASK) == STEXT) + if((s->cgoexport & CgoExportDynamic) && (s->type&SMASK) == STEXT) t |= STT_FUNC; else t |= STT_OBJECT; @@ -472,7 +477,7 @@ adddynsym(Sym *s) adduint8(d, 0); /* shndx */ - if(!s->dynexport && s->dynimpname != nil) + if(s->type == SDYNIMPORT) adduint16(d, SHN_UNDEF); else { switch(s->type) { @@ -600,7 +605,7 @@ asmb(void) Bprint(&bso, "%5.2f dwarf\n", cputime()); dwarfemitdebugsections(); - if(isobj) + if(linkmode == LinkExternal) elfemitreloc(); } break; diff --git a/src/cmd/5l/l.h b/src/cmd/5l/l.h index 62dd8947f..83c8b755c 100644 --- a/src/cmd/5l/l.h +++ b/src/cmd/5l/l.h @@ -38,6 +38,7 @@ enum thechar = '5', PtrSize = 4, IntSize = 4, + MaxAlign = 8, // max data alignment FuncAlign = 4 // single-instruction alignment }; @@ -95,9 +96,12 @@ struct Reloc { int32 off; uchar siz; + uchar done; int16 type; int32 add; + int32 xadd; Sym* sym; + Sym* xsym; }; struct Prog @@ -133,11 +137,12 @@ struct Prog struct Sym { char* name; + char* extname; // name used in external object files short type; short version; uchar dupok; uchar reachable; - uchar dynexport; + uchar cgoexport; uchar leaf; int32 dynid; int32 plt; @@ -162,7 +167,6 @@ struct Sym Sym* reachparent; Sym* queue; char* file; - char* dynimpname; char* dynimplib; char* dynimpvers; struct Section* sect; diff --git a/src/cmd/5l/obj.c b/src/cmd/5l/obj.c index 6aa7fdd69..1bcf436c4 100644 --- a/src/cmd/5l/obj.c +++ b/src/cmd/5l/obj.c @@ -82,6 +82,7 @@ main(int argc, char *argv[]) INITRND = -1; INITENTRY = 0; LIBINITENTRY = 0; + linkmode = LinkInternal; // TODO: LinkAuto once everything works. nuxiinit(); p = getgoarm(); @@ -116,22 +117,30 @@ main(int argc, char *argv[]) flagcount("f", "ignore version mismatch", &debug['f']); flagcount("g", "disable go package data checks", &debug['g']); flagstr("k", "sym: set field tracking symbol", &tracksym); + flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode); flagcount("n", "dump symbol table", &debug['n']); flagstr("o", "outfile: set output file", &outfile); flagcount("p", "insert profiling code", &debug['p']); flagstr("r", "dir1:dir2:...: set ELF dynamic linker search path", &rpath); flagcount("race", "enable race detector", &flag_race); flagcount("s", "disable symbol table", &debug['s']); + flagstr("tmpdir", "leave temporary files in this directory", &tmpdir); flagcount("u", "reject unsafe packages", &debug['u']); flagcount("v", "print link trace", &debug['v']); flagcount("w", "disable DWARF generation", &debug['w']); flagcount("shared", "generate shared object", &flag_shared); + // TODO: link mode flag flagparse(&argc, &argv, usage); if(argc != 1) usage(); + if(linkmode != LinkInternal) { + diag("only -linkmode=internal is supported"); + errorexit(); + } + libinit(); if(HEADTYPE == -1) @@ -268,6 +277,7 @@ main(int argc, char *argv[]) reloc(); asmb(); undef(); + hostlink(); if(debug['c']) print("ARM size = %d\n", armsize); @@ -424,6 +434,7 @@ ldobj1(Biobuf *f, char *pkg, int64 len, char *pn) ntext = 0; eof = Boffset(f) + len; src[0] = 0; + pn = estrdup(pn); // we keep it in Sym* references newloop: memset(h, 0, sizeof(h)); |