Skip to content

Commit

Permalink
liblink: support big-endian properly
Browse files Browse the repository at this point in the history
LGTM=rsc
R=rsc, iant
CC=golang-codereviews
https://golang.org/cl/115300044
  • Loading branch information
minux committed Aug 6, 2014
1 parent 2c181f0 commit 08ee266
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 10 deletions.
8 changes: 7 additions & 1 deletion include/link.h
Original file line number Diff line number Diff line change
Expand Up @@ -431,11 +431,17 @@ struct Link
LSym* filesyms;
};

enum {
LittleEndian = 0x04030201,
BigEndian = 0x01020304,
};

// LinkArch is the definition of a single architecture.
struct LinkArch
{
char* name; // "arm", "amd64", and so on
int thechar; // '5', '6', and so on
int32 endian; // LittleEndian or BigEndian

void (*addstacksplit)(Link*, LSym*);
void (*assemble)(Link*, LSym*);
Expand Down Expand Up @@ -560,7 +566,7 @@ int find1(int32 l, int c);
void linkgetline(Link *ctxt, int32 line, LSym **f, int32 *l);
void histtoauto(Link *ctxt);
void mkfwd(LSym*);
void nuxiinit(void);
void nuxiinit(LinkArch*);
void savehist(Link *ctxt, int32 line, int32 off);
Prog* copyp(Link*, Prog*);
Prog* appendp(Link*, Prog*);
Expand Down
31 changes: 23 additions & 8 deletions src/liblink/ld.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,26 @@ find1(int32 l, int c)
}

void
nuxiinit(void)
nuxiinit(LinkArch *arch)
{
int i, c;

if(arch->endian != BigEndian && arch->endian != LittleEndian)
sysfatal("unknown endian (%#x) for arch %s", arch->endian, arch->name);

for(i=0; i<4; i++) {
c = find1(0x04030201L, i+1);
if(i < 2)
inuxi2[i] = c;
if(i < 1)
inuxi1[i] = c;
c = find1(arch->endian, i+1);
if(arch->endian == LittleEndian) {
if(i < 2)
inuxi2[i] = c;
if(i < 1)
inuxi1[i] = c;
} else {
if(i >= 2)
inuxi2[i-2] = c;
if(i >= 3)
inuxi1[i-3] = c;
}
inuxi4[i] = c;
if(c == i) {
inuxi8[i] = c;
Expand All @@ -149,8 +159,13 @@ nuxiinit(void)
inuxi8[i+4] = c;
}
fnuxi4[i] = c;
fnuxi8[i] = c;
fnuxi8[i+4] = c+4;
if(c == i) {
fnuxi8[i] = c;
fnuxi8[i+4] = c+4;
} else {
fnuxi8[i] = c+4;
fnuxi8[i+4] = c;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/liblink/obj5.c
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,7 @@ xfol(Link *ctxt, Prog *p, Prog **last)
LinkArch linkarm = {
.name = "arm",
.thechar = '5',
.endian = LittleEndian,

.addstacksplit = addstacksplit,
.assemble = span5,
Expand Down
2 changes: 2 additions & 0 deletions src/liblink/obj6.c
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,7 @@ prg(void)
LinkArch linkamd64 = {
.name = "amd64",
.thechar = '6',
.endian = LittleEndian,

.addstacksplit = addstacksplit,
.assemble = span6,
Expand Down Expand Up @@ -1132,6 +1133,7 @@ LinkArch linkamd64 = {
LinkArch linkamd64p32 = {
.name = "amd64p32",
.thechar = '6',
.endian = LittleEndian,

.addstacksplit = addstacksplit,
.assemble = span6,
Expand Down
1 change: 1 addition & 0 deletions src/liblink/obj8.c
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,7 @@ xfol(Link *ctxt, Prog *p, Prog **last)
LinkArch link386 = {
.name = "386",
.thechar = '8',
.endian = LittleEndian,

.addstacksplit = addstacksplit,
.assemble = span8,
Expand Down
2 changes: 1 addition & 1 deletion src/liblink/sym.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ linknew(LinkArch *arch)
char *p;
char buf[1024];

nuxiinit();
nuxiinit(arch);

ctxt = emallocz(sizeof *ctxt);
ctxt->arch = arch;
Expand Down

0 comments on commit 08ee266

Please sign in to comment.