Commit 5f1efe73 authored by Russ Cox's avatar Russ Cox

cmd/ld: make cmd/ld a real library

Make cmd/ld a real library invoked by the individual linkers.
There are no reverse symbol references anymore
(symbols referred to in cmd/ld but defined in cmd/5l etc).

This means that in principle we could do an automatic
conversion of these to Go, as a stopgap until cmd/link is done
or as a replacement for cmd/link.

Change-Id: I4a94570257a3a7acc31601bfe0fad9dea0aea054
Reviewed-on: https://go-review.googlesource.com/4649Reviewed-by: default avatarRob Pike <r@golang.org>
parent 89228641
...@@ -36,13 +36,6 @@ ...@@ -36,13 +36,6 @@
#include "../ld/macho.h" #include "../ld/macho.h"
#include "../ld/dwarf.h" #include "../ld/dwarf.h"
char linuxdynld[] = "/lib/ld-linux.so.3"; // 2 for OABI, 3 for EABI
char freebsddynld[] = "/usr/libexec/ld-elf.so.1";
char openbsddynld[] = "XXX";
char netbsddynld[] = "/libexec/ld.elf_so";
char dragonflydynld[] = "XXX";
char solarisdynld[] = "XXX";
static int static int
needlib(char *name) needlib(char *name)
{ {
...@@ -63,8 +56,6 @@ needlib(char *name) ...@@ -63,8 +56,6 @@ needlib(char *name)
return 0; return 0;
} }
int nelfsym = 1;
static void addpltsym(Link*, LSym*); static void addpltsym(Link*, LSym*);
static void addgotsym(Link*, LSym*); static void addgotsym(Link*, LSym*);
static void addgotsyminternal(Link*, LSym*); static void addgotsyminternal(Link*, LSym*);
...@@ -127,11 +118,11 @@ adddynrel(LSym *s, Reloc *r) ...@@ -127,11 +118,11 @@ adddynrel(LSym *s, Reloc *r)
addgotsym(ctxt, targ); addgotsym(ctxt, targ);
} }
r->type = R_CONST; // write r->add during relocsym r->type = R_CONST; // write r->add during relocsym
r->sym = S; r->sym = nil;
r->add += targ->got; r->add += targ->got;
return; return;
case 256 + R_ARM_GOT_PREL: // GOT(S) + A - P case 256 + R_ARM_GOT_PREL: // GOT(nil) + A - nil
if(targ->type != SDYNIMPORT) { if(targ->type != SDYNIMPORT) {
addgotsyminternal(ctxt, targ); addgotsyminternal(ctxt, targ);
} else { } else {
...@@ -178,7 +169,7 @@ adddynrel(LSym *s, Reloc *r) ...@@ -178,7 +169,7 @@ adddynrel(LSym *s, Reloc *r)
// R_ARM_V4BX is ABS relocation, so this symbol is a dummy symbol, ignore it // R_ARM_V4BX is ABS relocation, so this symbol is a dummy symbol, ignore it
r->sym->type = 0; r->sym->type = 0;
} }
r->sym = S; r->sym = nil;
return; return;
case 256 + R_ARM_PC24: case 256 + R_ARM_PC24:
...@@ -210,9 +201,9 @@ adddynrel(LSym *s, Reloc *r) ...@@ -210,9 +201,9 @@ adddynrel(LSym *s, Reloc *r)
adddynsym(ctxt, targ); adddynsym(ctxt, targ);
rel = linklookup(ctxt, ".rel", 0); rel = linklookup(ctxt, ".rel", 0);
addaddrplus(ctxt, rel, s, r->off); addaddrplus(ctxt, rel, s, r->off);
adduint32(ctxt, rel, ELF32_R_INFO(targ->dynid, R_ARM_GLOB_DAT)); // we need a S + A dynmic reloc adduint32(ctxt, rel, ELF32_R_INFO(targ->dynid, R_ARM_GLOB_DAT)); // we need a nil + A dynmic reloc
r->type = R_CONST; // write r->add during relocsym r->type = R_CONST; // write r->add during relocsym
r->sym = S; r->sym = nil;
return; return;
} }
break; break;
...@@ -227,7 +218,7 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -227,7 +218,7 @@ elfreloc1(Reloc *r, vlong sectoff)
{ {
int32 elfsym; int32 elfsym;
LPUT(sectoff); thearch.lput(sectoff);
elfsym = r->xsym->elfsym; elfsym = r->xsym->elfsym;
switch(r->type) { switch(r->type) {
...@@ -236,14 +227,14 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -236,14 +227,14 @@ elfreloc1(Reloc *r, vlong sectoff)
case R_ADDR: case R_ADDR:
if(r->siz == 4) if(r->siz == 4)
LPUT(R_ARM_ABS32 | elfsym<<8); thearch.lput(R_ARM_ABS32 | elfsym<<8);
else else
return -1; return -1;
break; break;
case R_PCREL: case R_PCREL:
if(r->siz == 4) if(r->siz == 4)
LPUT(R_ARM_REL32 | elfsym<<8); thearch.lput(R_ARM_REL32 | elfsym<<8);
else else
return -1; return -1;
break; break;
...@@ -251,9 +242,9 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -251,9 +242,9 @@ elfreloc1(Reloc *r, vlong sectoff)
case R_CALLARM: case R_CALLARM:
if(r->siz == 4) { if(r->siz == 4) {
if((r->add & 0xff000000) == 0xeb000000) // BL if((r->add & 0xff000000) == 0xeb000000) // BL
LPUT(R_ARM_CALL | elfsym<<8); thearch.lput(R_ARM_CALL | elfsym<<8);
else else
LPUT(R_ARM_JUMP24 | elfsym<<8); thearch.lput(R_ARM_JUMP24 | elfsym<<8);
} else } else
return -1; return -1;
break; break;
...@@ -261,9 +252,9 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -261,9 +252,9 @@ elfreloc1(Reloc *r, vlong sectoff)
case R_TLS: case R_TLS:
if(r->siz == 4) { if(r->siz == 4) {
if(flag_shared) if(flag_shared)
LPUT(R_ARM_TLS_IE32 | elfsym<<8); thearch.lput(R_ARM_TLS_IE32 | elfsym<<8);
else else
LPUT(R_ARM_TLS_LE32 | elfsym<<8); thearch.lput(R_ARM_TLS_LE32 | elfsym<<8);
} else } else
return -1; return -1;
break; break;
...@@ -350,8 +341,8 @@ machoreloc1(Reloc *r, vlong sectoff) ...@@ -350,8 +341,8 @@ machoreloc1(Reloc *r, vlong sectoff)
break; break;
} }
LPUT(sectoff); thearch.lput(sectoff);
LPUT(v); thearch.lput(v);
return 0; return 0;
} }
...@@ -727,14 +718,14 @@ asmb(void) ...@@ -727,14 +718,14 @@ asmb(void)
switch(HEADTYPE) { switch(HEADTYPE) {
default: default:
case Hplan9: /* plan 9 */ case Hplan9: /* plan 9 */
LPUT(0x647); /* magic */ thearch.lput(0x647); /* magic */
LPUT(segtext.filelen); /* sizes */ thearch.lput(segtext.filelen); /* sizes */
LPUT(segdata.filelen); thearch.lput(segdata.filelen);
LPUT(segdata.len - segdata.filelen); thearch.lput(segdata.len - segdata.filelen);
LPUT(symsize); /* nsyms */ thearch.lput(symsize); /* nsyms */
LPUT(entryvalue()); /* va of entry */ thearch.lput(entryvalue()); /* va of entry */
LPUT(0L); thearch.lput(0L);
LPUT(lcsize); thearch.lput(lcsize);
break; break;
case Hlinux: case Hlinux:
case Hfreebsd: case Hfreebsd:
...@@ -757,18 +748,3 @@ asmb(void) ...@@ -757,18 +748,3 @@ asmb(void)
print("total=%lld\n", segtext.filelen+segdata.len+symsize+lcsize); print("total=%lld\n", segtext.filelen+segdata.len+symsize+lcsize);
} }
} }
int32
rnd(int32 v, int32 r)
{
int32 c;
if(r <= 0)
return v;
v += r - 1;
c = v % r;
if(c < 0)
c += r;
v -= c;
return v;
}
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
#include <libc.h> #include <libc.h>
#include <bio.h> #include <bio.h>
#include <link.h> #include <link.h>
#include "5.out.h"
enum enum
{ {
...@@ -41,43 +40,14 @@ enum ...@@ -41,43 +40,14 @@ enum
IntSize = 4, IntSize = 4,
RegSize = 4, RegSize = 4,
MaxAlign = 8, // max data alignment MaxAlign = 8, // max data alignment
FuncAlign = 4 // single-instruction alignment FuncAlign = 4, // single-instruction alignment
MINLC = 4,
}; };
#ifndef EXTERN #ifndef EXTERN
#define EXTERN extern #define EXTERN extern
#endif #endif
#define P ((Prog*)0)
#define S ((LSym*)0)
enum
{
/* mark flags */
FOLL = 1<<0,
LABEL = 1<<1,
LEAF = 1<<2,
MINLC = 4,
};
EXTERN int32 autosize;
EXTERN LSym* datap;
EXTERN int debug[128];
EXTERN char* noname;
EXTERN Prog* lastp;
EXTERN int32 lcsize;
EXTERN char literal[32];
EXTERN int nerrors;
EXTERN int32 instoffset;
EXTERN char* rpath;
EXTERN uint32 stroffset;
EXTERN int32 symsize;
EXTERN int armsize;
#pragma varargck type "I" uint32*
int Iconv(Fmt *fp);
void adddynlib(char *lib); void adddynlib(char *lib);
void adddynrel(LSym *s, Reloc *r); void adddynrel(LSym *s, Reloc *r);
void adddynrela(LSym *rel, LSym *s, Reloc *r); void adddynrela(LSym *rel, LSym *s, Reloc *r);
...@@ -89,13 +59,6 @@ int elfreloc1(Reloc *r, vlong sectoff); ...@@ -89,13 +59,6 @@ int elfreloc1(Reloc *r, vlong sectoff);
void elfsetupplt(void); void elfsetupplt(void);
void listinit(void); void listinit(void);
int machoreloc1(Reloc *r, vlong sectoff); int machoreloc1(Reloc *r, vlong sectoff);
void main(int argc, char *argv[]);
int32 rnd(int32 v, int32 r);
/* Native is little-endian */
#define LPUT(a) lputl(a)
#define WPUT(a) wputl(a)
#define VPUT(a) abort()
/* Used by ../ld/dwarf.c */ /* Used by ../ld/dwarf.c */
enum enum
......
...@@ -37,34 +37,4 @@ void ...@@ -37,34 +37,4 @@ void
listinit(void) listinit(void)
{ {
listinit5(); listinit5();
fmtinstall('I', Iconv);
}
int
Iconv(Fmt *fp)
{
int i, n;
uint32 *p;
char *s;
Fmt fmt;
n = fp->prec;
fp->prec = 0;
if(!(fp->flags&FmtPrec) || n < 0)
return fmtstrcpy(fp, "%I");
fp->flags &= ~FmtPrec;
p = va_arg(fp->args, uint32*);
// format into temporary buffer and
// call fmtstrcpy to handle padding.
fmtstrinit(&fmt);
for(i=0; i<n/4; i++) {
if(i > 0)
fmtprint(&fmt, " ");
fmtprint(&fmt, "%.8ux", *p++);
}
s = fmtstrflush(&fmt);
fmtstrcpy(fp, s);
free(s);
return 0;
} }
...@@ -37,12 +37,51 @@ ...@@ -37,12 +37,51 @@
#include "../ld/dwarf.h" #include "../ld/dwarf.h"
#include <ar.h> #include <ar.h>
char *thestring = "arm"; void
LinkArch *thelinkarch = &linkarm; main(int argc, char **argv)
{
linkarchinit();
ldmain(argc, argv);
}
void void
linkarchinit(void) linkarchinit(void)
{ {
thestring = "arm";
thelinkarch = &linkarm;
thearch.thechar = thechar;
thearch.ptrsize = thelinkarch->ptrsize;
thearch.intsize = thelinkarch->ptrsize;
thearch.regsize = thelinkarch->regsize;
thearch.funcalign = FuncAlign;
thearch.maxalign = MaxAlign;
thearch.minlc = MINLC;
thearch.dwarfregsp = DWARFREGSP;
thearch.adddynlib = adddynlib;
thearch.adddynrel = adddynrel;
thearch.adddynsym = adddynsym;
thearch.archinit = archinit;
thearch.archreloc = archreloc;
thearch.archrelocvariant = archrelocvariant;
thearch.asmb = asmb;
thearch.elfreloc1 = elfreloc1;
thearch.elfsetupplt = elfsetupplt;
thearch.gentext = gentext;
thearch.listinit = listinit;
thearch.machoreloc1 = machoreloc1;
thearch.lput = lputl;
thearch.wput = wputl;
thearch.vput = vputl;
thearch.linuxdynld = "/lib/ld-linux.so.3"; // 2 for OABI, 3 for EABI
thearch.freebsddynld = "/usr/libexec/ld-elf.so.1";
thearch.openbsddynld = "XXX";
thearch.netbsddynld = "/libexec/ld.elf_so";
thearch.dragonflydynld = "XXX";
thearch.solarisdynld = "XXX";
} }
void void
......
...@@ -39,13 +39,6 @@ ...@@ -39,13 +39,6 @@
#define PADDR(a) ((uint32)(a) & ~0x80000000) #define PADDR(a) ((uint32)(a) & ~0x80000000)
char linuxdynld[] = "/lib64/ld-linux-x86-64.so.2";
char freebsddynld[] = "/libexec/ld-elf.so.1";
char openbsddynld[] = "/usr/libexec/ld.so";
char netbsddynld[] = "/libexec/ld.elf_so";
char dragonflydynld[] = "/usr/libexec/ld-elf.so.2";
char solarisdynld[] = "/lib/amd64/ld.so.1";
char zeroes[32]; char zeroes[32];
static int static int
...@@ -68,8 +61,6 @@ needlib(char *name) ...@@ -68,8 +61,6 @@ needlib(char *name)
return 0; return 0;
} }
int nelfsym = 1;
static void addpltsym(LSym*); static void addpltsym(LSym*);
static void addgotsym(LSym*); static void addgotsym(LSym*);
...@@ -236,7 +227,7 @@ adddynrel(LSym *s, Reloc *r) ...@@ -236,7 +227,7 @@ adddynrel(LSym *s, Reloc *r)
r->type = 256; // ignore during relocsym r->type = 256; // ignore during relocsym
return; return;
} }
if(HEADTYPE == Hdarwin && s->size == PtrSize && r->off == 0) { if(HEADTYPE == Hdarwin && s->size == thearch.ptrsize && r->off == 0) {
// Mach-O relocations are a royal pain to lay out. // Mach-O relocations are a royal pain to lay out.
// They use a compact stateful bytecode representation // They use a compact stateful bytecode representation
// that is too much bother to deal with. // that is too much bother to deal with.
...@@ -271,7 +262,7 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -271,7 +262,7 @@ elfreloc1(Reloc *r, vlong sectoff)
{ {
int32 elfsym; int32 elfsym;
VPUT(sectoff); thearch.vput(sectoff);
elfsym = r->xsym->elfsym; elfsym = r->xsym->elfsym;
switch(r->type) { switch(r->type) {
...@@ -280,16 +271,16 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -280,16 +271,16 @@ elfreloc1(Reloc *r, vlong sectoff)
case R_ADDR: case R_ADDR:
if(r->siz == 4) if(r->siz == 4)
VPUT(R_X86_64_32 | (uint64)elfsym<<32); thearch.vput(R_X86_64_32 | (uint64)elfsym<<32);
else if(r->siz == 8) else if(r->siz == 8)
VPUT(R_X86_64_64 | (uint64)elfsym<<32); thearch.vput(R_X86_64_64 | (uint64)elfsym<<32);
else else
return -1; return -1;
break; break;
case R_TLS_LE: case R_TLS_LE:
if(r->siz == 4) if(r->siz == 4)
VPUT(R_X86_64_TPOFF32 | (uint64)elfsym<<32); thearch.vput(R_X86_64_TPOFF32 | (uint64)elfsym<<32);
else else
return -1; return -1;
break; break;
...@@ -297,16 +288,16 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -297,16 +288,16 @@ elfreloc1(Reloc *r, vlong sectoff)
case R_CALL: case R_CALL:
if(r->siz == 4) { if(r->siz == 4) {
if(r->xsym->type == SDYNIMPORT) if(r->xsym->type == SDYNIMPORT)
VPUT(R_X86_64_GOTPCREL | (uint64)elfsym<<32); thearch.vput(R_X86_64_GOTPCREL | (uint64)elfsym<<32);
else else
VPUT(R_X86_64_PC32 | (uint64)elfsym<<32); thearch.vput(R_X86_64_PC32 | (uint64)elfsym<<32);
} else } else
return -1; return -1;
break; break;
case R_PCREL: case R_PCREL:
if(r->siz == 4) { if(r->siz == 4) {
VPUT(R_X86_64_PC32 | (uint64)elfsym<<32); thearch.vput(R_X86_64_PC32 | (uint64)elfsym<<32);
} else } else
return -1; return -1;
break; break;
...@@ -314,15 +305,15 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -314,15 +305,15 @@ elfreloc1(Reloc *r, vlong sectoff)
case R_TLS: case R_TLS:
if(r->siz == 4) { if(r->siz == 4) {
if(flag_shared) if(flag_shared)
VPUT(R_X86_64_GOTTPOFF | (uint64)elfsym<<32); thearch.vput(R_X86_64_GOTTPOFF | (uint64)elfsym<<32);
else else
VPUT(R_X86_64_TPOFF32 | (uint64)elfsym<<32); thearch.vput(R_X86_64_TPOFF32 | (uint64)elfsym<<32);
} else } else
return -1; return -1;
break; break;
} }
VPUT(r->xadd); thearch.vput(r->xadd);
return 0; return 0;
} }
...@@ -382,8 +373,8 @@ machoreloc1(Reloc *r, vlong sectoff) ...@@ -382,8 +373,8 @@ machoreloc1(Reloc *r, vlong sectoff)
break; break;
} }
LPUT(sectoff); thearch.lput(sectoff);
LPUT(v); thearch.lput(v);
return 0; return 0;
} }
...@@ -798,18 +789,3 @@ asmb(void) ...@@ -798,18 +789,3 @@ asmb(void)
} }
cflush(); cflush();
} }
vlong
rnd(vlong v, vlong r)
{
vlong c;
if(r <= 0)
return v;
v += r - 1;
c = v % r;
if(c < 0)
c += r;
v -= c;
return v;
}
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
#include <libc.h> #include <libc.h>
#include <bio.h> #include <bio.h>
#include <link.h> #include <link.h>
#include "6.out.h"
#ifndef EXTERN #ifndef EXTERN
#define EXTERN extern #define EXTERN extern
...@@ -42,49 +41,14 @@ enum ...@@ -42,49 +41,14 @@ enum
{ {
thechar = '6', thechar = '6',
MaxAlign = 32, // max data alignment MaxAlign = 32, // max data alignment
// Loop alignment constants:
// want to align loop entry to LoopAlign-byte boundary,
// and willing to insert at most MaxLoopPad bytes of NOP to do so.
// We define a loop entry as the target of a backward jump.
//
// gcc uses MaxLoopPad = 10 for its 'generic x86-64' config,
// and it aligns all jump targets, not just backward jump targets.
//
// As of 6/1/2012, the effect of setting MaxLoopPad = 10 here
// is very slight but negative, so the alignment is disabled by
// setting MaxLoopPad = 0. The code is here for reference and
// for future experiments.
//
LoopAlign = 16,
MaxLoopPad = 0,
FuncAlign = 16 FuncAlign = 16
}; };
EXTERN int PtrSize;
EXTERN int IntSize;
EXTERN int RegSize;
#define P ((Prog*)0)
#define S ((LSym*)0)
enum enum
{ {
MINLC = 1, MINLC = 1,
}; };
#pragma varargck type "I" uchar*
EXTERN LSym* datap;
EXTERN int debug[128];
EXTERN char literal[32];
EXTERN int32 lcsize;
EXTERN char* rpath;
EXTERN int32 spsize;
EXTERN LSym* symlist;
EXTERN int32 symsize;
int Iconv(Fmt *fp);
void adddynlib(char *lib); void adddynlib(char *lib);
void adddynrel(LSym *s, Reloc *r); void adddynrel(LSym *s, Reloc *r);
void adddynrela(LSym *rela, LSym *s, Reloc *r); void adddynrela(LSym *rela, LSym *s, Reloc *r);
...@@ -96,12 +60,6 @@ int elfreloc1(Reloc *r, vlong sectoff); ...@@ -96,12 +60,6 @@ int elfreloc1(Reloc *r, vlong sectoff);
void elfsetupplt(void); void elfsetupplt(void);
void listinit(void); void listinit(void);
int machoreloc1(Reloc *r, vlong sectoff); int machoreloc1(Reloc *r, vlong sectoff);
vlong rnd(vlong v, vlong r);
/* Native is little-endian */
#define LPUT(a) lputl(a)
#define WPUT(a) wputl(a)
#define VPUT(a) vputl(a)
/* Used by ../ld/dwarf.c */ /* Used by ../ld/dwarf.c */
enum enum
......
...@@ -37,31 +37,4 @@ void ...@@ -37,31 +37,4 @@ void
listinit(void) listinit(void)
{ {
listinit6(); listinit6();
fmtinstall('I', Iconv);
}
int
Iconv(Fmt *fp)
{
int i, n;
uchar *p;
char *s;
Fmt fmt;
n = fp->prec;
fp->prec = 0;
if(!(fp->flags&FmtPrec) || n < 0)
return fmtstrcpy(fp, "%I");
fp->flags &= ~FmtPrec;
p = va_arg(fp->args, uchar*);
// format into temporary buffer and
// call fmtstrcpy to handle padding.
fmtstrinit(&fmt);
for(i=0; i<n; i++)
fmtprint(&fmt, "%.2ux", *p++);
s = fmtstrflush(&fmt);
fmtstrcpy(fp, s);
free(s);
return 0;
} }
...@@ -38,17 +38,52 @@ ...@@ -38,17 +38,52 @@
#include "../ld/pe.h" #include "../ld/pe.h"
#include <ar.h> #include <ar.h>
char* thestring = "amd64"; void
LinkArch* thelinkarch = &linkamd64; main(int argc, char **argv)
{
linkarchinit();
ldmain(argc, argv);
}
void void
linkarchinit(void) linkarchinit(void)
{ {
thestring = "amd64";
thelinkarch = &linkamd64;
if(strcmp(getgoarch(), "amd64p32") == 0) if(strcmp(getgoarch(), "amd64p32") == 0)
thelinkarch = &linkamd64p32; thelinkarch = &linkamd64p32;
PtrSize = thelinkarch->ptrsize;
IntSize = PtrSize; thearch.thechar = thechar;
RegSize = thelinkarch->regsize; thearch.ptrsize = thelinkarch->ptrsize;
thearch.intsize = thelinkarch->ptrsize;
thearch.regsize = thelinkarch->regsize;
thearch.funcalign = FuncAlign;
thearch.maxalign = MaxAlign;
thearch.minlc = MINLC;
thearch.dwarfregsp = DWARFREGSP;
thearch.adddynlib = adddynlib;
thearch.adddynrel = adddynrel;
thearch.adddynsym = adddynsym;
thearch.archinit = archinit;
thearch.archreloc = archreloc;
thearch.archrelocvariant = archrelocvariant;
thearch.asmb = asmb;
thearch.elfreloc1 = elfreloc1;
thearch.elfsetupplt = elfsetupplt;
thearch.gentext = gentext;
thearch.listinit = listinit;
thearch.machoreloc1 = machoreloc1;
thearch.lput = lputl;
thearch.wput = wputl;
thearch.vput = vputl;
thearch.linuxdynld = "/lib64/ld-linux-x86-64.so.2";
thearch.freebsddynld = "/libexec/ld-elf.so.1";
thearch.openbsddynld = "/usr/libexec/ld.so";
thearch.netbsddynld = "/libexec/ld.elf_so";
thearch.dragonflydynld = "/usr/libexec/ld-elf.so.2";
thearch.solarisdynld = "/lib/amd64/ld.so.1";
} }
void void
......
...@@ -37,13 +37,6 @@ ...@@ -37,13 +37,6 @@
#include "../ld/macho.h" #include "../ld/macho.h"
#include "../ld/pe.h" #include "../ld/pe.h"
char linuxdynld[] = "/lib/ld-linux.so.2";
char freebsddynld[] = "/usr/libexec/ld-elf.so.1";
char openbsddynld[] = "/usr/libexec/ld.so";
char netbsddynld[] = "/usr/libexec/ld.elf_so";
char dragonflydynld[] = "/usr/libexec/ld-elf.so.2";
char solarisdynld[] = "/lib/ld.so.1";
static int static int
needlib(char *name) needlib(char *name)
{ {
...@@ -64,8 +57,6 @@ needlib(char *name) ...@@ -64,8 +57,6 @@ needlib(char *name)
return 0; return 0;
} }
int nelfsym = 1;
static void addpltsym(Link*, LSym*); static void addpltsym(Link*, LSym*);
static void addgotsym(Link*, LSym*); static void addgotsym(Link*, LSym*);
...@@ -141,7 +132,7 @@ adddynrel(LSym *s, Reloc *r) ...@@ -141,7 +132,7 @@ adddynrel(LSym *s, Reloc *r)
} }
addgotsym(ctxt, targ); addgotsym(ctxt, targ);
r->type = R_CONST; // write r->add during relocsym r->type = R_CONST; // write r->add during relocsym
r->sym = S; r->sym = nil;
r->add += targ->got; r->add += targ->got;
return; return;
...@@ -218,7 +209,7 @@ adddynrel(LSym *s, Reloc *r) ...@@ -218,7 +209,7 @@ adddynrel(LSym *s, Reloc *r)
addaddrplus(ctxt, rel, s, r->off); addaddrplus(ctxt, rel, s, r->off);
adduint32(ctxt, rel, ELF32_R_INFO(targ->dynid, R_386_32)); adduint32(ctxt, rel, ELF32_R_INFO(targ->dynid, R_386_32));
r->type = R_CONST; // write r->add during relocsym r->type = R_CONST; // write r->add during relocsym
r->sym = S; r->sym = nil;
return; return;
} }
if(HEADTYPE == Hdarwin && s->size == PtrSize && r->off == 0) { if(HEADTYPE == Hdarwin && s->size == PtrSize && r->off == 0) {
...@@ -256,7 +247,7 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -256,7 +247,7 @@ elfreloc1(Reloc *r, vlong sectoff)
{ {
int32 elfsym; int32 elfsym;
LPUT(sectoff); thearch.lput(sectoff);
elfsym = r->xsym->elfsym; elfsym = r->xsym->elfsym;
switch(r->type) { switch(r->type) {
...@@ -265,7 +256,7 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -265,7 +256,7 @@ elfreloc1(Reloc *r, vlong sectoff)
case R_ADDR: case R_ADDR:
if(r->siz == 4) if(r->siz == 4)
LPUT(R_386_32 | elfsym<<8); thearch.lput(R_386_32 | elfsym<<8);
else else
return -1; return -1;
break; break;
...@@ -273,7 +264,7 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -273,7 +264,7 @@ elfreloc1(Reloc *r, vlong sectoff)
case R_CALL: case R_CALL:
case R_PCREL: case R_PCREL:
if(r->siz == 4) if(r->siz == 4)
LPUT(R_386_PC32 | elfsym<<8); thearch.lput(R_386_PC32 | elfsym<<8);
else else
return -1; return -1;
break; break;
...@@ -281,7 +272,7 @@ elfreloc1(Reloc *r, vlong sectoff) ...@@ -281,7 +272,7 @@ elfreloc1(Reloc *r, vlong sectoff)
case R_TLS_LE: case R_TLS_LE:
case R_TLS_IE: case R_TLS_IE:
if(r->siz == 4) if(r->siz == 4)
LPUT(R_386_TLS_LE | elfsym<<8); thearch.lput(R_386_TLS_LE | elfsym<<8);
else else
return -1; return -1;
} }
...@@ -342,8 +333,8 @@ machoreloc1(Reloc *r, vlong sectoff) ...@@ -342,8 +333,8 @@ machoreloc1(Reloc *r, vlong sectoff)
break; break;
} }
LPUT(sectoff); thearch.lput(sectoff);
LPUT(v); thearch.lput(v);
return 0; return 0;
} }
...@@ -715,29 +706,3 @@ asmb(void) ...@@ -715,29 +706,3 @@ asmb(void)
} }
cflush(); cflush();
} }
void
s8put(char *n)
{
char name[8];
int i;
strncpy(name, n, sizeof(name));
for(i=0; i<sizeof(name); i++)
cput(name[i]);
}
int32
rnd(int32 v, int32 r)
{
int32 c;
if(r <= 0)
return v;
v += r - 1;
c = v % r;
if(c < 0)
c += r;
v -= c;
return v;
}
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
#include <libc.h> #include <libc.h>
#include <bio.h> #include <bio.h>
#include <link.h> #include <link.h>
#include "8.out.h"
#ifndef EXTERN #ifndef EXTERN
#define EXTERN extern #define EXTERN extern
...@@ -45,30 +44,10 @@ enum ...@@ -45,30 +44,10 @@ enum
IntSize = 4, IntSize = 4,
RegSize = 4, RegSize = 4,
MaxAlign = 32, // max data alignment MaxAlign = 32, // max data alignment
FuncAlign = 16 FuncAlign = 16,
};
#define P ((Prog*)0)
#define S ((LSym*)0)
enum
{
MINLC = 1, MINLC = 1,
}; };
#pragma varargck type "I" uchar*
EXTERN LSym* datap;
EXTERN int debug[128];
EXTERN char literal[32];
EXTERN Prog* firstp;
EXTERN int32 lcsize;
EXTERN char* rpath;
EXTERN int32 spsize;
EXTERN LSym* symlist;
EXTERN int32 symsize;
int Iconv(Fmt *fp);
void adddynlib(char *lib); void adddynlib(char *lib);
void adddynrel(LSym *s, Reloc *r); void adddynrel(LSym *s, Reloc *r);
void adddynrela(LSym *rela, LSym *s, Reloc *r); void adddynrela(LSym *rela, LSym *s, Reloc *r);
...@@ -80,14 +59,6 @@ int elfreloc1(Reloc *r, vlong sectoff); ...@@ -80,14 +59,6 @@ int elfreloc1(Reloc *r, vlong sectoff);
void elfsetupplt(void); void elfsetupplt(void);
void listinit(void); void listinit(void);
int machoreloc1(Reloc *r, vlong sectoff); int machoreloc1(Reloc *r, vlong sectoff);
int32 rnd(int32 v, int32 r);
void s8put(char *n);
char* xsymname(LSym *s);
/* Native is little-endian */
#define LPUT(a) lputl(a)
#define WPUT(a) wputl(a)
#define VPUT(a) vputl(a)
/* Used by ../ld/dwarf.c */ /* Used by ../ld/dwarf.c */
enum enum
......
...@@ -37,31 +37,4 @@ void ...@@ -37,31 +37,4 @@ void
listinit(void) listinit(void)
{ {
listinit8(); listinit8();
fmtinstall('I', Iconv);
}
int
Iconv(Fmt *fp)
{
int i, n;
uchar *p;
char *s;
Fmt fmt;
n = fp->prec;
fp->prec = 0;
if(!(fp->flags&FmtPrec) || n < 0)
return fmtstrcpy(fp, "%I");
fp->flags &= ~FmtPrec;
p = va_arg(fp->args, uchar*);
// format into temporary buffer and
// call fmtstrcpy to handle padding.
fmtstrinit(&fmt);
for(i=0; i<n; i++)
fmtprint(&fmt, "%.2ux", *p++);
s = fmtstrflush(&fmt);
fmtstrcpy(fp, s);
free(s);
return 0;
} }
...@@ -38,12 +38,50 @@ ...@@ -38,12 +38,50 @@
#include "../ld/pe.h" #include "../ld/pe.h"
#include <ar.h> #include <ar.h>
char* thestring = "386"; void
LinkArch* thelinkarch = &link386; main(int argc, char **argv)
{
linkarchinit();
ldmain(argc, argv);
}
void void
linkarchinit(void) linkarchinit(void)
{ {
thestring = "386";
thelinkarch = &link386;
thearch.thechar = thechar;
thearch.ptrsize = thelinkarch->ptrsize;
thearch.intsize = thelinkarch->ptrsize;
thearch.regsize = thelinkarch->regsize;
thearch.funcalign = FuncAlign;
thearch.maxalign = MaxAlign;
thearch.minlc = MINLC;
thearch.dwarfregsp = DWARFREGSP;
thearch.adddynlib = adddynlib;
thearch.adddynrel = adddynrel;
thearch.adddynsym = adddynsym;
thearch.archinit = archinit;
thearch.archreloc = archreloc;
thearch.archrelocvariant = archrelocvariant;
thearch.asmb = asmb;
thearch.elfreloc1 = elfreloc1;
thearch.elfsetupplt = elfsetupplt;
thearch.gentext = gentext;
thearch.listinit = listinit;
thearch.machoreloc1 = machoreloc1;
thearch.lput = lputl;
thearch.wput = wputl;
thearch.vput = vputl;
thearch.linuxdynld = "/lib/ld-linux.so.2";
thearch.freebsddynld = "/usr/libexec/ld-elf.so.1";
thearch.openbsddynld = "/usr/libexec/ld.so";
thearch.netbsddynld = "/usr/libexec/ld.elf_so";
thearch.dragonflydynld = "/usr/libexec/ld-elf.so.2";
thearch.solarisdynld = "/lib/ld.so.1";
} }
void void
......
...@@ -35,15 +35,6 @@ ...@@ -35,15 +35,6 @@
#include "../ld/elf.h" #include "../ld/elf.h"
#include "../ld/dwarf.h" #include "../ld/dwarf.h"
// TODO(austin): ABI v1 uses /usr/lib/ld.so.1
char linuxdynld[] = "/lib64/ld64.so.1";
char freebsddynld[] = "XXX";
char openbsddynld[] = "XXX";
char netbsddynld[] = "XXX";
char dragonflydynld[] = "XXX";
char solarisdynld[] = "XXX";
static int static int
needlib(char *name) needlib(char *name)
{ {
...@@ -64,8 +55,6 @@ needlib(char *name) ...@@ -64,8 +55,6 @@ needlib(char *name)
return 0; return 0;
} }
int nelfsym = 1;
static void gencallstub(int abicase, LSym *stub, LSym *targ); static void gencallstub(int abicase, LSym *stub, LSym *targ);
static void addpltsym(Link*, LSym*); static void addpltsym(Link*, LSym*);
static LSym* ensureglinkresolver(void); static LSym* ensureglinkresolver(void);
...@@ -129,7 +118,7 @@ gentext(void) ...@@ -129,7 +118,7 @@ gentext(void)
// This assumes "case 1" from the ABI, where the caller needs // This assumes "case 1" from the ABI, where the caller needs
// us to save and restore the TOC pointer. // us to save and restore the TOC pointer.
pprevtextp = &ctxt->textp; pprevtextp = &ctxt->textp;
for(s=*pprevtextp; s!=S; pprevtextp=&s->next, s=*pprevtextp) { for(s=*pprevtextp; s!=nil; pprevtextp=&s->next, s=*pprevtextp) {
for(r=s->r; r<s->r+s->nr; r++) { for(r=s->r; r<s->r+s->nr; r++) {
if(!(r->type == 256 + R_PPC64_REL24 && if(!(r->type == 256 + R_PPC64_REL24 &&
r->sym->type == SDYNIMPORT)) r->sym->type == SDYNIMPORT))
...@@ -797,14 +786,14 @@ asmb(void) ...@@ -797,14 +786,14 @@ asmb(void)
switch(HEADTYPE) { switch(HEADTYPE) {
default: default:
case Hplan9: /* plan 9 */ case Hplan9: /* plan 9 */
LPUT(0x647); /* magic */ thearch.lput(0x647); /* magic */
LPUT(segtext.filelen); /* sizes */ thearch.lput(segtext.filelen); /* sizes */
LPUT(segdata.filelen); thearch.lput(segdata.filelen);
LPUT(segdata.len - segdata.filelen); thearch.lput(segdata.len - segdata.filelen);
LPUT(symsize); /* nsyms */ thearch.lput(symsize); /* nsyms */
LPUT(entryvalue()); /* va of entry */ thearch.lput(entryvalue()); /* va of entry */
LPUT(0L); thearch.lput(0L);
LPUT(lcsize); thearch.lput(lcsize);
break; break;
case Hlinux: case Hlinux:
case Hfreebsd: case Hfreebsd:
...@@ -824,18 +813,3 @@ asmb(void) ...@@ -824,18 +813,3 @@ asmb(void)
print("total=%lld\n", segtext.filelen+segdata.len+symsize+lcsize); print("total=%lld\n", segtext.filelen+segdata.len+symsize+lcsize);
} }
} }
vlong
rnd(vlong v, int32 r)
{
vlong c;
if(r <= 0)
return v;
v += r - 1;
c = v % r;
if(c < 0)
c += r;
v -= c;
return v;
}
...@@ -44,55 +44,21 @@ enum ...@@ -44,55 +44,21 @@ enum
IntSize = 8, IntSize = 8,
RegSize = 8, RegSize = 8,
MaxAlign = 32, // max data alignment MaxAlign = 32, // max data alignment
FuncAlign = 8 FuncAlign = 8,
};
#define P ((Prog*)0)
#define S ((LSym*)0)
enum
{
FPCHIP = 1,
STRINGSZ = 200,
MAXHIST = 20, /* limit of path elements for history symbols */
DATBLK = 1024,
NHASH = 10007,
NHUNK = 100000,
MINSIZ = 64,
NENT = 100,
NSCHED = 20,
MINLC = 4, MINLC = 4,
Roffset = 22, /* no. bits for offset in relocation address */
Rindex = 10 /* no. bits for index in relocation address */
}; };
EXTERN int32 autosize;
EXTERN LSym* datap;
EXTERN int debug[128];
EXTERN int32 lcsize;
EXTERN char literal[32];
EXTERN int nerrors;
EXTERN vlong instoffset;
EXTERN char* rpath;
EXTERN vlong pc;
EXTERN int32 symsize;
EXTERN int32 staticgen;
EXTERN Prog* lastp;
EXTERN vlong textsize;
void asmb(void);
void adddynlib(char *lib); void adddynlib(char *lib);
void adddynrel(LSym *s, Reloc *r); void adddynrel(LSym *s, Reloc *r);
void adddynrela(LSym *rela, LSym *s, Reloc *r);
void adddynsym(Link *ctxt, LSym *s); void adddynsym(Link *ctxt, LSym *s);
int archreloc(Reloc *r, LSym *s, vlong *val); int archreloc(Reloc *r, LSym *s, vlong *val);
vlong archrelocvariant(Reloc *r, LSym *s, vlong t); vlong archrelocvariant(Reloc *r, LSym *s, vlong t);
void asmb(void);
int elfreloc1(Reloc *r, vlong sectoff);
void elfsetupplt(void);
void listinit(void); void listinit(void);
vlong rnd(vlong, int32); int machoreloc1(Reloc *r, vlong sectoff);
#define LPUT(a) (ctxt->arch->endian == BigEndian ? lputb(a):lputl(a))
#define WPUT(a) (ctxt->arch->endian == BigEndian ? wputb(a):wputl(a))
#define VPUT(a) (ctxt->arch->endian == BigEndian ? vputb(a):vputl(a))
/* Used by ../ld/dwarf.c */ /* Used by ../ld/dwarf.c */
enum enum
......
...@@ -36,8 +36,12 @@ ...@@ -36,8 +36,12 @@
#include "../ld/dwarf.h" #include "../ld/dwarf.h"
#include <ar.h> #include <ar.h>
char *thestring = "ppc64"; void
LinkArch *thelinkarch; main(int argc, char **argv)
{
linkarchinit();
ldmain(argc, argv);
}
void void
linkarchinit(void) linkarchinit(void)
...@@ -47,6 +51,45 @@ linkarchinit(void) ...@@ -47,6 +51,45 @@ linkarchinit(void)
thelinkarch = &linkppc64le; thelinkarch = &linkppc64le;
else else
thelinkarch = &linkppc64; thelinkarch = &linkppc64;
thearch.thechar = thechar;
thearch.ptrsize = thelinkarch->ptrsize;
thearch.intsize = thelinkarch->ptrsize;
thearch.regsize = thelinkarch->regsize;
thearch.funcalign = FuncAlign;
thearch.maxalign = MaxAlign;
thearch.minlc = MINLC;
thearch.dwarfregsp = DWARFREGSP;
thearch.adddynlib = adddynlib;
thearch.adddynrel = adddynrel;
thearch.adddynsym = adddynsym;
thearch.archinit = archinit;
thearch.archreloc = archreloc;
thearch.archrelocvariant = archrelocvariant;
thearch.asmb = asmb;
thearch.elfreloc1 = elfreloc1;
thearch.elfsetupplt = elfsetupplt;
thearch.gentext = gentext;
thearch.listinit = listinit;
thearch.machoreloc1 = machoreloc1;
if(thelinkarch == &linkppc64le) {
thearch.lput = lputl;
thearch.wput = wputl;
thearch.vput = vputl;
} else {
thearch.lput = lputb;
thearch.wput = wputb;
thearch.vput = vputb;
}
// TODO(austin): ABI v1 uses /usr/lib/ld.so.1
thearch.linuxdynld = "/lib64/ld64.so.1";
thearch.freebsddynld = "XXX";
thearch.openbsddynld = "XXX";
thearch.netbsddynld = "XXX";
thearch.dragonflydynld = "XXX";
thearch.solarisdynld = "XXX";
} }
void void
......
...@@ -529,16 +529,16 @@ var deptab = []struct { ...@@ -529,16 +529,16 @@ var deptab = []struct {
"$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libgc.a", "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libgc.a",
}}, }},
{"cmd/5l", []string{ {"cmd/5l", []string{
"../ld/*", "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libld.a",
}}, }},
{"cmd/6l", []string{ {"cmd/6l", []string{
"../ld/*", "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libld.a",
}}, }},
{"cmd/8l", []string{ {"cmd/8l", []string{
"../ld/*", "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libld.a",
}}, }},
{"cmd/9l", []string{ {"cmd/9l", []string{
"../ld/*", "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libld.a",
}}, }},
{"cmd/go", []string{ {"cmd/go", []string{
"zdefaultcc.go", "zdefaultcc.go",
...@@ -624,7 +624,7 @@ func install(dir string) { ...@@ -624,7 +624,7 @@ func install(dir string) {
ldargs = splitfields(defaultldflags) ldargs = splitfields(defaultldflags)
} }
islib := strings.HasPrefix(dir, "lib") || dir == "cmd/gc" islib := strings.HasPrefix(dir, "lib") || dir == "cmd/gc" || dir == "cmd/ld"
ispkg := !islib && !strings.HasPrefix(dir, "cmd/") ispkg := !islib && !strings.HasPrefix(dir, "cmd/")
isgo := ispkg || dir == "cmd/go" || dir == "cmd/cgo" isgo := ispkg || dir == "cmd/go" || dir == "cmd/cgo"
...@@ -1101,6 +1101,7 @@ var buildorder = []string{ ...@@ -1101,6 +1101,7 @@ var buildorder = []string{
"liblink", "liblink",
"cmd/gc", // must be before g "cmd/gc", // must be before g
"cmd/ld", // must be before l
"cmd/%sl", // must be before a, g "cmd/%sl", // must be before a, g
"cmd/%sa", "cmd/%sa",
"cmd/%sg", "cmd/%sg",
......
# 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.dist
This diff is collapsed.
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
#include "l.h" #include <u.h>
#include <libc.h>
#include <bio.h>
#include <link.h>
#include "lib.h" #include "lib.h"
#include "../../runtime/typekind.h" #include "../../runtime/typekind.h"
...@@ -70,42 +73,42 @@ decode_inuxi(uchar* p, int sz) ...@@ -70,42 +73,42 @@ decode_inuxi(uchar* p, int sz)
static int static int
commonsize(void) commonsize(void)
{ {
return 8*PtrSize + 8; return 8*thearch.ptrsize + 8;
} }
// Type.commonType.kind // Type.commonType.kind
uint8 uint8
decodetype_kind(LSym *s) decodetype_kind(LSym *s)
{ {
return s->p[1*PtrSize + 7] & KindMask; // 0x13 / 0x1f return s->p[1*thearch.ptrsize + 7] & KindMask; // 0x13 / 0x1f
} }
// Type.commonType.kind // Type.commonType.kind
uint8 uint8
decodetype_noptr(LSym *s) decodetype_noptr(LSym *s)
{ {
return s->p[1*PtrSize + 7] & KindNoPointers; // 0x13 / 0x1f return s->p[1*thearch.ptrsize + 7] & KindNoPointers; // 0x13 / 0x1f
} }
// Type.commonType.kind // Type.commonType.kind
uint8 uint8
decodetype_usegcprog(LSym *s) decodetype_usegcprog(LSym *s)
{ {
return s->p[1*PtrSize + 7] & KindGCProg; // 0x13 / 0x1f return s->p[1*thearch.ptrsize + 7] & KindGCProg; // 0x13 / 0x1f
} }
// Type.commonType.size // Type.commonType.size
vlong vlong
decodetype_size(LSym *s) decodetype_size(LSym *s)
{ {
return decode_inuxi(s->p, PtrSize); // 0x8 / 0x10 return decode_inuxi(s->p, thearch.ptrsize); // 0x8 / 0x10
} }
// Type.commonType.gc // Type.commonType.gc
LSym* LSym*
decodetype_gcprog(LSym *s) decodetype_gcprog(LSym *s)
{ {
return decode_reloc_sym(s, 1*PtrSize + 8 + 2*PtrSize); return decode_reloc_sym(s, 1*thearch.ptrsize + 8 + 2*thearch.ptrsize);
} }
uint8* uint8*
...@@ -113,7 +116,7 @@ decodetype_gcmask(LSym *s) ...@@ -113,7 +116,7 @@ decodetype_gcmask(LSym *s)
{ {
LSym *mask; LSym *mask;
mask = decode_reloc_sym(s, 1*PtrSize + 8 + 1*PtrSize); mask = decode_reloc_sym(s, 1*thearch.ptrsize + 8 + 1*thearch.ptrsize);
return mask->p; return mask->p;
} }
...@@ -127,7 +130,7 @@ decodetype_arrayelem(LSym *s) ...@@ -127,7 +130,7 @@ decodetype_arrayelem(LSym *s)
vlong vlong
decodetype_arraylen(LSym *s) decodetype_arraylen(LSym *s)
{ {
return decode_inuxi(s->p + commonsize()+2*PtrSize, PtrSize); return decode_inuxi(s->p + commonsize()+2*thearch.ptrsize, thearch.ptrsize);
} }
// Type.PtrType.elem // Type.PtrType.elem
...@@ -147,7 +150,7 @@ decodetype_mapkey(LSym *s) ...@@ -147,7 +150,7 @@ decodetype_mapkey(LSym *s)
LSym* LSym*
decodetype_mapvalue(LSym *s) decodetype_mapvalue(LSym *s)
{ {
return decode_reloc_sym(s, commonsize()+PtrSize); // 0x20 / 0x38 return decode_reloc_sym(s, commonsize()+thearch.ptrsize); // 0x20 / 0x38
} }
// Type.ChanType.elem // Type.ChanType.elem
...@@ -168,13 +171,13 @@ decodetype_funcdotdotdot(LSym *s) ...@@ -168,13 +171,13 @@ decodetype_funcdotdotdot(LSym *s)
int int
decodetype_funcincount(LSym *s) decodetype_funcincount(LSym *s)
{ {
return decode_inuxi(s->p + commonsize()+2*PtrSize, IntSize); return decode_inuxi(s->p + commonsize()+2*thearch.ptrsize, thearch.intsize);
} }
int int
decodetype_funcoutcount(LSym *s) decodetype_funcoutcount(LSym *s)
{ {
return decode_inuxi(s->p + commonsize()+3*PtrSize + 2*IntSize, IntSize); return decode_inuxi(s->p + commonsize()+3*thearch.ptrsize + 2*thearch.intsize, thearch.intsize);
} }
LSym* LSym*
...@@ -182,10 +185,10 @@ decodetype_funcintype(LSym *s, int i) ...@@ -182,10 +185,10 @@ decodetype_funcintype(LSym *s, int i)
{ {
Reloc *r; Reloc *r;
r = decode_reloc(s, commonsize() + PtrSize); r = decode_reloc(s, commonsize() + thearch.ptrsize);
if (r == nil) if (r == nil)
return nil; return nil;
return decode_reloc_sym(r->sym, r->add + i * PtrSize); return decode_reloc_sym(r->sym, r->add + i * thearch.ptrsize);
} }
LSym* LSym*
...@@ -193,23 +196,23 @@ decodetype_funcouttype(LSym *s, int i) ...@@ -193,23 +196,23 @@ decodetype_funcouttype(LSym *s, int i)
{ {
Reloc *r; Reloc *r;
r = decode_reloc(s, commonsize() + 2*PtrSize + 2*IntSize); r = decode_reloc(s, commonsize() + 2*thearch.ptrsize + 2*thearch.intsize);
if (r == nil) if (r == nil)
return nil; return nil;
return decode_reloc_sym(r->sym, r->add + i * PtrSize); return decode_reloc_sym(r->sym, r->add + i * thearch.ptrsize);
} }
// Type.StructType.fields.Slice::len // Type.StructType.fields.Slice::len
int int
decodetype_structfieldcount(LSym *s) decodetype_structfieldcount(LSym *s)
{ {
return decode_inuxi(s->p + commonsize() + PtrSize, IntSize); return decode_inuxi(s->p + commonsize() + thearch.ptrsize, thearch.intsize);
} }
static int static int
structfieldsize(void) structfieldsize(void)
{ {
return 5*PtrSize; return 5*thearch.ptrsize;
} }
// Type.StructType.fields[]-> name, typ and offset. // Type.StructType.fields[]-> name, typ and offset.
...@@ -219,7 +222,7 @@ decodetype_structfieldname(LSym *s, int i) ...@@ -219,7 +222,7 @@ decodetype_structfieldname(LSym *s, int i)
Reloc *r; Reloc *r;
// go.string."foo" 0x28 / 0x40 // go.string."foo" 0x28 / 0x40
s = decode_reloc_sym(s, commonsize() + PtrSize + 2*IntSize + i*structfieldsize()); s = decode_reloc_sym(s, commonsize() + thearch.ptrsize + 2*thearch.intsize + i*structfieldsize());
if (s == nil) // embedded structs have a nil name. if (s == nil) // embedded structs have a nil name.
return nil; return nil;
r = decode_reloc(s, 0); // s has a pointer to the string data at offset 0 r = decode_reloc(s, 0); // s has a pointer to the string data at offset 0
...@@ -231,18 +234,18 @@ decodetype_structfieldname(LSym *s, int i) ...@@ -231,18 +234,18 @@ decodetype_structfieldname(LSym *s, int i)
LSym* LSym*
decodetype_structfieldtype(LSym *s, int i) decodetype_structfieldtype(LSym *s, int i)
{ {
return decode_reloc_sym(s, commonsize() + PtrSize + 2*IntSize + i*structfieldsize() + 2*PtrSize); return decode_reloc_sym(s, commonsize() + thearch.ptrsize + 2*thearch.intsize + i*structfieldsize() + 2*thearch.ptrsize);
} }
vlong vlong
decodetype_structfieldoffs(LSym *s, int i) decodetype_structfieldoffs(LSym *s, int i)
{ {
return decode_inuxi(s->p + commonsize() + PtrSize + 2*IntSize + i*structfieldsize() + 4*PtrSize, IntSize); return decode_inuxi(s->p + commonsize() + thearch.ptrsize + 2*thearch.intsize + i*structfieldsize() + 4*thearch.ptrsize, thearch.intsize);
} }
// InterfaceTYpe.methods.len // InterfaceTYpe.methods.len
vlong vlong
decodetype_ifacemethodcount(LSym *s) decodetype_ifacemethodcount(LSym *s)
{ {
return decode_inuxi(s->p + commonsize() + PtrSize, IntSize); return decode_inuxi(s->p + commonsize() + thearch.ptrsize, thearch.intsize);
} }
This diff is collapsed.
This diff is collapsed.
...@@ -1021,12 +1021,6 @@ void dwarfaddelfsectionsyms(void); ...@@ -1021,12 +1021,6 @@ void dwarfaddelfsectionsyms(void);
void dwarfaddelfheaders(void); void dwarfaddelfheaders(void);
void asmbelf(vlong symo); void asmbelf(vlong symo);
void asmbelfsetup(void); void asmbelfsetup(void);
extern char linuxdynld[];
extern char freebsddynld[];
extern char netbsddynld[];
extern char openbsddynld[];
extern char dragonflydynld[];
extern char solarisdynld[];
int elfreloc1(Reloc*, vlong sectoff); int elfreloc1(Reloc*, vlong sectoff);
void putelfsectionsyms(void); void putelfsectionsyms(void);
......
...@@ -4,8 +4,11 @@ ...@@ -4,8 +4,11 @@
// go-specific code shared across loaders (5l, 6l, 8l). // go-specific code shared across loaders (5l, 6l, 8l).
#include "l.h" #include <u.h>
#include "../ld/lib.h" #include <libc.h>
#include <bio.h>
#include <link.h>
#include "lib.h"
// accumulate all type information from .6 files. // accumulate all type information from .6 files.
// check for inconsistencies. // check for inconsistencies.
...@@ -401,7 +404,7 @@ loadcgo(char *file, char *pkg, char *p, int n) ...@@ -401,7 +404,7 @@ loadcgo(char *file, char *pkg, char *p, int n)
// allow #pragma dynimport _ _ "foo.so" // allow #pragma dynimport _ _ "foo.so"
// to force a link of foo.so. // to force a link of foo.so.
havedynamic = 1; havedynamic = 1;
adddynlib(lib); thearch.adddynlib(lib);
continue; continue;
} }
...@@ -518,7 +521,7 @@ static LSym *emarkq; ...@@ -518,7 +521,7 @@ static LSym *emarkq;
static void static void
mark1(LSym *s, LSym *parent) mark1(LSym *s, LSym *parent)
{ {
if(s == S || s->reachable) if(s == nil || s->reachable)
return; return;
if(strncmp(s->name, "go.weak.", 8) == 0) if(strncmp(s->name, "go.weak.", 8) == 0)
return; return;
...@@ -544,7 +547,7 @@ markflood(void) ...@@ -544,7 +547,7 @@ markflood(void)
LSym *s; LSym *s;
int i; int i;
for(s=markq; s!=S; s=s->queue) { for(s=markq; s!=nil; s=s->queue) {
if(s->type == STEXT) { if(s->type == STEXT) {
if(debug['v'] > 1) if(debug['v'] > 1)
Bprint(&bso, "marktext %s\n", s->name); Bprint(&bso, "marktext %s\n", s->name);
...@@ -608,7 +611,7 @@ deadcode(void) ...@@ -608,7 +611,7 @@ deadcode(void)
markflood(); markflood();
// keep each beginning with 'typelink.' if the symbol it points at is being kept. // keep each beginning with 'typelink.' if the symbol it points at is being kept.
for(s = ctxt->allsym; s != S; s = s->allsym) { for(s = ctxt->allsym; s != nil; s = s->allsym) {
if(strncmp(s->name, "go.typelink.", 12) == 0) if(strncmp(s->name, "go.typelink.", 12) == 0)
s->reachable = s->nr==1 && s->r[0].sym->reachable; s->reachable = s->nr==1 && s->r[0].sym->reachable;
} }
...@@ -630,7 +633,7 @@ deadcode(void) ...@@ -630,7 +633,7 @@ deadcode(void)
else else
last->next = nil; last->next = nil;
for(s = ctxt->allsym; s != S; s = s->allsym) for(s = ctxt->allsym; s != nil; s = s->allsym)
if(strncmp(s->name, "go.weak.", 8) == 0) { if(strncmp(s->name, "go.weak.", 8) == 0) {
s->special = 1; // do not lay out in data segment s->special = 1; // do not lay out in data segment
s->reachable = 1; s->reachable = 1;
...@@ -639,7 +642,7 @@ deadcode(void) ...@@ -639,7 +642,7 @@ deadcode(void)
// record field tracking references // record field tracking references
fmtstrinit(&fmt); fmtstrinit(&fmt);
for(s = ctxt->allsym; s != S; s = s->allsym) { for(s = ctxt->allsym; s != nil; s = s->allsym) {
if(strncmp(s->name, "go.track.", 9) == 0) { if(strncmp(s->name, "go.track.", 9) == 0) {
s->special = 1; // do not lay out in data segment s->special = 1; // do not lay out in data segment
s->hide = 1; s->hide = 1;
...@@ -668,7 +671,7 @@ doweak(void) ...@@ -668,7 +671,7 @@ doweak(void)
// resolve weak references only if // resolve weak references only if
// target symbol will be in binary anyway. // target symbol will be in binary anyway.
for(s = ctxt->allsym; s != S; s = s->allsym) { for(s = ctxt->allsym; s != nil; s = s->allsym) {
if(strncmp(s->name, "go.weak.", 8) == 0) { if(strncmp(s->name, "go.weak.", 8) == 0) {
t = linkrlookup(ctxt, s->name+8, s->version); t = linkrlookup(ctxt, s->name+8, s->version);
if(t && t->type != 0 && t->reachable) { if(t && t->type != 0 && t->reachable) {
...@@ -693,7 +696,7 @@ addexport(void) ...@@ -693,7 +696,7 @@ addexport(void)
return; return;
for(i=0; i<ndynexp; i++) for(i=0; i<ndynexp; i++)
adddynsym(ctxt, dynexp[i]); thearch.adddynsym(ctxt, dynexp[i]);
} }
/* %Z from gc, for quoting import paths */ /* %Z from gc, for quoting import paths */
......
...@@ -25,9 +25,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ...@@ -25,9 +25,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
*/ */
#include "l.h" #include <u.h>
#include <libc.h>
#include <bio.h>
#include <link.h>
#include "lib.h" #include "lib.h"
#include "../ld/elf.h" #include "elf.h"
enum enum
{ {
...@@ -414,7 +417,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -414,7 +417,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
return; return;
} }
switch(thechar) { switch(thearch.thechar) {
default: default:
diag("%s: elf %s unimplemented", pn, thestring); diag("%s: elf %s unimplemented", pn, thestring);
return; return;
...@@ -590,7 +593,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -590,7 +593,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
if(sym.shndx >= obj->nsect || sym.shndx == 0) if(sym.shndx >= obj->nsect || sym.shndx == 0)
continue; continue;
// even when we pass needSym == 1 to readsym, it might still return nil to skip some unwanted symbols // even when we pass needSym == 1 to readsym, it might still return nil to skip some unwanted symbols
if(sym.sym == S) if(sym.sym == nil)
continue; continue;
sect = obj->sect+sym.shndx; sect = obj->sect+sym.shndx;
if(sect->sym == nil) { if(sect->sym == nil) {
...@@ -600,7 +603,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -600,7 +603,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
continue; continue;
} }
s = sym.sym; s = sym.sym;
if(s->outer != S) { if(s->outer != nil) {
if(s->dupok) if(s->dupok)
continue; continue;
diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s->name, s->outer->name, sect->sym->name); diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s->name, s->outer->name, sect->sym->name);
...@@ -632,7 +635,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -632,7 +635,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
// This keeps textp in increasing address order. // This keeps textp in increasing address order.
for(i=0; i<obj->nsect; i++) { for(i=0; i<obj->nsect; i++) {
s = obj->sect[i].sym; s = obj->sect[i].sym;
if(s == S) if(s == nil)
continue; continue;
if(s->sub) if(s->sub)
s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub)); s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub));
...@@ -645,7 +648,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -645,7 +648,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
else else
ctxt->textp = s; ctxt->textp = s;
ctxt->etextp = s; ctxt->etextp = s;
for(s = s->sub; s != S; s = s->sub) { for(s = s->sub; s != nil; s = s->sub) {
if(s->onlist) if(s->onlist)
sysfatal("symbol %s listed multiple times", s->name); sysfatal("symbol %s listed multiple times", s->name);
s->onlist = 1; s->onlist = 1;
...@@ -700,7 +703,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -700,7 +703,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
continue; continue;
} }
if((info >> 32) == 0) { // absolute relocation, don't bother reading the null symbol if((info >> 32) == 0) { // absolute relocation, don't bother reading the null symbol
rp->sym = S; rp->sym = nil;
} else { } else {
if(readsym(obj, info>>32, &sym, 0) < 0) if(readsym(obj, info>>32, &sym, 0) < 0)
goto bad; goto bad;
...@@ -844,7 +847,7 @@ readsym(ElfObj *obj, int i, ElfSym *sym, int needSym) ...@@ -844,7 +847,7 @@ readsym(ElfObj *obj, int i, ElfSym *sym, int needSym)
} }
break; break;
case ElfSymBindLocal: case ElfSymBindLocal:
if(thechar == '5' && (strncmp(sym->name, "$a", 2) == 0 || strncmp(sym->name, "$d", 2) == 0)) { if(thearch.thechar == '5' && (strncmp(sym->name, "$a", 2) == 0 || strncmp(sym->name, "$d", 2) == 0)) {
// binutils for arm generate these mapping // binutils for arm generate these mapping
// symbols, ignore these // symbols, ignore these
break; break;
...@@ -905,7 +908,7 @@ rbyoff(const void *va, const void *vb) ...@@ -905,7 +908,7 @@ rbyoff(const void *va, const void *vb)
static int static int
reltype(char *pn, int elftype, uchar *siz) reltype(char *pn, int elftype, uchar *siz)
{ {
switch(R(thechar, elftype)) { switch(R(thearch.thechar, elftype)) {
default: default:
diag("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype); diag("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype);
case R('9', R_PPC64_TOC16): case R('9', R_PPC64_TOC16):
......
...@@ -25,7 +25,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ...@@ -25,7 +25,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
*/ */
#include "l.h" #include <u.h>
#include <libc.h>
#include <bio.h>
#include <link.h>
#include "lib.h" #include "lib.h"
enum { enum {
...@@ -477,7 +480,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -477,7 +480,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
m->len = len; m->len = len;
m->name = pn; m->name = pn;
switch(thechar) { switch(thearch.thechar) {
default: default:
diag("%s: mach-o %s unimplemented", pn, thestring); diag("%s: mach-o %s unimplemented", pn, thestring);
return; return;
...@@ -627,7 +630,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -627,7 +630,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
werrstr("reference to invalid section %s/%s", sect->segname, sect->name); werrstr("reference to invalid section %s/%s", sect->segname, sect->name);
continue; continue;
} }
if(s->outer != S) { if(s->outer != nil) {
if(s->dupok) if(s->dupok)
continue; continue;
diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s->name, s->outer->name, sect->sym->name); diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s->name, s->outer->name, sect->sym->name);
...@@ -652,13 +655,13 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -652,13 +655,13 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
// This keeps textp in increasing address order. // This keeps textp in increasing address order.
for(i=0; i<c->seg.nsect; i++) { for(i=0; i<c->seg.nsect; i++) {
sect = &c->seg.sect[i]; sect = &c->seg.sect[i];
if((s = sect->sym) == S) if((s = sect->sym) == nil)
continue; continue;
if(s->sub) { if(s->sub) {
s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub)); s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub));
// assign sizes, now that we know symbols in sorted order. // assign sizes, now that we know symbols in sorted order.
for(s1 = s->sub; s1 != S; s1 = s1->sub) { for(s1 = s->sub; s1 != nil; s1 = s1->sub) {
if(s1->sub) if(s1->sub)
s1->size = s1->sub->value - s1->value; s1->size = s1->sub->value - s1->value;
else else
...@@ -674,7 +677,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -674,7 +677,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
else else
ctxt->textp = s; ctxt->textp = s;
ctxt->etextp = s; ctxt->etextp = s;
for(s1 = s->sub; s1 != S; s1 = s1->sub) { for(s1 = s->sub; s1 != nil; s1 = s1->sub) {
if(s1->onlist) if(s1->onlist)
sysfatal("symbol %s listed multiple times", s1->name); sysfatal("symbol %s listed multiple times", s1->name);
s1->onlist = 1; s1->onlist = 1;
...@@ -687,7 +690,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -687,7 +690,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
// load relocations // load relocations
for(i=0; i<c->seg.nsect; i++) { for(i=0; i<c->seg.nsect; i++) {
sect = &c->seg.sect[i]; sect = &c->seg.sect[i];
if((s = sect->sym) == S) if((s = sect->sym) == nil)
continue; continue;
macholoadrel(m, sect); macholoadrel(m, sect);
if(sect->rel == nil) if(sect->rel == nil)
...@@ -700,7 +703,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -700,7 +703,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
int k; int k;
MachoSect *ks; MachoSect *ks;
if(thechar != '8') { if(thearch.thechar != '8') {
// mach-o only uses scattered relocation on 32-bit platforms // mach-o only uses scattered relocation on 32-bit platforms
diag("unexpected scattered relocation"); diag("unexpected scattered relocation");
continue; continue;
...@@ -750,7 +753,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -750,7 +753,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
werrstr("unsupported scattered relocation: invalid address %#ux", rel->addr); werrstr("unsupported scattered relocation: invalid address %#ux", rel->addr);
goto bad; goto bad;
foundk: foundk:
if(ks->sym != S) { if(ks->sym != nil) {
rp->sym = ks->sym; rp->sym = ks->sym;
rp->add += rel->value - ks->addr; rp->add += rel->value - ks->addr;
} else if(strcmp(ks->segname, "__IMPORT") == 0 && strcmp(ks->name, "__pointers") == 0) { } else if(strcmp(ks->segname, "__IMPORT") == 0 && strcmp(ks->name, "__pointers") == 0) {
...@@ -788,7 +791,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -788,7 +791,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
rp->off = rel->addr; rp->off = rel->addr;
// Handle X86_64_RELOC_SIGNED referencing a section (rel->extrn == 0). // Handle X86_64_RELOC_SIGNED referencing a section (rel->extrn == 0).
if (thechar == '6' && rel->extrn == 0 && rel->type == 1) { if (thearch.thechar == '6' && rel->extrn == 0 && rel->type == 1) {
// Calculate the addend as the offset into the section. // Calculate the addend as the offset into the section.
// //
// The rip-relative offset stored in the object file is encoded // The rip-relative offset stored in the object file is encoded
...@@ -812,7 +815,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -812,7 +815,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
// For i386 Mach-O PC-relative, the addend is written such that // For i386 Mach-O PC-relative, the addend is written such that
// it *is* the PC being subtracted. Use that to make // it *is* the PC being subtracted. Use that to make
// it match our version of PC-relative. // it match our version of PC-relative.
if(rel->pcrel && thechar == '8') if(rel->pcrel && thearch.thechar == '8')
rp->add += rp->off+rp->siz; rp->add += rp->off+rp->siz;
if(!rel->extrn) { if(!rel->extrn) {
if(rel->symnum < 1 || rel->symnum > c->seg.nsect) { if(rel->symnum < 1 || rel->symnum > c->seg.nsect) {
...@@ -828,7 +831,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -828,7 +831,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
// include that information in the addend. // include that information in the addend.
// We only care about the delta from the // We only care about the delta from the
// section base. // section base.
if(thechar == '8') if(thearch.thechar == '8')
rp->add -= c->seg.sect[rel->symnum-1].addr; rp->add -= c->seg.sect[rel->symnum-1].addr;
} else { } else {
if(rel->symnum >= symtab->nsym) { if(rel->symnum >= symtab->nsym) {
......
...@@ -2,9 +2,12 @@ ...@@ -2,9 +2,12 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
#include "l.h" #include <u.h>
#include <libc.h>
#include <bio.h>
#include <link.h>
#include "lib.h" #include "lib.h"
#include "../ld/pe.h" #include "pe.h"
#define IMAGE_SCN_MEM_DISCARDABLE 0x2000000 #define IMAGE_SCN_MEM_DISCARDABLE 0x2000000
...@@ -363,7 +366,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -363,7 +366,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
if(sect == nil) if(sect == nil)
return; return;
if(s->outer != S) { if(s->outer != nil) {
if(s->dupok) if(s->dupok)
continue; continue;
diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s->name, s->outer->name, sect->sym->name); diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s->name, s->outer->name, sect->sym->name);
...@@ -386,7 +389,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -386,7 +389,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
// This keeps textp in increasing address order. // This keeps textp in increasing address order.
for(i=0; i<obj->nsect; i++) { for(i=0; i<obj->nsect; i++) {
s = obj->sect[i].sym; s = obj->sect[i].sym;
if(s == S) if(s == nil)
continue; continue;
if(s->sub) if(s->sub)
s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub)); s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub));
...@@ -399,7 +402,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -399,7 +402,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
else else
ctxt->textp = s; ctxt->textp = s;
ctxt->etextp = s; ctxt->etextp = s;
for(s = s->sub; s != S; s = s->sub) { for(s = s->sub; s != nil; s = s->sub) {
if(s->onlist) if(s->onlist)
sysfatal("symbol %s listed multiple times", s->name); sysfatal("symbol %s listed multiple times", s->name);
s->onlist = 1; s->onlist = 1;
...@@ -458,7 +461,7 @@ readsym(PeObj *obj, int i, PeSym **y) ...@@ -458,7 +461,7 @@ readsym(PeObj *obj, int i, PeSym **y)
name = sym->name; name = sym->name;
if(strncmp(name, "__imp_", 6) == 0) if(strncmp(name, "__imp_", 6) == 0)
name = &name[6]; // __imp_Name => Name name = &name[6]; // __imp_Name => Name
if(thechar == '8' && name[0] == '_') if(thearch.thechar == '8' && name[0] == '_')
name = &name[1]; // _Name => Name name = &name[1]; // _Name => Name
} }
// remove last @XXX // remove last @XXX
......
...@@ -29,10 +29,13 @@ ...@@ -29,10 +29,13 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include "l.h" #include <u.h>
#include <libc.h>
#include <bio.h>
#include <link.h>
#include "lib.h" #include "lib.h"
#include "../ld/elf.h" #include "elf.h"
#include "../ld/dwarf.h" #include "dwarf.h"
#include "../../runtime/stack.h" #include "../../runtime/stack.h"
#include "../../runtime/funcdata.h" #include "../../runtime/funcdata.h"
...@@ -105,7 +108,7 @@ libinit(void) ...@@ -105,7 +108,7 @@ libinit(void)
{ {
char *suffix, *suffixsep; char *suffix, *suffixsep;
funcalign = FuncAlign; funcalign = thearch.funcalign;
fmtinstall('i', iconv); fmtinstall('i', iconv);
fmtinstall('Y', Yconv); fmtinstall('Y', Yconv);
fmtinstall('Z', Zconv); fmtinstall('Z', Zconv);
...@@ -191,7 +194,7 @@ loadlib(void) ...@@ -191,7 +194,7 @@ loadlib(void)
} }
loadinternal("runtime"); loadinternal("runtime");
if(thechar == '5') if(thearch.thechar == '5')
loadinternal("math"); loadinternal("math");
if(flag_race) if(flag_race)
loadinternal("runtime/race"); loadinternal("runtime/race");
...@@ -218,7 +221,7 @@ loadlib(void) ...@@ -218,7 +221,7 @@ loadlib(void)
// dependency problems when compiling natively (external linking requires // dependency problems when compiling natively (external linking requires
// runtime/cgo, runtime/cgo requires cmd/cgo, but cmd/cgo needs to be // runtime/cgo, runtime/cgo requires cmd/cgo, but cmd/cgo needs to be
// compiled using external linking.) // compiled using external linking.)
if(thechar == '5' && HEADTYPE == Hdarwin && iscgo) if(thearch.thechar == '5' && HEADTYPE == Hdarwin && iscgo)
linkmode = LinkExternal; linkmode = LinkExternal;
} }
...@@ -251,7 +254,7 @@ loadlib(void) ...@@ -251,7 +254,7 @@ loadlib(void)
if(linkmode == LinkInternal) { if(linkmode == LinkInternal) {
// Drop all the cgo_import_static declarations. // Drop all the cgo_import_static declarations.
// Turns out we won't be needing them. // Turns out we won't be needing them.
for(s = ctxt->allsym; s != S; s = s->allsym) for(s = ctxt->allsym; s != nil; s = s->allsym)
if(s->type == SHOSTOBJ) { if(s->type == SHOSTOBJ) {
// If a symbol was marked both // If a symbol was marked both
// cgo_import_static and cgo_import_dynamic, // cgo_import_static and cgo_import_dynamic,
...@@ -272,7 +275,7 @@ loadlib(void) ...@@ -272,7 +275,7 @@ loadlib(void)
// when the runtime has not declared its type already. // when the runtime has not declared its type already.
if(tlsg->type == 0) if(tlsg->type == 0)
tlsg->type = STLSBSS; tlsg->type = STLSBSS;
tlsg->size = PtrSize; tlsg->size = thearch.ptrsize;
tlsg->hide = 1; tlsg->hide = 1;
tlsg->reachable = 1; tlsg->reachable = 1;
ctxt->tlsg = tlsg; ctxt->tlsg = tlsg;
...@@ -440,7 +443,7 @@ dowrite(int fd, char *p, int n) ...@@ -440,7 +443,7 @@ dowrite(int fd, char *p, int n)
while(n > 0) { while(n > 0) {
m = write(fd, p, n); m = write(fd, p, n);
if(m <= 0) { if(m <= 0) {
ctxt->cursym = S; ctxt->cursym = nil;
diag("write error: %r"); diag("write error: %r");
errorexit(); errorexit();
} }
...@@ -529,7 +532,7 @@ hostobjs(void) ...@@ -529,7 +532,7 @@ hostobjs(void)
h = &hostobj[i]; h = &hostobj[i];
f = Bopen(h->file, OREAD); f = Bopen(h->file, OREAD);
if(f == nil) { if(f == nil) {
ctxt->cursym = S; ctxt->cursym = nil;
diag("cannot reopen %s: %r", h->pn); diag("cannot reopen %s: %r", h->pn);
errorexit(); errorexit();
} }
...@@ -603,7 +606,7 @@ hostlink(void) ...@@ -603,7 +606,7 @@ hostlink(void)
if(extld == nil) if(extld == nil)
extld = "gcc"; extld = "gcc";
argv[argc++] = extld; argv[argc++] = extld;
switch(thechar){ switch(thearch.thechar){
case '8': case '8':
argv[argc++] = "-m32"; argv[argc++] = "-m32";
break; break;
...@@ -651,7 +654,7 @@ hostlink(void) ...@@ -651,7 +654,7 @@ hostlink(void)
h = &hostobj[i]; h = &hostobj[i];
f = Bopen(h->file, OREAD); f = Bopen(h->file, OREAD);
if(f == nil) { if(f == nil) {
ctxt->cursym = S; ctxt->cursym = nil;
diag("cannot reopen %s: %r", h->pn); diag("cannot reopen %s: %r", h->pn);
errorexit(); errorexit();
} }
...@@ -660,7 +663,7 @@ hostlink(void) ...@@ -660,7 +663,7 @@ hostlink(void)
argv[argc++] = p; argv[argc++] = p;
w = create(p, 1, 0775); w = create(p, 1, 0775);
if(w < 0) { if(w < 0) {
ctxt->cursym = S; ctxt->cursym = nil;
diag("cannot create %s: %r", p); diag("cannot create %s: %r", p);
errorexit(); errorexit();
} }
...@@ -672,7 +675,7 @@ hostlink(void) ...@@ -672,7 +675,7 @@ hostlink(void)
len -= n; len -= n;
} }
if(close(w) < 0) { if(close(w) < 0) {
ctxt->cursym = S; ctxt->cursym = nil;
diag("cannot write %s: %r", p); diag("cannot write %s: %r", p);
errorexit(); errorexit();
} }
...@@ -719,7 +722,7 @@ hostlink(void) ...@@ -719,7 +722,7 @@ hostlink(void)
} }
if(runcmd(argv) < 0) { if(runcmd(argv) < 0) {
ctxt->cursym = S; ctxt->cursym = nil;
diag("%s: running %s failed: %r", argv0, argv[0]); diag("%s: running %s failed: %r", argv0, argv[0]);
errorexit(); errorexit();
} }
...@@ -774,7 +777,7 @@ ldobj(Biobuf *f, char *pkg, int64 len, char *pn, char *file, int whence) ...@@ -774,7 +777,7 @@ ldobj(Biobuf *f, char *pkg, int64 len, char *pn, char *file, int whence)
line[n] = '\0'; line[n] = '\0';
if(strncmp(line, "go object ", 10) != 0) { if(strncmp(line, "go object ", 10) != 0) {
if(strlen(pn) > 3 && strcmp(pn+strlen(pn)-3, ".go") == 0) { if(strlen(pn) > 3 && strcmp(pn+strlen(pn)-3, ".go") == 0) {
print("%cl: input %s is not .%c file (use %cg to compile .go files)\n", thechar, pn, thechar, thechar); print("%cl: input %s is not .%c file (use %cg to compile .go files)\n", thearch.thechar, pn, thearch.thechar, thearch.thechar);
errorexit(); errorexit();
} }
if(strcmp(line, thestring) == 0) { if(strcmp(line, thestring) == 0) {
...@@ -860,7 +863,7 @@ mywhatsys(void) ...@@ -860,7 +863,7 @@ mywhatsys(void)
goarch = getgoarch(); goarch = getgoarch();
if(strncmp(goarch, thestring, strlen(thestring)) != 0) if(strncmp(goarch, thestring, strlen(thestring)) != 0)
sysfatal("cannot use %cc with GOARCH=%s", thechar, goarch); sysfatal("cannot use %cc with GOARCH=%s", thearch.thechar, goarch);
} }
int int
...@@ -988,7 +991,7 @@ addsection(Segment *seg, char *name, int rwx) ...@@ -988,7 +991,7 @@ addsection(Segment *seg, char *name, int rwx)
sect->rwx = rwx; sect->rwx = rwx;
sect->name = name; sect->name = name;
sect->seg = seg; sect->seg = seg;
sect->align = PtrSize; // everything is at least pointer-aligned sect->align = thearch.ptrsize; // everything is at least pointer-aligned
*l = sect; *l = sect;
return sect; return sect;
} }
...@@ -1046,20 +1049,21 @@ static void stkbroke(Chain*, int); ...@@ -1046,20 +1049,21 @@ static void stkbroke(Chain*, int);
static LSym *morestack; static LSym *morestack;
static LSym *newstack; static LSym *newstack;
enum
{
HasLinkRegister = (thechar == '5' || thechar == '9'),
};
// TODO: Record enough information in new object files to // TODO: Record enough information in new object files to
// allow stack checks here. // allow stack checks here.
static int
haslinkregister(void)
{
return thearch.thechar == '5' || thearch.thechar == '9';
}
static int static int
callsize(void) callsize(void)
{ {
if(HasLinkRegister) if(haslinkregister())
return 0; return 0;
return RegSize; return thearch.regsize;
} }
void void
...@@ -1180,8 +1184,8 @@ stkcheck(Chain *up, int depth) ...@@ -1180,8 +1184,8 @@ stkcheck(Chain *up, int depth)
// to StackLimit beyond the frame size. // to StackLimit beyond the frame size.
if(strncmp(r->sym->name, "runtime.morestack", 17) == 0) { if(strncmp(r->sym->name, "runtime.morestack", 17) == 0) {
limit = StackLimit + s->locals; limit = StackLimit + s->locals;
if(HasLinkRegister) if(haslinkregister())
limit += RegSize; limit += thearch.regsize;
} }
break; break;
...@@ -1229,8 +1233,8 @@ stkprint(Chain *ch, int limit) ...@@ -1229,8 +1233,8 @@ stkprint(Chain *ch, int limit)
else else
print("\t%d\tguaranteed after split check in %s\n", ch->limit, name); print("\t%d\tguaranteed after split check in %s\n", ch->limit, name);
} else { } else {
stkprint(ch->up, ch->limit + (!HasLinkRegister)*RegSize); stkprint(ch->up, ch->limit + callsize());
if(!HasLinkRegister) if(!haslinkregister())
print("\t%d\ton entry to %s\n", ch->limit, name); print("\t%d\ton entry to %s\n", ch->limit, name);
} }
if(ch->limit != limit) if(ch->limit != limit)
...@@ -1246,7 +1250,7 @@ Yconv(Fmt *fp) ...@@ -1246,7 +1250,7 @@ Yconv(Fmt *fp)
char *str; char *str;
s = va_arg(fp->args, LSym*); s = va_arg(fp->args, LSym*);
if (s == S) { if (s == nil) {
fmtprint(fp, "<nil>"); fmtprint(fp, "<nil>");
} else { } else {
fmtstrinit(&fmt); fmtstrinit(&fmt);
...@@ -1331,7 +1335,7 @@ cwrite(void *buf, int n) ...@@ -1331,7 +1335,7 @@ cwrite(void *buf, int n)
void void
usage(void) usage(void)
{ {
fprint(2, "usage: %cl [options] main.%c\n", thechar, thechar); fprint(2, "usage: %cl [options] main.%c\n", thearch.thechar, thearch.thechar);
flagprint(2); flagprint(2);
exits("usage"); exits("usage");
} }
...@@ -1360,7 +1364,7 @@ setinterp(char *s) ...@@ -1360,7 +1364,7 @@ setinterp(char *s)
void void
doversion(void) doversion(void)
{ {
print("%cl version %s\n", thechar, getgoversion()); print("%cl version %s\n", thearch.thechar, getgoversion());
errorexit(); errorexit();
} }
...@@ -1380,7 +1384,7 @@ genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*)) ...@@ -1380,7 +1384,7 @@ genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*))
if(s->type == STEXT) if(s->type == STEXT)
put(s, s->name, 'T', s->value, s->size, s->version, 0); put(s, s->name, 'T', s->value, s->size, s->version, 0);
for(s=ctxt->allsym; s!=S; s=s->allsym) { for(s=ctxt->allsym; s!=nil; s=s->allsym) {
if(s->hide || (s->name[0] == '.' && s->version == 0 && strcmp(s->name, ".rathole") != 0)) if(s->hide || (s->name[0] == '.' && s->version == 0 && strcmp(s->name, ".rathole") != 0))
continue; continue;
switch(s->type&SMASK) { switch(s->type&SMASK) {
...@@ -1420,7 +1424,7 @@ genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*)) ...@@ -1420,7 +1424,7 @@ genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*))
put(s, s->name, 'T', s->value, s->size, s->version, s->gotype); put(s, s->name, 'T', s->value, s->size, s->version, s->gotype);
// NOTE(ality): acid can't produce a stack trace without .frame symbols // NOTE(ality): acid can't produce a stack trace without .frame symbols
put(nil, ".frame", 'm', s->locals+PtrSize, 0, 0, 0); put(nil, ".frame", 'm', s->locals+thearch.ptrsize, 0, 0, 0);
for(a=s->autom; a; a=a->link) { for(a=s->autom; a; a=a->link) {
// Emit a or p according to actual offset, even if label is wrong. // Emit a or p according to actual offset, even if label is wrong.
...@@ -1432,7 +1436,7 @@ genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*)) ...@@ -1432,7 +1436,7 @@ genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*))
if(a->name == A_PARAM) if(a->name == A_PARAM)
off = a->aoffset; off = a->aoffset;
else else
off = a->aoffset - PtrSize; off = a->aoffset - thearch.ptrsize;
// FP // FP
if(off >= 0) { if(off >= 0) {
...@@ -1441,8 +1445,8 @@ genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*)) ...@@ -1441,8 +1445,8 @@ genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*))
} }
// SP // SP
if(off <= -PtrSize) { if(off <= -thearch.ptrsize) {
put(nil, a->asym->name, 'a', -(off+PtrSize), 0, 0, a->gotype); put(nil, a->asym->name, 'a', -(off+thearch.ptrsize), 0, 0, a->gotype);
continue; continue;
} }
...@@ -1563,7 +1567,7 @@ diag(char *fmt, ...) ...@@ -1563,7 +1567,7 @@ diag(char *fmt, ...)
tn = ""; tn = "";
sep = ""; sep = "";
if(ctxt->cursym != S) { if(ctxt->cursym != nil) {
tn = ctxt->cursym->name; tn = ctxt->cursym->name;
sep = ": "; sep = ": ";
} }
...@@ -1631,3 +1635,18 @@ checkgo(void) ...@@ -1631,3 +1635,18 @@ checkgo(void)
} }
} }
} }
vlong
rnd(vlong v, vlong r)
{
vlong c;
if(r <= 0)
return v;
v += r - 1;
c = v % r;
if(c < 0)
c += r;
v -= c;
return v;
}
...@@ -28,6 +28,58 @@ ...@@ -28,6 +28,58 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#ifndef EXTERN
#define EXTERN extern
#endif
typedef struct Arch Arch;
struct Arch {
int thechar;
int ptrsize;
int intsize;
int regsize;
int funcalign;
int maxalign;
int minlc;
int dwarfregsp;
char *linuxdynld;
char *freebsddynld;
char *netbsddynld;
char *openbsddynld;
char *dragonflydynld;
char *solarisdynld;
void (*adddynlib)(char*);
void (*adddynrel)(LSym*, Reloc*);
void (*adddynsym)(Link*, LSym*);
void (*archinit)(void);
int (*archreloc)(Reloc*, LSym*, vlong*);
vlong (*archrelocvariant)(Reloc*, LSym*, vlong);
void (*asmb)(void);
int (*elfreloc1)(Reloc*, vlong);
void (*elfsetupplt)(void);
void (*gentext)(void);
void (*listinit)(void);
int (*machoreloc1)(Reloc*, vlong);
void (*lput)(uint32);
void (*wput)(uint16);
void (*vput)(uint64);
};
vlong rnd(vlong, vlong);
EXTERN Arch thearch;
EXTERN LSym* datap;
EXTERN int debug[128];
EXTERN char literal[32];
EXTERN int32 lcsize;
EXTERN char* rpath;
EXTERN int32 spsize;
EXTERN LSym* symlist;
EXTERN int32 symsize;
// Terrible but standard terminology. // Terrible but standard terminology.
// A segment describes a block of file to load into memory. // A segment describes a block of file to load into memory.
// A section further describes the pieces of that block for // A section further describes the pieces of that block for
...@@ -71,8 +123,8 @@ struct Section ...@@ -71,8 +123,8 @@ struct Section
extern char symname[]; extern char symname[];
EXTERN char* INITENTRY; EXTERN char* INITENTRY;
extern char* thestring; EXTERN char* thestring;
extern LinkArch* thelinkarch; EXTERN LinkArch* thelinkarch;
EXTERN char* outfile; EXTERN char* outfile;
EXTERN int ndynexp; EXTERN int ndynexp;
EXTERN LSym** dynexp; EXTERN LSym** dynexp;
...@@ -82,6 +134,7 @@ EXTERN int havedynamic; ...@@ -82,6 +134,7 @@ EXTERN int havedynamic;
EXTERN int funcalign; EXTERN int funcalign;
EXTERN int iscgo; EXTERN int iscgo;
EXTERN int elfglobalsymndx; EXTERN int elfglobalsymndx;
extern int nelfsym;
EXTERN char* flag_installsuffix; EXTERN char* flag_installsuffix;
EXTERN int flag_race; EXTERN int flag_race;
EXTERN int flag_shared; EXTERN int flag_shared;
...@@ -250,8 +303,8 @@ void libinit(void); ...@@ -250,8 +303,8 @@ void libinit(void);
LSym* listsort(LSym *l, int (*cmp)(LSym*, LSym*), int off); LSym* listsort(LSym *l, int (*cmp)(LSym*, LSym*), int off);
void loadinternal(char *name); void loadinternal(char *name);
void loadlib(void); void loadlib(void);
void lputb(int32 l); void lputb(uint32 l);
void lputl(int32 l); void lputl(uint32 l);
void* mal(uint32 n); void* mal(uint32 n);
void mark(LSym *s); void mark(LSym *s);
void mywhatsys(void); void mywhatsys(void);
...@@ -289,4 +342,8 @@ void zerosig(char *sp); ...@@ -289,4 +342,8 @@ void zerosig(char *sp);
void archinit(void); void archinit(void);
void diag(char *fmt, ...); void diag(char *fmt, ...);
void ldmain(int, char**);
#pragma varargck argpos diag 1 #pragma varargck argpos diag 1
#define SYMDEF "__.GOSYMDEF"
\ No newline at end of file
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
// Mach-O file writing // Mach-O file writing
// http://developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html // http://developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
#include "l.h" #include <u.h>
#include "../ld/dwarf.h" #include <libc.h>
#include "../ld/lib.h" #include <bio.h>
#include "../ld/macho.h" #include <link.h>
#include "dwarf.h"
#include "lib.h"
#include "macho.h"
static int macho64; static int macho64;
static MachoHdr hdr; static MachoHdr hdr;
...@@ -41,7 +44,7 @@ static void machodysymtab(void); ...@@ -41,7 +44,7 @@ static void machodysymtab(void);
void void
machoinit(void) machoinit(void)
{ {
switch(thechar) { switch(thearch.thechar) {
// 64-bit architectures // 64-bit architectures
case '6': case '6':
case '9': case '9':
...@@ -146,85 +149,85 @@ machowrite(void) ...@@ -146,85 +149,85 @@ machowrite(void)
} }
if(macho64) if(macho64)
LPUT(0xfeedfacf); thearch.lput(0xfeedfacf);
else else
LPUT(0xfeedface); thearch.lput(0xfeedface);
LPUT(hdr.cpu); thearch.lput(hdr.cpu);
LPUT(hdr.subcpu); thearch.lput(hdr.subcpu);
if(linkmode == LinkExternal) if(linkmode == LinkExternal)
LPUT(1); /* file type - mach object */ thearch.lput(1); /* file type - mach object */
else else
LPUT(2); /* file type - mach executable */ thearch.lput(2); /* file type - mach executable */
LPUT(nload+nseg+ndebug); thearch.lput(nload+nseg+ndebug);
LPUT(loadsize); thearch.lput(loadsize);
LPUT(1); /* flags - no undefines */ thearch.lput(1); /* flags - no undefines */
if(macho64) if(macho64)
LPUT(0); /* reserved */ thearch.lput(0); /* reserved */
for(i=0; i<nseg; i++) { for(i=0; i<nseg; i++) {
s = &seg[i]; s = &seg[i];
if(macho64) { if(macho64) {
LPUT(25); /* segment 64 */ thearch.lput(25); /* segment 64 */
LPUT(72+80*s->nsect); thearch.lput(72+80*s->nsect);
strnput(s->name, 16); strnput(s->name, 16);
VPUT(s->vaddr); thearch.vput(s->vaddr);
VPUT(s->vsize); thearch.vput(s->vsize);
VPUT(s->fileoffset); thearch.vput(s->fileoffset);
VPUT(s->filesize); thearch.vput(s->filesize);
LPUT(s->prot1); thearch.lput(s->prot1);
LPUT(s->prot2); thearch.lput(s->prot2);
LPUT(s->nsect); thearch.lput(s->nsect);
LPUT(s->flag); thearch.lput(s->flag);
} else { } else {
LPUT(1); /* segment 32 */ thearch.lput(1); /* segment 32 */
LPUT(56+68*s->nsect); thearch.lput(56+68*s->nsect);
strnput(s->name, 16); strnput(s->name, 16);
LPUT(s->vaddr); thearch.lput(s->vaddr);
LPUT(s->vsize); thearch.lput(s->vsize);
LPUT(s->fileoffset); thearch.lput(s->fileoffset);
LPUT(s->filesize); thearch.lput(s->filesize);
LPUT(s->prot1); thearch.lput(s->prot1);
LPUT(s->prot2); thearch.lput(s->prot2);
LPUT(s->nsect); thearch.lput(s->nsect);
LPUT(s->flag); thearch.lput(s->flag);
} }
for(j=0; j<s->nsect; j++) { for(j=0; j<s->nsect; j++) {
t = &s->sect[j]; t = &s->sect[j];
if(macho64) { if(macho64) {
strnput(t->name, 16); strnput(t->name, 16);
strnput(t->segname, 16); strnput(t->segname, 16);
VPUT(t->addr); thearch.vput(t->addr);
VPUT(t->size); thearch.vput(t->size);
LPUT(t->off); thearch.lput(t->off);
LPUT(t->align); thearch.lput(t->align);
LPUT(t->reloc); thearch.lput(t->reloc);
LPUT(t->nreloc); thearch.lput(t->nreloc);
LPUT(t->flag); thearch.lput(t->flag);
LPUT(t->res1); /* reserved */ thearch.lput(t->res1); /* reserved */
LPUT(t->res2); /* reserved */ thearch.lput(t->res2); /* reserved */
LPUT(0); /* reserved */ thearch.lput(0); /* reserved */
} else { } else {
strnput(t->name, 16); strnput(t->name, 16);
strnput(t->segname, 16); strnput(t->segname, 16);
LPUT(t->addr); thearch.lput(t->addr);
LPUT(t->size); thearch.lput(t->size);
LPUT(t->off); thearch.lput(t->off);
LPUT(t->align); thearch.lput(t->align);
LPUT(t->reloc); thearch.lput(t->reloc);
LPUT(t->nreloc); thearch.lput(t->nreloc);
LPUT(t->flag); thearch.lput(t->flag);
LPUT(t->res1); /* reserved */ thearch.lput(t->res1); /* reserved */
LPUT(t->res2); /* reserved */ thearch.lput(t->res2); /* reserved */
} }
} }
} }
for(i=0; i<nload; i++) { for(i=0; i<nload; i++) {
l = &load[i]; l = &load[i];
LPUT(l->type); thearch.lput(l->type);
LPUT(4*(l->ndata+2)); thearch.lput(4*(l->ndata+2));
for(j=0; j<l->ndata; j++) for(j=0; j<l->ndata; j++)
LPUT(l->data[j]); thearch.lput(l->data[j]);
} }
return cpos() - o1; return cpos() - o1;
...@@ -353,7 +356,7 @@ asmbmacho(void) ...@@ -353,7 +356,7 @@ asmbmacho(void)
/* apple MACH */ /* apple MACH */
va = INITTEXT - HEADR; va = INITTEXT - HEADR;
mh = getMachoHdr(); mh = getMachoHdr();
switch(thechar){ switch(thearch.thechar){
default: default:
diag("unknown mach architecture"); diag("unknown mach architecture");
errorexit(); errorexit();
...@@ -416,7 +419,7 @@ asmbmacho(void) ...@@ -416,7 +419,7 @@ asmbmacho(void)
machoshbits(ms, sect, "__DATA"); machoshbits(ms, sect, "__DATA");
if(linkmode != LinkExternal) { if(linkmode != LinkExternal) {
switch(thechar) { switch(thearch.thechar) {
default: default:
diag("unknown macho architecture"); diag("unknown macho architecture");
errorexit(); errorexit();
...@@ -615,7 +618,7 @@ machosymtab(void) ...@@ -615,7 +618,7 @@ machosymtab(void)
adduint8(ctxt, symtab, 0x01); // type N_EXT, external symbol adduint8(ctxt, symtab, 0x01); // type N_EXT, external symbol
adduint8(ctxt, symtab, 0); // no section adduint8(ctxt, symtab, 0); // no section
adduint16(ctxt, symtab, 0); // desc adduint16(ctxt, symtab, 0); // desc
adduintxx(ctxt, symtab, 0, PtrSize); // no value adduintxx(ctxt, symtab, 0, thearch.ptrsize); // no value
} else { } else {
if(s->cgoexport) if(s->cgoexport)
adduint8(ctxt, symtab, 0x0f); adduint8(ctxt, symtab, 0x0f);
...@@ -630,7 +633,7 @@ machosymtab(void) ...@@ -630,7 +633,7 @@ machosymtab(void)
} else } else
adduint8(ctxt, symtab, o->sect->extnum); adduint8(ctxt, symtab, o->sect->extnum);
adduint16(ctxt, symtab, 0); // desc adduint16(ctxt, symtab, 0); // desc
adduintxx(ctxt, symtab, symaddr(s), PtrSize); adduintxx(ctxt, symtab, symaddr(s), thearch.ptrsize);
} }
} }
} }
...@@ -756,7 +759,7 @@ machorelocsect(Section *sect, LSym *first) ...@@ -756,7 +759,7 @@ machorelocsect(Section *sect, LSym *first)
for(r = sym->r; r < sym->r+sym->nr; r++) { for(r = sym->r; r < sym->r+sym->nr; r++) {
if(r->done) if(r->done)
continue; continue;
if(machoreloc1(r, sym->value+r->off - sect->vaddr) < 0) if(thearch.machoreloc1(r, sym->value+r->off - sect->vaddr) < 0)
diag("unsupported obj reloc %d/%d to %s", r->type, r->siz, r->sym->name); diag("unsupported obj reloc %d/%d to %s", r->type, r->siz, r->sym->name);
} }
} }
......
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
#include "l.h" #include <u.h>
#include <libc.h>
#include <bio.h>
#include <link.h>
#include "lib.h" #include "lib.h"
#include "../../runtime/funcdata.h" #include "../../runtime/funcdata.h"
...@@ -134,23 +137,23 @@ pclntab(void) ...@@ -134,23 +137,23 @@ pclntab(void)
// See golang.org/s/go12symtab for the format. Briefly: // See golang.org/s/go12symtab for the format. Briefly:
// 8-byte header // 8-byte header
// nfunc [PtrSize bytes] // nfunc [thearch.ptrsize bytes]
// function table, alternating PC and offset to func struct [each entry PtrSize bytes] // function table, alternating PC and offset to func struct [each entry thearch.ptrsize bytes]
// end PC [PtrSize bytes] // end PC [thearch.ptrsize bytes]
// offset to file table [4 bytes] // offset to file table [4 bytes]
nfunc = 0; nfunc = 0;
for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next) { for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next) {
if(!container(ctxt->cursym)) if(!container(ctxt->cursym))
nfunc++; nfunc++;
} }
symgrow(ctxt, ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize+4); symgrow(ctxt, ftab, 8+thearch.ptrsize+nfunc*2*thearch.ptrsize+thearch.ptrsize+4);
setuint32(ctxt, ftab, 0, 0xfffffffb); setuint32(ctxt, ftab, 0, 0xfffffffb);
setuint8(ctxt, ftab, 6, MINLC); setuint8(ctxt, ftab, 6, thearch.minlc);
setuint8(ctxt, ftab, 7, PtrSize); setuint8(ctxt, ftab, 7, thearch.ptrsize);
setuintxx(ctxt, ftab, 8, nfunc, PtrSize); setuintxx(ctxt, ftab, 8, nfunc, thearch.ptrsize);
nfunc = 0; nfunc = 0;
last = S; last = nil;
for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next) { for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next) {
last = ctxt->cursym; last = ctxt->cursym;
if(container(ctxt->cursym)) if(container(ctxt->cursym))
...@@ -160,15 +163,15 @@ pclntab(void) ...@@ -160,15 +163,15 @@ pclntab(void)
pcln = &zpcln; pcln = &zpcln;
funcstart = ftab->np; funcstart = ftab->np;
funcstart += -ftab->np & (PtrSize-1); funcstart += -ftab->np & (thearch.ptrsize-1);
setaddr(ctxt, ftab, 8+PtrSize+nfunc*2*PtrSize, ctxt->cursym); setaddr(ctxt, ftab, 8+thearch.ptrsize+nfunc*2*thearch.ptrsize, ctxt->cursym);
setuintxx(ctxt, ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize, funcstart, PtrSize); setuintxx(ctxt, ftab, 8+thearch.ptrsize+nfunc*2*thearch.ptrsize+thearch.ptrsize, funcstart, thearch.ptrsize);
// fixed size of struct, checked below // fixed size of struct, checked below
off = funcstart; off = funcstart;
end = funcstart + PtrSize + 3*4 + 5*4 + pcln->npcdata*4 + pcln->nfuncdata*PtrSize; end = funcstart + thearch.ptrsize + 3*4 + 5*4 + pcln->npcdata*4 + pcln->nfuncdata*thearch.ptrsize;
if(pcln->nfuncdata > 0 && (end&(PtrSize-1))) if(pcln->nfuncdata > 0 && (end&(thearch.ptrsize-1)))
end += 4; end += 4;
symgrow(ctxt, ftab, end); symgrow(ctxt, ftab, end);
...@@ -188,7 +191,7 @@ pclntab(void) ...@@ -188,7 +191,7 @@ pclntab(void)
// when a called function doesn't have argument information. // when a called function doesn't have argument information.
// We need to make sure everything has argument information // We need to make sure everything has argument information
// and then remove this. // and then remove this.
frameptrsize = PtrSize; frameptrsize = thearch.ptrsize;
if(ctxt->cursym->leaf) if(ctxt->cursym->leaf)
frameptrsize = 0; frameptrsize = 0;
off = setuint32(ctxt, ftab, off, ctxt->cursym->locals + frameptrsize); off = setuint32(ctxt, ftab, off, ctxt->cursym->locals + frameptrsize);
...@@ -218,38 +221,38 @@ pclntab(void) ...@@ -218,38 +221,38 @@ pclntab(void)
// funcdata, must be pointer-aligned and we're only int32-aligned. // funcdata, must be pointer-aligned and we're only int32-aligned.
// Missing funcdata will be 0 (nil pointer). // Missing funcdata will be 0 (nil pointer).
if(pcln->nfuncdata > 0) { if(pcln->nfuncdata > 0) {
if(off&(PtrSize-1)) if(off&(thearch.ptrsize-1))
off += 4; off += 4;
for(i=0; i<pcln->nfuncdata; i++) { for(i=0; i<pcln->nfuncdata; i++) {
if(pcln->funcdata[i] == nil) if(pcln->funcdata[i] == nil)
setuintxx(ctxt, ftab, off+PtrSize*i, pcln->funcdataoff[i], PtrSize); setuintxx(ctxt, ftab, off+thearch.ptrsize*i, pcln->funcdataoff[i], thearch.ptrsize);
else { else {
// TODO: Dedup. // TODO: Dedup.
funcdata_bytes += pcln->funcdata[i]->size; funcdata_bytes += pcln->funcdata[i]->size;
setaddrplus(ctxt, ftab, off+PtrSize*i, pcln->funcdata[i], pcln->funcdataoff[i]); setaddrplus(ctxt, ftab, off+thearch.ptrsize*i, pcln->funcdata[i], pcln->funcdataoff[i]);
} }
} }
off += pcln->nfuncdata*PtrSize; off += pcln->nfuncdata*thearch.ptrsize;
} }
if(off != end) { if(off != end) {
diag("bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, pcln->npcdata, pcln->nfuncdata, PtrSize); diag("bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, pcln->npcdata, pcln->nfuncdata, thearch.ptrsize);
errorexit(); errorexit();
} }
nfunc++; nfunc++;
} }
// Final entry of table is just end pc. // Final entry of table is just end pc.
setaddrplus(ctxt, ftab, 8+PtrSize+nfunc*2*PtrSize, last, last->size); setaddrplus(ctxt, ftab, 8+thearch.ptrsize+nfunc*2*thearch.ptrsize, last, last->size);
// Start file table. // Start file table.
start = ftab->np; start = ftab->np;
start += -ftab->np & (PtrSize-1); start += -ftab->np & (thearch.ptrsize-1);
setuint32(ctxt, ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize, start); setuint32(ctxt, ftab, 8+thearch.ptrsize+nfunc*2*thearch.ptrsize+thearch.ptrsize, start);
symgrow(ctxt, ftab, start+(ctxt->nhistfile+1)*4); symgrow(ctxt, ftab, start+(ctxt->nhistfile+1)*4);
setuint32(ctxt, ftab, start, ctxt->nhistfile); setuint32(ctxt, ftab, start, ctxt->nhistfile);
for(s = ctxt->filesyms; s != S; s = s->next) for(s = ctxt->filesyms; s != nil; s = s->next)
setuint32(ctxt, ftab, start + s->value*4, ftabaddstring(ftab, s->name)); setuint32(ctxt, ftab, start + s->value*4, ftabaddstring(ftab, s->name));
ftab->size = ftab->np; ftab->size = ftab->np;
......
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
// PE (Portable Executable) file writing // PE (Portable Executable) file writing
// http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx // http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
#include "l.h" #include <u.h>
#include "../ld/lib.h" #include <libc.h>
#include "../ld/pe.h" #include <bio.h>
#include "../ld/dwarf.h" #include <link.h>
#include "lib.h"
#include "pe.h"
#include "dwarf.h"
// DOS stub that prints out // DOS stub that prints out
// "This program cannot be run in DOS mode." // "This program cannot be run in DOS mode."
...@@ -139,7 +142,7 @@ peinit(void) ...@@ -139,7 +142,7 @@ peinit(void)
{ {
int32 l; int32 l;
switch(thechar) { switch(thearch.thechar) {
// 64-bit architectures // 64-bit architectures
case '6': case '6':
pe64 = 1; pe64 = 1;
...@@ -204,7 +207,7 @@ initdynimport(void) ...@@ -204,7 +207,7 @@ initdynimport(void)
dr = nil; dr = nil;
m = nil; m = nil;
for(s = ctxt->allsym; s != S; s = s->allsym) { for(s = ctxt->allsym; s != nil; s = s->allsym) {
if(!s->reachable || s->type != SDYNIMPORT) if(!s->reachable || s->type != SDYNIMPORT)
continue; continue;
for(d = dr; d != nil; d = d->next) { for(d = dr; d != nil; d = d->next) {
...@@ -234,9 +237,9 @@ initdynimport(void) ...@@ -234,9 +237,9 @@ initdynimport(void)
m->s->sub = dynamic->sub; m->s->sub = dynamic->sub;
dynamic->sub = m->s; dynamic->sub = m->s;
m->s->value = dynamic->size; m->s->value = dynamic->size;
dynamic->size += PtrSize; dynamic->size += thearch.ptrsize;
} }
dynamic->size += PtrSize; dynamic->size += thearch.ptrsize;
} }
return dr; return dr;
...@@ -344,7 +347,7 @@ initdynexport(void) ...@@ -344,7 +347,7 @@ initdynexport(void)
LSym *s; LSym *s;
nexport = 0; nexport = 0;
for(s = ctxt->allsym; s != S; s = s->allsym) { for(s = ctxt->allsym; s != nil; s = s->allsym) {
if(!s->reachable || !(s->cgoexport & CgoExportDynamic)) if(!s->reachable || !(s->cgoexport & CgoExportDynamic))
continue; continue;
if(nexport+1 > sizeof(dexport)/sizeof(dexport[0])) { if(nexport+1 > sizeof(dexport)/sizeof(dexport[0])) {
...@@ -611,7 +614,7 @@ asmbpe(void) ...@@ -611,7 +614,7 @@ asmbpe(void)
{ {
IMAGE_SECTION_HEADER *t, *d; IMAGE_SECTION_HEADER *t, *d;
switch(thechar) { switch(thearch.thechar) {
default: default:
diag("unknown PE architecture"); diag("unknown PE architecture");
errorexit(); errorexit();
......
...@@ -31,31 +31,33 @@ ...@@ -31,31 +31,33 @@
// Reading object files. // Reading object files.
#define EXTERN #define EXTERN
#include "l.h" #include <u.h>
#include "../ld/lib.h" #include <libc.h>
#include "../ld/elf.h" #include <bio.h>
#include "../ld/macho.h" #include <link.h>
#include "../ld/dwarf.h" #include "lib.h"
#include "../ld/pe.h" #include "elf.h"
#include "macho.h"
#include "dwarf.h"
#include "pe.h"
#include <ar.h> #include <ar.h>
char *noname = "<none>"; char *noname = "<none>";
char* paramspace = "FP"; char* paramspace = "FP";
void void
main(int argc, char *argv[]) ldmain(int argc, char **argv)
{ {
int i; int i;
linkarchinit();
ctxt = linknew(thelinkarch); ctxt = linknew(thelinkarch);
ctxt->thechar = thechar; ctxt->thechar = thearch.thechar;
ctxt->thestring = thestring; ctxt->thestring = thestring;
ctxt->diag = diag; ctxt->diag = diag;
ctxt->bso = &bso; ctxt->bso = &bso;
Binit(&bso, 1, OWRITE); Binit(&bso, 1, OWRITE);
listinit(); thearch.listinit();
memset(debug, 0, sizeof(debug)); memset(debug, 0, sizeof(debug));
nerrors = 0; nerrors = 0;
outfile = nil; outfile = nil;
...@@ -73,30 +75,30 @@ main(int argc, char *argv[]) ...@@ -73,30 +75,30 @@ main(int argc, char *argv[])
if(strcmp(argv[i], "-crash_for_testing") == 0) if(strcmp(argv[i], "-crash_for_testing") == 0)
*(volatile int*)0 = 0; *(volatile int*)0 = 0;
if(thechar == '5' && ctxt->goarm == 5) if(thearch.thechar == '5' && ctxt->goarm == 5)
debug['F'] = 1; debug['F'] = 1;
flagcount("1", "use alternate profiling code", &debug['1']); flagcount("1", "use alternate profiling code", &debug['1']);
if(thechar == '6') if(thearch.thechar == '6')
flagcount("8", "assume 64-bit addresses", &debug['8']); flagcount("8", "assume 64-bit addresses", &debug['8']);
flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo); flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo);
flagcount("C", "check Go calls to C code", &debug['C']); flagcount("C", "check Go calls to C code", &debug['C']);
flagint64("D", "addr: data address", &INITDAT); flagint64("D", "addr: data address", &INITDAT);
flagstr("E", "sym: entry symbol", &INITENTRY); flagstr("E", "sym: entry symbol", &INITENTRY);
if(thechar == '5') if(thearch.thechar == '5')
flagcount("G", "debug pseudo-ops", &debug['G']); flagcount("G", "debug pseudo-ops", &debug['G']);
flagfn1("I", "interp: set ELF interp", setinterp); flagfn1("I", "interp: set ELF interp", setinterp);
flagfn1("L", "dir: add dir to library path", Lflag); flagfn1("L", "dir: add dir to library path", Lflag);
flagfn1("H", "head: header type", setheadtype); flagfn1("H", "head: header type", setheadtype);
flagcount("K", "add stack underflow checks", &debug['K']); flagcount("K", "add stack underflow checks", &debug['K']);
if(thechar == '5') if(thearch.thechar == '5')
flagcount("M", "disable software div/mod", &debug['M']); flagcount("M", "disable software div/mod", &debug['M']);
flagcount("O", "print pc-line tables", &debug['O']); flagcount("O", "print pc-line tables", &debug['O']);
flagcount("Q", "debug byte-register code gen", &debug['Q']); flagcount("Q", "debug byte-register code gen", &debug['Q']);
if(thechar == '5') if(thearch.thechar == '5')
flagcount("P", "debug code generation", &debug['P']); flagcount("P", "debug code generation", &debug['P']);
flagint32("R", "rnd: address rounding", &INITRND); flagint32("R", "rnd: address rounding", &INITRND);
flagcount("S", "check type signatures", &debug['S']); flagcount("nil", "check type signatures", &debug['S']);
flagint64("T", "addr: text address", &INITTEXT); flagint64("T", "addr: text address", &INITTEXT);
flagfn0("V", "print version and exit", doversion); flagfn0("V", "print version and exit", doversion);
flagcount("W", "disassemble input", &debug['W']); flagcount("W", "disassemble input", &debug['W']);
...@@ -117,7 +119,7 @@ main(int argc, char *argv[]) ...@@ -117,7 +119,7 @@ main(int argc, char *argv[])
flagstr("r", "dir1:dir2:...: set ELF dynamic linker search path", &rpath); flagstr("r", "dir1:dir2:...: set ELF dynamic linker search path", &rpath);
flagcount("race", "enable race detector", &flag_race); flagcount("race", "enable race detector", &flag_race);
flagcount("s", "disable symbol table", &debug['s']); flagcount("s", "disable symbol table", &debug['s']);
if(thechar == '5' || thechar == '6') if(thearch.thechar == '5' || thearch.thechar == '6')
flagcount("shared", "generate shared object (implies -linkmode external)", &flag_shared); flagcount("shared", "generate shared object (implies -linkmode external)", &flag_shared);
flagstr("tmpdir", "dir: leave temporary files in this directory", &tmpdir); flagstr("tmpdir", "dir: leave temporary files in this directory", &tmpdir);
flagcount("u", "reject unsafe packages", &debug['u']); flagcount("u", "reject unsafe packages", &debug['u']);
...@@ -139,9 +141,9 @@ main(int argc, char *argv[]) ...@@ -139,9 +141,9 @@ main(int argc, char *argv[])
if(outfile == nil) { if(outfile == nil) {
if(HEADTYPE == Hwindows) if(HEADTYPE == Hwindows)
outfile = smprint("%c.out.exe", thechar); outfile = smprint("%c.out.exe", thearch.thechar);
else else
outfile = smprint("%c.out", thechar); outfile = smprint("%c.out", thearch.thechar);
} }
libinit(); // creates outfile libinit(); // creates outfile
...@@ -151,7 +153,7 @@ main(int argc, char *argv[]) ...@@ -151,7 +153,7 @@ main(int argc, char *argv[])
if(headstring == nil) if(headstring == nil)
headstring = headstr(HEADTYPE); headstring = headstr(HEADTYPE);
archinit(); thearch.archinit();
ctxt->debugfloat = debug['F']; ctxt->debugfloat = debug['F'];
if(debug['v']) if(debug['v'])
...@@ -165,7 +167,7 @@ main(int argc, char *argv[]) ...@@ -165,7 +167,7 @@ main(int argc, char *argv[])
addlibpath(ctxt, "command line", "command line", argv[0], "main"); addlibpath(ctxt, "command line", "command line", argv[0], "main");
loadlib(); loadlib();
if(thechar == '5') { if(thearch.thechar == '5') {
// mark some functions that are only referenced after linker code editing // mark some functions that are only referenced after linker code editing
if(debug['F']) if(debug['F'])
mark(linkrlookup(ctxt, "_sfloat", 0)); mark(linkrlookup(ctxt, "_sfloat", 0));
...@@ -184,7 +186,7 @@ main(int argc, char *argv[]) ...@@ -184,7 +186,7 @@ main(int argc, char *argv[])
if(HEADTYPE == Hwindows) if(HEADTYPE == Hwindows)
dope(); dope();
addexport(); addexport();
gentext(); // trampolines, call stubs, etc. thearch.gentext(); // trampolines, call stubs, etc.
textaddress(); textaddress();
pclntab(); pclntab();
findfunctab(); findfunctab();
...@@ -193,7 +195,7 @@ main(int argc, char *argv[]) ...@@ -193,7 +195,7 @@ main(int argc, char *argv[])
address(); address();
doweak(); doweak();
reloc(); reloc();
asmb(); thearch.asmb();
undef(); undef();
hostlink(); hostlink();
if(debug['v']) { if(debug['v']) {
......
...@@ -30,9 +30,12 @@ ...@@ -30,9 +30,12 @@
// Symbol table. // Symbol table.
#include "l.h" #include <u.h>
#include "../ld/lib.h" #include <libc.h>
#include "../ld/elf.h" #include <bio.h>
#include <link.h>
#include "lib.h"
#include "elf.h"
static int maxelfstr; static int maxelfstr;
...@@ -76,24 +79,24 @@ putelfstr(char *s) ...@@ -76,24 +79,24 @@ putelfstr(char *s)
static void static void
putelfsyment(int off, vlong addr, vlong size, int info, int shndx, int other) putelfsyment(int off, vlong addr, vlong size, int info, int shndx, int other)
{ {
switch(thechar) { switch(thearch.thechar) {
case '6': case '6':
case '9': case '9':
LPUT(off); thearch.lput(off);
cput(info); cput(info);
cput(other); cput(other);
WPUT(shndx); thearch.wput(shndx);
VPUT(addr); thearch.vput(addr);
VPUT(size); thearch.vput(size);
symsize += ELF64SYMSIZE; symsize += ELF64SYMSIZE;
break; break;
default: default:
LPUT(off); thearch.lput(off);
LPUT(addr); thearch.lput(addr);
LPUT(size); thearch.lput(size);
cput(info); cput(info);
cput(other); cput(other);
WPUT(shndx); thearch.wput(shndx);
symsize += ELF32SYMSIZE; symsize += ELF32SYMSIZE;
break; break;
} }
...@@ -172,7 +175,7 @@ putelfsymshndx(vlong sympos, int shndx) ...@@ -172,7 +175,7 @@ putelfsymshndx(vlong sympos, int shndx)
vlong here; vlong here;
here = cpos(); here = cpos();
switch(thechar) { switch(thearch.thechar) {
case '6': case '6':
cseek(sympos+6); cseek(sympos+6);
break; break;
...@@ -180,7 +183,7 @@ putelfsymshndx(vlong sympos, int shndx) ...@@ -180,7 +183,7 @@ putelfsymshndx(vlong sympos, int shndx)
cseek(sympos+14); cseek(sympos+14);
break; break;
} }
WPUT(shndx); thearch.wput(shndx);
cseek(here); cseek(here);
} }
...@@ -218,7 +221,7 @@ asmelfsym(void) ...@@ -218,7 +221,7 @@ asmelfsym(void)
elfglobalsymndx = numelfsym; elfglobalsymndx = numelfsym;
genasmsym(putelfsym); genasmsym(putelfsym);
for(s=ctxt->allsym; s!=S; s=s->allsym) { for(s=ctxt->allsym; s!=nil; s=s->allsym) {
if(s->type != SHOSTOBJ && !(s->type == SDYNIMPORT && s->reachable)) if(s->type != SHOSTOBJ && !(s->type == SDYNIMPORT && s->reachable))
continue; continue;
if(s->type == SDYNIMPORT) if(s->type == SDYNIMPORT)
...@@ -253,7 +256,7 @@ putplan9sym(LSym *x, char *s, int t, vlong addr, vlong size, int ver, LSym *go) ...@@ -253,7 +256,7 @@ putplan9sym(LSym *x, char *s, int t, vlong addr, vlong size, int ver, LSym *go)
case 'Z': case 'Z':
case 'm': case 'm':
l = 4; l = 4;
if(HEADTYPE == Hplan9 && thechar == '6' && !debug['8']) { if(HEADTYPE == Hplan9 && thearch.thechar == '6' && !debug['8']) {
lputb(addr>>32); lputb(addr>>32);
l = 8; l = 8;
} }
...@@ -307,7 +310,7 @@ wputb(ushort w) ...@@ -307,7 +310,7 @@ wputb(ushort w)
} }
void void
lputb(int32 l) lputb(uint32 l)
{ {
cput(l>>24); cput(l>>24);
cput(l>>16); cput(l>>16);
...@@ -316,7 +319,7 @@ lputb(int32 l) ...@@ -316,7 +319,7 @@ lputb(int32 l)
} }
void void
lputl(int32 l) lputl(uint32 l)
{ {
cput(l); cput(l);
cput(l>>8); cput(l>>8);
...@@ -408,7 +411,7 @@ symtab(void) ...@@ -408,7 +411,7 @@ symtab(void)
// within a type they sort by size, so the .* symbols // within a type they sort by size, so the .* symbols
// just defined above will be first. // just defined above will be first.
// hide the specific symbols. // hide the specific symbols.
for(s = ctxt->allsym; s != S; s = s->allsym) { for(s = ctxt->allsym; s != nil; s = s->allsym) {
if(!s->reachable || s->special || s->type != SRODATA) if(!s->reachable || s->special || s->type != SRODATA)
continue; continue;
if(strncmp(s->name, "type.", 5) == 0) { if(strncmp(s->name, "type.", 5) == 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment