OFILES=\
asm.$O\
compat.$O\
+ elf64.$O\
enam.$O\
go.$O\
list.$O\
HFILES=\
l.h\
../6l/6.out.h\
+ ../ld/elf64.h\
$(TARG): $(OFILES)
cp $(TARG) $(BIN)/$(TARG)
go.o: ../ld/go.c
+
+elf64.o: ../ld/elf64.c
// THE SOFTWARE.
#include "l.h"
+#include "../ld/elf64.h"
#define Dbufslop 100
vlong vl, va, fo, w, symo;
int strtabsize;
vlong symdatva = 0x99LL<<32;
+ Elf64SHdr *sh;
strtabsize = 0;
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);
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 */
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 */
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 */
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 */
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;
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();
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;
-}
--- /dev/null
+// 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"
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*);
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*
#define EXTERN
#include "l.h"
+#include "../ld/elf64.h"
#include <ar.h>
char *noname = "<none>";
INITRND = 4096;
break;
case 7: /* elf64 executable */
- HEADR = linuxheadr();
+ HEADR = elf64headr();
if(INITTEXT == -1)
INITTEXT = (1<<22)+HEADR;
if(INITDAT == -1)
--- /dev/null
+// 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;
+}
+
--- /dev/null
+/*
+ * 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);