Commit 6e02e1cf authored by Shenghou Ma's avatar Shenghou Ma

[dev.power64] cmd/ld: update for power64

LGTM=rsc
R=rsc, iant
CC=golang-codereviews
https://golang.org/cl/121380043
parent 95e8a3a1
...@@ -441,11 +441,11 @@ blk(LSym *start, int32 addr, int32 size) ...@@ -441,11 +441,11 @@ blk(LSym *start, int32 addr, int32 size)
continue; continue;
if(sym->value >= eaddr) if(sym->value >= eaddr)
break; break;
ctxt->cursym = sym;
if(sym->value < addr) { if(sym->value < addr) {
diag("phase error: addr=%#llx but sym=%#llx type=%d", (vlong)addr, (vlong)sym->value, sym->type); diag("phase error: addr=%#llx but sym=%#llx type=%d", (vlong)addr, (vlong)sym->value, sym->type);
errorexit(); errorexit();
} }
ctxt->cursym = sym;
for(; addr < sym->value; addr++) for(; addr < sym->value; addr++)
cput(0); cput(0);
p = sym->p; p = sym->p;
...@@ -459,6 +459,8 @@ blk(LSym *start, int32 addr, int32 size) ...@@ -459,6 +459,8 @@ blk(LSym *start, int32 addr, int32 size)
diag("phase error: addr=%#llx value+size=%#llx", (vlong)addr, (vlong)sym->value+sym->size); diag("phase error: addr=%#llx value+size=%#llx", (vlong)addr, (vlong)sym->value+sym->size);
errorexit(); errorexit();
} }
if(sym->value+sym->size >= eaddr)
break;
} }
for(; addr < eaddr; addr++) for(; addr < eaddr; addr++)
......
...@@ -10,8 +10,8 @@ Ld is the portable code for a modified version of the Plan 9 linker. The origin ...@@ -10,8 +10,8 @@ Ld is the portable code for a modified version of the Plan 9 linker. The origin
http://plan9.bell-labs.com/magic/man2html/1/8l http://plan9.bell-labs.com/magic/man2html/1/8l
It reads object files (.5, .6, or .8 files) and writes a binary named for the It reads object files (.5, .6, .8, .9 files) and writes a binary named for the
architecture (5.out, 6.out, 8.out) by default (if $GOOS is windows, a .exe suffix architecture (5.out, 6.out, 8.out, 9.out) by default (if $GOOS is windows, a .exe suffix
will be appended). will be appended).
Major changes include: Major changes include:
...@@ -22,7 +22,7 @@ Original options are listed on the manual page linked above. ...@@ -22,7 +22,7 @@ Original options are listed on the manual page linked above.
Usage: Usage:
go tool 6l [flags] mainObj go tool 6l [flags] mainObj
Substitute 6l with 8l or 5l as appropriate. Substitute 6l with 5l, 8l or 9l as appropriate.
Options new in this version: Options new in this version:
......
...@@ -2179,7 +2179,7 @@ dwarfaddshstrings(LSym *shstrtab) ...@@ -2179,7 +2179,7 @@ dwarfaddshstrings(LSym *shstrtab)
elfstrdbg[ElfStrDebugStr] = addstring(shstrtab, ".debug_str"); elfstrdbg[ElfStrDebugStr] = addstring(shstrtab, ".debug_str");
elfstrdbg[ElfStrGDBScripts] = addstring(shstrtab, ".debug_gdb_scripts"); elfstrdbg[ElfStrGDBScripts] = addstring(shstrtab, ".debug_gdb_scripts");
if(linkmode == LinkExternal) { if(linkmode == LinkExternal) {
if(thechar == '6') { if(thechar == '6' || thechar == '9') {
elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rela.debug_info"); elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rela.debug_info");
elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rela.debug_aranges"); elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rela.debug_aranges");
elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rela.debug_line"); elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rela.debug_line");
...@@ -2234,7 +2234,7 @@ dwarfaddelfrelocheader(int elfstr, ElfShdr *shdata, vlong off, vlong size) ...@@ -2234,7 +2234,7 @@ dwarfaddelfrelocheader(int elfstr, ElfShdr *shdata, vlong off, vlong size)
ElfShdr *sh; ElfShdr *sh;
sh = newElfShdr(elfstrdbg[elfstr]); sh = newElfShdr(elfstrdbg[elfstr]);
if(thechar == '6') { if(thechar == '6' || thechar == '9') {
sh->type = SHT_RELA; sh->type = SHT_RELA;
} else { } else {
sh->type = SHT_REL; sh->type = SHT_REL;
......
...@@ -45,6 +45,7 @@ elfinit(void) ...@@ -45,6 +45,7 @@ elfinit(void)
switch(thechar) { switch(thechar) {
// 64-bit architectures // 64-bit architectures
case '6': case '6':
case '9':
elf64 = 1; elf64 = 1;
hdr.phoff = ELF64HDRSIZE; /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */ hdr.phoff = ELF64HDRSIZE; /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */
hdr.shoff = ELF64HDRSIZE; /* Will move as we add PHeaders */ hdr.shoff = ELF64HDRSIZE; /* Will move as we add PHeaders */
...@@ -678,7 +679,7 @@ elfdynhash(void) ...@@ -678,7 +679,7 @@ elfdynhash(void)
elfwritedynentsym(s, DT_VERSYM, linklookup(ctxt, ".gnu.version", 0)); elfwritedynentsym(s, DT_VERSYM, linklookup(ctxt, ".gnu.version", 0));
} }
if(thechar == '6') { if(thechar == '6' || thechar == '9') {
sy = linklookup(ctxt, ".rela.plt", 0); sy = linklookup(ctxt, ".rela.plt", 0);
if(sy->size > 0) { if(sy->size > 0) {
elfwritedynent(s, DT_PLTREL, DT_RELA); elfwritedynent(s, DT_PLTREL, DT_RELA);
...@@ -804,7 +805,7 @@ elfshreloc(Section *sect) ...@@ -804,7 +805,7 @@ elfshreloc(Section *sect)
if(strcmp(sect->name, ".shstrtab") == 0 || strcmp(sect->name, ".tbss") == 0) if(strcmp(sect->name, ".shstrtab") == 0 || strcmp(sect->name, ".tbss") == 0)
return nil; return nil;
if(thechar == '6') { if(thechar == '6' || thechar == '9') {
prefix = ".rela"; prefix = ".rela";
typ = SHT_RELA; typ = SHT_RELA;
} else { } else {
...@@ -931,7 +932,7 @@ doelf(void) ...@@ -931,7 +932,7 @@ doelf(void)
debug['s'] = 0; debug['s'] = 0;
debug['d'] = 1; debug['d'] = 1;
if(thechar == '6') { if(thechar == '6' || thechar == '9') {
addstring(shstrtab, ".rela.text"); addstring(shstrtab, ".rela.text");
addstring(shstrtab, ".rela.rodata"); addstring(shstrtab, ".rela.rodata");
addstring(shstrtab, ".rela.typelink"); addstring(shstrtab, ".rela.typelink");
...@@ -954,7 +955,7 @@ doelf(void) ...@@ -954,7 +955,7 @@ doelf(void)
if(flag_shared) { if(flag_shared) {
addstring(shstrtab, ".init_array"); addstring(shstrtab, ".init_array");
if(thechar == '6') if(thechar == '6' || thechar == '9')
addstring(shstrtab, ".rela.init_array"); addstring(shstrtab, ".rela.init_array");
else else
addstring(shstrtab, ".rel.init_array"); addstring(shstrtab, ".rel.init_array");
...@@ -975,7 +976,7 @@ doelf(void) ...@@ -975,7 +976,7 @@ doelf(void)
addstring(shstrtab, ".dynamic"); addstring(shstrtab, ".dynamic");
addstring(shstrtab, ".dynsym"); addstring(shstrtab, ".dynsym");
addstring(shstrtab, ".dynstr"); addstring(shstrtab, ".dynstr");
if(thechar == '6') { if(thechar == '6' || thechar == '9') {
addstring(shstrtab, ".rela"); addstring(shstrtab, ".rela");
addstring(shstrtab, ".rela.plt"); addstring(shstrtab, ".rela.plt");
} else { } else {
...@@ -990,7 +991,7 @@ doelf(void) ...@@ -990,7 +991,7 @@ doelf(void)
s = linklookup(ctxt, ".dynsym", 0); s = linklookup(ctxt, ".dynsym", 0);
s->type = SELFROSECT; s->type = SELFROSECT;
s->reachable = 1; s->reachable = 1;
if(thechar == '6') if(thechar == '6' || thechar == '9')
s->size += ELF64SYMSIZE; s->size += ELF64SYMSIZE;
else else
s->size += ELF32SYMSIZE; s->size += ELF32SYMSIZE;
...@@ -1004,7 +1005,7 @@ doelf(void) ...@@ -1004,7 +1005,7 @@ doelf(void)
dynstr = s; dynstr = s;
/* relocation table */ /* relocation table */
if(thechar == '6') if(thechar == '6' || thechar == '9')
s = linklookup(ctxt, ".rela", 0); s = linklookup(ctxt, ".rela", 0);
else else
s = linklookup(ctxt, ".rel", 0); s = linklookup(ctxt, ".rel", 0);
...@@ -1031,7 +1032,7 @@ doelf(void) ...@@ -1031,7 +1032,7 @@ doelf(void)
elfsetupplt(); elfsetupplt();
if(thechar == '6') if(thechar == '6' || thechar == '9')
s = linklookup(ctxt, ".rela.plt", 0); s = linklookup(ctxt, ".rela.plt", 0);
else else
s = linklookup(ctxt, ".rel.plt", 0); s = linklookup(ctxt, ".rel.plt", 0);
...@@ -1056,13 +1057,13 @@ doelf(void) ...@@ -1056,13 +1057,13 @@ doelf(void)
*/ */
elfwritedynentsym(s, DT_HASH, linklookup(ctxt, ".hash", 0)); elfwritedynentsym(s, DT_HASH, linklookup(ctxt, ".hash", 0));
elfwritedynentsym(s, DT_SYMTAB, linklookup(ctxt, ".dynsym", 0)); elfwritedynentsym(s, DT_SYMTAB, linklookup(ctxt, ".dynsym", 0));
if(thechar == '6') if(thechar == '6' || thechar == '9')
elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE); elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE);
else else
elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE); elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE);
elfwritedynentsym(s, DT_STRTAB, linklookup(ctxt, ".dynstr", 0)); elfwritedynentsym(s, DT_STRTAB, linklookup(ctxt, ".dynstr", 0));
elfwritedynentsymsize(s, DT_STRSZ, linklookup(ctxt, ".dynstr", 0)); elfwritedynentsymsize(s, DT_STRSZ, linklookup(ctxt, ".dynstr", 0));
if(thechar == '6') { if(thechar == '6' || thechar == '9') {
elfwritedynentsym(s, DT_RELA, linklookup(ctxt, ".rela", 0)); elfwritedynentsym(s, DT_RELA, linklookup(ctxt, ".rela", 0));
elfwritedynentsymsize(s, DT_RELASZ, linklookup(ctxt, ".rela", 0)); elfwritedynentsymsize(s, DT_RELASZ, linklookup(ctxt, ".rela", 0));
elfwritedynent(s, DT_RELAENT, ELF64RELASIZE); elfwritedynent(s, DT_RELAENT, ELF64RELASIZE);
...@@ -1148,6 +1149,9 @@ asmbelf(vlong symo) ...@@ -1148,6 +1149,9 @@ asmbelf(vlong symo)
case '8': case '8':
eh->machine = EM_386; eh->machine = EM_386;
break; break;
case '9':
eh->machine = EM_PPC64;
break;
} }
startva = INITTEXT - HEADR; startva = INITTEXT - HEADR;
...@@ -1488,7 +1492,10 @@ elfobj: ...@@ -1488,7 +1492,10 @@ elfobj:
eh->ident[EI_CLASS] = ELFCLASS64; eh->ident[EI_CLASS] = ELFCLASS64;
else else
eh->ident[EI_CLASS] = ELFCLASS32; eh->ident[EI_CLASS] = ELFCLASS32;
eh->ident[EI_DATA] = ELFDATA2LSB; if(ctxt->arch->endian == BigEndian)
eh->ident[EI_DATA] = ELFDATA2MSB;
else
eh->ident[EI_DATA] = ELFDATA2LSB;
eh->ident[EI_VERSION] = EV_CURRENT; eh->ident[EI_VERSION] = EV_CURRENT;
if(linkmode == LinkExternal) if(linkmode == LinkExternal)
......
...@@ -436,6 +436,12 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn) ...@@ -436,6 +436,12 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
return; return;
} }
break; break;
case '9':
if(obj->machine != ElfMachPower64 || hdr->ident[4] != ElfClass64) {
diag("%s: elf object but not power64", pn);
return;
}
break;
} }
// load section list into memory. // load section list into memory.
......
...@@ -586,6 +586,7 @@ hostlink(void) ...@@ -586,6 +586,7 @@ hostlink(void)
argv[argc++] = "-m32"; argv[argc++] = "-m32";
break; break;
case '6': case '6':
case '9':
argv[argc++] = "-m64"; argv[argc++] = "-m64";
break; break;
case '5': case '5':
...@@ -1146,6 +1147,7 @@ stkcheck(Chain *up, int depth) ...@@ -1146,6 +1147,7 @@ stkcheck(Chain *up, int depth)
switch(r->type) { switch(r->type) {
case R_CALL: case R_CALL:
case R_CALLARM: case R_CALLARM:
case R_CALLPOWER:
// Direct call. // Direct call.
ch.limit = limit - pcsp.value - callsize(); ch.limit = limit - pcsp.value - callsize();
ch.sym = r->sym; ch.sym = r->sym;
...@@ -1525,7 +1527,7 @@ callgraph(void) ...@@ -1525,7 +1527,7 @@ callgraph(void)
r = &s->r[i]; r = &s->r[i];
if(r->sym == nil) if(r->sym == nil)
continue; continue;
if((r->type == R_CALL || r->type == R_CALLARM) && r->sym->type == STEXT) if((r->type == R_CALL || r->type == R_CALLARM || r->type == R_CALLPOWER) && r->sym->type == STEXT)
Bprint(&bso, "%s calls %s\n", s->name, r->sym->name); Bprint(&bso, "%s calls %s\n", s->name, r->sym->name);
} }
} }
......
...@@ -33,10 +33,6 @@ ...@@ -33,10 +33,6 @@
// A section further describes the pieces of that block for // A section further describes the pieces of that block for
// use in debuggers and such. // use in debuggers and such.
enum {
MAXIO = 8192,
};
typedef struct Segment Segment; typedef struct Segment Segment;
typedef struct Section Section; typedef struct Section Section;
......
...@@ -44,6 +44,7 @@ machoinit(void) ...@@ -44,6 +44,7 @@ machoinit(void)
switch(thechar) { switch(thechar) {
// 64-bit architectures // 64-bit architectures
case '6': case '6':
case '9':
macho64 = 1; macho64 = 1;
break; break;
......
...@@ -78,6 +78,7 @@ putelfsyment(int off, vlong addr, vlong size, int info, int shndx, int other) ...@@ -78,6 +78,7 @@ putelfsyment(int off, vlong addr, vlong size, int info, int shndx, int other)
{ {
switch(thechar) { switch(thechar) {
case '6': case '6':
case '9':
LPUT(off); LPUT(off);
cput(info); cput(info);
cput(other); cput(other);
......
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