mirror of
https://github.com/golang/go
synced 2024-11-20 05:04:43 -07:00
First steps towards cleaner support for ELF64 in 6l.
R=rsc DELTA=337 (165 added, 119 deleted, 53 changed) OCL=31786 CL=31794
This commit is contained in:
parent
ba0cf083a2
commit
1593b1fc23
@ -10,6 +10,7 @@ TARG=\
|
||||
OFILES=\
|
||||
asm.$O\
|
||||
compat.$O\
|
||||
elf64.$O\
|
||||
enam.$O\
|
||||
go.$O\
|
||||
list.$O\
|
||||
@ -21,6 +22,7 @@ OFILES=\
|
||||
HFILES=\
|
||||
l.h\
|
||||
../6l/6.out.h\
|
||||
../ld/elf64.h\
|
||||
|
||||
|
||||
$(TARG): $(OFILES)
|
||||
@ -38,3 +40,5 @@ install: $(TARG)
|
||||
cp $(TARG) $(BIN)/$(TARG)
|
||||
|
||||
go.o: ../ld/go.c
|
||||
|
||||
elf64.o: ../ld/elf64.c
|
||||
|
217
src/cmd/6l/asm.c
217
src/cmd/6l/asm.c
@ -29,6 +29,7 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "l.h"
|
||||
#include "../ld/elf64.h"
|
||||
|
||||
#define Dbufslop 100
|
||||
|
||||
@ -126,6 +127,7 @@ asmb(void)
|
||||
vlong vl, va, fo, w, symo;
|
||||
int strtabsize;
|
||||
vlong symdatva = 0x99LL<<32;
|
||||
Elf64SHdr *sh;
|
||||
|
||||
strtabsize = 0;
|
||||
|
||||
@ -194,7 +196,7 @@ asmb(void)
|
||||
case 7:
|
||||
debug['8'] = 1; /* 64-bit addresses */
|
||||
seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
|
||||
strtabsize = linuxstrtable();
|
||||
strtabsize = elf64strtable();
|
||||
cflush();
|
||||
v = rnd(HEADR+textsize, INITRND);
|
||||
seek(cout, v, 0);
|
||||
@ -448,7 +450,7 @@ asmb(void)
|
||||
va = INITTEXT & ~((vlong)INITRND - 1);
|
||||
w = HEADR+textsize;
|
||||
|
||||
linuxphdr(1, /* text - type = PT_LOAD */
|
||||
elf64phdr(1, /* text - type = PT_LOAD */
|
||||
1L+4L, /* text - flags = PF_X+PF_R */
|
||||
0, /* file offset */
|
||||
va, /* vaddr */
|
||||
@ -461,7 +463,7 @@ asmb(void)
|
||||
va = rnd(va+w, INITRND);
|
||||
w = datsize;
|
||||
|
||||
linuxphdr(1, /* data - type = PT_LOAD */
|
||||
elf64phdr(1, /* data - type = PT_LOAD */
|
||||
2L+4L, /* data - flags = PF_W+PF_R */
|
||||
fo, /* file offset */
|
||||
va, /* vaddr */
|
||||
@ -471,7 +473,7 @@ asmb(void)
|
||||
INITRND); /* alignment */
|
||||
|
||||
if(!debug['s']) {
|
||||
linuxphdr(1, /* data - type = PT_LOAD */
|
||||
elf64phdr(1, /* data - type = PT_LOAD */
|
||||
2L+4L, /* data - flags = PF_W+PF_R */
|
||||
symo, /* file offset */
|
||||
symdatva, /* vaddr */
|
||||
@ -481,7 +483,7 @@ asmb(void)
|
||||
INITRND); /* alignment */
|
||||
}
|
||||
|
||||
linuxphdr(0x6474e551, /* gok - type = gok */
|
||||
elf64phdr(0x6474e551, /* gok - type = gok */
|
||||
1L+2L+4L, /* gok - flags = PF_X+PF_W+PF_R */
|
||||
0, /* file offset */
|
||||
0, /* vaddr */
|
||||
@ -490,75 +492,57 @@ asmb(void)
|
||||
0, /* memory size */
|
||||
8); /* alignment */
|
||||
|
||||
linuxshdr(nil, /* name */
|
||||
0, /* type */
|
||||
0, /* flags */
|
||||
0, /* addr */
|
||||
0, /* off */
|
||||
0, /* size */
|
||||
0, /* link */
|
||||
0, /* info */
|
||||
0, /* align */
|
||||
0); /* entsize */
|
||||
sh = newElf64SHdr();
|
||||
elf64shdr(nil, sh);
|
||||
|
||||
stroffset = 1; /* 0 means no name, so start at 1 */
|
||||
fo = HEADR;
|
||||
va = (INITTEXT & ~((vlong)INITRND - 1)) + HEADR;
|
||||
w = textsize;
|
||||
|
||||
linuxshdr(".text", /* name */
|
||||
1, /* type */
|
||||
6, /* flags */
|
||||
va, /* addr */
|
||||
fo, /* off */
|
||||
w, /* size */
|
||||
0, /* link */
|
||||
0, /* info */
|
||||
8, /* align */
|
||||
0); /* entsize */
|
||||
sh = newElf64SHdr();
|
||||
sh->type = 1;
|
||||
sh->flags = 6;
|
||||
sh->addr = va;
|
||||
sh->off = fo;
|
||||
sh->size = w;
|
||||
sh->addralign = 8;
|
||||
elf64shdr(".text", sh);
|
||||
|
||||
fo = rnd(fo+w, INITRND);
|
||||
va = rnd(va+w, INITRND);
|
||||
w = datsize;
|
||||
|
||||
linuxshdr(".data", /* name */
|
||||
1, /* type */
|
||||
3, /* flags */
|
||||
va, /* addr */
|
||||
fo, /* off */
|
||||
w, /* size */
|
||||
0, /* link */
|
||||
0, /* info */
|
||||
8, /* align */
|
||||
0); /* entsize */
|
||||
sh = newElf64SHdr();
|
||||
sh->type = 1;
|
||||
sh->flags = 3;
|
||||
sh->addr = va;
|
||||
sh->off = fo;
|
||||
sh->size = w;
|
||||
sh->addralign = 8;
|
||||
elf64shdr(".data", sh);
|
||||
|
||||
fo += w;
|
||||
va += w;
|
||||
w = bsssize;
|
||||
|
||||
linuxshdr(".bss", /* name */
|
||||
8, /* type */
|
||||
3, /* flags */
|
||||
va, /* addr */
|
||||
fo, /* off */
|
||||
w, /* size */
|
||||
0, /* link */
|
||||
0, /* info */
|
||||
8, /* align */
|
||||
0); /* entsize */
|
||||
sh = newElf64SHdr();
|
||||
sh->type = 8;
|
||||
sh->flags = 3;
|
||||
sh->addr = va;
|
||||
sh->off = fo;
|
||||
sh->size = w;
|
||||
sh->addralign = 8;
|
||||
elf64shdr(".bss", sh);
|
||||
|
||||
w = strtabsize;
|
||||
|
||||
linuxshdr(".shstrtab", /* name */
|
||||
3, /* type */
|
||||
0, /* flags */
|
||||
0, /* addr */
|
||||
fo, /* off */
|
||||
w, /* size */
|
||||
0, /* link */
|
||||
0, /* info */
|
||||
1, /* align */
|
||||
0); /* entsize */
|
||||
sh = newElf64SHdr();
|
||||
sh->type = 3;
|
||||
sh->off = fo;
|
||||
sh->size = w;
|
||||
sh->addralign = 1;
|
||||
elf64shdr(".shstrtab", sh);
|
||||
|
||||
if (debug['s'])
|
||||
break;
|
||||
@ -566,30 +550,25 @@ asmb(void)
|
||||
fo = symo+8;
|
||||
w = symsize;
|
||||
|
||||
linuxshdr(".gosymtab", /* name */
|
||||
1, /* type 1 = SHT_PROGBITS */
|
||||
0, /* flags */
|
||||
0, /* addr */
|
||||
fo, /* off */
|
||||
w, /* size */
|
||||
0, /* link */
|
||||
0, /* info */
|
||||
1, /* align */
|
||||
24); /* entsize */
|
||||
sh = newElf64SHdr();
|
||||
sh->type = 1; /* type 1 = SHT_PROGBITS */
|
||||
sh->off = fo;
|
||||
sh->size = w;
|
||||
sh->addralign = 1;
|
||||
sh->entsize = 24;
|
||||
elf64shdr(".gosymtab", sh);
|
||||
|
||||
fo += w;
|
||||
w = lcsize;
|
||||
|
||||
linuxshdr(".gopclntab", /* name */
|
||||
1, /* type 1 = SHT_PROGBITS*/
|
||||
0, /* flags */
|
||||
0, /* addr */
|
||||
fo, /* off */
|
||||
w, /* size */
|
||||
0, /* link */
|
||||
0, /* info */
|
||||
1, /* align */
|
||||
24); /* entsize */
|
||||
sh = newElf64SHdr();
|
||||
sh->type = 1; /* type 1 = SHT_PROGBITS */
|
||||
sh->off = fo;
|
||||
sh->size = w;
|
||||
sh->addralign = 1;
|
||||
sh->entsize = 24;
|
||||
elf64shdr(".gopclntab", sh);
|
||||
|
||||
break;
|
||||
}
|
||||
cflush();
|
||||
@ -899,91 +878,3 @@ machheadr(void)
|
||||
|
||||
return a*4;
|
||||
}
|
||||
|
||||
uint32
|
||||
linuxheadr(void)
|
||||
{
|
||||
uint32 a;
|
||||
|
||||
a = 64; /* a.out header */
|
||||
|
||||
a += 56; /* page zero seg */
|
||||
a += 56; /* text seg */
|
||||
a += 56; /* stack seg */
|
||||
|
||||
a += 64; /* nil sect */
|
||||
a += 64; /* .text sect */
|
||||
a += 64; /* .data seg */
|
||||
a += 64; /* .bss sect */
|
||||
a += 64; /* .shstrtab sect - strings for headers */
|
||||
if (!debug['s']) {
|
||||
a += 56; /* symdat seg */
|
||||
a += 64; /* .gosymtab sect */
|
||||
a += 64; /* .gopclntab sect */
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
linuxphdr(int type, int flags, vlong foff,
|
||||
vlong vaddr, vlong paddr,
|
||||
vlong filesize, vlong memsize, vlong align)
|
||||
{
|
||||
|
||||
lputl(type); /* text - type = PT_LOAD */
|
||||
lputl(flags); /* text - flags = PF_X+PF_R */
|
||||
vputl(foff); /* file offset */
|
||||
vputl(vaddr); /* vaddr */
|
||||
vputl(paddr); /* paddr */
|
||||
vputl(filesize); /* file size */
|
||||
vputl(memsize); /* memory size */
|
||||
vputl(align); /* alignment */
|
||||
}
|
||||
|
||||
void
|
||||
linuxshdr(char *name, uint32 type, vlong flags, vlong addr, vlong off,
|
||||
vlong size, uint32 link, uint32 info, vlong align, vlong entsize)
|
||||
{
|
||||
lputl(stroffset);
|
||||
lputl(type);
|
||||
vputl(flags);
|
||||
vputl(addr);
|
||||
vputl(off);
|
||||
vputl(size);
|
||||
lputl(link);
|
||||
lputl(info);
|
||||
vputl(align);
|
||||
vputl(entsize);
|
||||
|
||||
if(name != nil)
|
||||
stroffset += strlen(name)+1;
|
||||
}
|
||||
|
||||
int
|
||||
putstrtab(char* name) {
|
||||
int w;
|
||||
|
||||
w = strlen(name)+1;
|
||||
strnput(name, w);
|
||||
return w;
|
||||
}
|
||||
|
||||
int
|
||||
linuxstrtable(void)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = 0;
|
||||
size += putstrtab("");
|
||||
size += putstrtab(".text");
|
||||
size += putstrtab(".data");
|
||||
size += putstrtab(".bss");
|
||||
size += putstrtab(".shstrtab");
|
||||
if (!debug['s']) {
|
||||
size += putstrtab(".gosymtab");
|
||||
size += putstrtab(".gopclntab");
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
6
src/cmd/6l/elf64.c
Normal file
6
src/cmd/6l/elf64.c
Normal file
@ -0,0 +1,6 @@
|
||||
// Copyright 2009 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 "l.h"
|
||||
#include "../ld/elf64.c"
|
@ -432,9 +432,11 @@ int relinv(int);
|
||||
int32 reuse(Prog*, Sym*);
|
||||
vlong rnd(vlong, vlong);
|
||||
void span(void);
|
||||
void strnput(char*, int);
|
||||
void undef(void);
|
||||
void undefsym(Sym*);
|
||||
vlong vaddr(Adr*);
|
||||
void vputl(vlong);
|
||||
void wput(ushort);
|
||||
void xdefine(char*, int, vlong);
|
||||
void xfol(Prog*);
|
||||
@ -448,14 +450,6 @@ void machstack(vlong);
|
||||
void machdylink(void);
|
||||
uint32 machheadr(void);
|
||||
|
||||
uint32 linuxheadr(void);
|
||||
void linuxphdr(int type, int flags, vlong foff,
|
||||
vlong vaddr, vlong paddr,
|
||||
vlong filesize, vlong memsize, vlong align);
|
||||
void linuxshdr(char *name, uint32 type, vlong flags, vlong addr, vlong off,
|
||||
vlong size, uint32 link, uint32 info, vlong align, vlong entsize);
|
||||
int linuxstrtable(void);
|
||||
|
||||
|
||||
#pragma varargck type "D" Adr*
|
||||
#pragma varargck type "P" Prog*
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#define EXTERN
|
||||
#include "l.h"
|
||||
#include "../ld/elf64.h"
|
||||
#include <ar.h>
|
||||
|
||||
char *noname = "<none>";
|
||||
@ -196,7 +197,7 @@ main(int argc, char *argv[])
|
||||
INITRND = 4096;
|
||||
break;
|
||||
case 7: /* elf64 executable */
|
||||
HEADR = linuxheadr();
|
||||
HEADR = elf64headr();
|
||||
if(INITTEXT == -1)
|
||||
INITTEXT = (1<<22)+HEADR;
|
||||
if(INITDAT == -1)
|
||||
|
108
src/cmd/ld/elf64.c
Normal file
108
src/cmd/ld/elf64.c
Normal file
@ -0,0 +1,108 @@
|
||||
// Copyright 2009 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.
|
||||
|
||||
// Support for 64-bit Elf binaries
|
||||
|
||||
#include "../ld/elf64.h"
|
||||
|
||||
void
|
||||
elf64phdr(int type, int flags, vlong foff,
|
||||
vlong vaddr, vlong paddr,
|
||||
vlong filesize, vlong memsize, vlong align)
|
||||
{
|
||||
|
||||
lputl(type); /* type */
|
||||
lputl(flags); /* flags */
|
||||
vputl(foff); /* file offset */
|
||||
vputl(vaddr); /* vaddr */
|
||||
vputl(paddr); /* paddr */
|
||||
vputl(filesize); /* file size */
|
||||
vputl(memsize); /* memory size */
|
||||
vputl(align); /* alignment */
|
||||
}
|
||||
|
||||
void
|
||||
elf64shdr(char *name, Elf64SHdr *e)
|
||||
{
|
||||
lputl(e->name);
|
||||
lputl(e->type);
|
||||
vputl(e->flags);
|
||||
vputl(e->addr);
|
||||
vputl(e->off);
|
||||
vputl(e->size);
|
||||
lputl(e->link);
|
||||
lputl(e->info);
|
||||
vputl(e->addralign);
|
||||
vputl(e->entsize);
|
||||
|
||||
if(name != nil)
|
||||
stroffset += strlen(name)+1;
|
||||
}
|
||||
|
||||
int
|
||||
putelf64strtab(char* name)
|
||||
{
|
||||
int w;
|
||||
|
||||
w = strlen(name)+1;
|
||||
strnput(name, w);
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
elf64strtable(void)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = 0;
|
||||
size += putelf64strtab("");
|
||||
size += putelf64strtab(".text");
|
||||
size += putelf64strtab(".data");
|
||||
size += putelf64strtab(".bss");
|
||||
size += putelf64strtab(".shstrtab");
|
||||
if (!debug['s']) {
|
||||
size += putelf64strtab(".gosymtab");
|
||||
size += putelf64strtab(".gopclntab");
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
elf64headr(void)
|
||||
{
|
||||
uint32 a;
|
||||
|
||||
a = 64; /* a.out header */
|
||||
|
||||
a += 56; /* page zero seg */
|
||||
a += 56; /* text seg */
|
||||
a += 56; /* stack seg */
|
||||
|
||||
a += 64; /* nil sect */
|
||||
a += 64; /* .text sect */
|
||||
a += 64; /* .data seg */
|
||||
a += 64; /* .bss sect */
|
||||
a += 64; /* .shstrtab sect - strings for headers */
|
||||
if (!debug['s']) {
|
||||
a += 56; /* symdat seg */
|
||||
a += 64; /* .gosymtab sect */
|
||||
a += 64; /* .gopclntab sect */
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
Elf64SHdr*
|
||||
newElf64SHdr()
|
||||
{
|
||||
Elf64SHdr *e;
|
||||
|
||||
e = malloc(sizeof *e);
|
||||
memset(e, 0, sizeof *e);
|
||||
e->name = stroffset;
|
||||
return e;
|
||||
}
|
||||
|
89
src/cmd/ld/elf64.h
Normal file
89
src/cmd/ld/elf64.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Derived from:
|
||||
* $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $
|
||||
* $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $
|
||||
* $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $
|
||||
* $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $
|
||||
* $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $
|
||||
* $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $
|
||||
* $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $
|
||||
* $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $
|
||||
* $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $
|
||||
*
|
||||
* Copyright (c) 1996-1998 John D. Polstra. All rights reserved.
|
||||
* Copyright (c) 2001 David E. O'Brien
|
||||
* Portions Copyright 2009 The Go Authors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef uint64 Elf64_Addr; /* Unsigned program address */
|
||||
typedef uint64 Elf64_Off; /* Unsigned file offset */
|
||||
typedef uint16 Elf64_Half; /* Unsigned medium integer */
|
||||
typedef uint32 Elf64_Word; /* Unsigned integer */
|
||||
typedef int32 Elf64_Sword; /* Signed integer */
|
||||
typedef uint64 Elf64_Xword; /* Unsigned long integer */
|
||||
typedef int64 Elf64_Sxword; /* Signed long integer */
|
||||
|
||||
typedef struct Elf64Hdr Elf64Hdr;
|
||||
typedef struct Elf64SHdr Elf64SHdr;
|
||||
|
||||
struct Elf64Hdr
|
||||
{
|
||||
uchar ident[16]; /* ELF identification */
|
||||
Elf64_Half type; /* Object file type */
|
||||
Elf64_Half machine; /* Machine type */
|
||||
Elf64_Word version; /* Object file version */
|
||||
Elf64_Addr entry; /* Entry point address */
|
||||
Elf64_Off phoff; /* Program header offset */
|
||||
Elf64_Off shoff; /* Section header offset */
|
||||
Elf64_Word flags; /* Processor-specific flags */
|
||||
Elf64_Half ehsize; /* ELF header size */
|
||||
Elf64_Half phentsize; /* Size of program header entry */
|
||||
Elf64_Half phnum; /* Number of program header entries */
|
||||
Elf64_Half shentsize; /* Size of section header entry */
|
||||
Elf64_Half shnum; /* Number of section header entries */
|
||||
Elf64_Half shstrndx; /* Section name string table index */
|
||||
};
|
||||
|
||||
struct Elf64SHdr
|
||||
{
|
||||
Elf64_Word name; /* Section name */
|
||||
Elf64_Word type; /* Section type */
|
||||
Elf64_Xword flags; /* Section attributes */
|
||||
Elf64_Addr addr; /* Virtual address in memory */
|
||||
Elf64_Off off; /* Offset in file */
|
||||
Elf64_Xword size; /* Size of section */
|
||||
Elf64_Word link; /* Link to other section */
|
||||
Elf64_Word info; /* Miscellaneous information */
|
||||
Elf64_Xword addralign; /* Address alignment boundary */
|
||||
Elf64_Xword entsize; /* Size of entries, if section has table */
|
||||
};
|
||||
|
||||
Elf64SHdr *newElf64SHdr();
|
||||
uint32 elf64headr(void);
|
||||
void elf64phdr(int type, int flags, vlong foff,
|
||||
vlong vaddr, vlong paddr,
|
||||
vlong filesize, vlong memsize, vlong align);
|
||||
void elf64shdr(char*, Elf64SHdr*);
|
||||
int elf64strtable(void);
|
Loading…
Reference in New Issue
Block a user