]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/5l etc: replace C code with Go code
authorRuss Cox <rsc@golang.org>
Sat, 28 Feb 2015 18:48:09 +0000 (13:48 -0500)
committerRuss Cox <rsc@golang.org>
Sun, 1 Mar 2015 00:40:11 +0000 (00:40 +0000)
mv cmd/new5l cmd/5l and so on.

Minimal changes to cmd/dist and cmd/go to keep things building.
More can be deleted in followup CLs.

Change-Id: I1449eca7654ce2580d1f413a56dc4a75f3d4618b
Reviewed-on: https://go-review.googlesource.com/6361
Reviewed-by: Rob Pike <r@golang.org>
60 files changed:
src/cmd/5l/Makefile [deleted file]
src/cmd/5l/asm.c [deleted file]
src/cmd/5l/asm.go [moved from src/cmd/new5l/asm.go with 100% similarity]
src/cmd/5l/doc.go [deleted file]
src/cmd/5l/l.go [moved from src/cmd/new5l/l.go with 100% similarity]
src/cmd/5l/l.h [deleted file]
src/cmd/5l/obj.c [deleted file]
src/cmd/5l/obj.go [moved from src/cmd/new5l/obj.go with 100% similarity]
src/cmd/6l/Makefile [deleted file]
src/cmd/6l/asm.c [deleted file]
src/cmd/6l/asm.go [moved from src/cmd/new6l/asm.go with 100% similarity]
src/cmd/6l/doc.go [deleted file]
src/cmd/6l/l.go [moved from src/cmd/new6l/l.go with 100% similarity]
src/cmd/6l/l.h [deleted file]
src/cmd/6l/obj.c [deleted file]
src/cmd/6l/obj.go [moved from src/cmd/new6l/obj.go with 100% similarity]
src/cmd/6l/z.go [moved from src/cmd/new6l/z.go with 100% similarity]
src/cmd/8l/Makefile [deleted file]
src/cmd/8l/asm.c [deleted file]
src/cmd/8l/asm.go [moved from src/cmd/new8l/asm.go with 100% similarity]
src/cmd/8l/doc.go [deleted file]
src/cmd/8l/l.go [moved from src/cmd/new8l/l.go with 100% similarity]
src/cmd/8l/l.h [deleted file]
src/cmd/8l/obj.c [deleted file]
src/cmd/8l/obj.go [moved from src/cmd/new8l/obj.go with 100% similarity]
src/cmd/9l/Makefile [deleted file]
src/cmd/9l/asm.c [deleted file]
src/cmd/9l/asm.go [moved from src/cmd/new9l/asm.go with 100% similarity]
src/cmd/9l/doc.go [deleted file]
src/cmd/9l/l.go [moved from src/cmd/new9l/l.go with 100% similarity]
src/cmd/9l/l.h [deleted file]
src/cmd/9l/obj.c [deleted file]
src/cmd/9l/obj.go [moved from src/cmd/new9l/obj.go with 100% similarity]
src/cmd/dist/build.go
src/cmd/dist/buildtool.go
src/cmd/go/build.go
src/cmd/go/pkg.go
src/cmd/ld/Makefile [deleted file]
src/cmd/ld/data.c [deleted file]
src/cmd/ld/decodesym.c [deleted file]
src/cmd/ld/doc.go [deleted file]
src/cmd/ld/dwarf.c [deleted file]
src/cmd/ld/dwarf.h [deleted file]
src/cmd/ld/dwarf_defs.h [deleted file]
src/cmd/ld/elf.c [deleted file]
src/cmd/ld/elf.h [deleted file]
src/cmd/ld/go.c [deleted file]
src/cmd/ld/ldelf.c [deleted file]
src/cmd/ld/ldmacho.c [deleted file]
src/cmd/ld/ldpe.c [deleted file]
src/cmd/ld/lib.c [deleted file]
src/cmd/ld/lib.h [deleted file]
src/cmd/ld/macho.c [deleted file]
src/cmd/ld/macho.h [deleted file]
src/cmd/ld/pcln.c [deleted file]
src/cmd/ld/pe.c [deleted file]
src/cmd/ld/pe.h [deleted file]
src/cmd/ld/pobj.c [deleted file]
src/cmd/ld/symtab.c [deleted file]
src/runtime/textflag.h [moved from src/cmd/ld/textflag.h with 87% similarity]

diff --git a/src/cmd/5l/Makefile b/src/cmd/5l/Makefile
deleted file mode 100644 (file)
index 3f528d7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# 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
diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c
deleted file mode 100644 (file)
index 079c973..0000000
+++ /dev/null
@@ -1,749 +0,0 @@
-// Inferno utils/5l/asm.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Writing object files.
-
-#include       "l.h"
-#include       "../ld/lib.h"
-#include       "../ld/elf.h"
-#include       "../ld/macho.h"
-#include       "../ld/dwarf.h"
-
-static int
-needlib(char *name)
-{
-       char *p;
-       LSym *s;
-
-       if(*name == '\0')
-               return 0;
-
-       /* reuse hash code in symbol table */
-       p = smprint(".dynlib.%s", name);
-       s = linklookup(ctxt, p, 0);
-       free(p);
-       if(s->type == 0) {
-               s->type = 100;  // avoid SDATA, etc.
-               return 1;
-       }
-       return 0;
-}
-
-static void    addpltsym(Link*, LSym*);
-static void    addgotsym(Link*, LSym*);
-static void    addgotsyminternal(Link*, LSym*);
-
-void
-gentext(void)
-{
-}
-
-// Preserve highest 8 bits of a, and do addition to lower 24-bit
-// of a and b; used to adjust ARM branch intruction's target
-static int32
-braddoff(int32 a, int32 b)
-{
-       return (((uint32)a) & 0xff000000U) | (0x00ffffffU & (uint32)(a + b));
-}
-
-void
-adddynrela(LSym *rel, LSym *s, Reloc *r)
-{
-       addaddrplus(ctxt, rel, s, r->off);
-       adduint32(ctxt, rel, R_ARM_RELATIVE);
-}
-
-void
-adddynrel(LSym *s, Reloc *r)
-{
-       LSym *targ, *rel;
-
-       targ = r->sym;
-       ctxt->cursym = s;
-
-       switch(r->type) {
-       default:
-               if(r->type >= 256) {
-                       diag("unexpected relocation type %d", r->type);
-                       return;
-               }
-               break;
-
-       // Handle relocations found in ELF object files.
-       case 256 + R_ARM_PLT32:
-               r->type = R_CALLARM;
-               if(targ->type == SDYNIMPORT) {
-                       addpltsym(ctxt, targ);
-                       r->sym = linklookup(ctxt, ".plt", 0);
-                       r->add = braddoff(r->add, targ->plt / 4);
-               }
-               return;
-
-       case 256 + R_ARM_THM_PC22: // R_ARM_THM_CALL
-               diag("R_ARM_THM_CALL, are you using -marm?");
-               errorexit();
-               return;
-
-       case 256 + R_ARM_GOT32: // R_ARM_GOT_BREL
-               if(targ->type != SDYNIMPORT) {
-                       addgotsyminternal(ctxt, targ);
-               } else {
-                       addgotsym(ctxt, targ);
-               }
-               r->type = R_CONST;      // write r->add during relocsym
-               r->sym = nil;
-               r->add += targ->got;
-               return;
-
-       case 256 + R_ARM_GOT_PREL: // GOT(nil) + A - nil
-               if(targ->type != SDYNIMPORT) {
-                       addgotsyminternal(ctxt, targ);
-               } else {
-                       addgotsym(ctxt, targ);
-               }
-               r->type = R_PCREL;
-               r->sym = linklookup(ctxt, ".got", 0);
-               r->add += targ->got + 4;
-               return;
-
-       case 256 + R_ARM_GOTOFF: // R_ARM_GOTOFF32
-               r->type = R_GOTOFF;
-               return;
-
-       case 256 + R_ARM_GOTPC: // R_ARM_BASE_PREL
-               r->type = R_PCREL;
-               r->sym = linklookup(ctxt, ".got", 0);
-               r->add += 4;
-               return;
-
-       case 256 + R_ARM_CALL:
-               r->type = R_CALLARM;
-               if(targ->type == SDYNIMPORT) {
-                       addpltsym(ctxt, targ);
-                       r->sym = linklookup(ctxt, ".plt", 0);
-                       r->add = braddoff(r->add, targ->plt / 4);
-               }
-               return;
-
-       case 256 + R_ARM_REL32: // R_ARM_REL32
-               r->type = R_PCREL;
-               r->add += 4;
-               return;
-
-       case 256 + R_ARM_ABS32: 
-               if(targ->type == SDYNIMPORT)
-                       diag("unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ->name);
-               r->type = R_ADDR;
-               return;
-
-       case 256 + R_ARM_V4BX:
-               // we can just ignore this, because we are targeting ARM V5+ anyway
-               if(r->sym) {
-                       // R_ARM_V4BX is ABS relocation, so this symbol is a dummy symbol, ignore it
-                       r->sym->type = 0;
-               }
-               r->sym = nil;
-               return;
-
-       case 256 + R_ARM_PC24:
-       case 256 + R_ARM_JUMP24:
-               r->type = R_CALLARM;
-               if(targ->type == SDYNIMPORT) {
-                       addpltsym(ctxt, targ);
-                       r->sym = linklookup(ctxt, ".plt", 0);
-                       r->add = braddoff(r->add, targ->plt / 4);
-               }
-               return;
-       }
-       
-       // Handle references to ELF symbols from our own object files.
-       if(targ->type != SDYNIMPORT)
-               return;
-
-       switch(r->type) {
-       case R_CALLARM:
-               addpltsym(ctxt, targ);
-               r->sym = linklookup(ctxt, ".plt", 0);
-               r->add = targ->plt;
-               return;
-       
-       case R_ADDR:
-               if(s->type != SDATA)
-                       break;
-               if(iself) {
-                       adddynsym(ctxt, targ);
-                       rel = linklookup(ctxt, ".rel", 0);
-                       addaddrplus(ctxt, rel, s, r->off);
-                       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->sym = nil;
-                       return;
-               }
-               break;
-       }
-
-       ctxt->cursym = s;
-       diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ->name, r->type, targ->type);
-}
-
-int
-elfreloc1(Reloc *r, vlong sectoff)
-{
-       int32 elfsym;
-       
-       thearch.lput(sectoff);
-
-       elfsym = r->xsym->elfsym;
-       switch(r->type) {
-       default:
-               return -1;
-
-       case R_ADDR:
-               if(r->siz == 4)
-                       thearch.lput(R_ARM_ABS32 | elfsym<<8);
-               else
-                       return -1;
-               break;
-
-       case R_PCREL:
-               if(r->siz == 4)
-                       thearch.lput(R_ARM_REL32 | elfsym<<8);
-               else
-                       return -1;
-               break;
-
-       case R_CALLARM:
-               if(r->siz == 4) {
-                       if((r->add & 0xff000000) == 0xeb000000) // BL
-                               thearch.lput(R_ARM_CALL | elfsym<<8);
-                       else
-                               thearch.lput(R_ARM_JUMP24 | elfsym<<8);
-               } else
-                       return -1;
-               break;
-
-       case R_TLS:
-               if(r->siz == 4) {
-                       if(flag_shared)
-                               thearch.lput(R_ARM_TLS_IE32 | elfsym<<8);
-                       else
-                               thearch.lput(R_ARM_TLS_LE32 | elfsym<<8);
-               } else
-                       return -1;
-               break;
-       }
-
-       return 0;
-}
-
-void
-elfsetupplt(void)
-{
-       LSym *plt, *got;
-       
-       plt = linklookup(ctxt, ".plt", 0);
-       got = linklookup(ctxt, ".got.plt", 0);
-       if(plt->size == 0) {
-               // str lr, [sp, #-4]!
-               adduint32(ctxt, plt, 0xe52de004);
-               // ldr lr, [pc, #4]
-               adduint32(ctxt, plt, 0xe59fe004);
-               // add lr, pc, lr
-               adduint32(ctxt, plt, 0xe08fe00e);
-               // ldr pc, [lr, #8]!
-               adduint32(ctxt, plt, 0xe5bef008);
-               // .word &GLOBAL_OFFSET_TABLE[0] - .
-               addpcrelplus(ctxt, plt, got, 4);
-
-               // the first .plt entry requires 3 .plt.got entries
-               adduint32(ctxt, got, 0);
-               adduint32(ctxt, got, 0);
-               adduint32(ctxt, got, 0);
-       }
-}
-
-int
-machoreloc1(Reloc *r, vlong sectoff)
-{
-       uint32 v;
-       LSym *rs;
-
-       rs = r->xsym;
-
-       if(rs->type == SHOSTOBJ || r->type == R_CALLARM) {
-               if(rs->dynid < 0) {
-                       diag("reloc %d to non-macho symbol %s type=%d", r->type, rs->name, rs->type);
-                       return -1;
-               }
-               v = rs->dynid;
-               v |= 1<<27; // external relocation
-       } else {
-               v = ((Section*)rs->sect)->extnum;
-               if(v == 0) {
-                       diag("reloc %d to symbol %s in non-macho section %s type=%d", r->type, rs->name, ((Section*)rs->sect)->name, rs->type);
-                       return -1;
-               }
-       }
-
-       switch(r->type) {
-       default:
-               return -1;
-       case R_ADDR:
-               v |= MACHO_GENERIC_RELOC_VANILLA<<28;
-               break;
-       case R_CALLARM:
-               v |= 1<<24; // pc-relative bit
-               v |= MACHO_ARM_RELOC_BR24<<28;
-               break;
-       }
-
-       switch(r->siz) {
-       default:
-               return -1;
-       case 1:
-               v |= 0<<25;
-               break;
-       case 2:
-               v |= 1<<25;
-               break;
-       case 4:
-               v |= 2<<25;
-               break;
-       case 8:
-               v |= 3<<25;
-               break;
-       }
-
-       thearch.lput(sectoff);
-       thearch.lput(v);
-       return 0;
-}
-
-
-int
-archreloc(Reloc *r, LSym *s, vlong *val)
-{
-       LSym *rs;
-
-       if(linkmode == LinkExternal) {
-               switch(r->type) {
-               case R_CALLARM:
-                       r->done = 0;
-
-                       // set up addend for eventual relocation via outer symbol.
-                       rs = r->sym;
-                       r->xadd = r->add;
-                       if(r->xadd & 0x800000)
-                               r->xadd |= ~0xffffff;
-                       r->xadd *= 4;
-                       while(rs->outer != nil) {
-                               r->xadd += symaddr(rs) - symaddr(rs->outer);
-                               rs = rs->outer;
-                       }
-
-                       if(rs->type != SHOSTOBJ && rs->sect == nil)
-                               diag("missing section for %s", rs->name);
-                       r->xsym = rs;
-
-                       // ld64 for arm seems to want the symbol table to contain offset
-                       // into the section rather than pseudo virtual address that contains
-                       // the section load address.
-                       // we need to compensate that by removing the instruction's address
-                       // from addend.
-                       if(HEADTYPE == Hdarwin)
-                               r->xadd -= symaddr(s) + r->off;
-
-                       *val = braddoff((0xff000000U & (uint32)r->add), 
-                                                       (0xffffff & (uint32)(r->xadd / 4)));
-                       return 0;
-               }
-               return -1;
-       }
-       switch(r->type) {
-       case R_CONST:
-               *val = r->add;
-               return 0;
-       case R_GOTOFF:
-               *val = symaddr(r->sym) + r->add - symaddr(linklookup(ctxt, ".got", 0));
-               return 0;
-       // The following three arch specific relocations are only for generation of 
-       // Linux/ARM ELF's PLT entry (3 assembler instruction)
-       case R_PLT0: // add ip, pc, #0xXX00000
-               if (symaddr(linklookup(ctxt, ".got.plt", 0)) < symaddr(linklookup(ctxt, ".plt", 0)))
-                       diag(".got.plt should be placed after .plt section.");
-               *val = 0xe28fc600U +
-                       (0xff & ((uint32)(symaddr(r->sym) - (symaddr(linklookup(ctxt, ".plt", 0)) + r->off) + r->add) >> 20));
-               return 0;
-       case R_PLT1: // add ip, ip, #0xYY000
-               *val = 0xe28cca00U +
-                       (0xff & ((uint32)(symaddr(r->sym) - (symaddr(linklookup(ctxt, ".plt", 0)) + r->off) + r->add + 4) >> 12));
-               return 0;
-       case R_PLT2: // ldr pc, [ip, #0xZZZ]!
-               *val = 0xe5bcf000U +
-                       (0xfff & (uint32)(symaddr(r->sym) - (symaddr(linklookup(ctxt, ".plt", 0)) + r->off) + r->add + 8));
-               return 0;
-       case R_CALLARM: // bl XXXXXX or b YYYYYY
-               *val = braddoff((0xff000000U & (uint32)r->add), 
-                               (0xffffff & (uint32)
-                                  ((symaddr(r->sym) + ((uint32)r->add) * 4 - (s->value + r->off)) / 4)));
-               return 0;
-       }
-       return -1;
-}
-
-vlong
-archrelocvariant(Reloc *r, LSym *s, vlong t)
-{
-       USED(r);
-       USED(s);
-       sysfatal("unexpected relocation variant");
-       return t;
-}
-
-static Reloc *
-addpltreloc(Link *ctxt, LSym *plt, LSym *got, LSym *sym, int typ)
-{
-       Reloc *r;
-
-       r = addrel(plt);
-       r->sym = got;
-       r->off = plt->size;
-       r->siz = 4;
-       r->type = typ;
-       r->add = sym->got - 8;
-
-       plt->reachable = 1;
-       plt->size += 4;
-       symgrow(ctxt, plt, plt->size);
-
-       return r;
-}
-
-static void
-addpltsym(Link *ctxt, LSym *s)
-{
-       LSym *plt, *got, *rel;
-       
-       if(s->plt >= 0)
-               return;
-
-       adddynsym(ctxt, s);
-       
-       if(iself) {
-               plt = linklookup(ctxt, ".plt", 0);
-               got = linklookup(ctxt, ".got.plt", 0);
-               rel = linklookup(ctxt, ".rel.plt", 0);
-               if(plt->size == 0)
-                       elfsetupplt();
-               
-               // .got entry
-               s->got = got->size;
-               // In theory, all GOT should point to the first PLT entry,
-               // Linux/ARM's dynamic linker will do that for us, but FreeBSD/ARM's
-               // dynamic linker won't, so we'd better do it ourselves.
-               addaddrplus(ctxt, got, plt, 0);
-
-               // .plt entry, this depends on the .got entry
-               s->plt = plt->size;
-               addpltreloc(ctxt, plt, got, s, R_PLT0); // add lr, pc, #0xXX00000
-               addpltreloc(ctxt, plt, got, s, R_PLT1); // add lr, lr, #0xYY000
-               addpltreloc(ctxt, plt, got, s, R_PLT2); // ldr pc, [lr, #0xZZZ]!
-
-               // rel
-               addaddrplus(ctxt, rel, got, s->got);
-               adduint32(ctxt, rel, ELF32_R_INFO(s->dynid, R_ARM_JUMP_SLOT));
-       } else {
-               diag("addpltsym: unsupported binary format");
-       }
-}
-
-static void
-addgotsyminternal(Link *ctxt, LSym *s)
-{
-       LSym *got;
-       
-       if(s->got >= 0)
-               return;
-
-       got = linklookup(ctxt, ".got", 0);
-       s->got = got->size;
-
-       addaddrplus(ctxt, got, s, 0);
-
-       if(iself) {
-               ;
-       } else {
-               diag("addgotsyminternal: unsupported binary format");
-       }
-}
-
-static void
-addgotsym(Link *ctxt, LSym *s)
-{
-       LSym *got, *rel;
-       
-       if(s->got >= 0)
-               return;
-       
-       adddynsym(ctxt, s);
-       got = linklookup(ctxt, ".got", 0);
-       s->got = got->size;
-       adduint32(ctxt, got, 0);
-       
-       if(iself) {
-               rel = linklookup(ctxt, ".rel", 0);
-               addaddrplus(ctxt, rel, got, s->got);
-               adduint32(ctxt, rel, ELF32_R_INFO(s->dynid, R_ARM_GLOB_DAT));
-       } else {
-               diag("addgotsym: unsupported binary format");
-       }
-}
-
-void
-adddynsym(Link *ctxt, LSym *s)
-{
-       LSym *d;
-       int t;
-       char *name;
-
-       if(s->dynid >= 0)
-               return;
-
-       if(iself) {
-               s->dynid = nelfsym++;
-
-               d = linklookup(ctxt, ".dynsym", 0);
-
-               /* name */
-               name = s->extname;
-               adduint32(ctxt, d, addstring(linklookup(ctxt, ".dynstr", 0), name));
-
-               /* value */
-               if(s->type == SDYNIMPORT)
-                       adduint32(ctxt, d, 0);
-               else
-                       addaddr(ctxt, d, s);
-
-               /* size */
-               adduint32(ctxt, d, 0);
-
-               /* type */
-               t = STB_GLOBAL << 4;
-               if((s->cgoexport & CgoExportDynamic) && (s->type&SMASK) == STEXT)
-                       t |= STT_FUNC;
-               else
-                       t |= STT_OBJECT;
-               adduint8(ctxt, d, t);
-               adduint8(ctxt, d, 0);
-
-               /* shndx */
-               if(s->type == SDYNIMPORT)
-                       adduint16(ctxt, d, SHN_UNDEF);
-               else
-                       adduint16(ctxt, d, 1);
-       } else {
-               diag("adddynsym: unsupported binary format");
-       }
-}
-
-void
-adddynlib(char *lib)
-{
-       LSym *s;
-       
-       if(!needlib(lib))
-               return;
-       
-       if(iself) {
-               s = linklookup(ctxt, ".dynstr", 0);
-               if(s->size == 0)
-                       addstring(s, "");
-               elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addstring(s, lib));
-       } else if(HEADTYPE == Hdarwin) {
-               machoadddynlib(lib);
-       } else {
-               diag("adddynlib: unsupported binary format");
-       }
-}
-
-void
-asmb(void)
-{
-       uint32 symo, dwarfoff, machlink;
-       Section *sect;
-       LSym *sym;
-       int i;
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f asmb\n", cputime());
-       Bflush(&bso);
-
-       if(iself)
-               asmbelfsetup();
-
-       sect = segtext.sect;
-       cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
-       codeblk(sect->vaddr, sect->length);
-       for(sect = sect->next; sect != nil; sect = sect->next) {
-               cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
-               datblk(sect->vaddr, sect->length);
-       }
-
-       if(segrodata.filelen > 0) {
-               if(debug['v'])
-                       Bprint(&bso, "%5.2f rodatblk\n", cputime());
-               Bflush(&bso);
-
-               cseek(segrodata.fileoff);
-               datblk(segrodata.vaddr, segrodata.filelen);
-       }
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f datblk\n", cputime());
-       Bflush(&bso);
-
-       cseek(segdata.fileoff);
-       datblk(segdata.vaddr, segdata.filelen);
-
-       machlink = 0;
-       if(HEADTYPE == Hdarwin) {
-               if(debug['v'])
-                       Bprint(&bso, "%5.2f dwarf\n", cputime());
-
-               if(!debug['w']) { // TODO(minux): enable DWARF Support
-                       dwarfoff = rnd(HEADR+segtext.length, INITRND) + rnd(segdata.filelen, INITRND);
-                       cseek(dwarfoff);
-
-                       segdwarf.fileoff = cpos();
-                       dwarfemitdebugsections();
-                       segdwarf.filelen = cpos() - segdwarf.fileoff;
-               }
-               machlink = domacholink();
-       }
-
-       /* output symbol table */
-       symsize = 0;
-       lcsize = 0;
-       symo = 0;
-       if(!debug['s']) {
-               // TODO: rationalize
-               if(debug['v'])
-                       Bprint(&bso, "%5.2f sym\n", cputime());
-               Bflush(&bso);
-               switch(HEADTYPE) {
-               default:
-                       if(iself) {
-                               symo = segdata.fileoff+segdata.filelen;
-                               symo = rnd(symo, INITRND);
-                       }
-                       break;
-               case Hplan9:
-                       symo = segdata.fileoff+segdata.filelen;
-                       break;
-               case Hdarwin:
-                       symo = rnd(HEADR+segtext.filelen, INITRND)+rnd(segdata.filelen, INITRND)+machlink;
-                       break;
-               }
-               cseek(symo);
-               switch(HEADTYPE) {
-               default:
-                       if(iself) {
-                               if(debug['v'])
-                                       Bprint(&bso, "%5.2f elfsym\n", cputime());
-                               asmelfsym();
-                               cflush();
-                               cwrite(elfstrdat, elfstrsize);
-       
-                               if(debug['v'])
-                                       Bprint(&bso, "%5.2f dwarf\n", cputime());
-                               dwarfemitdebugsections();
-                               
-                               if(linkmode == LinkExternal)
-                                       elfemitreloc();
-                       }
-                       break;
-               case Hplan9:
-                       asmplan9sym();
-                       cflush();
-
-                       sym = linklookup(ctxt, "pclntab", 0);
-                       if(sym != nil) {
-                               lcsize = sym->np;
-                               for(i=0; i < lcsize; i++)
-                                       cput(sym->p[i]);
-
-                               cflush();
-                       }
-                       break;
-               case Hdarwin:
-                       if(linkmode == LinkExternal)
-                               machoemitreloc();
-                       break;
-               }
-       }
-
-       ctxt->cursym = nil;
-       if(debug['v'])
-               Bprint(&bso, "%5.2f header\n", cputime());
-       Bflush(&bso);
-       cseek(0L);
-       switch(HEADTYPE) {
-       default:
-       case Hplan9:    /* plan 9 */
-               thearch.lput(0x647);                    /* magic */
-               thearch.lput(segtext.filelen);                  /* sizes */
-               thearch.lput(segdata.filelen);
-               thearch.lput(segdata.length - segdata.filelen);
-               thearch.lput(symsize);                  /* nsyms */
-               thearch.lput(entryvalue());             /* va of entry */
-               thearch.lput(0L);
-               thearch.lput(lcsize);
-               break;
-       case Hlinux:
-       case Hfreebsd:
-       case Hnetbsd:
-       case Hopenbsd:
-       case Hnacl:
-               asmbelf(symo);
-               break;
-       case Hdarwin:
-               asmbmacho();
-               break;
-       }
-       cflush();
-       if(debug['c']){
-               print("textsize=%ulld\n", segtext.filelen);
-               print("datsize=%ulld\n", segdata.filelen);
-               print("bsssize=%ulld\n", segdata.length - segdata.filelen);
-               print("symsize=%d\n", symsize);
-               print("lcsize=%d\n", lcsize);
-               print("total=%lld\n", segtext.filelen+segdata.length+symsize+lcsize);
-       }
-}
similarity index 100%
rename from src/cmd/new5l/asm.go
rename to src/cmd/5l/asm.go
diff --git a/src/cmd/5l/doc.go b/src/cmd/5l/doc.go
deleted file mode 100644 (file)
index a054a22..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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.
-
-// +build ignore
-
-/*
-
-5l is the linker for the ARM.
-The $GOARCH for these tools is arm.
-
-The flags are documented in ../ld/doc.go.
-
-*/
-package main
similarity index 100%
rename from src/cmd/new5l/l.go
rename to src/cmd/5l/l.go
diff --git a/src/cmd/5l/l.h b/src/cmd/5l/l.h
deleted file mode 100644 (file)
index 0258d5a..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-// Inferno utils/5l/l.h
-// http://code.google.com/p/inferno-os/source/browse/utils/5l/l.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-
-enum
-{
-       thechar = '5',
-       PtrSize = 4,
-       IntSize = 4,
-       RegSize = 4,
-       MaxAlign = 8,   // max data alignment
-       FuncAlign = 4,  // single-instruction alignment
-       MINLC   = 4,
-};
-
-#ifndef        EXTERN
-#define        EXTERN  extern
-#endif
-
-void   adddynlib(char *lib);
-void   adddynrel(LSym *s, Reloc *r);
-void   adddynrela(LSym *rel, LSym *s, Reloc *r);
-void   adddynsym(Link *ctxt, LSym *s);
-int    archreloc(Reloc *r, LSym *s, vlong *val);
-vlong  archrelocvariant(Reloc *r, LSym *s, vlong t);
-void   asmb(void);
-int    elfreloc1(Reloc *r, vlong sectoff);
-void   elfsetupplt(void);
-int    machoreloc1(Reloc *r, vlong sectoff);
-
-/* Used by ../ld/dwarf.c */
-enum
-{
-       DWARFREGSP = 13
-};
diff --git a/src/cmd/5l/obj.c b/src/cmd/5l/obj.c
deleted file mode 100644 (file)
index 887cc5a..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-// Inferno utils/5l/obj.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5l/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Reading object files.
-
-#include       "l.h"
-#include       "../ld/lib.h"
-#include       "../ld/elf.h"
-#include       "../ld/macho.h"
-#include       "../ld/dwarf.h"
-#include       <ar.h>
-
-void
-main(int argc, char **argv)
-{
-       linkarchinit();
-       ldmain(argc, argv);
-}
-
-
-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.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
-archinit(void)
-{
-       LSym *s;
-
-       // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
-       // Go was built; see ../../make.bash.
-       if(linkmode == LinkAuto && strcmp(getgoextlinkenabled(), "0") == 0)
-               linkmode = LinkInternal;
-
-       switch(HEADTYPE) {
-       default:
-               if(linkmode == LinkAuto)
-                       linkmode = LinkInternal;
-               if(linkmode == LinkExternal && strcmp(getgoextlinkenabled(), "1") != 0)
-                       sysfatal("cannot use -linkmode=external with -H %s", headstr(HEADTYPE));
-               break;
-       case Hlinux:
-       case Hfreebsd:
-       case Hnacl:
-       case Hdarwin:
-               break;
-       }
-
-       switch(HEADTYPE) {
-       default:
-               diag("unknown -H option");
-               errorexit();
-       case Hplan9:    /* plan 9 */
-               HEADR = 32L;
-               if(INITTEXT == -1)
-                       INITTEXT = 4128;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 4096;
-               break;
-       case Hlinux:    /* arm elf */
-       case Hfreebsd:
-       case Hnetbsd:
-               debug['d'] = 0; // with dynamic linking
-               elfinit();
-               HEADR = ELFRESERVE;
-               if(INITTEXT == -1)
-                       INITTEXT = 0x10000 + HEADR;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 4096;
-               break;
-       case Hnacl:
-               elfinit();
-               HEADR = 0x10000;
-               funcalign = 16;
-               if(INITTEXT == -1)
-                       INITTEXT = 0x20000;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 0x10000;
-               break;
-       case Hdarwin:   /* apple MACH */
-               debug['w'] = 1; // disable DWARF generataion
-               machoinit();
-               HEADR = INITIAL_MACHO_HEADR;
-               if(INITTEXT == -1)
-                       INITTEXT = 4096+HEADR;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 4096;
-               break;
-       }
-       if(INITDAT != 0 && INITRND != 0)
-               print("warning: -D0x%ux is ignored because of -R0x%ux\n",
-                       INITDAT, INITRND);
-
-       // embed goarm to runtime.goarm
-       s = linklookup(ctxt, "runtime.goarm", 0);
-       s->type = SRODATA;
-       adduint8(ctxt, s, ctxt->goarm);
-}
similarity index 100%
rename from src/cmd/new5l/obj.go
rename to src/cmd/5l/obj.go
diff --git a/src/cmd/6l/Makefile b/src/cmd/6l/Makefile
deleted file mode 100644 (file)
index 3f528d7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# 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
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c
deleted file mode 100644 (file)
index b817cf5..0000000
+++ /dev/null
@@ -1,795 +0,0 @@
-// Inferno utils/6l/asm.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Writing object files.
-
-#include       "l.h"
-#include       "../ld/lib.h"
-#include       "../ld/elf.h"
-#include       "../ld/dwarf.h"
-#include       "../ld/macho.h"
-#include       "../ld/pe.h"
-
-uint32
-PADDR(uint32 x)
-{
-       return x & ~0x80000000;
-}
-
-char   zeroes[32];
-
-static int
-needlib(char *name)
-{
-       char *p;
-       LSym *s;
-
-       if(*name == '\0')
-               return 0;
-
-       /* reuse hash code in symbol table */
-       p = smprint(".elfload.%s", name);
-       s = linklookup(ctxt, p, 0);
-       free(p);
-       if(s->type == 0) {
-               s->type = 100;  // avoid SDATA, etc.
-               return 1;
-       }
-       return 0;
-}
-
-static void addpltsym(LSym*);
-static void addgotsym(LSym*);
-
-void
-gentext(void)
-{
-}
-
-void
-adddynrela(LSym *rela, LSym *s, Reloc *r)
-{
-       addaddrplus(ctxt, rela, s, r->off);
-       adduint64(ctxt, rela, R_X86_64_RELATIVE);
-       addaddrplus(ctxt, rela, r->sym, r->add); // Addend
-}
-
-void
-adddynrel(LSym *s, Reloc *r)
-{
-       LSym *targ, *rela, *got;
-       
-       targ = r->sym;
-       ctxt->cursym = s;
-
-       switch(r->type) {
-       default:
-               if(r->type >= 256) {
-                       diag("unexpected relocation type %d", r->type);
-                       return;
-               }
-               break;
-
-       // Handle relocations found in ELF object files.
-       case 256 + R_X86_64_PC32:
-               if(targ->type == SDYNIMPORT)
-                       diag("unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ->name);
-               if(targ->type == 0 || targ->type == SXREF)
-                       diag("unknown symbol %s in pcrel", targ->name);
-               r->type = R_PCREL;
-               r->add += 4;
-               return;
-       
-       case 256 + R_X86_64_PLT32:
-               r->type = R_PCREL;
-               r->add += 4;
-               if(targ->type == SDYNIMPORT) {
-                       addpltsym(targ);
-                       r->sym = linklookup(ctxt, ".plt", 0);
-                       r->add += targ->plt;
-               }
-               return;
-       
-       case 256 + R_X86_64_GOTPCREL:
-               if(targ->type != SDYNIMPORT) {
-                       // have symbol
-                       if(r->off >= 2 && s->p[r->off-2] == 0x8b) {
-                               // turn MOVQ of GOT entry into LEAQ of symbol itself
-                               s->p[r->off-2] = 0x8d;
-                               r->type = R_PCREL;
-                               r->add += 4;
-                               return;
-                       }
-                       // fall back to using GOT and hope for the best (CMOV*)
-                       // TODO: just needs relocation, no need to put in .dynsym
-               }
-               addgotsym(targ);
-               r->type = R_PCREL;
-               r->sym = linklookup(ctxt, ".got", 0);
-               r->add += 4;
-               r->add += targ->got;
-               return;
-       
-       case 256 + R_X86_64_64:
-               if(targ->type == SDYNIMPORT)
-                       diag("unexpected R_X86_64_64 relocation for dynamic symbol %s", targ->name);
-               r->type = R_ADDR;
-               return;
-       
-       // Handle relocations found in Mach-O object files.
-       case 512 + MACHO_X86_64_RELOC_UNSIGNED*2 + 0:
-       case 512 + MACHO_X86_64_RELOC_SIGNED*2 + 0:
-       case 512 + MACHO_X86_64_RELOC_BRANCH*2 + 0:
-               // TODO: What is the difference between all these?
-               r->type = R_ADDR;
-               if(targ->type == SDYNIMPORT)
-                       diag("unexpected reloc for dynamic symbol %s", targ->name);
-               return;
-
-       case 512 + MACHO_X86_64_RELOC_BRANCH*2 + 1:
-               if(targ->type == SDYNIMPORT) {
-                       addpltsym(targ);
-                       r->sym = linklookup(ctxt, ".plt", 0);
-                       r->add = targ->plt;
-                       r->type = R_PCREL;
-                       return;
-               }
-               // fall through
-       case 512 + MACHO_X86_64_RELOC_UNSIGNED*2 + 1:
-       case 512 + MACHO_X86_64_RELOC_SIGNED*2 + 1:
-       case 512 + MACHO_X86_64_RELOC_SIGNED_1*2 + 1:
-       case 512 + MACHO_X86_64_RELOC_SIGNED_2*2 + 1:
-       case 512 + MACHO_X86_64_RELOC_SIGNED_4*2 + 1:
-               r->type = R_PCREL;
-               if(targ->type == SDYNIMPORT)
-                       diag("unexpected pc-relative reloc for dynamic symbol %s", targ->name);
-               return;
-
-       case 512 + MACHO_X86_64_RELOC_GOT_LOAD*2 + 1:
-               if(targ->type != SDYNIMPORT) {
-                       // have symbol
-                       // turn MOVQ of GOT entry into LEAQ of symbol itself
-                       if(r->off < 2 || s->p[r->off-2] != 0x8b) {
-                               diag("unexpected GOT_LOAD reloc for non-dynamic symbol %s", targ->name);
-                               return;
-                       }
-                       s->p[r->off-2] = 0x8d;
-                       r->type = R_PCREL;
-                       return;
-               }
-               // fall through
-       case 512 + MACHO_X86_64_RELOC_GOT*2 + 1:
-               if(targ->type != SDYNIMPORT)
-                       diag("unexpected GOT reloc for non-dynamic symbol %s", targ->name);
-               addgotsym(targ);
-               r->type = R_PCREL;
-               r->sym = linklookup(ctxt, ".got", 0);
-               r->add += targ->got;
-               return;
-       }
-       
-       // Handle references to ELF symbols from our own object files.
-       if(targ->type != SDYNIMPORT)
-               return;
-
-       switch(r->type) {
-       case R_CALL:
-       case R_PCREL:
-               addpltsym(targ);
-               r->sym = linklookup(ctxt, ".plt", 0);
-               r->add = targ->plt;
-               return;
-       
-       case R_ADDR:
-               if(s->type == STEXT && iself) {
-                       // The code is asking for the address of an external
-                       // function.  We provide it with the address of the
-                       // correspondent GOT symbol.
-                       addgotsym(targ);
-                       r->sym = linklookup(ctxt, ".got", 0);
-                       r->add += targ->got;
-                       return;
-               }
-               if(s->type != SDATA)
-                       break;
-               if(iself) {
-                       adddynsym(ctxt, targ);
-                       rela = linklookup(ctxt, ".rela", 0);
-                       addaddrplus(ctxt, rela, s, r->off);
-                       if(r->siz == 8)
-                               adduint64(ctxt, rela, ELF64_R_INFO(targ->dynid, R_X86_64_64));
-                       else
-                               adduint64(ctxt, rela, ELF64_R_INFO(targ->dynid, R_X86_64_32));
-                       adduint64(ctxt, rela, r->add);
-                       r->type = 256;  // ignore during relocsym
-                       return;
-               }
-               if(HEADTYPE == Hdarwin && s->size == thearch.ptrsize && r->off == 0) {
-                       // Mach-O relocations are a royal pain to lay out.
-                       // They use a compact stateful bytecode representation
-                       // that is too much bother to deal with.
-                       // Instead, interpret the C declaration
-                       //      void *_Cvar_stderr = &stderr;
-                       // as making _Cvar_stderr the name of a GOT entry
-                       // for stderr.  This is separate from the usual GOT entry,
-                       // just in case the C code assigns to the variable,
-                       // and of course it only works for single pointers,
-                       // but we only need to support cgo and that's all it needs.
-                       adddynsym(ctxt, targ);
-                       got = linklookup(ctxt, ".got", 0);
-                       s->type = got->type | SSUB;
-                       s->outer = got;
-                       s->sub = got->sub;
-                       got->sub = s;
-                       s->value = got->size;
-                       adduint64(ctxt, got, 0);
-                       adduint32(ctxt, linklookup(ctxt, ".linkedit.got", 0), targ->dynid);
-                       r->type = 256;  // ignore during relocsym
-                       return;
-               }
-               break;
-       }
-       
-       ctxt->cursym = s;
-       diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ->name, r->type, targ->type);
-}
-
-int
-elfreloc1(Reloc *r, vlong sectoff)
-{
-       int32 elfsym;
-
-       thearch.vput(sectoff);
-
-       elfsym = r->xsym->elfsym;
-       switch(r->type) {
-       default:
-               return -1;
-
-       case R_ADDR:
-               if(r->siz == 4)
-                       thearch.vput(R_X86_64_32 | (uint64)elfsym<<32);
-               else if(r->siz == 8)
-                       thearch.vput(R_X86_64_64 | (uint64)elfsym<<32);
-               else
-                       return -1;
-               break;
-
-       case R_TLS_LE:
-               if(r->siz == 4)
-                       thearch.vput(R_X86_64_TPOFF32 | (uint64)elfsym<<32);
-               else
-                       return -1;
-               break;
-               
-       case R_CALL:
-               if(r->siz == 4) {
-                       if(r->xsym->type == SDYNIMPORT)
-                               thearch.vput(R_X86_64_GOTPCREL | (uint64)elfsym<<32);
-                       else
-                               thearch.vput(R_X86_64_PC32 | (uint64)elfsym<<32);
-               } else
-                       return -1;
-               break;
-
-       case R_PCREL:
-               if(r->siz == 4) {
-                       thearch.vput(R_X86_64_PC32 | (uint64)elfsym<<32);
-               } else
-                       return -1;
-               break;
-
-       case R_TLS:
-               if(r->siz == 4) {
-                       if(flag_shared)
-                               thearch.vput(R_X86_64_GOTTPOFF | (uint64)elfsym<<32);
-                       else
-                               thearch.vput(R_X86_64_TPOFF32 | (uint64)elfsym<<32);
-               } else
-                       return -1;
-               break;          
-       }
-
-       thearch.vput(r->xadd);
-       return 0;
-}
-
-int
-machoreloc1(Reloc *r, vlong sectoff)
-{
-       uint32 v;
-       LSym *rs;
-       
-       rs = r->xsym;
-
-       if(rs->type == SHOSTOBJ || r->type == R_PCREL) {
-               if(rs->dynid < 0) {
-                       diag("reloc %d to non-macho symbol %s type=%d", r->type, rs->name, rs->type);
-                       return -1;
-               }
-               v = rs->dynid;                  
-               v |= 1<<27; // external relocation
-       } else {
-               v = ((Section*)rs->sect)->extnum;
-               if(v == 0) {
-                       diag("reloc %d to symbol %s in non-macho section %s type=%d", r->type, rs->name, ((Section*)rs->sect)->name, rs->type);
-                       return -1;
-               }
-       }
-
-       switch(r->type) {
-       default:
-               return -1;
-       case R_ADDR:
-               v |= MACHO_X86_64_RELOC_UNSIGNED<<28;
-               break;
-       case R_CALL:
-               v |= 1<<24; // pc-relative bit
-               v |= MACHO_X86_64_RELOC_BRANCH<<28;
-               break;
-       case R_PCREL:
-               // NOTE: Only works with 'external' relocation. Forced above.
-               v |= 1<<24; // pc-relative bit
-               v |= MACHO_X86_64_RELOC_SIGNED<<28;
-       }
-       
-       switch(r->siz) {
-       default:
-               return -1;
-       case 1:
-               v |= 0<<25;
-               break;
-       case 2:
-               v |= 1<<25;
-               break;
-       case 4:
-               v |= 2<<25;
-               break;
-       case 8:
-               v |= 3<<25;
-               break;
-       }
-
-       thearch.lput(sectoff);
-       thearch.lput(v);
-       return 0;
-}
-
-int
-archreloc(Reloc *r, LSym *s, vlong *val)
-{
-       USED(r);
-       USED(s);
-       USED(val);
-       return -1;
-}
-
-vlong
-archrelocvariant(Reloc *r, LSym *s, vlong t)
-{
-       USED(r);
-       USED(s);
-       sysfatal("unexpected relocation variant");
-       return t;
-}
-
-void
-elfsetupplt(void)
-{
-       LSym *plt, *got;
-
-       plt = linklookup(ctxt, ".plt", 0);
-       got = linklookup(ctxt, ".got.plt", 0);
-       if(plt->size == 0) {
-               // pushq got+8(IP)
-               adduint8(ctxt, plt, 0xff);
-               adduint8(ctxt, plt, 0x35);
-               addpcrelplus(ctxt, plt, got, 8);
-               
-               // jmpq got+16(IP)
-               adduint8(ctxt, plt, 0xff);
-               adduint8(ctxt, plt, 0x25);
-               addpcrelplus(ctxt, plt, got, 16);
-               
-               // nopl 0(AX)
-               adduint32(ctxt, plt, 0x00401f0f);
-               
-               // assume got->size == 0 too
-               addaddrplus(ctxt, got, linklookup(ctxt, ".dynamic", 0), 0);
-               adduint64(ctxt, got, 0);
-               adduint64(ctxt, got, 0);
-       }
-}
-
-static void
-addpltsym(LSym *s)
-{
-       if(s->plt >= 0)
-               return;
-       
-       adddynsym(ctxt, s);
-       
-       if(iself) {
-               LSym *plt, *got, *rela;
-
-               plt = linklookup(ctxt, ".plt", 0);
-               got = linklookup(ctxt, ".got.plt", 0);
-               rela = linklookup(ctxt, ".rela.plt", 0);
-               if(plt->size == 0)
-                       elfsetupplt();
-               
-               // jmpq *got+size(IP)
-               adduint8(ctxt, plt, 0xff);
-               adduint8(ctxt, plt, 0x25);
-               addpcrelplus(ctxt, plt, got, got->size);
-       
-               // add to got: pointer to current pos in plt
-               addaddrplus(ctxt, got, plt, plt->size);
-               
-               // pushq $x
-               adduint8(ctxt, plt, 0x68);
-               adduint32(ctxt, plt, (got->size-24-8)/8);
-               
-               // jmpq .plt
-               adduint8(ctxt, plt, 0xe9);
-               adduint32(ctxt, plt, -(plt->size+4));
-               
-               // rela
-               addaddrplus(ctxt, rela, got, got->size-8);
-               adduint64(ctxt, rela, ELF64_R_INFO(s->dynid, R_X86_64_JMP_SLOT));
-               adduint64(ctxt, rela, 0);
-               
-               s->plt = plt->size - 16;
-       } else if(HEADTYPE == Hdarwin) {
-               // To do lazy symbol lookup right, we're supposed
-               // to tell the dynamic loader which library each 
-               // symbol comes from and format the link info
-               // section just so.  I'm too lazy (ha!) to do that
-               // so for now we'll just use non-lazy pointers,
-               // which don't need to be told which library to use.
-               //
-               // http://networkpx.blogspot.com/2009/09/about-lcdyldinfoonly-command.html
-               // has details about what we're avoiding.
-
-               LSym *plt;
-               
-               addgotsym(s);
-               plt = linklookup(ctxt, ".plt", 0);
-
-               adduint32(ctxt, linklookup(ctxt, ".linkedit.plt", 0), s->dynid);
-
-               // jmpq *got+size(IP)
-               s->plt = plt->size;
-
-               adduint8(ctxt, plt, 0xff);
-               adduint8(ctxt, plt, 0x25);
-               addpcrelplus(ctxt, plt, linklookup(ctxt, ".got", 0), s->got);
-       } else {
-               diag("addpltsym: unsupported binary format");
-       }
-}
-
-static void
-addgotsym(LSym *s)
-{
-       LSym *got, *rela;
-
-       if(s->got >= 0)
-               return;
-
-       adddynsym(ctxt, s);
-       got = linklookup(ctxt, ".got", 0);
-       s->got = got->size;
-       adduint64(ctxt, got, 0);
-
-       if(iself) {
-               rela = linklookup(ctxt, ".rela", 0);
-               addaddrplus(ctxt, rela, got, s->got);
-               adduint64(ctxt, rela, ELF64_R_INFO(s->dynid, R_X86_64_GLOB_DAT));
-               adduint64(ctxt, rela, 0);
-       } else if(HEADTYPE == Hdarwin) {
-               adduint32(ctxt, linklookup(ctxt, ".linkedit.got", 0), s->dynid);
-       } else {
-               diag("addgotsym: unsupported binary format");
-       }
-}
-
-void
-adddynsym(Link *ctxt, LSym *s)
-{
-       LSym *d;
-       int t;
-       char *name;
-
-       if(s->dynid >= 0)
-               return;
-
-       if(iself) {
-               s->dynid = nelfsym++;
-
-               d = linklookup(ctxt, ".dynsym", 0);
-
-               name = s->extname;
-               adduint32(ctxt, d, addstring(linklookup(ctxt, ".dynstr", 0), name));
-               /* type */
-               t = STB_GLOBAL << 4;
-               if(s->cgoexport && (s->type&SMASK) == STEXT)
-                       t |= STT_FUNC;
-               else
-                       t |= STT_OBJECT;
-               adduint8(ctxt, d, t);
-       
-               /* reserved */
-               adduint8(ctxt, d, 0);
-       
-               /* section where symbol is defined */
-               if(s->type == SDYNIMPORT)
-                       adduint16(ctxt, d, SHN_UNDEF);
-               else
-                       adduint16(ctxt, d, 1);
-       
-               /* value */
-               if(s->type == SDYNIMPORT)
-                       adduint64(ctxt, d, 0);
-               else
-                       addaddr(ctxt, d, s);
-       
-               /* size of object */
-               adduint64(ctxt, d, s->size);
-       
-               if(!(s->cgoexport & CgoExportDynamic) && s->dynimplib && needlib(s->dynimplib)) {
-                       elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED,
-                               addstring(linklookup(ctxt, ".dynstr", 0), s->dynimplib));
-               }
-       } else if(HEADTYPE == Hdarwin) {
-               diag("adddynsym: missed symbol %s (%s)", s->name, s->extname);
-       } else if(HEADTYPE == Hwindows) {
-               // already taken care of
-       } else {
-               diag("adddynsym: unsupported binary format");
-       }
-}
-
-void
-adddynlib(char *lib)
-{
-       LSym *s;
-       
-       if(!needlib(lib))
-               return;
-       
-       if(iself) {
-               s = linklookup(ctxt, ".dynstr", 0);
-               if(s->size == 0)
-                       addstring(s, "");
-               elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addstring(s, lib));
-       } else if(HEADTYPE == Hdarwin) {
-               machoadddynlib(lib);
-       } else {
-               diag("adddynlib: unsupported binary format");
-       }
-}
-
-void
-asmb(void)
-{
-       int32 magic;
-       int i;
-       vlong vl, symo, dwarfoff, machlink;
-       Section *sect;
-       LSym *sym;
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f asmb\n", cputime());
-       Bflush(&bso);
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f codeblk\n", cputime());
-       Bflush(&bso);
-
-       if(iself)
-               asmbelfsetup();
-
-       sect = segtext.sect;
-       cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
-       codeblk(sect->vaddr, sect->length);
-       for(sect = sect->next; sect != nil; sect = sect->next) {
-               cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
-               datblk(sect->vaddr, sect->length);
-       }
-
-       if(segrodata.filelen > 0) {
-               if(debug['v'])
-                       Bprint(&bso, "%5.2f rodatblk\n", cputime());
-               Bflush(&bso);
-
-               cseek(segrodata.fileoff);
-               datblk(segrodata.vaddr, segrodata.filelen);
-       }
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f datblk\n", cputime());
-       Bflush(&bso);
-
-       cseek(segdata.fileoff);
-       datblk(segdata.vaddr, segdata.filelen);
-
-       machlink = 0;
-       if(HEADTYPE == Hdarwin) {
-               if(debug['v'])
-                       Bprint(&bso, "%5.2f dwarf\n", cputime());
-
-               dwarfoff = rnd(HEADR+segtext.length, INITRND) + rnd(segdata.filelen, INITRND);
-               cseek(dwarfoff);
-
-               segdwarf.fileoff = cpos();
-               dwarfemitdebugsections();
-               segdwarf.filelen = cpos() - segdwarf.fileoff;
-
-               machlink = domacholink();
-       }
-
-       switch(HEADTYPE) {
-       default:
-               diag("unknown header type %d", HEADTYPE);
-       case Hplan9:
-       case Helf:
-               break;
-       case Hdarwin:
-               debug['8'] = 1; /* 64-bit addresses */
-               break;
-       case Hlinux:
-       case Hfreebsd:
-       case Hnetbsd:
-       case Hopenbsd:
-       case Hdragonfly:
-       case Hsolaris:
-               debug['8'] = 1; /* 64-bit addresses */
-               break;
-       case Hnacl:
-       case Hwindows:
-               break;
-       }
-
-       symsize = 0;
-       spsize = 0;
-       lcsize = 0;
-       symo = 0;
-       if(!debug['s']) {
-               if(debug['v'])
-                       Bprint(&bso, "%5.2f sym\n", cputime());
-               Bflush(&bso);
-               switch(HEADTYPE) {
-               default:
-               case Hplan9:
-               case Helf:
-                       debug['s'] = 1;
-                       symo = segdata.fileoff+segdata.filelen;
-                       break;
-               case Hdarwin:
-                       symo = segdata.fileoff+rnd(segdata.filelen, INITRND)+machlink;
-                       break;
-               case Hlinux:
-               case Hfreebsd:
-               case Hnetbsd:
-               case Hopenbsd:
-               case Hdragonfly:
-               case Hsolaris:
-               case Hnacl:
-                       symo = segdata.fileoff+segdata.filelen;
-                       symo = rnd(symo, INITRND);
-                       break;
-               case Hwindows:
-                       symo = segdata.fileoff+segdata.filelen;
-                       symo = rnd(symo, PEFILEALIGN);
-                       break;
-               }
-               cseek(symo);
-               switch(HEADTYPE) {
-               default:
-                       if(iself) {
-                               cseek(symo);
-                               asmelfsym();
-                               cflush();
-                               cwrite(elfstrdat, elfstrsize);
-
-                               if(debug['v'])
-                                      Bprint(&bso, "%5.2f dwarf\n", cputime());
-
-                               dwarfemitdebugsections();
-                               
-                               if(linkmode == LinkExternal)
-                                       elfemitreloc();
-                       }
-                       break;
-               case Hplan9:
-                       asmplan9sym();
-                       cflush();
-
-                       sym = linklookup(ctxt, "pclntab", 0);
-                       if(sym != nil) {
-                               lcsize = sym->np;
-                               for(i=0; i < lcsize; i++)
-                                       cput(sym->p[i]);
-                               
-                               cflush();
-                       }
-                       break;
-               case Hwindows:
-                       if(debug['v'])
-                              Bprint(&bso, "%5.2f dwarf\n", cputime());
-
-                       dwarfemitdebugsections();
-                       break;
-               case Hdarwin:
-                       if(linkmode == LinkExternal)
-                               machoemitreloc();
-                       break;
-               }
-       }
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f headr\n", cputime());
-       Bflush(&bso);
-       cseek(0L);
-       switch(HEADTYPE) {
-       default:
-       case Hplan9:    /* plan9 */
-               magic = 4*26*26+7;
-               magic |= 0x00008000;            /* fat header */
-               lputb(magic);                   /* magic */
-               lputb(segtext.filelen);                 /* sizes */
-               lputb(segdata.filelen);
-               lputb(segdata.length - segdata.filelen);
-               lputb(symsize);                 /* nsyms */
-               vl = entryvalue();
-               lputb(PADDR(vl));               /* va of entry */
-               lputb(spsize);                  /* sp offsets */
-               lputb(lcsize);                  /* line offsets */
-               vputb(vl);                      /* va of entry */
-               break;
-       case Hdarwin:
-               asmbmacho();
-               break;
-       case Hlinux:
-       case Hfreebsd:
-       case Hnetbsd:
-       case Hopenbsd:
-       case Hdragonfly:
-       case Hsolaris:
-       case Hnacl:
-               asmbelf(symo);
-               break;
-       case Hwindows:
-               asmbpe();
-               break;
-       }
-       cflush();
-}
similarity index 100%
rename from src/cmd/new6l/asm.go
rename to src/cmd/6l/asm.go
diff --git a/src/cmd/6l/doc.go b/src/cmd/6l/doc.go
deleted file mode 100644 (file)
index 6287dd9..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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.
-
-// +build ignore
-
-/*
-
-6l is the linker for the x86-64.
-The $GOARCH for these tools is amd64.
-
-The flags are documented in ../ld/doc.go.
-
-*/
-package main
similarity index 100%
rename from src/cmd/new6l/l.go
rename to src/cmd/6l/l.go
diff --git a/src/cmd/6l/l.h b/src/cmd/6l/l.h
deleted file mode 100644 (file)
index b314e25..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-// Inferno utils/6l/l.h
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/l.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-
-#ifndef        EXTERN
-#define        EXTERN  extern
-#endif
-
-enum
-{
-       thechar = '6',
-       MaxAlign = 32,  // max data alignment
-       FuncAlign = 16
-};
-
-enum
-{
-       MINLC           = 1,
-};
-
-void   adddynlib(char *lib);
-void   adddynrel(LSym *s, Reloc *r);
-void   adddynrela(LSym *rela, LSym *s, Reloc *r);
-void   adddynsym(Link *ctxt, LSym *s);
-int    archreloc(Reloc *r, LSym *s, vlong *val);
-vlong  archrelocvariant(Reloc *r, LSym *s, vlong t);
-void   asmb(void);
-int    elfreloc1(Reloc *r, vlong sectoff);
-void   elfsetupplt(void);
-int    machoreloc1(Reloc *r, vlong sectoff);
-
-/* Used by ../ld/dwarf.c */
-enum
-{
-       DWARFREGSP = 7
-};
diff --git a/src/cmd/6l/obj.c b/src/cmd/6l/obj.c
deleted file mode 100644 (file)
index ebd4bae..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-// Inferno utils/6l/obj.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Reading object files.
-
-#include       "l.h"
-#include       "../ld/lib.h"
-#include       "../ld/elf.h"
-#include       "../ld/macho.h"
-#include       "../ld/dwarf.h"
-#include       "../ld/pe.h"
-#include       <ar.h>
-
-void
-main(int argc, char **argv)
-{
-       linkarchinit();
-       ldmain(argc, argv);
-}
-
-void
-linkarchinit(void)
-{
-       thestring = "amd64";
-       thelinkarch = &linkamd64;
-       if(strcmp(getgoarch(), "amd64p32") == 0)
-               thelinkarch = &linkamd64p32;
-
-       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.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
-archinit(void)
-{
-       // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
-       // Go was built; see ../../make.bash.
-       if(linkmode == LinkAuto && strcmp(getgoextlinkenabled(), "0") == 0)
-               linkmode = LinkInternal;
-
-       if(flag_shared)
-               linkmode = LinkExternal;
-
-       switch(HEADTYPE) {
-       default:
-               if(linkmode == LinkAuto)
-                       linkmode = LinkInternal;
-               if(linkmode == LinkExternal && strcmp(getgoextlinkenabled(), "1") != 0)
-                       sysfatal("cannot use -linkmode=external with -H %s", headstr(HEADTYPE));
-               break;
-       case Hdarwin:
-       case Hdragonfly:
-       case Hfreebsd:
-       case Hlinux:
-       case Hnacl:
-       case Hnetbsd:
-       case Hopenbsd:
-       case Hsolaris:
-               break;
-       }
-
-       switch(HEADTYPE) {
-       default:
-               diag("unknown -H option");
-               errorexit();
-       case Hplan9:            /* plan 9 */
-               HEADR = 32L + 8L;
-               if(INITTEXT == -1)
-                       INITTEXT = 0x200000+HEADR;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 0x200000;
-               break;
-       case Helf:              /* elf32 executable */
-               HEADR = rnd(52L+3*32L, 16);
-               if(INITTEXT == -1)
-                       INITTEXT = 0x80110000L;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 4096;
-               break;
-       case Hdarwin:           /* apple MACH */
-               machoinit();
-               HEADR = INITIAL_MACHO_HEADR;
-               if(INITRND == -1)
-                       INITRND = 4096;
-               if(INITTEXT == -1)
-                       INITTEXT = 4096+HEADR;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               break;
-       case Hlinux:            /* elf64 executable */
-       case Hfreebsd:          /* freebsd */
-       case Hnetbsd:           /* netbsd */
-       case Hopenbsd:          /* openbsd */
-       case Hdragonfly:        /* dragonfly */
-       case Hsolaris:          /* solaris */
-               elfinit();
-               HEADR = ELFRESERVE;
-               if(INITTEXT == -1)
-                       INITTEXT = (1<<22)+HEADR;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 4096;
-               break;
-       case Hnacl:
-               elfinit();
-               debug['w']++; // disable dwarf, which gets confused and is useless anyway
-               HEADR = 0x10000;
-               funcalign = 32;
-               if(INITTEXT == -1)
-                       INITTEXT = 0x20000;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 0x10000;
-               break;
-       case Hwindows:          /* PE executable */
-               peinit();
-               HEADR = PEFILEHEADR;
-               if(INITTEXT == -1)
-                       INITTEXT = PEBASE+PESECTHEADR;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = PESECTALIGN;
-               break;
-       }
-
-       if(INITDAT != 0 && INITRND != 0)
-               print("warning: -D0x%llux is ignored because of -R0x%ux\n",
-                       INITDAT, INITRND);
-}
similarity index 100%
rename from src/cmd/new6l/obj.go
rename to src/cmd/6l/obj.go
similarity index 100%
rename from src/cmd/new6l/z.go
rename to src/cmd/6l/z.go
diff --git a/src/cmd/8l/Makefile b/src/cmd/8l/Makefile
deleted file mode 100644 (file)
index 3f528d7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# 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
diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c
deleted file mode 100644 (file)
index d7622f7..0000000
+++ /dev/null
@@ -1,707 +0,0 @@
-// Inferno utils/8l/asm.c
-// http://code.google.com/p/inferno-os/source/browse/utils/8l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Writing object files.
-
-#include       "l.h"
-#include       "../ld/lib.h"
-#include       "../ld/elf.h"
-#include       "../ld/dwarf.h"
-#include       "../ld/macho.h"
-#include       "../ld/pe.h"
-
-static int
-needlib(char *name)
-{
-       char *p;
-       LSym *s;
-
-       if(*name == '\0')
-               return 0;
-
-       /* reuse hash code in symbol table */
-       p = smprint(".dynlib.%s", name);
-       s = linklookup(ctxt, p, 0);
-       free(p);
-       if(s->type == 0) {
-               s->type = 100;  // avoid SDATA, etc.
-               return 1;
-       }
-       return 0;
-}
-
-static void    addpltsym(Link*, LSym*);
-static void    addgotsym(Link*, LSym*);
-
-void
-gentext(void)
-{
-}
-
-void
-adddynrela(LSym *rela, LSym *s, Reloc *r)
-{
-       USED(rela);
-       USED(s);
-       USED(r);
-       sysfatal("adddynrela not implemented");
-}
-
-void
-adddynrel(LSym *s, Reloc *r)
-{
-       LSym *targ, *rel, *got;
-
-       targ = r->sym;
-       ctxt->cursym = s;
-
-       switch(r->type) {
-       default:
-               if(r->type >= 256) {
-                       diag("unexpected relocation type %d", r->type);
-                       return;
-               }
-               break;
-
-       // Handle relocations found in ELF object files.
-       case 256 + R_386_PC32:
-               if(targ->type == SDYNIMPORT)
-                       diag("unexpected R_386_PC32 relocation for dynamic symbol %s", targ->name);
-               if(targ->type == 0 || targ->type == SXREF)
-                       diag("unknown symbol %s in pcrel", targ->name);
-               r->type = R_PCREL;
-               r->add += 4;
-               return;
-
-       case 256 + R_386_PLT32:
-               r->type = R_PCREL;
-               r->add += 4;
-               if(targ->type == SDYNIMPORT) {
-                       addpltsym(ctxt, targ);
-                       r->sym = linklookup(ctxt, ".plt", 0);
-                       r->add += targ->plt;
-               }
-               return;         
-       
-       case 256 + R_386_GOT32:
-               if(targ->type != SDYNIMPORT) {
-                       // have symbol
-                       if(r->off >= 2 && s->p[r->off-2] == 0x8b) {
-                               // turn MOVL of GOT entry into LEAL of symbol address, relative to GOT.
-                               s->p[r->off-2] = 0x8d;
-                               r->type = R_GOTOFF;
-                               return;
-                       }
-                       if(r->off >= 2 && s->p[r->off-2] == 0xff && s->p[r->off-1] == 0xb3) {
-                               // turn PUSHL of GOT entry into PUSHL of symbol itself.
-                               // use unnecessary SS prefix to keep instruction same length.
-                               s->p[r->off-2] = 0x36;
-                               s->p[r->off-1] = 0x68;
-                               r->type = R_ADDR;
-                               return;
-                       }
-                       diag("unexpected GOT reloc for non-dynamic symbol %s", targ->name);
-                       return;
-               }
-               addgotsym(ctxt, targ);
-               r->type = R_CONST;      // write r->add during relocsym
-               r->sym = nil;
-               r->add += targ->got;
-               return;
-       
-       case 256 + R_386_GOTOFF:
-               r->type = R_GOTOFF;
-               return;
-       
-       case 256 + R_386_GOTPC:
-               r->type = R_PCREL;
-               r->sym = linklookup(ctxt, ".got", 0);
-               r->add += 4;
-               return;
-
-       case 256 + R_386_32:
-               if(targ->type == SDYNIMPORT)
-                       diag("unexpected R_386_32 relocation for dynamic symbol %s", targ->name);
-               r->type = R_ADDR;
-               return;
-       
-       case 512 + MACHO_GENERIC_RELOC_VANILLA*2 + 0:
-               r->type = R_ADDR;
-               if(targ->type == SDYNIMPORT)
-                       diag("unexpected reloc for dynamic symbol %s", targ->name);
-               return;
-       
-       case 512 + MACHO_GENERIC_RELOC_VANILLA*2 + 1:
-               if(targ->type == SDYNIMPORT) {
-                       addpltsym(ctxt, targ);
-                       r->sym = linklookup(ctxt, ".plt", 0);
-                       r->add = targ->plt;
-                       r->type = R_PCREL;
-                       return;
-               }
-               r->type = R_PCREL;
-               return;
-       
-       case 512 + MACHO_FAKE_GOTPCREL:
-               if(targ->type != SDYNIMPORT) {
-                       // have symbol
-                       // turn MOVL of GOT entry into LEAL of symbol itself
-                       if(r->off < 2 || s->p[r->off-2] != 0x8b) {
-                               diag("unexpected GOT reloc for non-dynamic symbol %s", targ->name);
-                               return;
-                       }
-                       s->p[r->off-2] = 0x8d;
-                       r->type = R_PCREL;
-                       return;
-               }
-               addgotsym(ctxt, targ);
-               r->sym = linklookup(ctxt, ".got", 0);
-               r->add += targ->got;
-               r->type = R_PCREL;
-               return;
-       }
-       
-       // Handle references to ELF symbols from our own object files.
-       if(targ->type != SDYNIMPORT)
-               return;
-
-       switch(r->type) {
-       case R_CALL:
-       case R_PCREL:
-               addpltsym(ctxt, targ);
-               r->sym = linklookup(ctxt, ".plt", 0);
-               r->add = targ->plt;
-               return;
-       
-       case R_ADDR:
-               if(s->type != SDATA)
-                       break;
-               if(iself) {
-                       adddynsym(ctxt, targ);
-                       rel = linklookup(ctxt, ".rel", 0);
-                       addaddrplus(ctxt, rel, s, r->off);
-                       adduint32(ctxt, rel, ELF32_R_INFO(targ->dynid, R_386_32));
-                       r->type = R_CONST;      // write r->add during relocsym
-                       r->sym = nil;
-                       return;
-               }
-               if(HEADTYPE == Hdarwin && s->size == PtrSize && r->off == 0) {
-                       // Mach-O relocations are a royal pain to lay out.
-                       // They use a compact stateful bytecode representation
-                       // that is too much bother to deal with.
-                       // Instead, interpret the C declaration
-                       //      void *_Cvar_stderr = &stderr;
-                       // as making _Cvar_stderr the name of a GOT entry
-                       // for stderr.  This is separate from the usual GOT entry,
-                       // just in case the C code assigns to the variable,
-                       // and of course it only works for single pointers,
-                       // but we only need to support cgo and that's all it needs.
-                       adddynsym(ctxt, targ);
-                       got = linklookup(ctxt, ".got", 0);
-                       s->type = got->type | SSUB;
-                       s->outer = got;
-                       s->sub = got->sub;
-                       got->sub = s;
-                       s->value = got->size;
-                       adduint32(ctxt, got, 0);
-                       adduint32(ctxt, linklookup(ctxt, ".linkedit.got", 0), targ->dynid);
-                       r->type = 256;  // ignore during relocsym
-                       return;
-               }
-               break;
-       }
-       
-       ctxt->cursym = s;
-       diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ->name, r->type, targ->type);
-}
-
-int
-elfreloc1(Reloc *r, vlong sectoff)
-{
-       int32 elfsym;
-
-       thearch.lput(sectoff);
-
-       elfsym = r->xsym->elfsym;
-       switch(r->type) {
-       default:
-               return -1;
-
-       case R_ADDR:
-               if(r->siz == 4)
-                       thearch.lput(R_386_32 | elfsym<<8);
-               else
-                       return -1;
-               break;
-
-       case R_CALL:
-       case R_PCREL:
-               if(r->siz == 4)
-                       thearch.lput(R_386_PC32 | elfsym<<8);
-               else
-                       return -1;
-               break;
-       
-       case R_TLS_LE:
-       case R_TLS_IE:
-               if(r->siz == 4)
-                       thearch.lput(R_386_TLS_LE | elfsym<<8);
-               else
-                       return -1;
-       }
-
-       return 0;
-}
-
-int
-machoreloc1(Reloc *r, vlong sectoff)
-{
-       uint32 v;
-       LSym *rs;
-       
-       rs = r->xsym;
-
-       if(rs->type == SHOSTOBJ) {
-               if(rs->dynid < 0) {
-                       diag("reloc %d to non-macho symbol %s type=%d", r->type, rs->name, rs->type);
-                       return -1;
-               }
-               v = rs->dynid;                  
-               v |= 1<<27; // external relocation
-       } else {
-               v = ((Section*)rs->sect)->extnum;
-               if(v == 0) {
-                       diag("reloc %d to symbol %s in non-macho section %s type=%d", r->type, rs->name, ((Section*)rs->sect)->name, rs->type);
-                       return -1;
-               }
-       }
-
-       switch(r->type) {
-       default:
-               return -1;
-       case R_ADDR:
-               v |= MACHO_GENERIC_RELOC_VANILLA<<28;
-               break;
-       case R_CALL:
-       case R_PCREL:
-               v |= 1<<24; // pc-relative bit
-               v |= MACHO_GENERIC_RELOC_VANILLA<<28;
-               break;
-       }
-       
-       switch(r->siz) {
-       default:
-               return -1;
-       case 1:
-               v |= 0<<25;
-               break;
-       case 2:
-               v |= 1<<25;
-               break;
-       case 4:
-               v |= 2<<25;
-               break;
-       case 8:
-               v |= 3<<25;
-               break;
-       }
-
-       thearch.lput(sectoff);
-       thearch.lput(v);
-       return 0;
-}
-
-int
-archreloc(Reloc *r, LSym *s, vlong *val)
-{
-       USED(s);
-       if(linkmode == LinkExternal)
-               return -1;
-       switch(r->type) {
-       case R_CONST:
-               *val = r->add;
-               return 0;
-       case R_GOTOFF:
-               *val = symaddr(r->sym) + r->add - symaddr(linklookup(ctxt, ".got", 0));
-               return 0;
-       }
-       return -1;
-}
-
-vlong
-archrelocvariant(Reloc *r, LSym *s, vlong t)
-{
-       USED(r);
-       USED(s);
-       sysfatal("unexpected relocation variant");
-       return t;
-}
-
-void
-elfsetupplt(void)
-{
-       LSym *plt, *got;
-       
-       plt = linklookup(ctxt, ".plt", 0);
-       got = linklookup(ctxt, ".got.plt", 0);
-       if(plt->size == 0) {
-               // pushl got+4
-               adduint8(ctxt, plt, 0xff);
-               adduint8(ctxt, plt, 0x35);
-               addaddrplus(ctxt, plt, got, 4);
-               
-               // jmp *got+8
-               adduint8(ctxt, plt, 0xff);
-               adduint8(ctxt, plt, 0x25);
-               addaddrplus(ctxt, plt, got, 8);
-
-               // zero pad
-               adduint32(ctxt, plt, 0);
-               
-               // assume got->size == 0 too
-               addaddrplus(ctxt, got, linklookup(ctxt, ".dynamic", 0), 0);
-               adduint32(ctxt, got, 0);
-               adduint32(ctxt, got, 0);
-       }
-}
-
-static void
-addpltsym(Link *ctxt, LSym *s)
-{
-       LSym *plt, *got, *rel;
-       
-       if(s->plt >= 0)
-               return;
-
-       adddynsym(ctxt, s);
-       
-       if(iself) {
-               plt = linklookup(ctxt, ".plt", 0);
-               got = linklookup(ctxt, ".got.plt", 0);
-               rel = linklookup(ctxt, ".rel.plt", 0);
-               if(plt->size == 0)
-                       elfsetupplt();
-               
-               // jmpq *got+size
-               adduint8(ctxt, plt, 0xff);
-               adduint8(ctxt, plt, 0x25);
-               addaddrplus(ctxt, plt, got, got->size);
-               
-               // add to got: pointer to current pos in plt
-               addaddrplus(ctxt, got, plt, plt->size);
-               
-               // pushl $x
-               adduint8(ctxt, plt, 0x68);
-               adduint32(ctxt, plt, rel->size);
-               
-               // jmp .plt
-               adduint8(ctxt, plt, 0xe9);
-               adduint32(ctxt, plt, -(plt->size+4));
-               
-               // rel
-               addaddrplus(ctxt, rel, got, got->size-4);
-               adduint32(ctxt, rel, ELF32_R_INFO(s->dynid, R_386_JMP_SLOT));
-               
-               s->plt = plt->size - 16;
-       } else if(HEADTYPE == Hdarwin) {
-               // Same laziness as in 6l.
-               
-               LSym *plt;
-
-               plt = linklookup(ctxt, ".plt", 0);
-
-               addgotsym(ctxt, s);
-
-               adduint32(ctxt, linklookup(ctxt, ".linkedit.plt", 0), s->dynid);
-
-               // jmpq *got+size(IP)
-               s->plt = plt->size;
-
-               adduint8(ctxt, plt, 0xff);
-               adduint8(ctxt, plt, 0x25);
-               addaddrplus(ctxt, plt, linklookup(ctxt, ".got", 0), s->got);
-       } else {
-               diag("addpltsym: unsupported binary format");
-       }
-}
-
-static void
-addgotsym(Link *ctxt, LSym *s)
-{
-       LSym *got, *rel;
-       
-       if(s->got >= 0)
-               return;
-       
-       adddynsym(ctxt, s);
-       got = linklookup(ctxt, ".got", 0);
-       s->got = got->size;
-       adduint32(ctxt, got, 0);
-       
-       if(iself) {
-               rel = linklookup(ctxt, ".rel", 0);
-               addaddrplus(ctxt, rel, got, s->got);
-               adduint32(ctxt, rel, ELF32_R_INFO(s->dynid, R_386_GLOB_DAT));
-       } else if(HEADTYPE == Hdarwin) {
-               adduint32(ctxt, linklookup(ctxt, ".linkedit.got", 0), s->dynid);
-       } else {
-               diag("addgotsym: unsupported binary format");
-       }
-}
-
-void
-adddynsym(Link *ctxt, LSym *s)
-{
-       LSym *d;
-       int t;
-       char *name;
-       
-       if(s->dynid >= 0)
-               return;
-       
-       if(iself) {
-               s->dynid = nelfsym++;
-               
-               d = linklookup(ctxt, ".dynsym", 0);
-
-               /* name */
-               name = s->extname;
-               adduint32(ctxt, d, addstring(linklookup(ctxt, ".dynstr", 0), name));
-               
-               /* value */
-               if(s->type == SDYNIMPORT)
-                       adduint32(ctxt, d, 0);
-               else
-                       addaddr(ctxt, d, s);
-               
-               /* size */
-               adduint32(ctxt, d, 0);
-       
-               /* type */
-               t = STB_GLOBAL << 4;
-               if(s->cgoexport && (s->type&SMASK) == STEXT)
-                       t |= STT_FUNC;
-               else
-                       t |= STT_OBJECT;
-               adduint8(ctxt, d, t);
-               adduint8(ctxt, d, 0);
-       
-               /* shndx */
-               if(s->type == SDYNIMPORT)
-                       adduint16(ctxt, d, SHN_UNDEF);
-               else
-                       adduint16(ctxt, d, 1);
-       } else if(HEADTYPE == Hdarwin) {
-               diag("adddynsym: missed symbol %s (%s)", s->name, s->extname);
-       } else if(HEADTYPE == Hwindows) {
-               // already taken care of
-       } else {
-               diag("adddynsym: unsupported binary format");
-       }
-}
-
-void
-adddynlib(char *lib)
-{
-       LSym *s;
-       
-       if(!needlib(lib))
-               return;
-       
-       if(iself) {
-               s = linklookup(ctxt, ".dynstr", 0);
-               if(s->size == 0)
-                       addstring(s, "");
-               elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addstring(s, lib));
-       } else if(HEADTYPE == Hdarwin) {
-               machoadddynlib(lib);
-       } else if(HEADTYPE != Hwindows) {
-               diag("adddynlib: unsupported binary format");
-       }
-}
-
-void
-asmb(void)
-{
-       int32 magic;
-       uint32 symo, dwarfoff, machlink;
-       Section *sect;
-       LSym *sym;
-       int i;
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f asmb\n", cputime());
-       Bflush(&bso);
-
-       if(iself)
-               asmbelfsetup();
-
-       sect = segtext.sect;
-       cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
-       codeblk(sect->vaddr, sect->length);
-       for(sect = sect->next; sect != nil; sect = sect->next) {
-               cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
-               datblk(sect->vaddr, sect->length);
-       }
-       
-       if(segrodata.filelen > 0) {
-               if(debug['v'])
-                       Bprint(&bso, "%5.2f rodatblk\n", cputime());
-               Bflush(&bso);
-
-               cseek(segrodata.fileoff);
-               datblk(segrodata.vaddr, segrodata.filelen);
-       }
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f datblk\n", cputime());
-       Bflush(&bso);
-
-       cseek(segdata.fileoff);
-       datblk(segdata.vaddr, segdata.filelen);
-
-       machlink = 0;
-       if(HEADTYPE == Hdarwin) {
-               if(debug['v'])
-                       Bprint(&bso, "%5.2f dwarf\n", cputime());
-
-               dwarfoff = rnd(HEADR+segtext.length, INITRND) + rnd(segdata.filelen, INITRND);
-               cseek(dwarfoff);
-
-               segdwarf.fileoff = cpos();
-               dwarfemitdebugsections();
-               segdwarf.filelen = cpos() - segdwarf.fileoff;
-
-               machlink = domacholink();
-       }
-
-       symsize = 0;
-       spsize = 0;
-       lcsize = 0;
-       symo = 0;
-       if(!debug['s']) {
-               // TODO: rationalize
-               if(debug['v'])
-                       Bprint(&bso, "%5.2f sym\n", cputime());
-               Bflush(&bso);
-               switch(HEADTYPE) {
-               default:
-                       if(iself) {
-                               symo = segdata.fileoff+segdata.filelen;
-                               symo = rnd(symo, INITRND);
-                       }
-                       break;
-               case Hplan9:
-                       symo = segdata.fileoff+segdata.filelen;
-                       break;
-               case Hdarwin:
-                       symo = segdata.fileoff+rnd(segdata.filelen, INITRND)+machlink;
-                       break;
-               case Hwindows:
-                       symo = segdata.fileoff+segdata.filelen;
-                       symo = rnd(symo, PEFILEALIGN);
-                       break;
-               }
-               cseek(symo);
-               switch(HEADTYPE) {
-               default:
-                       if(iself) {
-                               if(debug['v'])
-                                       Bprint(&bso, "%5.2f elfsym\n", cputime());
-                               asmelfsym();
-                               cflush();
-                               cwrite(elfstrdat, elfstrsize);
-
-                               if(debug['v'])
-                                       Bprint(&bso, "%5.2f dwarf\n", cputime());
-                               dwarfemitdebugsections();
-                               
-                               if(linkmode == LinkExternal)
-                                       elfemitreloc();
-                       }
-                       break;
-               case Hplan9:
-                       asmplan9sym();
-                       cflush();
-
-                       sym = linklookup(ctxt, "pclntab", 0);
-                       if(sym != nil) {
-                               lcsize = sym->np;
-                               for(i=0; i < lcsize; i++)
-                                       cput(sym->p[i]);
-                               
-                               cflush();
-                       }
-                       break;
-               case Hwindows:
-                       if(debug['v'])
-                               Bprint(&bso, "%5.2f dwarf\n", cputime());
-                       dwarfemitdebugsections();
-                       break;
-               case Hdarwin:
-                       if(linkmode == LinkExternal)
-                               machoemitreloc();
-                       break;
-               }
-       }
-       if(debug['v'])
-               Bprint(&bso, "%5.2f headr\n", cputime());
-       Bflush(&bso);
-       cseek(0L);
-       switch(HEADTYPE) {
-       default:
-       case Hplan9:    /* plan9 */
-               magic = 4*11*11+7;
-               lputb(magic);           /* magic */
-               lputb(segtext.filelen);                 /* sizes */
-               lputb(segdata.filelen);
-               lputb(segdata.length - segdata.filelen);
-               lputb(symsize);                 /* nsyms */
-               lputb(entryvalue());            /* va of entry */
-               lputb(spsize);                  /* sp offsets */
-               lputb(lcsize);                  /* line offsets */
-               break;
-       case Hdarwin:
-               asmbmacho();
-               break;
-       case Hlinux:
-       case Hfreebsd:
-       case Hnetbsd:
-       case Hopenbsd:
-       case Hdragonfly:
-       case Hnacl:
-               asmbelf(symo);
-               break;
-       case Hwindows:
-               asmbpe();
-               break;
-       }
-       cflush();
-}
similarity index 100%
rename from src/cmd/new8l/asm.go
rename to src/cmd/8l/asm.go
diff --git a/src/cmd/8l/doc.go b/src/cmd/8l/doc.go
deleted file mode 100644 (file)
index ff06bc3..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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.
-
-// +build ignore
-
-/*
-
-8l is the linker for the 32-bit x86.
-The $GOARCH for these tools is 386.
-
-The flags are documented in ../ld/doc.go.
-
-*/
-package main
similarity index 100%
rename from src/cmd/new8l/l.go
rename to src/cmd/8l/l.go
diff --git a/src/cmd/8l/l.h b/src/cmd/8l/l.h
deleted file mode 100644 (file)
index 77c06b3..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-// Inferno utils/8l/l.h
-// http://code.google.com/p/inferno-os/source/browse/utils/8l/l.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-
-#ifndef        EXTERN
-#define        EXTERN  extern
-#endif
-
-enum
-{
-       thechar = '8',
-       PtrSize = 4,
-       IntSize = 4,
-       RegSize = 4,
-       MaxAlign = 32,  // max data alignment
-       FuncAlign = 16,
-       MINLC           = 1,
-};
-
-void   adddynlib(char *lib);
-void   adddynrel(LSym *s, Reloc *r);
-void   adddynrela(LSym *rela, LSym *s, Reloc *r);
-void   adddynsym(Link *ctxt, LSym *s);
-int    archreloc(Reloc *r, LSym *s, vlong *val);
-vlong  archrelocvariant(Reloc *r, LSym *s, vlong t);
-void   asmb(void);
-int    elfreloc1(Reloc *r, vlong sectoff);
-void   elfsetupplt(void);
-int    machoreloc1(Reloc *r, vlong sectoff);
-
-/* Used by ../ld/dwarf.c */
-enum
-{
-       DWARFREGSP = 4
-};
diff --git a/src/cmd/8l/obj.c b/src/cmd/8l/obj.c
deleted file mode 100644 (file)
index 767db33..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-// Inferno utils/8l/obj.c
-// http://code.google.com/p/inferno-os/source/browse/utils/8l/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Reading object files.
-
-#include       "l.h"
-#include       "../ld/lib.h"
-#include       "../ld/elf.h"
-#include       "../ld/macho.h"
-#include       "../ld/dwarf.h"
-#include       "../ld/pe.h"
-#include       <ar.h>
-
-void
-main(int argc, char **argv)
-{
-       linkarchinit();
-       ldmain(argc, argv);
-}
-
-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.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
-archinit(void)
-{
-       // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
-       // Go was built; see ../../make.bash.
-       if(linkmode == LinkAuto && strcmp(getgoextlinkenabled(), "0") == 0)
-               linkmode = LinkInternal;
-
-       switch(HEADTYPE) {
-       default:
-               if(linkmode == LinkAuto)
-                       linkmode = LinkInternal;
-               if(linkmode == LinkExternal && strcmp(getgoextlinkenabled(), "1") != 0)
-                       sysfatal("cannot use -linkmode=external with -H %s", headstr(HEADTYPE));
-               break;
-       case Hdarwin:
-       case Hdragonfly:
-       case Hfreebsd:
-       case Hlinux:
-       case Hnetbsd:
-       case Hopenbsd:
-               break;
-       }
-
-       switch(HEADTYPE) {
-       default:
-               diag("unknown -H option");
-               errorexit();
-
-       case Hplan9:    /* plan 9 */
-               HEADR = 32L;
-               if(INITTEXT == -1)
-                       INITTEXT = 4096+32;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 4096;
-               break;
-       case Hdarwin:   /* apple MACH */
-               machoinit();
-               HEADR = INITIAL_MACHO_HEADR;
-               if(INITTEXT == -1)
-                       INITTEXT = 4096+HEADR;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 4096;
-               break;
-       case Hlinux:    /* elf32 executable */
-       case Hfreebsd:
-       case Hnetbsd:
-       case Hopenbsd:
-       case Hdragonfly:
-               elfinit();
-               HEADR = ELFRESERVE;
-               if(INITTEXT == -1)
-                       INITTEXT = 0x08048000+HEADR;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 4096;
-               break;
-       
-       case Hnacl:
-               elfinit();
-               HEADR = 0x10000;
-               funcalign = 32;
-               if(INITTEXT == -1)
-                       INITTEXT = 0x20000;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 0x10000;
-               break;
-       
-       case Hwindows: /* PE executable */
-               peinit();
-               HEADR = PEFILEHEADR;
-               if(INITTEXT == -1)
-                       INITTEXT = PEBASE+PESECTHEADR;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = PESECTALIGN;
-               break;
-       }
-       if(INITDAT != 0 && INITRND != 0)
-               print("warning: -D0x%llux is ignored because of -R0x%ux\n",
-                       INITDAT, INITRND);
-}
similarity index 100%
rename from src/cmd/new8l/obj.go
rename to src/cmd/8l/obj.go
diff --git a/src/cmd/9l/Makefile b/src/cmd/9l/Makefile
deleted file mode 100644 (file)
index 3f528d7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# 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
diff --git a/src/cmd/9l/asm.c b/src/cmd/9l/asm.c
deleted file mode 100644 (file)
index 3dbadf7..0000000
+++ /dev/null
@@ -1,814 +0,0 @@
-// Inferno utils/5l/asm.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Writing object files.
-
-#include       "l.h"
-#include       "../ld/lib.h"
-#include       "../ld/elf.h"
-#include       "../ld/dwarf.h"
-
-static int
-needlib(char *name)
-{
-       char *p;
-       LSym *s;
-
-       if(*name == '\0')
-               return 0;
-
-       /* reuse hash code in symbol table */
-       p = smprint(".dynlib.%s", name);
-       s = linklookup(ctxt, p, 0);
-       free(p);
-       if(s->type == 0) {
-               s->type = 100;  // avoid SDATA, etc.
-               return 1;
-       }
-       return 0;
-}
-
-static void    gencallstub(int abicase, LSym *stub, LSym *targ);
-static void    addpltsym(Link*, LSym*);
-static LSym*   ensureglinkresolver(void);
-
-void
-gentext(void)
-{
-       LSym *s, *stub, **pprevtextp;
-       Reloc *r;
-       char *n;
-       uint32 o1;
-       uchar *cast;
-       int i;
-
-       // The ppc64 ABI PLT has similar concepts to other
-       // architectures, but is laid out quite differently.  When we
-       // see an R_PPC64_REL24 relocation to a dynamic symbol
-       // (indicating that the call needs to go through the PLT), we
-       // generate up to three stubs and reserve a PLT slot.
-       //
-       // 1) The call site will be bl x; nop (where the relocation
-       //    applies to the bl).  We rewrite this to bl x_stub; ld
-       //    r2,24(r1).  The ld is necessary because x_stub will save
-       //    r2 (the TOC pointer) at 24(r1) (the "TOC save slot").
-       //
-       // 2) We reserve space for a pointer in the .plt section (once
-       //    per referenced dynamic function).  .plt is a data
-       //    section filled solely by the dynamic linker (more like
-       //    .plt.got on other architectures).  Initially, the
-       //    dynamic linker will fill each slot with a pointer to the
-       //    corresponding x@plt entry point.
-       //
-       // 3) We generate the "call stub" x_stub (once per dynamic
-       //    function/object file pair).  This saves the TOC in the
-       //    TOC save slot, reads the function pointer from x's .plt
-       //    slot and calls it like any other global entry point
-       //    (including setting r12 to the function address).
-       //
-       // 4) We generate the "symbol resolver stub" x@plt (once per
-       //    dynamic function).  This is solely a branch to the glink
-       //    resolver stub.
-       //
-       // 5) We generate the glink resolver stub (only once).  This
-       //    computes which symbol resolver stub we came through and
-       //    invokes the dynamic resolver via a pointer provided by
-       //    the dynamic linker.  This will patch up the .plt slot to
-       //    point directly at the function so future calls go
-       //    straight from the call stub to the real function, and
-       //    then call the function.
-
-       // NOTE: It's possible we could make ppc64 closer to other
-       // architectures: ppc64's .plt is like .plt.got on other
-       // platforms and ppc64's .glink is like .plt on other
-       // platforms.
-
-       // Find all R_PPC64_REL24 relocations that reference dynamic
-       // imports.  Reserve PLT entries for these symbols and
-       // generate call stubs.  The call stubs need to live in .text,
-       // which is why we need to do this pass this early.
-       //
-       // This assumes "case 1" from the ABI, where the caller needs
-       // us to save and restore the TOC pointer.
-       pprevtextp = &ctxt->textp;
-       for(s=*pprevtextp; s!=nil; pprevtextp=&s->next, s=*pprevtextp) {
-               for(r=s->r; r<s->r+s->nr; r++) {
-                       if(!(r->type == 256 + R_PPC64_REL24 &&
-                            r->sym->type == SDYNIMPORT))
-                               continue;
-
-                       // Reserve PLT entry and generate symbol
-                       // resolver
-                       addpltsym(ctxt, r->sym);
-
-                       // Generate call stub
-                       n = smprint("%s.%s", s->name, r->sym->name);
-                       stub = linklookup(ctxt, n, 0);
-                       free(n);
-                       stub->reachable |= s->reachable;
-                       if(stub->size == 0) {
-                               // Need outer to resolve .TOC.
-                               stub->outer = s;
-
-                               // Link in to textp before s (we could
-                               // do it after, but would have to skip
-                               // the subsymbols)
-                               *pprevtextp = stub;
-                               stub->next = s;
-                               pprevtextp = &stub->next;
-
-                               gencallstub(1, stub, r->sym);
-                       }
-
-                       // Update the relocation to use the call stub
-                       r->sym = stub;
-
-                       // Restore TOC after bl.  The compiler put a
-                       // nop here for us to overwrite.
-                       o1 = 0xe8410018; // ld r2,24(r1)
-                       cast = (uchar*)&o1;
-                       for(i=0; i<4; i++)
-                               s->p[r->off+4+i] = cast[inuxi4[i]];
-               }
-       }
-}
-
-// Construct a call stub in stub that calls symbol targ via its PLT
-// entry.
-static void
-gencallstub(int abicase, LSym *stub, LSym *targ)
-{
-       LSym *plt;
-       Reloc *r;
-
-       if(abicase != 1)
-               // If we see R_PPC64_TOCSAVE or R_PPC64_REL24_NOTOC
-               // relocations, we'll need to implement cases 2 and 3.
-               sysfatal("gencallstub only implements case 1 calls");
-
-       plt = linklookup(ctxt, ".plt", 0);
-
-       stub->type = STEXT;
-
-       // Save TOC pointer in TOC save slot
-       adduint32(ctxt, stub, 0xf8410018); // std r2,24(r1)
-
-       // Load the function pointer from the PLT.
-       r = addrel(stub);
-       r->off = stub->size;
-       r->sym = plt;
-       r->add = targ->plt;
-       r->siz = 2;
-       if(ctxt->arch->endian == BigEndian)
-               r->off += r->siz;
-       r->type = R_POWER_TOC;
-       r->variant = RV_POWER_HA;
-       adduint32(ctxt, stub, 0x3d820000); // addis r12,r2,targ@plt@toc@ha
-       r = addrel(stub);
-       r->off = stub->size;
-       r->sym = plt;
-       r->add = targ->plt;
-       r->siz = 2;
-       if(ctxt->arch->endian == BigEndian)
-               r->off += r->siz;
-       r->type = R_POWER_TOC;
-       r->variant = RV_POWER_LO;
-       adduint32(ctxt, stub, 0xe98c0000); // ld r12,targ@plt@toc@l(r12)
-
-       // Jump to the loaded pointer
-       adduint32(ctxt, stub, 0x7d8903a6); // mtctr r12
-       adduint32(ctxt, stub, 0x4e800420); // bctr
-}
-
-void
-adddynrela(LSym *rel, LSym *s, Reloc *r)
-{
-       USED(rel); USED(s); USED(r);
-       sysfatal("adddynrela not implemented");
-}
-
-void
-adddynrel(LSym *s, Reloc *r)
-{
-       LSym *targ, *rela;
-
-       targ = r->sym;
-       ctxt->cursym = s;
-
-       switch(r->type) {
-       default:
-               if(r->type >= 256) {
-                       diag("unexpected relocation type %d", r->type);
-                       return;
-               }
-               break;
-
-       // Handle relocations found in ELF object files.
-       case 256 + R_PPC64_REL24:
-               r->type = R_CALLPOWER;
-               // This is a local call, so the caller isn't setting
-               // up r12 and r2 is the same for the caller and
-               // callee.  Hence, we need to go to the local entry
-               // point.  (If we don't do this, the callee will try
-               // to use r12 to compute r2.)
-               r->add += r->sym->localentry * 4;
-               if(targ->type == SDYNIMPORT)
-                       // Should have been handled in elfsetupplt
-                       diag("unexpected R_PPC64_REL24 for dyn import");
-               return;
-
-       case 256 + R_PPC64_ADDR64:
-               r->type = R_ADDR;
-               if(targ->type == SDYNIMPORT) {
-                       // These happen in .toc sections
-                       adddynsym(ctxt, targ);
-
-                       rela = linklookup(ctxt, ".rela", 0);
-                       addaddrplus(ctxt, rela, s, r->off);
-                       adduint64(ctxt, rela, ELF64_R_INFO(targ->dynid, R_PPC64_ADDR64));
-                       adduint64(ctxt, rela, r->add);
-                       r->type = 256;  // ignore during relocsym
-               }
-               return;
-
-       case 256 + R_PPC64_TOC16:
-               r->type = R_POWER_TOC;
-               r->variant = RV_POWER_LO | RV_CHECK_OVERFLOW;
-               return;
-
-       case 256 + R_PPC64_TOC16_LO:
-               r->type = R_POWER_TOC;
-               r->variant = RV_POWER_LO;
-               return;
-
-       case 256 + R_PPC64_TOC16_HA:
-               r->type = R_POWER_TOC;
-               r->variant = RV_POWER_HA | RV_CHECK_OVERFLOW;
-               return;
-
-       case 256 + R_PPC64_TOC16_HI:
-               r->type = R_POWER_TOC;
-               r->variant = RV_POWER_HI | RV_CHECK_OVERFLOW;
-               return;
-
-       case 256 + R_PPC64_TOC16_DS:
-               r->type = R_POWER_TOC;
-               r->variant = RV_POWER_DS | RV_CHECK_OVERFLOW;
-               return;
-
-       case 256 + R_PPC64_TOC16_LO_DS:
-               r->type = R_POWER_TOC;
-               r->variant = RV_POWER_DS;
-               return;
-
-       case 256 + R_PPC64_REL16_LO:
-               r->type = R_PCREL;
-               r->variant = RV_POWER_LO;
-               r->add += 2;    // Compensate for relocation size of 2
-               return;
-
-       case 256 + R_PPC64_REL16_HI:
-               r->type = R_PCREL;
-               r->variant = RV_POWER_HI | RV_CHECK_OVERFLOW;
-               r->add += 2;
-               return;
-
-       case 256 + R_PPC64_REL16_HA:
-               r->type = R_PCREL;
-               r->variant = RV_POWER_HA | RV_CHECK_OVERFLOW;
-               r->add += 2;
-               return;
-       }
-
-       // Handle references to ELF symbols from our own object files.
-       if(targ->type != SDYNIMPORT)
-               return;
-
-       // TODO(austin): Translate our relocations to ELF
-
-       diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ->name, r->type, targ->type);
-}
-
-int
-elfreloc1(Reloc *r, vlong sectoff)
-{
-       USED(r); USED(sectoff);
-       // TODO(minux)
-       return -1;
-}
-
-void
-elfsetupplt(void)
-{
-       LSym *plt;
-
-       plt = linklookup(ctxt, ".plt", 0);
-       if(plt->size == 0) {
-               // The dynamic linker stores the address of the
-               // dynamic resolver and the DSO identifier in the two
-               // doublewords at the beginning of the .plt section
-               // before the PLT array.  Reserve space for these.
-               plt->size = 16;
-       }
-}
-
-int
-machoreloc1(Reloc *r, vlong sectoff)
-{
-       USED(r);
-       USED(sectoff);
-
-       return -1;
-}
-
-// Return the value of .TOC. for symbol s
-static vlong
-symtoc(LSym *s)
-{
-       LSym *toc;
-
-       if(s->outer != nil)
-               toc = linkrlookup(ctxt, ".TOC.", s->outer->version);
-       else
-               toc = linkrlookup(ctxt, ".TOC.", s->version);
-
-       if(toc == nil) {
-               diag("TOC-relative relocation in object without .TOC.");
-               return 0;
-       }
-       return toc->value;
-}
-
-int
-archreloc(Reloc *r, LSym *s, vlong *val)
-{
-       uint32 o1, o2;
-       vlong t;
-
-       if(linkmode == LinkExternal) {
-               // TODO(minux): translate R_ADDRPOWER and R_CALLPOWER into standard ELF relocations.
-               // R_ADDRPOWER corresponds to R_PPC_ADDR16_HA and R_PPC_ADDR16_LO.
-               // R_CALLPOWER corresponds to R_PPC_REL24.
-               return -1;
-       }
-       switch(r->type) {
-       case R_CONST:
-               *val = r->add;
-               return 0;
-       case R_GOTOFF:
-               *val = symaddr(r->sym) + r->add - symaddr(linklookup(ctxt, ".got", 0));
-               return 0;
-       case R_ADDRPOWER:
-               // r->add is two ppc64 instructions holding an immediate 32-bit constant.
-               // We want to add r->sym's address to that constant.
-               // The encoding of the immediate x<<16 + y,
-               // where x is the low 16 bits of the first instruction and y is the low 16
-               // bits of the second. Both x and y are signed (int16, not uint16).
-               o1 = r->add >> 32;
-               o2 = r->add;
-               t = symaddr(r->sym);
-               if(t < 0) {
-                       ctxt->diag("relocation for %s is too big (>=2G): %lld", s->name, symaddr(r->sym));
-               }
-               t += ((o1 & 0xffff) << 16) + ((int32)o2 << 16 >> 16);
-               if(t & 0x8000)
-                       t += 0x10000;
-               o1 = (o1 & 0xffff0000) | ((t >> 16) & 0xffff);
-               o2 = (o2 & 0xffff0000) | (t & 0xffff);
-               // when laid out, the instruction order must always be o1, o2.
-               if(ctxt->arch->endian == BigEndian)
-                       *val = ((vlong)o1 << 32) | o2;
-               else
-                       *val = ((vlong)o2 << 32) | o1;
-               return 0;
-       case R_CALLPOWER:
-               // Bits 6 through 29 = (S + A - P) >> 2
-               if(ctxt->arch->endian == BigEndian)
-                       o1 = be32(s->p + r->off);
-               else
-                       o1 = le32(s->p + r->off);
-
-               t = symaddr(r->sym) + r->add - (s->value + r->off);
-               if(t & 3)
-                       ctxt->diag("relocation for %s+%d is not aligned: %lld", r->sym->name, r->off, t);
-               if((int32)(t << 6) >> 6 != t)
-                       // TODO(austin) This can happen if text > 32M.
-                       // Add a call trampoline to .text in that case.
-                       ctxt->diag("relocation for %s+%d is too big: %lld", r->sym->name, r->off, t);
-
-               *val = (o1 & 0xfc000003U) | (t & ~0xfc000003U);
-               return 0;
-       case R_POWER_TOC:       // S + A - .TOC.
-               *val = symaddr(r->sym) + r->add - symtoc(s);
-               return 0;
-       }
-       return -1;
-}
-
-vlong
-archrelocvariant(Reloc *r, LSym *s, vlong t)
-{
-       uint32 o1;
-       switch(r->variant & RV_TYPE_MASK) {
-       default:
-               diag("unexpected relocation variant %d", r->variant);
-
-       case RV_NONE:
-               return t;
-
-       case RV_POWER_LO:
-               if(r->variant & RV_CHECK_OVERFLOW) {
-                       // Whether to check for signed or unsigned
-                       // overflow depends on the instruction
-                       if(ctxt->arch->endian == BigEndian)
-                               o1 = be32(s->p + r->off - 2);
-                       else
-                               o1 = le32(s->p + r->off);
-                       switch(o1 >> 26) {
-                       case 24:        // ori
-                       case 26:        // xori
-                       case 28:        // andi
-                               if((t >> 16) != 0)
-                                       goto overflow;
-                               break;
-                       default:
-                               if((int16)t != t)
-                                       goto overflow;
-                               break;
-                       }
-               }
-               return (int16)t;
-
-       case RV_POWER_HA:
-               t += 0x8000;
-               // Fallthrough
-       case RV_POWER_HI:
-               t >>= 16;
-               if(r->variant & RV_CHECK_OVERFLOW) {
-                       // Whether to check for signed or unsigned
-                       // overflow depends on the instruction
-                       if(ctxt->arch->endian == BigEndian)
-                               o1 = be32(s->p + r->off - 2);
-                       else
-                               o1 = le32(s->p + r->off);
-                       switch(o1 >> 26) {
-                       case 25:        // oris
-                       case 27:        // xoris
-                       case 29:        // andis
-                               if((t >> 16) != 0)
-                                       goto overflow;
-                               break;
-                       default:
-                               if((int16)t != t)
-                                       goto overflow;
-                               break;
-                       }
-               }
-               return (int16)t;
-
-       case RV_POWER_DS:
-               if(ctxt->arch->endian == BigEndian)
-                       o1 = be16(s->p + r->off);
-               else
-                       o1 = le16(s->p + r->off);
-               if(t & 3)
-                       diag("relocation for %s+%d is not aligned: %lld", r->sym->name, r->off, t);
-               if((r->variant & RV_CHECK_OVERFLOW) && (int16)t != t)
-                       goto overflow;
-               return (o1 & 0x3) | (vlong)(int16)t;
-       }
-
-overflow:
-       diag("relocation for %s+%d is too big: %lld", r->sym->name, r->off, t);
-       return t;
-}
-
-static void
-addpltsym(Link *ctxt, LSym *s)
-{
-       if(s->plt >= 0)
-               return;
-
-       adddynsym(ctxt, s);
-
-       if(iself) {
-               LSym *plt, *rela, *glink;
-               Reloc *r;
-
-               plt = linklookup(ctxt, ".plt", 0);
-               rela = linklookup(ctxt, ".rela.plt", 0);
-               if(plt->size == 0)
-                       elfsetupplt();
-
-               // Create the glink resolver if necessary
-               glink = ensureglinkresolver();
-
-               // Write symbol resolver stub (just a branch to the
-               // glink resolver stub)
-               r = addrel(glink);
-               r->sym = glink;
-               r->off = glink->size;
-               r->siz = 4;
-               r->type = R_CALLPOWER;
-               adduint32(ctxt, glink, 0x48000000); // b .glink
-
-               // In the ppc64 ABI, the dynamic linker is responsible
-               // for writing the entire PLT.  We just need to
-               // reserve 8 bytes for each PLT entry and generate a
-               // JMP_SLOT dynamic relocation for it.
-               //
-               // TODO(austin): ABI v1 is different
-               s->plt = plt->size;
-               plt->size += 8;
-
-               addaddrplus(ctxt, rela, plt, s->plt);
-               adduint64(ctxt, rela, ELF64_R_INFO(s->dynid, R_PPC64_JMP_SLOT));
-               adduint64(ctxt, rela, 0);
-       } else {
-               diag("addpltsym: unsupported binary format");
-       }
-}
-
-// Generate the glink resolver stub if necessary and return the .glink section
-static LSym*
-ensureglinkresolver(void)
-{
-       LSym *glink, *s;
-       Reloc *r;
-
-       glink = linklookup(ctxt, ".glink", 0);
-       if(glink->size != 0)
-               return glink;
-
-       // This is essentially the resolver from the ppc64 ELF ABI.
-       // At entry, r12 holds the address of the symbol resolver stub
-       // for the target routine and the argument registers hold the
-       // arguments for the target routine.
-       //
-       // This stub is PIC, so first get the PC of label 1 into r11.
-       // Other things will be relative to this.
-       adduint32(ctxt, glink, 0x7c0802a6); // mflr r0
-       adduint32(ctxt, glink, 0x429f0005); // bcl 20,31,1f
-       adduint32(ctxt, glink, 0x7d6802a6); // 1: mflr r11
-       adduint32(ctxt, glink, 0x7c0803a6); // mtlf r0
-
-       // Compute the .plt array index from the entry point address.
-       // Because this is PIC, everything is relative to label 1b (in
-       // r11):
-       //   r0 = ((r12 - r11) - (res_0 - r11)) / 4 = (r12 - res_0) / 4
-       adduint32(ctxt, glink, 0x3800ffd0); // li r0,-(res_0-1b)=-48
-       adduint32(ctxt, glink, 0x7c006214); // add r0,r0,r12
-       adduint32(ctxt, glink, 0x7c0b0050); // sub r0,r0,r11
-       adduint32(ctxt, glink, 0x7800f082); // srdi r0,r0,2
-
-       // r11 = address of the first byte of the PLT
-       r = addrel(glink);
-       r->off = glink->size;
-       r->sym = linklookup(ctxt, ".plt", 0);
-       r->siz = 8;
-       r->type = R_ADDRPOWER;
-       // addis r11,0,.plt@ha; addi r11,r11,.plt@l
-       r->add = (0x3d600000ull << 32) | 0x396b0000;
-       glink->size += 8;
-
-       // Load r12 = dynamic resolver address and r11 = DSO
-       // identifier from the first two doublewords of the PLT.
-       adduint32(ctxt, glink, 0xe98b0000); // ld r12,0(r11)
-       adduint32(ctxt, glink, 0xe96b0008); // ld r11,8(r11)
-
-       // Jump to the dynamic resolver
-       adduint32(ctxt, glink, 0x7d8903a6); // mtctr r12
-       adduint32(ctxt, glink, 0x4e800420); // bctr
-
-       // The symbol resolvers must immediately follow.
-       //   res_0:
-
-       // Add DT_PPC64_GLINK .dynamic entry, which points to 32 bytes
-       // before the first symbol resolver stub.
-       s = linklookup(ctxt, ".dynamic", 0);
-       elfwritedynentsymplus(s, DT_PPC64_GLINK, glink, glink->size - 32);
-
-       return glink;
-}
-
-void
-adddynsym(Link *ctxt, LSym *s)
-{
-       LSym *d;
-       int t;
-       char *name;
-
-       if(s->dynid >= 0)
-               return;
-
-       if(iself) {
-               s->dynid = nelfsym++;
-
-               d = linklookup(ctxt, ".dynsym", 0);
-
-               name = s->extname;
-               adduint32(ctxt, d, addstring(linklookup(ctxt, ".dynstr", 0), name));
-
-               /* type */
-               t = STB_GLOBAL << 4;
-               if(s->cgoexport && (s->type&SMASK) == STEXT)
-                       t |= STT_FUNC;
-               else
-                       t |= STT_OBJECT;
-               adduint8(ctxt, d, t);
-
-               /* reserved */
-               adduint8(ctxt, d, 0);
-
-               /* section where symbol is defined */
-               if(s->type == SDYNIMPORT)
-                       adduint16(ctxt, d, SHN_UNDEF);
-               else
-                       adduint16(ctxt, d, 1);
-
-               /* value */
-               if(s->type == SDYNIMPORT)
-                       adduint64(ctxt, d, 0);
-               else
-                       addaddr(ctxt, d, s);
-
-               /* size of object */
-               adduint64(ctxt, d, s->size);
-       } else {
-               diag("adddynsym: unsupported binary format");
-       }
-}
-
-void
-adddynlib(char *lib)
-{
-       LSym *s;
-       
-       if(!needlib(lib))
-               return;
-       
-       if(iself) {
-               s = linklookup(ctxt, ".dynstr", 0);
-               if(s->size == 0)
-                       addstring(s, "");
-               elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addstring(s, lib));
-       } else {
-               diag("adddynlib: unsupported binary format");
-       }
-}
-
-void
-asmb(void)
-{
-       uint32 symo;
-       Section *sect;
-       LSym *sym;
-       int i;
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f asmb\n", cputime());
-       Bflush(&bso);
-
-       if(iself)
-               asmbelfsetup();
-
-       sect = segtext.sect;
-       cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
-       codeblk(sect->vaddr, sect->length);
-       for(sect = sect->next; sect != nil; sect = sect->next) {
-               cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
-               datblk(sect->vaddr, sect->length);
-       }
-
-       if(segrodata.filelen > 0) {
-               if(debug['v'])
-                       Bprint(&bso, "%5.2f rodatblk\n", cputime());
-               Bflush(&bso);
-
-               cseek(segrodata.fileoff);
-               datblk(segrodata.vaddr, segrodata.filelen);
-       }
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f datblk\n", cputime());
-       Bflush(&bso);
-
-       cseek(segdata.fileoff);
-       datblk(segdata.vaddr, segdata.filelen);
-
-       /* output symbol table */
-       symsize = 0;
-       lcsize = 0;
-       symo = 0;
-       if(!debug['s']) {
-               // TODO: rationalize
-               if(debug['v'])
-                       Bprint(&bso, "%5.2f sym\n", cputime());
-               Bflush(&bso);
-               switch(HEADTYPE) {
-               default:
-                       if(iself) {
-                               symo = segdata.fileoff+segdata.filelen;
-                               symo = rnd(symo, INITRND);
-                       }
-                       break;
-               case Hplan9:
-                       symo = segdata.fileoff+segdata.filelen;
-                       break;
-               }
-               cseek(symo);
-               switch(HEADTYPE) {
-               default:
-                       if(iself) {
-                               if(debug['v'])
-                                       Bprint(&bso, "%5.2f elfsym\n", cputime());
-                               asmelfsym();
-                               cflush();
-                               cwrite(elfstrdat, elfstrsize);
-       
-                               if(debug['v'])
-                                       Bprint(&bso, "%5.2f dwarf\n", cputime());
-                               dwarfemitdebugsections();
-                               
-                               if(linkmode == LinkExternal)
-                                       elfemitreloc();
-                       }
-                       break;
-               case Hplan9:
-                       asmplan9sym();
-                       cflush();
-
-                       sym = linklookup(ctxt, "pclntab", 0);
-                       if(sym != nil) {
-                               lcsize = sym->np;
-                               for(i=0; i < lcsize; i++)
-                                       cput(sym->p[i]);
-
-                               cflush();
-                       }
-                       break;
-               }
-       }
-
-       ctxt->cursym = nil;
-       if(debug['v'])
-               Bprint(&bso, "%5.2f header\n", cputime());
-       Bflush(&bso);
-       cseek(0L);
-       switch(HEADTYPE) {
-       default:
-       case Hplan9:    /* plan 9 */
-               thearch.lput(0x647);                    /* magic */
-               thearch.lput(segtext.filelen);                  /* sizes */
-               thearch.lput(segdata.filelen);
-               thearch.lput(segdata.length - segdata.filelen);
-               thearch.lput(symsize);                  /* nsyms */
-               thearch.lput(entryvalue());             /* va of entry */
-               thearch.lput(0L);
-               thearch.lput(lcsize);
-               break;
-       case Hlinux:
-       case Hfreebsd:
-       case Hnetbsd:
-       case Hopenbsd:
-       case Hnacl:
-               asmbelf(symo);
-               break;
-       }
-       cflush();
-       if(debug['c']){
-               print("textsize=%ulld\n", segtext.filelen);
-               print("datsize=%ulld\n", segdata.filelen);
-               print("bsssize=%ulld\n", segdata.length - segdata.filelen);
-               print("symsize=%d\n", symsize);
-               print("lcsize=%d\n", lcsize);
-               print("total=%lld\n", segtext.filelen+segdata.length+symsize+lcsize);
-       }
-}
similarity index 100%
rename from src/cmd/new9l/asm.go
rename to src/cmd/9l/asm.go
diff --git a/src/cmd/9l/doc.go b/src/cmd/9l/doc.go
deleted file mode 100644 (file)
index 3e3c480..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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.
-
-// +build ignore
-
-/*
-
-9l is the linker for 64-bit PowerPC and Power Architecture processors.
-The $GOARCH for these tools is ppc64 (big endian) or
-ppc64le (little endian).
-
-The flags are documented in ../ld/doc.go.
-
-*/
-package main
similarity index 100%
rename from src/cmd/new9l/l.go
rename to src/cmd/9l/l.go
diff --git a/src/cmd/9l/l.h b/src/cmd/9l/l.h
deleted file mode 100644 (file)
index 5c048d2..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-// cmd/9l/l.h from Vita Nuova.
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-
-#ifndef        EXTERN
-#define        EXTERN  extern
-#endif
-
-enum
-{
-       thechar = '9',
-       PtrSize = 8,
-       IntSize = 8,
-       RegSize = 8,
-       MaxAlign = 32,  // max data alignment
-       FuncAlign = 8,
-       MINLC           = 4,
-};
-
-void   adddynlib(char *lib);
-void   adddynrel(LSym *s, Reloc *r);
-void   adddynrela(LSym *rela, LSym *s, Reloc *r);
-void   adddynsym(Link *ctxt, LSym *s);
-int    archreloc(Reloc *r, LSym *s, vlong *val);
-vlong  archrelocvariant(Reloc *r, LSym *s, vlong t);
-void   asmb(void);
-int    elfreloc1(Reloc *r, vlong sectoff);
-void   elfsetupplt(void);
-int    machoreloc1(Reloc *r, vlong sectoff);
-
-/* Used by ../ld/dwarf.c */
-enum
-{
-       DWARFREGSP = 1
-};
diff --git a/src/cmd/9l/obj.c b/src/cmd/9l/obj.c
deleted file mode 100644 (file)
index 5449319..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-// Inferno utils/5l/obj.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5l/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Reading object files.
-
-#include       "l.h"
-#include       "../ld/lib.h"
-#include       "../ld/elf.h"
-#include       "../ld/dwarf.h"
-#include       <ar.h>
-
-void
-main(int argc, char **argv)
-{
-       linkarchinit();
-       ldmain(argc, argv);
-}
-
-void
-linkarchinit(void)
-{
-       thestring = getgoarch();
-       if(strcmp(thestring, "ppc64le") == 0)
-               thelinkarch = &linkppc64le;
-       else
-               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.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
-archinit(void)
-{
-       // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
-       // Go was built; see ../../make.bash.
-       if(linkmode == LinkAuto && strcmp(getgoextlinkenabled(), "0") == 0)
-               linkmode = LinkInternal;
-
-       switch(HEADTYPE) {
-       default:
-               if(linkmode == LinkAuto)
-                       linkmode = LinkInternal;
-               if(linkmode == LinkExternal && strcmp(getgoextlinkenabled(), "1") != 0)
-                       sysfatal("cannot use -linkmode=external with -H %s", headstr(HEADTYPE));
-               break;
-       }
-
-       switch(HEADTYPE) {
-       default:
-               diag("unknown -H option");
-               errorexit();
-       case Hplan9:    /* plan 9 */
-               HEADR = 32L;
-               if(INITTEXT == -1)
-                       INITTEXT = 4128;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 4096;
-               break;
-       case Hlinux:    /* ppc64 elf */
-               if(strcmp(thestring, "ppc64") == 0)
-                       debug['d'] = 1; // TODO(austin): ELF ABI v1 not supported yet
-               elfinit();
-               HEADR = ELFRESERVE;
-               if(INITTEXT == -1)
-                       INITTEXT = 0x10000 + HEADR;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 0x10000;
-               break;
-       case Hnacl:
-               elfinit();
-               HEADR = 0x10000;
-               funcalign = 16;
-               if(INITTEXT == -1)
-                       INITTEXT = 0x20000;
-               if(INITDAT == -1)
-                       INITDAT = 0;
-               if(INITRND == -1)
-                       INITRND = 0x10000;
-               break;
-       }
-       if(INITDAT != 0 && INITRND != 0)
-               print("warning: -D0x%ux is ignored because of -R0x%ux\n",
-                       INITDAT, INITRND);
-}
similarity index 100%
rename from src/cmd/new9l/obj.go
rename to src/cmd/9l/obj.go
index 00d289cf29d95e18e9f527fd55a542cdce1067cd..f21331055f177df02b396ba4f3833cd3f33332b9 100644 (file)
@@ -135,7 +135,7 @@ func xinit() {
        }
        go386 = b
 
-       p := pathf("%s/include/u.h", goroot)
+       p := pathf("%s/src/all.bash", goroot)
        if !isfile(p) {
                fatal("$GOROOT is not set correctly or not exported\n"+
                        "\tGOROOT=%s\n"+
@@ -507,50 +507,9 @@ var deptab = []struct {
        prefix string   // prefix of target
        dep    []string // dependency tweaks for targets with that prefix
 }{
-       {"lib9", []string{
-               "$GOROOT/include/u.h",
-               "$GOROOT/include/utf.h",
-               "$GOROOT/include/fmt.h",
-               "$GOROOT/include/libc.h",
-               "fmt/*",
-               "utf/*",
-       }},
-       {"libbio", []string{
-               "$GOROOT/include/u.h",
-               "$GOROOT/include/utf.h",
-               "$GOROOT/include/fmt.h",
-               "$GOROOT/include/libc.h",
-               "$GOROOT/include/bio.h",
-       }},
-       {"liblink", []string{
-               "$GOROOT/include/u.h",
-               "$GOROOT/include/utf.h",
-               "$GOROOT/include/fmt.h",
-               "$GOROOT/include/libc.h",
-               "$GOROOT/include/bio.h",
-               "$GOROOT/include/ar.h",
-               "$GOROOT/include/link.h",
-       }},
-       {"cmd/5l", []string{
-               "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libld.a",
-       }},
-       {"cmd/6l", []string{
-               "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libld.a",
-       }},
-       {"cmd/8l", []string{
-               "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libld.a",
-       }},
-       {"cmd/9l", []string{
-               "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libld.a",
-       }},
        {"cmd/go", []string{
                "zdefaultcc.go",
        }},
-       {"cmd/", []string{
-               "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/liblink.a",
-               "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libbio.a",
-               "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/lib9.a",
-       }},
        {"runtime", []string{
                "zversion.go",
        }},
@@ -635,11 +594,6 @@ func install(dir string) {
        case "lib9", "libbio", "liblink", "cmd/gc", "cmd/ld":
                islib = true
                isgo = false
-       case "cmd/5l",
-               "cmd/6l",
-               "cmd/8l",
-               "cmd/9l":
-               isgo = false
        }
 
        // Start final link command line.
@@ -800,7 +754,7 @@ func install(dir string) {
        if dir == "runtime" {
                // For use by assembly and C files.
                copyfile(pathf("%s/pkg/%s_%s/textflag.h", goroot, goos, goarch),
-                       pathf("%s/src/cmd/ld/textflag.h", goroot), 0)
+                       pathf("%s/src/runtime/textflag.h", goroot), 0)
                copyfile(pathf("%s/pkg/%s_%s/funcdata.h", goroot, goos, goarch),
                        pathf("%s/src/runtime/funcdata.h", goroot), 0)
        }
@@ -1109,13 +1063,6 @@ func dopack(dst, src string, extra []string) {
 // The Go packages and commands must be in dependency order,
 // maintained by hand, but the order doesn't change often.
 var buildorder = []string{
-       // Legacy C programs.
-       "lib9",
-       "libbio",
-       "liblink",
-       "cmd/ld",  // must be before l
-       "cmd/%sl", // must be before a, g
-
        // Go libraries and programs for bootstrap.
        "runtime",
        "errors",
index 1b4f42973069afd216467854bb0b6ca09f0d5739..d8192f67366e6c8e5fb688e1dc13b0b2bfa33318 100644 (file)
@@ -25,12 +25,16 @@ import (
 var bootstrapDirs = []string{
        "5a",
        "5g",
+       "5l",
        "6a",
        "6g",
+       "6l",
        "8a",
        "8g",
+       "8l",
        "9a",
        "9g",
+       "9l",
        "asm",
        "asm/internal/arch",
        "asm/internal/asm",
@@ -44,10 +48,6 @@ var bootstrapDirs = []string{
        "internal/obj/i386",
        "internal/obj/ppc64",
        "internal/obj/x86",
-       "new5l",
-       "new6l",
-       "new8l",
-       "new9l",
 }
 
 func bootstrapBuildTools() {
index 784c751def5712fdbf7e649070d81c26d4cd0b8a..292bc730034726ecf4930b996527101bec43da4d 100644 (file)
@@ -1892,7 +1892,7 @@ func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action,
                }
        }
        ldflags = append(ldflags, buildLdflags...)
-       return b.run(".", p.ImportPath, nil, buildToolExec, tool("new"+archChar+"l"), "-o", out, importArgs, ldflags, mainpkg)
+       return b.run(".", p.ImportPath, nil, buildToolExec, tool(archChar+"l"), "-o", out, importArgs, ldflags, mainpkg)
 }
 
 func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
index 39be2c0c15b14d70c9de3359f186d54eb185bc70..d303d7f81163ca435fd1e940a24a132095fd505a 100644 (file)
@@ -393,12 +393,16 @@ const (
 var goTools = map[string]targetDir{
        "cmd/5a":                               toTool,
        "cmd/5g":                               toTool,
+       "cmd/5l":                               toTool,
        "cmd/6a":                               toTool,
        "cmd/6g":                               toTool,
+       "cmd/6l":                               toTool,
        "cmd/8a":                               toTool,
        "cmd/8g":                               toTool,
+       "cmd/8l":                               toTool,
        "cmd/9a":                               toTool,
        "cmd/9g":                               toTool,
+       "cmd/9l":                               toTool,
        "cmd/addr2line":                        toTool,
        "cmd/api":                              toTool,
        "cmd/asm":                              toTool,
@@ -406,10 +410,6 @@ var goTools = map[string]targetDir{
        "cmd/dist":                             toTool,
        "cmd/fix":                              toTool,
        "cmd/link":                             toTool,
-       "cmd/new5l":                            toTool,
-       "cmd/new6l":                            toTool,
-       "cmd/new8l":                            toTool,
-       "cmd/new9l":                            toTool,
        "cmd/nm":                               toTool,
        "cmd/objdump":                          toTool,
        "cmd/pack":                             toTool,
diff --git a/src/cmd/ld/Makefile b/src/cmd/ld/Makefile
deleted file mode 100644 (file)
index 3f528d7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# 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
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
deleted file mode 100644 (file)
index c039463..0000000
+++ /dev/null
@@ -1,1460 +0,0 @@
-// Inferno utils/8l/asm.c
-// http://code.google.com/p/inferno-os/source/browse/utils/8l/asm.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Data layout and relocation.
-
-#include       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-#include       "lib.h"
-#include       "elf.h"
-#include       "macho.h"
-#include       "pe.h"
-#include       "../../runtime/mgc0.h"
-
-void   dynreloc(void);
-
-/*
- * divide-and-conquer list-link
- * sort of LSym* structures.
- * Used for the data block.
- */
-int
-datcmp(LSym *s1, LSym *s2)
-{
-       if(s1->type != s2->type)
-               return (int)s1->type - (int)s2->type;
-       // For ppc64, we want to interleave the .got and .toc sections
-       // from input files.  Both are type SELFGOT, so in that case
-       // fall through to the name comparison (conveniently, .got
-       // sorts before .toc).
-       if(s1->type != SELFGOT && s1->size != s2->size) {
-               if(s1->size < s2->size)
-                       return -1;
-               return +1;
-       }
-       return strcmp(s1->name, s2->name);
-}
-
-LSym**
-listnextp(LSym *s)
-{
-       return &s->next;
-}
-
-LSym**
-listsubp(LSym *s)
-{
-       return &s->sub;
-}
-
-LSym*
-listsort(LSym *l, int (*cmp)(LSym*, LSym*), LSym **(*nextp)(LSym*))
-{
-       LSym *l1, *l2, *le;
-
-       if(l == 0 || *nextp(l) == 0)
-               return l;
-
-       l1 = l;
-       l2 = l;
-       for(;;) {
-               l2 = *nextp(l2);
-               if(l2 == 0)
-                       break;
-               l2 = *nextp(l2);
-               if(l2 == 0)
-                       break;
-               l1 = *nextp(l1);
-       }
-
-       l2 = *nextp(l1);
-       *nextp(l1) = 0;
-       l1 = listsort(l, cmp, nextp);
-       l2 = listsort(l2, cmp, nextp);
-
-       /* set up lead element */
-       if(cmp(l1, l2) < 0) {
-               l = l1;
-               l1 = *nextp(l1);
-       } else {
-               l = l2;
-               l2 = *nextp(l2);
-       }
-       le = l;
-
-       for(;;) {
-               if(l1 == 0) {
-                       while(l2) {
-                               *nextp(le) = l2;
-                               le = l2;
-                               l2 = *nextp(l2);
-                       }
-                       *nextp(le) = 0;
-                       break;
-               }
-               if(l2 == 0) {
-                       while(l1) {
-                               *nextp(le) = l1;
-                               le = l1;
-                               l1 = *nextp(l1);
-                       }
-                       break;
-               }
-               if(cmp(l1, l2) < 0) {
-                       *nextp(le) = l1;
-                       le = l1;
-                       l1 = *nextp(l1);
-               } else {
-                       *nextp(le) = l2;
-                       le = l2;
-                       l2 = *nextp(l2);
-               }
-       }
-       *nextp(le) = 0;
-       return l;
-}
-
-void
-relocsym(LSym *s)
-{
-       Reloc *r;
-       LSym *rs;
-       int16 i16;
-       int32 i, ri, off, siz, fl;
-       vlong o;
-       uchar *cast;
-
-       ctxt->cursym = s;
-       for(ri=0; ri<s->nr; ri++) {
-               r = &s->r[ri];
-               r->done = 1;
-               off = r->off;
-               siz = r->siz;
-               if(off < 0 || off+siz > s->np) {
-                       diag("%s: invalid relocation %d+%d not in [%d,%d)", s->name, off, siz, 0, s->np);
-                       continue;
-               }
-               if(r->sym != nil && ((r->sym->type & (SMASK | SHIDDEN)) == 0 || (r->sym->type & SMASK) == SXREF)) {
-                       diag("%s: not defined", r->sym->name);
-                       continue;
-               }
-               if(r->type >= 256)
-                       continue;
-               if(r->siz == 0) // informational relocation - no work to do
-                       continue;
-
-               // Solaris needs the ability to reference dynimport symbols.
-               if(HEADTYPE != Hsolaris && r->sym != nil && r->sym->type == SDYNIMPORT)
-                       diag("unhandled relocation for %s (type %d rtype %d)", r->sym->name, r->sym->type, r->type);
-               if(r->sym != nil && r->sym->type != STLSBSS && !r->sym->reachable)
-                       diag("unreachable sym in relocation: %s %s", s->name, r->sym->name);
-
-               // Android emulates runtime.tlsg as a regular variable.
-               if (r->type == R_TLS && strcmp(goos, "android") == 0)
-                       r->type = R_ADDR;
-
-               switch(r->type) {
-               default:
-                       o = 0;
-                       if(thearch.archreloc(r, s, &o) < 0)
-                               diag("unknown reloc %d", r->type);
-                       break;
-               case R_TLS:
-                       if(linkmode == LinkInternal && iself && thearch.thechar == '5') {
-                               // On ELF ARM, the thread pointer is 8 bytes before
-                               // the start of the thread-local data block, so add 8
-                               // to the actual TLS offset (r->sym->value).
-                               // This 8 seems to be a fundamental constant of
-                               // ELF on ARM (or maybe Glibc on ARM); it is not
-                               // related to the fact that our own TLS storage happens
-                               // to take up 8 bytes.
-                               o = 8 + r->sym->value;
-                               break;
-                       }
-                       r->done = 0;
-                       o = 0;
-                       if(thearch.thechar != '6')
-                               o = r->add;
-                       break;
-               case R_TLS_LE:
-                       if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd) {
-                               r->done = 0;
-                               r->sym = ctxt->tlsg;
-                               r->xsym = ctxt->tlsg;
-                               r->xadd = r->add;
-                               o = 0;
-                               if(thearch.thechar != '6')
-                                       o = r->add;
-                               break;
-                       }
-                       o = ctxt->tlsoffset + r->add;
-                       break;
-
-               case R_TLS_IE:
-                       if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd) {
-                               r->done = 0;
-                               r->sym = ctxt->tlsg;
-                               r->xsym = ctxt->tlsg;
-                               r->xadd = r->add;
-                               o = 0;
-                               if(thearch.thechar != '6')
-                                       o = r->add;
-                               break;
-                       }
-                       if(iself || ctxt->headtype == Hplan9)
-                               o = ctxt->tlsoffset + r->add;
-                       else if(ctxt->headtype == Hwindows)
-                               o = r->add;
-                       else
-                               sysfatal("unexpected R_TLS_IE relocation for %s", headstr(ctxt->headtype));
-                       break;
-               case R_ADDR:
-                       if(linkmode == LinkExternal && r->sym->type != SCONST) {
-                               r->done = 0;
-
-                               // set up addend for eventual relocation via outer symbol.
-                               rs = r->sym;
-                               r->xadd = r->add;
-                               while(rs->outer != nil) {
-                                       r->xadd += symaddr(rs) - symaddr(rs->outer);
-                                       rs = rs->outer;
-                               }
-                               if(rs->type != SHOSTOBJ && rs->type != SDYNIMPORT && rs->sect == nil)
-                                       diag("missing section for %s", rs->name);
-                               r->xsym = rs;
-
-                               o = r->xadd;
-                               if(iself) {
-                                       if(thearch.thechar == '6')
-                                               o = 0;
-                               } else if(HEADTYPE == Hdarwin) {
-                                       if(rs->type != SHOSTOBJ)
-                                               o += symaddr(rs);
-                               } else {
-                                       diag("unhandled pcrel relocation for %s", headstring);
-                               }
-                               break;
-                       }
-                       o = symaddr(r->sym) + r->add;
-
-                       // On amd64, 4-byte offsets will be sign-extended, so it is impossible to
-                       // access more than 2GB of static data; fail at link time is better than
-                       // fail at runtime. See http://golang.org/issue/7980.
-                       // Instead of special casing only amd64, we treat this as an error on all
-                       // 64-bit architectures so as to be future-proof.
-                       if((int32)o < 0 && thearch.ptrsize > 4 && siz == 4) {
-                               diag("non-pc-relative relocation address is too big: %#llux", o);
-                               errorexit();
-                       }
-                       break;
-               case R_CALL:
-               case R_PCREL:
-                       // r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call.
-                       if(linkmode == LinkExternal && r->sym && r->sym->type != SCONST && r->sym->sect != ctxt->cursym->sect) {
-                               r->done = 0;
-
-                               // set up addend for eventual relocation via outer symbol.
-                               rs = r->sym;
-                               r->xadd = r->add;
-                               while(rs->outer != nil) {
-                                       r->xadd += symaddr(rs) - symaddr(rs->outer);
-                                       rs = rs->outer;
-                               }
-                               r->xadd -= r->siz; // relative to address after the relocated chunk
-                               if(rs->type != SHOSTOBJ && rs->type != SDYNIMPORT && rs->sect == nil)
-                                       diag("missing section for %s", rs->name);
-                               r->xsym = rs;
-
-                               o = r->xadd;
-                               if(iself) {
-                                       if(thearch.thechar == '6')
-                                               o = 0;
-                               } else if(HEADTYPE == Hdarwin) {
-                                       if(r->type == R_CALL) {
-                                               if(rs->type != SHOSTOBJ)
-                                                       o += symaddr(rs) - ((Section*)rs->sect)->vaddr;
-                                               o -= r->off; // relative to section offset, not symbol
-                                       } else {
-                                               o += r->siz;
-                                       }
-                               } else {
-                                       diag("unhandled pcrel relocation for %s", headstring);
-                               }
-                               break;
-                       }
-                       o = 0;
-                       if(r->sym)
-                               o += symaddr(r->sym);
-                       // NOTE: The (int32) cast on the next line works around a bug in Plan 9's 8c
-                       // compiler. The expression s->value + r->off + r->siz is int32 + int32 +
-                       // uchar, and Plan 9 8c incorrectly treats the expression as type uint32
-                       // instead of int32, causing incorrect values when sign extended for adding
-                       // to o. The bug only occurs on Plan 9, because this C program is compiled by
-                       // the standard host compiler (gcc on most other systems).
-                       o += r->add - (s->value + r->off + (int32)r->siz);
-                       break;
-               case R_SIZE:
-                       o = r->sym->size + r->add;
-                       break;
-               }
-               if(r->variant != RV_NONE)
-                       o = thearch.archrelocvariant(r, s, o);
-//print("relocate %s %#llux (%#llux+%#llux, size %d) => %s %#llux +%#llx [%llx]\n", s->name, (uvlong)(s->value+off), (uvlong)s->value, (uvlong)r->off, r->siz, r->sym ? r->sym->name : "<nil>", (uvlong)symaddr(r->sym), (vlong)r->add, (vlong)o);
-               switch(siz) {
-               default:
-                       ctxt->cursym = s;
-                       diag("bad reloc size %#ux for %s", siz, r->sym->name);
-               case 1:
-                       // TODO(rsc): Remove.
-                       s->p[off] = (int8)o;
-                       break;
-               case 2:
-                       if(o != (int16)o)
-                               diag("relocation address is too big: %#llx", o);
-                       i16 = o;
-                       cast = (uchar*)&i16;
-                       for(i=0; i<2; i++)
-                               s->p[off+i] = cast[inuxi2[i]];
-                       break;
-               case 4:
-                       if(r->type == R_PCREL || r->type == R_CALL) {
-                               if(o != (int32)o)
-                                       diag("pc-relative relocation address is too big: %#llx", o);
-                       } else {
-                               if(o != (int32)o && o != (uint32)o)
-                                       diag("non-pc-relative relocation address is too big: %#llux", o);
-                       }
-                       fl = o;
-                       cast = (uchar*)&fl;
-                       for(i=0; i<4; i++)
-                               s->p[off+i] = cast[inuxi4[i]];
-                       break;
-               case 8:
-                       cast = (uchar*)&o;
-                       for(i=0; i<8; i++)
-                               s->p[off+i] = cast[inuxi8[i]];
-                       break;
-               }
-       }
-}
-
-void
-reloc(void)
-{
-       LSym *s;
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f reloc\n", cputime());
-       Bflush(&bso);
-
-       for(s=ctxt->textp; s!=nil; s=s->next)
-               relocsym(s);
-       for(s=datap; s!=nil; s=s->next)
-               relocsym(s);
-}
-
-void
-dynrelocsym(LSym *s)
-{
-       int ri;
-       Reloc *r;
-
-       if(HEADTYPE == Hwindows) {
-               LSym *rel, *targ;
-
-               rel = linklookup(ctxt, ".rel", 0);
-               if(s == rel)
-                       return;
-               for(ri=0; ri<s->nr; ri++) {
-                       r = &s->r[ri];
-                       targ = r->sym;
-                       if(targ == nil)
-                               continue;
-                       if(!targ->reachable)
-                               diag("internal inconsistency: dynamic symbol %s is not reachable.", targ->name);
-                       if(r->sym->plt == -2 && r->sym->got != -2) { // make dynimport JMP table for PE object files.
-                               targ->plt = rel->size;
-                               r->sym = rel;
-                               r->add = targ->plt;
-
-                               // jmp *addr
-                               if(thearch.thechar == '8') {
-                                       adduint8(ctxt, rel, 0xff);
-                                       adduint8(ctxt, rel, 0x25);
-                                       addaddr(ctxt, rel, targ);
-                                       adduint8(ctxt, rel, 0x90);
-                                       adduint8(ctxt, rel, 0x90);
-                               } else {
-                                       adduint8(ctxt, rel, 0xff);
-                                       adduint8(ctxt, rel, 0x24);
-                                       adduint8(ctxt, rel, 0x25);
-                                       addaddrplus4(ctxt, rel, targ, 0);
-                                       adduint8(ctxt, rel, 0x90);
-                               }
-                       } else if(r->sym->plt >= 0) {
-                               r->sym = rel;
-                               r->add = targ->plt;
-                       }
-               }
-               return;
-       }
-
-       for(ri=0; ri<s->nr; ri++) {
-               r = &s->r[ri];
-               if(r->sym != nil && r->sym->type == SDYNIMPORT || r->type >= 256) {
-                       if(r->sym != nil && !r->sym->reachable)
-                               diag("internal inconsistency: dynamic symbol %s is not reachable.", r->sym->name);
-                       thearch.adddynrel(s, r);
-               }
-       }
-}
-
-void
-dynreloc(void)
-{
-       LSym *s;
-
-       // -d suppresses dynamic loader format, so we may as well not
-       // compute these sections or mark their symbols as reachable.
-       if(debug['d'] && HEADTYPE != Hwindows)
-               return;
-       if(debug['v'])
-               Bprint(&bso, "%5.2f reloc\n", cputime());
-       Bflush(&bso);
-
-       for(s=ctxt->textp; s!=nil; s=s->next)
-               dynrelocsym(s);
-       for(s=datap; s!=nil; s=s->next)
-               dynrelocsym(s);
-       if(iself)
-               elfdynhash();
-}
-
-static void
-blk(LSym *start, int64 addr, int64 size)
-{
-       LSym *sym;
-       int64 eaddr;
-       uchar *p, *ep;
-
-       for(sym = start; sym != nil; sym = sym->next)
-               if(!(sym->type&SSUB) && sym->value >= addr)
-                       break;
-
-       eaddr = addr+size;
-       for(; sym != nil; sym = sym->next) {
-               if(sym->type&SSUB)
-                       continue;
-               if(sym->value >= eaddr)
-                       break;
-               ctxt->cursym = sym;
-               if(sym->value < addr) {
-                       diag("phase error: addr=%#llx but sym=%#llx type=%d", (vlong)addr, (vlong)sym->value, sym->type);
-                       errorexit();
-               }
-               for(; addr < sym->value; addr++)
-                       cput(0);
-               p = sym->p;
-               ep = p + sym->np;
-               while(p < ep)
-                       cput(*p++);
-               addr += sym->np;
-               for(; addr < sym->value+sym->size; addr++)
-                       cput(0);
-               if(addr != sym->value+sym->size) {
-                       diag("phase error: addr=%#llx value+size=%#llx", (vlong)addr, (vlong)sym->value+sym->size);
-                       errorexit();
-               }
-               if(sym->value+sym->size >= eaddr)
-                       break;
-       }
-
-       for(; addr < eaddr; addr++)
-               cput(0);
-       cflush();
-}
-
-void
-codeblk(int64 addr, int64 size)
-{
-       LSym *sym;
-       int64 eaddr, n;
-       uchar *q;
-
-       if(debug['a'])
-               Bprint(&bso, "codeblk [%#x,%#x) at offset %#llx\n", addr, addr+size, cpos());
-
-       blk(ctxt->textp, addr, size);
-
-       /* again for printing */
-       if(!debug['a'])
-               return;
-
-       for(sym = ctxt->textp; sym != nil; sym = sym->next) {
-               if(!sym->reachable)
-                       continue;
-               if(sym->value >= addr)
-                       break;
-       }
-
-       eaddr = addr + size;
-       for(; sym != nil; sym = sym->next) {
-               if(!sym->reachable)
-                       continue;
-               if(sym->value >= eaddr)
-                       break;
-
-               if(addr < sym->value) {
-                       Bprint(&bso, "%-20s %.8llux|", "_", (vlong)addr);
-                       for(; addr < sym->value; addr++)
-                               Bprint(&bso, " %.2ux", 0);
-                       Bprint(&bso, "\n");
-               }
-
-               Bprint(&bso, "%.6llux\t%-20s\n", (vlong)addr, sym->name);
-               n = sym->size;
-               q = sym->p;
-
-               while(n >= 16) {
-                       Bprint(&bso, "%.6ux\t%-20.16I\n", addr, q);
-                       addr += 16;
-                       q += 16;
-                       n -= 16;
-               }
-               if(n > 0)
-                       Bprint(&bso, "%.6ux\t%-20.*I\n", addr, (int)n, q);
-               addr += n;
-       }
-
-       if(addr < eaddr) {
-               Bprint(&bso, "%-20s %.8llux|", "_", (vlong)addr);
-               for(; addr < eaddr; addr++)
-                       Bprint(&bso, " %.2ux", 0);
-       }
-       Bflush(&bso);
-}
-
-void
-datblk(int64 addr, int64 size)
-{
-       LSym *sym;
-       int64 i, eaddr;
-       uchar *p, *ep;
-       char *typ, *rsname;
-       Reloc *r;
-
-       if(debug['a'])
-               Bprint(&bso, "datblk [%#x,%#x) at offset %#llx\n", addr, addr+size, cpos());
-
-       blk(datap, addr, size);
-
-       /* again for printing */
-       if(!debug['a'])
-               return;
-
-       for(sym = datap; sym != nil; sym = sym->next)
-               if(sym->value >= addr)
-                       break;
-
-       eaddr = addr + size;
-       for(; sym != nil; sym = sym->next) {
-               if(sym->value >= eaddr)
-                       break;
-               if(addr < sym->value) {
-                       Bprint(&bso, "\t%.8ux| 00 ...\n", addr);
-                       addr = sym->value;
-               }
-               Bprint(&bso, "%s\n\t%.8ux|", sym->name, (uint)addr);
-               p = sym->p;
-               ep = p + sym->np;
-               while(p < ep) {
-                       if(p > sym->p && (int)(p-sym->p)%16 == 0)
-                               Bprint(&bso, "\n\t%.8ux|", (uint)(addr+(p-sym->p)));
-                       Bprint(&bso, " %.2ux", *p++);
-               }
-               addr += sym->np;
-               for(; addr < sym->value+sym->size; addr++)
-                       Bprint(&bso, " %.2ux", 0);
-               Bprint(&bso, "\n");
-               
-               if(linkmode == LinkExternal) {
-                       for(i=0; i<sym->nr; i++) {
-                               r = &sym->r[i];
-                               rsname = "";
-                               if(r->sym)
-                                       rsname = r->sym->name;
-                               typ = "?";
-                               switch(r->type) {
-                               case R_ADDR:
-                                       typ = "addr";
-                                       break;
-                               case R_PCREL:
-                                       typ = "pcrel";
-                                       break;
-                               case R_CALL:
-                                       typ = "call";
-                                       break;
-                               }
-                               Bprint(&bso, "\treloc %.8ux/%d %s %s+%#llx [%#llx]\n",
-                                       (uint)(sym->value+r->off), r->siz, typ, rsname, (vlong)r->add, (vlong)(r->sym->value+r->add));
-                       }
-               }                               
-       }
-
-       if(addr < eaddr)
-               Bprint(&bso, "\t%.8ux| 00 ...\n", (uint)addr);
-       Bprint(&bso, "\t%.8ux|\n", (uint)eaddr);
-}
-
-void
-strnput(char *s, int n)
-{
-       for(; n > 0 && *s; s++) {
-               cput(*s);
-               n--;
-       }
-       while(n > 0) {
-               cput(0);
-               n--;
-       }
-}
-
-void
-addstrdata(char *name, char *value)
-{
-       LSym *s, *sp;
-       char *p;
-       uchar reachable;
-
-       p = smprint("%s.str", name);
-       sp = linklookup(ctxt, p, 0);
-       free(p);
-       addstring(sp, value);
-       sp->type = SRODATA;
-
-       s = linklookup(ctxt, name, 0);
-       s->size = 0;
-       s->dupok = 1;
-       reachable = s->reachable;
-       addaddr(ctxt, s, sp);
-       adduintxx(ctxt, s, strlen(value), thearch.ptrsize);
-
-       // addstring, addaddr, etc., mark the symbols as reachable.
-       // In this case that is not necessarily true, so stick to what
-       // we know before entering this function.
-       s->reachable = reachable;
-       sp->reachable = reachable;
-}
-
-vlong
-addstring(LSym *s, char *str)
-{
-       int n;
-       int32 r;
-
-       if(s->type == 0)
-               s->type = SNOPTRDATA;
-       s->reachable = 1;
-       r = s->size;
-       n = strlen(str)+1;
-       if(strcmp(s->name, ".shstrtab") == 0)
-               elfsetstring(str, r);
-       symgrow(ctxt, s, r+n);
-       memmove(s->p+r, str, n);
-       s->size += n;
-       return r;
-}
-
-void
-dosymtype(void)
-{
-       LSym *s;
-
-       for(s = ctxt->allsym; s != nil; s = s->allsym) {
-               if(s->np > 0) {
-                       if(s->type == SBSS)
-                               s->type = SDATA;
-                       if(s->type == SNOPTRBSS)
-                               s->type = SNOPTRDATA;
-               }
-       }
-}
-
-static int32
-symalign(LSym *s)
-{
-       int32 align;
-
-       if(s->align != 0)
-               return s->align;
-
-       align = thearch.maxalign;
-       while(align > s->size && align > 1)
-               align >>= 1;
-       if(align < s->align)
-               align = s->align;
-       return align;
-}
-       
-static vlong
-aligndatsize(vlong datsize, LSym *s)
-{
-       return rnd(datsize, symalign(s));
-}
-
-// maxalign returns the maximum required alignment for
-// the list of symbols s; the list stops when s->type exceeds type.
-static int32
-maxalign(LSym *s, int type)
-{
-       int32 align, max;
-       
-       max = 0;
-       for(; s != nil && s->type <= type; s = s->next) {
-               align = symalign(s);
-               if(max < align)
-                       max = align;
-       }
-       return max;
-}
-
-// Helper object for building GC type programs.
-typedef struct ProgGen ProgGen;
-struct ProgGen
-{
-       LSym*   s;
-       int32   datasize;
-       uint8   data[256/PointersPerByte];
-       vlong   pos;
-};
-
-static void
-proggeninit(ProgGen *g, LSym *s)
-{
-       g->s = s;
-       g->datasize = 0;
-       g->pos = 0;
-       memset(g->data, 0, sizeof(g->data));
-}
-
-static void
-proggenemit(ProgGen *g, uint8 v)
-{
-       adduint8(ctxt, g->s, v);
-}
-
-// Writes insData block from g->data.
-static void
-proggendataflush(ProgGen *g)
-{
-       int32 i, s;
-
-       if(g->datasize == 0)
-               return;
-       proggenemit(g, insData);
-       proggenemit(g, g->datasize);
-       s = (g->datasize + PointersPerByte - 1)/PointersPerByte;
-       for(i = 0; i < s; i++)
-               proggenemit(g, g->data[i]);
-       g->datasize = 0;
-       memset(g->data, 0, sizeof(g->data));
-}
-
-static void
-proggendata(ProgGen *g, uint8 d)
-{
-       g->data[g->datasize/PointersPerByte] |= d << ((g->datasize%PointersPerByte)*BitsPerPointer);
-       g->datasize++;
-       if(g->datasize == 255)
-               proggendataflush(g);
-}
-
-// Skip v bytes due to alignment, etc.
-static void
-proggenskip(ProgGen *g, vlong off, vlong v)
-{
-       vlong i;
-
-       for(i = off; i < off+v; i++) {
-               if((i%thearch.ptrsize) == 0)
-                       proggendata(g, BitsScalar);
-       }
-}
-
-// Emit insArray instruction.
-static void
-proggenarray(ProgGen *g, vlong length)
-{
-       int32 i;
-
-       proggendataflush(g);
-       proggenemit(g, insArray);
-       for(i = 0; i < thearch.ptrsize; i++, length >>= 8)
-               proggenemit(g, length);
-}
-
-static void
-proggenarrayend(ProgGen *g)
-{
-       proggendataflush(g);
-       proggenemit(g, insArrayEnd);
-}
-
-static void
-proggenfini(ProgGen *g, vlong size)
-{
-       proggenskip(g, g->pos, size - g->pos);
-       proggendataflush(g);
-       proggenemit(g, insEnd);
-}
-
-
-// This function generates GC pointer info for global variables.
-static void
-proggenaddsym(ProgGen *g, LSym *s)
-{
-       LSym *gcprog;
-       uint8 *mask;
-       vlong i, size;
-
-       if(s->size == 0)
-               return;
-
-       // Skip alignment hole from the previous symbol.
-       proggenskip(g, g->pos, s->value - g->pos);
-       g->pos += s->value - g->pos;
-
-       // The test for names beginning with . here is meant
-       // to keep .dynamic and .dynsym from turning up as
-       // conservative symbols. They should be marked SELFSECT
-       // and not SDATA, but sometimes that doesn't happen.
-       // Leave debugging the SDATA issue for the Go rewrite.
-
-       if(s->gotype == nil && s->size >= thearch.ptrsize && s->name[0] != '.') {
-               // conservative scan
-               diag("missing Go type information for global symbol: %s size %d", s->name, (int)s->size);
-               if((s->size%thearch.ptrsize) || (g->pos%thearch.ptrsize))
-                       diag("proggenaddsym: unaligned conservative symbol %s: size=%lld pos=%lld",
-                               s->name, s->size, g->pos);
-               size = (s->size+thearch.ptrsize-1)/thearch.ptrsize*thearch.ptrsize;
-               if(size < 32*thearch.ptrsize) {
-                       // Emit small symbols as data.
-                       for(i = 0; i < size/thearch.ptrsize; i++)
-                               proggendata(g, BitsPointer);
-               } else {
-                       // Emit large symbols as array.
-                       proggenarray(g, size/thearch.ptrsize);
-                       proggendata(g, BitsPointer);
-                       proggenarrayend(g);
-               }
-               g->pos = s->value + size;
-       } else if(s->gotype == nil || decodetype_noptr(s->gotype) || s->size < thearch.ptrsize || s->name[0] == '.') {
-               // no scan
-               if(s->size < 32*thearch.ptrsize) {
-                       // Emit small symbols as data.
-                       // This case also handles unaligned and tiny symbols, so tread carefully.
-                       for(i = s->value; i < s->value+s->size; i++) {
-                               if((i%thearch.ptrsize) == 0)
-                                       proggendata(g, BitsScalar);
-                       }
-               } else {
-                       // Emit large symbols as array.
-                       if((s->size%thearch.ptrsize) || (g->pos%thearch.ptrsize))
-                               diag("proggenaddsym: unaligned noscan symbol %s: size=%lld pos=%lld",
-                                       s->name, s->size, g->pos);
-                       proggenarray(g, s->size/thearch.ptrsize);
-                       proggendata(g, BitsScalar);
-                       proggenarrayend(g);
-               }
-               g->pos = s->value + s->size;
-       } else if(decodetype_usegcprog(s->gotype)) {
-               // gc program, copy directly
-               proggendataflush(g);
-               gcprog = decodetype_gcprog(s->gotype);
-               size = decodetype_size(s->gotype);
-               if((size%thearch.ptrsize) || (g->pos%thearch.ptrsize))
-                       diag("proggenaddsym: unaligned gcprog symbol %s: size=%lld pos=%lld",
-                               s->name, s->size, g->pos);
-               for(i = 0; i < gcprog->np-1; i++)
-                       proggenemit(g, gcprog->p[i]);
-               g->pos = s->value + size;
-       } else {
-               // gc mask, it's small so emit as data
-               mask = decodetype_gcmask(s->gotype);
-               size = decodetype_size(s->gotype);
-               if((size%thearch.ptrsize) || (g->pos%thearch.ptrsize))
-                       diag("proggenaddsym: unaligned gcmask symbol %s: size=%lld pos=%lld",
-                               s->name, s->size, g->pos);
-               for(i = 0; i < size; i += thearch.ptrsize)
-                       proggendata(g, (mask[i/thearch.ptrsize/2]>>((i/thearch.ptrsize%2)*4+2))&BitsMask);
-               g->pos = s->value + size;
-       }
-}
-
-void
-growdatsize(vlong *datsizep, LSym *s)
-{
-       vlong datsize;
-       
-       datsize = *datsizep;
-       if(s->size < 0)
-               diag("negative size (datsize = %lld, s->size = %lld)", datsize, s->size);
-       if(datsize + s->size < datsize)
-               diag("symbol too large (datsize = %lld, s->size = %lld)", datsize, s->size);
-       *datsizep = datsize + s->size;
-}
-
-void
-dodata(void)
-{
-       int32 n;
-       vlong datsize;
-       Section *sect;
-       Segment *segro;
-       LSym *s, *last, **l, *toc;
-       LSym *gcdata, *gcbss;
-       ProgGen gen;
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f dodata\n", cputime());
-       Bflush(&bso);
-
-       last = nil;
-       datap = nil;
-
-       for(s=ctxt->allsym; s!=nil; s=s->allsym) {
-               if(!s->reachable || s->special)
-                       continue;
-               if(STEXT < s->type && s->type < SXREF) {
-                       if(s->onlist)
-                               sysfatal("symbol %s listed multiple times", s->name);
-                       s->onlist = 1;
-                       if(last == nil)
-                               datap = s;
-                       else
-                               last->next = s;
-                       s->next = nil;
-                       last = s;
-               }
-       }
-
-       for(s = datap; s != nil; s = s->next) {
-               if(s->np > s->size)
-                       diag("%s: initialize bounds (%lld < %d)",
-                               s->name, (vlong)s->size, s->np);
-       }
-
-
-       /*
-        * now that we have the datap list, but before we start
-        * to assign addresses, record all the necessary
-        * dynamic relocations.  these will grow the relocation
-        * symbol, which is itself data.
-        *
-        * on darwin, we need the symbol table numbers for dynreloc.
-        */
-       if(HEADTYPE == Hdarwin)
-               machosymorder();
-       dynreloc();
-
-       /* some symbols may no longer belong in datap (Mach-O) */
-       for(l=&datap; (s=*l) != nil; ) {
-               if(s->type <= STEXT || SXREF <= s->type)
-                       *l = s->next;
-               else
-                       l = &s->next;
-       }
-       *l = nil;
-
-       datap = listsort(datap, datcmp, listnextp);
-
-       /*
-        * allocate sections.  list is sorted by type,
-        * so we can just walk it for each piece we want to emit.
-        * segdata is processed before segtext, because we need
-        * to see all symbols in the .data and .bss sections in order
-        * to generate garbage collection information.
-        */
-
-       /* begin segdata */
-
-       /* skip symbols belonging to segtext */
-       s = datap;
-       for(; s != nil && s->type < SELFSECT; s = s->next)
-               ;
-
-       /* writable ELF sections */
-       datsize = 0;
-       for(; s != nil && s->type < SELFGOT; s = s->next) {
-               sect = addsection(&segdata, s->name, 06);
-               sect->align = symalign(s);
-               datsize = rnd(datsize, sect->align);
-               sect->vaddr = datsize;
-               s->sect = sect;
-               s->type = SDATA;
-               s->value = datsize - sect->vaddr;
-               growdatsize(&datsize, s);
-               sect->length = datsize - sect->vaddr;
-       }
-
-       /* .got (and .toc on ppc64) */
-       if(s->type == SELFGOT) {
-               sect = addsection(&segdata, ".got", 06);
-               sect->align = maxalign(s, SELFGOT);
-               datsize = rnd(datsize, sect->align);
-               sect->vaddr = datsize;
-               for(; s != nil && s->type == SELFGOT; s = s->next) {
-                       datsize = aligndatsize(datsize, s);
-                       s->sect = sect;
-                       s->type = SDATA;
-                       s->value = datsize - sect->vaddr;
-
-                       // Resolve .TOC. symbol for this object file (ppc64)
-                       toc = linkrlookup(ctxt, ".TOC.", s->version);
-                       if(toc != nil) {
-                               toc->sect = sect;
-                               toc->outer = s;
-                               toc->sub = s->sub;
-                               s->sub = toc;
-
-                               toc->value = 0x8000;
-                       }
-                       growdatsize(&datsize, s);
-               }
-               sect->length = datsize - sect->vaddr;
-       }
-
-       /* pointer-free data */
-       sect = addsection(&segdata, ".noptrdata", 06);
-       sect->align = maxalign(s, SINITARR-1);
-       datsize = rnd(datsize, sect->align);
-       sect->vaddr = datsize;
-       linklookup(ctxt, "runtime.noptrdata", 0)->sect = sect;
-       linklookup(ctxt, "runtime.enoptrdata", 0)->sect = sect;
-       for(; s != nil && s->type < SINITARR; s = s->next) {
-               datsize = aligndatsize(datsize, s);
-               s->sect = sect;
-               s->type = SDATA;
-               s->value = datsize - sect->vaddr;
-               growdatsize(&datsize, s);
-       }
-       sect->length = datsize - sect->vaddr;
-
-       /* shared library initializer */
-       if(flag_shared) {
-               sect = addsection(&segdata, ".init_array", 06);
-               sect->align = maxalign(s, SINITARR);
-               datsize = rnd(datsize, sect->align);
-               sect->vaddr = datsize;
-               for(; s != nil && s->type == SINITARR; s = s->next) {
-                       datsize = aligndatsize(datsize, s);
-                       s->sect = sect;
-                       s->value = datsize - sect->vaddr;
-                       growdatsize(&datsize, s);
-               }
-               sect->length = datsize - sect->vaddr;
-       }
-
-       /* data */
-       sect = addsection(&segdata, ".data", 06);
-       sect->align = maxalign(s, SBSS-1);
-       datsize = rnd(datsize, sect->align);
-       sect->vaddr = datsize;
-       linklookup(ctxt, "runtime.data", 0)->sect = sect;
-       linklookup(ctxt, "runtime.edata", 0)->sect = sect;
-       gcdata = linklookup(ctxt, "runtime.gcdata", 0);
-       proggeninit(&gen, gcdata);
-       for(; s != nil && s->type < SBSS; s = s->next) {
-               if(s->type == SINITARR) {
-                       ctxt->cursym = s;
-                       diag("unexpected symbol type %d", s->type);
-               }
-               s->sect = sect;
-               s->type = SDATA;
-               datsize = aligndatsize(datsize, s);
-               s->value = datsize - sect->vaddr;
-               proggenaddsym(&gen, s);  // gc
-               growdatsize(&datsize, s);
-       }
-       sect->length = datsize - sect->vaddr;
-       proggenfini(&gen, sect->length);  // gc
-
-       /* bss */
-       sect = addsection(&segdata, ".bss", 06);
-       sect->align = maxalign(s, SNOPTRBSS-1);
-       datsize = rnd(datsize, sect->align);
-       sect->vaddr = datsize;
-       linklookup(ctxt, "runtime.bss", 0)->sect = sect;
-       linklookup(ctxt, "runtime.ebss", 0)->sect = sect;
-       gcbss = linklookup(ctxt, "runtime.gcbss", 0);
-       proggeninit(&gen, gcbss);
-       for(; s != nil && s->type < SNOPTRBSS; s = s->next) {
-               s->sect = sect;
-               datsize = aligndatsize(datsize, s);
-               s->value = datsize - sect->vaddr;
-               proggenaddsym(&gen, s);  // gc
-               growdatsize(&datsize, s);
-       }
-       sect->length = datsize - sect->vaddr;
-       proggenfini(&gen, sect->length);  // gc
-
-       /* pointer-free bss */
-       sect = addsection(&segdata, ".noptrbss", 06);
-       sect->align = maxalign(s, SNOPTRBSS);
-       datsize = rnd(datsize, sect->align);
-       sect->vaddr = datsize;
-       linklookup(ctxt, "runtime.noptrbss", 0)->sect = sect;
-       linklookup(ctxt, "runtime.enoptrbss", 0)->sect = sect;
-       for(; s != nil && s->type == SNOPTRBSS; s = s->next) {
-               datsize = aligndatsize(datsize, s);
-               s->sect = sect;
-               s->value = datsize - sect->vaddr;
-               growdatsize(&datsize, s);
-       }
-       sect->length = datsize - sect->vaddr;
-       linklookup(ctxt, "runtime.end", 0)->sect = sect;
-
-       // 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
-       if(datsize != (uint32)datsize) {
-               diag("data or bss segment too large");
-       }
-       
-       if(iself && linkmode == LinkExternal && s != nil && s->type == STLSBSS && HEADTYPE != Hopenbsd) {
-               sect = addsection(&segdata, ".tbss", 06);
-               sect->align = thearch.ptrsize;
-               sect->vaddr = 0;
-               datsize = 0;
-               for(; s != nil && s->type == STLSBSS; s = s->next) {
-                       datsize = aligndatsize(datsize, s);
-                       s->sect = sect;
-                       s->value = datsize - sect->vaddr;
-                       growdatsize(&datsize, s);
-               }
-               sect->length = datsize;
-       } else {
-               // Might be internal linking but still using cgo.
-               // In that case, the only possible STLSBSS symbol is runtime.tlsg.
-               // Give it offset 0, because it's the only thing here.
-               if(s != nil && s->type == STLSBSS && strcmp(s->name, "runtime.tlsg") == 0) {
-                       s->value = 0;
-                       s = s->next;
-               }
-       }
-       
-       if(s != nil) {
-               ctxt->cursym = nil;
-               diag("unexpected symbol type %d for %s", s->type, s->name);
-       }
-
-       /*
-        * We finished data, begin read-only data.
-        * Not all systems support a separate read-only non-executable data section.
-        * ELF systems do.
-        * OS X and Plan 9 do not.
-        * Windows PE may, but if so we have not implemented it.
-        * And if we're using external linking mode, the point is moot,
-        * since it's not our decision; that code expects the sections in
-        * segtext.
-        */
-       if(iself && linkmode == LinkInternal)
-               segro = &segrodata;
-       else
-               segro = &segtext;
-
-       s = datap;
-       
-       datsize = 0;
-       
-       /* read-only executable ELF, Mach-O sections */
-       for(; s != nil && s->type < STYPE; s = s->next) {
-               sect = addsection(&segtext, s->name, 04);
-               sect->align = symalign(s);
-               datsize = rnd(datsize, sect->align);
-               sect->vaddr = datsize;
-               s->sect = sect;
-               s->type = SRODATA;
-               s->value = datsize - sect->vaddr;
-               growdatsize(&datsize, s);
-               sect->length = datsize - sect->vaddr;
-       }
-
-       /* read-only data */
-       sect = addsection(segro, ".rodata", 04);
-       sect->align = maxalign(s, STYPELINK-1);
-       datsize = rnd(datsize, sect->align);
-       sect->vaddr = 0;
-       linklookup(ctxt, "runtime.rodata", 0)->sect = sect;
-       linklookup(ctxt, "runtime.erodata", 0)->sect = sect;
-       for(; s != nil && s->type < STYPELINK; s = s->next) {
-               datsize = aligndatsize(datsize, s);
-               s->sect = sect;
-               s->type = SRODATA;
-               s->value = datsize - sect->vaddr;
-               growdatsize(&datsize, s);
-       }
-       sect->length = datsize - sect->vaddr;
-
-       /* typelink */
-       sect = addsection(segro, ".typelink", 04);
-       sect->align = maxalign(s, STYPELINK);
-       datsize = rnd(datsize, sect->align);
-       sect->vaddr = datsize;
-       linklookup(ctxt, "runtime.typelink", 0)->sect = sect;
-       linklookup(ctxt, "runtime.etypelink", 0)->sect = sect;
-       for(; s != nil && s->type == STYPELINK; s = s->next) {
-               datsize = aligndatsize(datsize, s);
-               s->sect = sect;
-               s->type = SRODATA;
-               s->value = datsize - sect->vaddr;
-               growdatsize(&datsize, s);
-       }
-       sect->length = datsize - sect->vaddr;
-
-       /* gosymtab */
-       sect = addsection(segro, ".gosymtab", 04);
-       sect->align = maxalign(s, SPCLNTAB-1);
-       datsize = rnd(datsize, sect->align);
-       sect->vaddr = datsize;
-       linklookup(ctxt, "runtime.symtab", 0)->sect = sect;
-       linklookup(ctxt, "runtime.esymtab", 0)->sect = sect;
-       for(; s != nil && s->type < SPCLNTAB; s = s->next) {
-               datsize = aligndatsize(datsize, s);
-               s->sect = sect;
-               s->type = SRODATA;
-               s->value = datsize - sect->vaddr;
-               growdatsize(&datsize, s);
-       }
-       sect->length = datsize - sect->vaddr;
-
-       /* gopclntab */
-       sect = addsection(segro, ".gopclntab", 04);
-       sect->align = maxalign(s, SELFROSECT-1);
-       datsize = rnd(datsize, sect->align);
-       sect->vaddr = datsize;
-       linklookup(ctxt, "runtime.pclntab", 0)->sect = sect;
-       linklookup(ctxt, "runtime.epclntab", 0)->sect = sect;
-       for(; s != nil && s->type < SELFROSECT; s = s->next) {
-               datsize = aligndatsize(datsize, s);
-               s->sect = sect;
-               s->type = SRODATA;
-               s->value = datsize - sect->vaddr;
-               growdatsize(&datsize, s);
-       }
-       sect->length = datsize - sect->vaddr;
-
-       /* read-only ELF, Mach-O sections */
-       for(; s != nil && s->type < SELFSECT; s = s->next) {
-               sect = addsection(segro, s->name, 04);
-               sect->align = symalign(s);
-               datsize = rnd(datsize, sect->align);
-               sect->vaddr = datsize;
-               s->sect = sect;
-               s->type = SRODATA;
-               s->value = datsize - sect->vaddr;
-               growdatsize(&datsize, s);
-               sect->length = datsize - sect->vaddr;
-       }
-
-       // 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
-       if(datsize != (uint32)datsize) {
-               diag("read-only data segment too large");
-       }
-       
-       /* number the sections */
-       n = 1;
-       for(sect = segtext.sect; sect != nil; sect = sect->next)
-               sect->extnum = n++;
-       for(sect = segrodata.sect; sect != nil; sect = sect->next)
-               sect->extnum = n++;
-       for(sect = segdata.sect; sect != nil; sect = sect->next)
-               sect->extnum = n++;
-}
-
-// assign addresses to text
-void
-textaddress(void)
-{
-       uvlong va;
-       Section *sect;
-       LSym *sym, *sub;
-
-       addsection(&segtext, ".text", 05);
-
-       // Assign PCs in text segment.
-       // Could parallelize, by assigning to text
-       // and then letting threads copy down, but probably not worth it.
-       sect = segtext.sect;
-       sect->align = funcalign;
-       linklookup(ctxt, "runtime.text", 0)->sect = sect;
-       linklookup(ctxt, "runtime.etext", 0)->sect = sect;
-       va = INITTEXT;
-       sect->vaddr = va;
-       for(sym = ctxt->textp; sym != nil; sym = sym->next) {
-               sym->sect = sect;
-               if(sym->type & SSUB)
-                       continue;
-               if(sym->align != 0)
-                       va = rnd(va, sym->align);
-               else
-                       va = rnd(va, funcalign);
-               sym->value = 0;
-               for(sub = sym; sub != nil; sub = sub->sub)
-                       sub->value += va;
-               if(sym->size == 0 && sym->sub != nil)
-                       ctxt->cursym = sym;
-               if(sym->size < MINFUNC)
-                       va += MINFUNC; // spacing required for findfunctab
-               else
-                       va += sym->size;
-       }
-       sect->length = va - sect->vaddr;
-}
-
-// assign addresses
-void
-address(void)
-{
-       Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr, *bss, *noptrbss;
-       Section *typelink;
-       LSym *sym, *sub;
-       uvlong va;
-       vlong vlen;
-
-       va = INITTEXT;
-       segtext.rwx = 05;
-       segtext.vaddr = va;
-       segtext.fileoff = HEADR;
-       for(s=segtext.sect; s != nil; s=s->next) {
-               va = rnd(va, s->align);
-               s->vaddr = va;
-               va += s->length;
-       }
-       segtext.length = va - INITTEXT;
-       segtext.filelen = segtext.length;
-       if(HEADTYPE == Hnacl)
-               va += 32; // room for the "halt sled"
-
-       if(segrodata.sect != nil) {
-               // align to page boundary so as not to mix
-               // rodata and executable text.
-               va = rnd(va, INITRND);
-
-               segrodata.rwx = 04;
-               segrodata.vaddr = va;
-               segrodata.fileoff = va - segtext.vaddr + segtext.fileoff;
-               segrodata.filelen = 0;
-               for(s=segrodata.sect; s != nil; s=s->next) {
-                       va = rnd(va, s->align);
-                       s->vaddr = va;
-                       va += s->length;
-               }
-               segrodata.length = va - segrodata.vaddr;
-               segrodata.filelen = segrodata.length;
-       }
-
-       va = rnd(va, INITRND);
-       segdata.rwx = 06;
-       segdata.vaddr = va;
-       segdata.fileoff = va - segtext.vaddr + segtext.fileoff;
-       segdata.filelen = 0;
-       if(HEADTYPE == Hwindows)
-               segdata.fileoff = segtext.fileoff + rnd(segtext.length, PEFILEALIGN);
-       if(HEADTYPE == Hplan9)
-               segdata.fileoff = segtext.fileoff + segtext.filelen;
-       data = nil;
-       noptr = nil;
-       bss = nil;
-       noptrbss = nil;
-       for(s=segdata.sect; s != nil; s=s->next) {
-               vlen = s->length;
-               if(s->next)
-                       vlen = s->next->vaddr - s->vaddr;
-               s->vaddr = va;
-               va += vlen;
-               segdata.length = va - segdata.vaddr;
-               if(strcmp(s->name, ".data") == 0)
-                       data = s;
-               if(strcmp(s->name, ".noptrdata") == 0)
-                       noptr = s;
-               if(strcmp(s->name, ".bss") == 0)
-                       bss = s;
-               if(strcmp(s->name, ".noptrbss") == 0)
-                       noptrbss = s;
-       }
-       segdata.filelen = bss->vaddr - segdata.vaddr;
-
-       text = segtext.sect;
-       if(segrodata.sect)
-               rodata = segrodata.sect;
-       else
-               rodata = text->next;
-       typelink = rodata->next;
-       symtab = typelink->next;
-       pclntab = symtab->next;
-
-       for(sym = datap; sym != nil; sym = sym->next) {
-               ctxt->cursym = sym;
-               if(sym->sect != nil)
-                       sym->value += ((Section*)sym->sect)->vaddr;
-               for(sub = sym->sub; sub != nil; sub = sub->sub)
-                       sub->value += sym->value;
-       }
-
-       xdefine("runtime.text", STEXT, text->vaddr);
-       xdefine("runtime.etext", STEXT, text->vaddr + text->length);
-       xdefine("runtime.rodata", SRODATA, rodata->vaddr);
-       xdefine("runtime.erodata", SRODATA, rodata->vaddr + rodata->length);
-       xdefine("runtime.typelink", SRODATA, typelink->vaddr);
-       xdefine("runtime.etypelink", SRODATA, typelink->vaddr + typelink->length);
-
-       sym = linklookup(ctxt, "runtime.gcdata", 0);
-       xdefine("runtime.egcdata", SRODATA, symaddr(sym) + sym->size);
-       linklookup(ctxt, "runtime.egcdata", 0)->sect = sym->sect;
-
-       sym = linklookup(ctxt, "runtime.gcbss", 0);
-       xdefine("runtime.egcbss", SRODATA, symaddr(sym) + sym->size);
-       linklookup(ctxt, "runtime.egcbss", 0)->sect = sym->sect;
-
-       xdefine("runtime.symtab", SRODATA, symtab->vaddr);
-       xdefine("runtime.esymtab", SRODATA, symtab->vaddr + symtab->length);
-       xdefine("runtime.pclntab", SRODATA, pclntab->vaddr);
-       xdefine("runtime.epclntab", SRODATA, pclntab->vaddr + pclntab->length);
-       xdefine("runtime.noptrdata", SNOPTRDATA, noptr->vaddr);
-       xdefine("runtime.enoptrdata", SNOPTRDATA, noptr->vaddr + noptr->length);
-       xdefine("runtime.bss", SBSS, bss->vaddr);
-       xdefine("runtime.ebss", SBSS, bss->vaddr + bss->length);
-       xdefine("runtime.data", SDATA, data->vaddr);
-       xdefine("runtime.edata", SDATA, data->vaddr + data->length);
-       xdefine("runtime.noptrbss", SNOPTRBSS, noptrbss->vaddr);
-       xdefine("runtime.enoptrbss", SNOPTRBSS, noptrbss->vaddr + noptrbss->length);
-       xdefine("runtime.end", SBSS, segdata.vaddr + segdata.length);
-}
diff --git a/src/cmd/ld/decodesym.c b/src/cmd/ld/decodesym.c
deleted file mode 100644 (file)
index e320e0f..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-// 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       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-#include       "lib.h"
-#include       "../../runtime/typekind.h"
-
-// Decoding the type.* symbols.         This has to be in sync with
-// ../../runtime/type.go, or more specifically, with what
-// ../gc/reflect.c stuffs in these.
-
-static Reloc*
-decode_reloc(LSym *s, int32 off)
-{
-       int i;
-
-       for (i = 0; i < s->nr; i++)
-               if (s->r[i].off == off)
-                       return s->r + i;
-       return nil;
-}
-
-static LSym*
-decode_reloc_sym(LSym *s, int32 off)
-{
-       Reloc *r;
-
-       r = decode_reloc(s,off);
-       if (r == nil)
-               return nil;
-       return r->sym;
-}
-
-static uvlong
-decode_inuxi(uchar* p, int sz)
-{
-       uint64 v;
-       uint32 l;
-       uchar *cast, *inuxi;
-       int i;
-
-       v = l = 0;
-       cast = nil;
-       inuxi = nil;
-       switch (sz) {
-       case 2:
-               cast = (uchar*)&l;
-               inuxi = inuxi2;
-               break;
-       case 4:
-               cast = (uchar*)&l;
-               inuxi = inuxi4;
-               break;
-       case 8:
-               cast = (uchar*)&v;
-               inuxi = inuxi8;
-               break;
-       default:
-               diag("dwarf: decode inuxi %d", sz);
-               errorexit();
-       }
-       for (i = 0; i < sz; i++)
-               cast[inuxi[i]] = p[i];
-       if (sz == 8)
-               return v;
-       return l;
-}
-
-static int
-commonsize(void)
-{
-       return 8*thearch.ptrsize + 8;
-}
-
-// Type.commonType.kind
-uint8
-decodetype_kind(LSym *s)
-{
-       return s->p[1*thearch.ptrsize + 7] & KindMask;  //  0x13 / 0x1f
-}
-
-// Type.commonType.kind
-uint8
-decodetype_noptr(LSym *s)
-{
-       return s->p[1*thearch.ptrsize + 7] & KindNoPointers;    //  0x13 / 0x1f
-}
-
-// Type.commonType.kind
-uint8
-decodetype_usegcprog(LSym *s)
-{
-       return s->p[1*thearch.ptrsize + 7] & KindGCProg;        //  0x13 / 0x1f
-}
-
-// Type.commonType.size
-vlong
-decodetype_size(LSym *s)
-{
-       return decode_inuxi(s->p, thearch.ptrsize);      // 0x8 / 0x10
-}
-
-// Type.commonType.gc
-LSym*
-decodetype_gcprog(LSym *s)
-{
-       return decode_reloc_sym(s, 1*thearch.ptrsize + 8 + 2*thearch.ptrsize);
-}
-
-uint8*
-decodetype_gcmask(LSym *s)
-{
-       LSym *mask;
-       
-       mask = decode_reloc_sym(s, 1*thearch.ptrsize + 8 + 1*thearch.ptrsize);
-       return mask->p;
-}
-
-// Type.ArrayType.elem and Type.SliceType.Elem
-LSym*
-decodetype_arrayelem(LSym *s)
-{
-       return decode_reloc_sym(s, commonsize());       // 0x1c / 0x30
-}
-
-vlong
-decodetype_arraylen(LSym *s)
-{
-       return decode_inuxi(s->p + commonsize()+2*thearch.ptrsize, thearch.ptrsize);
-}
-
-// Type.PtrType.elem
-LSym*
-decodetype_ptrelem(LSym *s)
-{
-       return decode_reloc_sym(s, commonsize());       // 0x1c / 0x30
-}
-
-// Type.MapType.key, elem
-LSym*
-decodetype_mapkey(LSym *s)
-{
-       return decode_reloc_sym(s, commonsize());       // 0x1c / 0x30
-}
-
-LSym*
-decodetype_mapvalue(LSym *s)
-{
-       return decode_reloc_sym(s, commonsize()+thearch.ptrsize);       // 0x20 / 0x38
-}
-
-// Type.ChanType.elem
-LSym*
-decodetype_chanelem(LSym *s)
-{
-       return decode_reloc_sym(s, commonsize());       // 0x1c / 0x30
-}
-
-// Type.FuncType.dotdotdot
-int
-decodetype_funcdotdotdot(LSym *s)
-{
-       return s->p[commonsize()];
-}
-
-// Type.FuncType.in.length
-int
-decodetype_funcincount(LSym *s)
-{
-       return decode_inuxi(s->p + commonsize()+2*thearch.ptrsize, thearch.intsize);
-}
-
-int
-decodetype_funcoutcount(LSym *s)
-{
-       return decode_inuxi(s->p + commonsize()+3*thearch.ptrsize + 2*thearch.intsize, thearch.intsize);
-}
-
-LSym*
-decodetype_funcintype(LSym *s, int i)
-{
-       Reloc *r;
-
-       r = decode_reloc(s, commonsize() + thearch.ptrsize);
-       if (r == nil)
-               return nil;
-       return decode_reloc_sym(r->sym, r->add + i * thearch.ptrsize);
-}
-
-LSym*
-decodetype_funcouttype(LSym *s, int i)
-{
-       Reloc *r;
-
-       r = decode_reloc(s, commonsize() + 2*thearch.ptrsize + 2*thearch.intsize);
-       if (r == nil)
-               return nil;
-       return decode_reloc_sym(r->sym, r->add + i * thearch.ptrsize);
-}
-
-// Type.StructType.fields.Slice::length
-int
-decodetype_structfieldcount(LSym *s)
-{
-       return decode_inuxi(s->p + commonsize() + thearch.ptrsize, thearch.intsize);
-}
-
-static int
-structfieldsize(void)
-{
-       return 5*thearch.ptrsize;
-}
-
-// Type.StructType.fields[]-> name, typ and offset.
-char*
-decodetype_structfieldname(LSym *s, int i)
-{
-       Reloc *r;
-
-       // go.string."foo"  0x28 / 0x40
-       s = decode_reloc_sym(s, commonsize() + thearch.ptrsize + 2*thearch.intsize + i*structfieldsize());
-       if (s == nil)                   // embedded structs have a nil name.
-               return nil;
-       r = decode_reloc(s, 0);         // s has a pointer to the string data at offset 0
-       if (r == nil)                   // shouldn't happen.
-               return nil;
-       return (char*) r->sym->p + r->add;      // the c-string
-}
-
-LSym*
-decodetype_structfieldtype(LSym *s, int i)
-{
-       return decode_reloc_sym(s, commonsize() + thearch.ptrsize + 2*thearch.intsize + i*structfieldsize() + 2*thearch.ptrsize);
-}
-
-vlong
-decodetype_structfieldoffs(LSym *s, int i)
-{
-       return decode_inuxi(s->p + commonsize() + thearch.ptrsize + 2*thearch.intsize + i*structfieldsize() + 4*thearch.ptrsize, thearch.intsize);
-}
-
-// InterfaceTYpe.methods.length
-vlong
-decodetype_ifacemethodcount(LSym *s)
-{
-       return decode_inuxi(s->p + commonsize() + thearch.ptrsize, thearch.intsize);
-}
diff --git a/src/cmd/ld/doc.go b/src/cmd/ld/doc.go
deleted file mode 100644 (file)
index ad35df7..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-// 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.
-
-// +build ignore
-
-/*
-
-Ld is the portable code for a modified version of the Plan 9 linker.  The original is documented at
-
-       http://plan9.bell-labs.com/magic/man2html/1/8l
-
-It reads object files (.5, .6, .8, .9 files) and writes a binary named for the
-architecture (5.out, 6.out, 8.out, 9.out) by default (if $GOOS is windows, a .exe suffix
-will be appended).
-
-Major changes include:
-       - support for ELF, Mach-O and PE binary files
-       - support for segmented stacks (this feature is implemented here, not in the compilers).
-
-Original options are listed on the manual page linked above.
-
-Usage:
-       go tool 6l [flags] mainObj
-Substitute 6l with 5l, 8l or 9l as appropriate.
-
-Options new in this version:
-
-       -d
-               Elide the dynamic linking header.  With this option, the binary
-               is statically linked and does not refer to a dynamic linker.  Without this option
-               (the default), the binary's contents are identical but it is loaded with a dynamic
-               linker. This flag cannot be used when $GOOS is windows.
-       -H darwin     (only in 6l/8l)
-               Write Apple Mach-O binaries (default when $GOOS is darwin)
-       -H dragonfly  (only in 6l/8l)
-               Write DragonFly ELF binaries (default when $GOOS is dragonfly)
-       -H linux
-               Write Linux ELF binaries (default when $GOOS is linux)
-       -H freebsd
-               Write FreeBSD ELF binaries (default when $GOOS is freebsd)
-       -H netbsd
-               Write NetBSD ELF binaries (default when $GOOS is netbsd)
-       -H openbsd    (only in 6l/8l)
-               Write OpenBSD ELF binaries (default when $GOOS is openbsd)
-       -H solaris    (only in 6l)
-               Write Solaris ELF binaries (default when $GOOS is solaris)
-       -H windows    (only in 6l/8l)
-               Write Windows PE32+ Console binaries (default when $GOOS is windows)
-       -H windowsgui (only in 6l/8l)
-               Write Windows PE32+ GUI binaries
-       -I interpreter
-               Set the ELF dynamic linker to use.
-       -L dir1 -L dir2
-               Search for libraries (package files) in dir1, dir2, etc.
-               The default is the single location $GOROOT/pkg/$GOOS_$GOARCH.
-       -r dir1:dir2:...
-               Set the dynamic linker search path when using ELF.
-       -s
-               Omit the symbol table and debug information.
-       -V
-               Print the linker version.
-       -w
-               Omit the DWARF symbol table.
-       -X symbol value
-               Set the value of a string variable. The symbol name
-               should be of the form importpath.name, as displayed
-               in the symbol table printed by "go tool nm".
-       -race
-               Link with race detection libraries.
-       -B value
-               Add a NT_GNU_BUILD_ID note when using ELF.  The value
-               should start with 0x and be an even number of hex digits.
-       -Z
-               Zero stack on function entry. This is expensive but it might
-               be useful in cases where you are suffering from false positives
-               during garbage collection and are willing to trade the CPU time
-               for getting rid of the false positives.
-               NOTE: it only eliminates false positives caused by other function
-               calls, not false positives caused by dead temporaries stored in
-               the current function call.
-       -linkmode argument
-               Set the linkmode.  The argument must be one of
-               internal, external, or auto.  The default is auto.
-               This sets the linking mode as described in
-               ../cgo/doc.go.
-       -tmpdir dir
-               Set the location to use for any temporary files.  The
-               default is a newly created directory that is removed
-               after the linker completes.  Temporary files are only
-               used in external linking mode.
-       -extld name
-               Set the name of the external linker to use in external
-               linking mode.  The default is "gcc".
-       -extldflags flags
-               Set space-separated trailing flags to pass to the
-               external linker in external linking mode.  The default
-               is to not pass any additional trailing flags.
-*/
-package main
diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c
deleted file mode 100644 (file)
index d3be409..0000000
+++ /dev/null
@@ -1,2498 +0,0 @@
-// Copyright 2010 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.
-
-// TODO/NICETOHAVE:
-//   - eliminate DW_CLS_ if not used
-//   - package info in compilation units
-//   - assign global variables and types to their packages
-//   - gdb uses c syntax, meaning clumsy quoting is needed for go identifiers. eg
-//     ptype struct '[]uint8' and qualifiers need to be quoted away
-//   - lexical scoping is lost, so gdb gets confused as to which 'main.i' you mean.
-//   - file:line info for variables
-//   - make strings a typedef so prettyprinters can see the underlying string type
-//
-#include       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-#include       "lib.h"
-#include       "dwarf.h"
-#include       "dwarf_defs.h"
-#include       "elf.h"
-#include       "macho.h"
-#include       "pe.h"
-#include       "../../runtime/typekind.h"
-
-/*
- * Offsets and sizes of the debug_* sections in the cout file.
- */
-
-static vlong abbrevo;
-static vlong abbrevsize;
-static LSym*  abbrevsym;
-static vlong abbrevsympos;
-static vlong lineo;
-static vlong linesize;
-static LSym*  linesym;
-static vlong linesympos;
-static vlong infoo;    // also the base for DWDie->offs and reference attributes.
-static vlong infosize;
-static LSym*  infosym;
-static vlong infosympos;
-static vlong frameo;
-static vlong framesize;
-static LSym*  framesym;
-static vlong framesympos;
-static vlong pubnameso;
-static vlong pubnamessize;
-static vlong pubtypeso;
-static vlong pubtypessize;
-static vlong arangeso;
-static vlong arangessize;
-static vlong gdbscripto;
-static vlong gdbscriptsize;
-
-static LSym *infosec;
-static vlong inforeloco;
-static vlong inforelocsize;
-
-static LSym *arangessec;
-static vlong arangesreloco;
-static vlong arangesrelocsize;
-
-static LSym *linesec;
-static vlong linereloco;
-static vlong linerelocsize;
-
-static LSym *framesec;
-static vlong framereloco;
-static vlong framerelocsize;
-
-static char  gdbscript[1024];
-
-/*
- *  Basic I/O
- */
-
-static void
-addrput(vlong addr)
-{
-       switch(thearch.ptrsize) {
-       case 4:
-               thearch.lput(addr);
-               break;
-       case 8:
-               thearch.vput(addr);
-               break;
-       }
-}
-
-static int
-uleb128enc(uvlong v, char* dst)
-{
-       uint8 c, length;
-
-       length = 0;
-       do {
-               c = v & 0x7f;
-               v >>= 7;
-               if (v)
-                       c |= 0x80;
-               if (dst)
-                       *dst++ = c;
-               length++;
-       } while (c & 0x80);
-       return length;
-}
-
-static int
-sleb128enc(vlong v, char *dst)
-{
-       uint8 c, s, length;
-
-       length = 0;
-       do {
-               c = v & 0x7f;
-               s = v & 0x40;
-               v >>= 7;
-               if ((v != -1 || !s) && (v != 0 || s))
-                       c |= 0x80;
-               if (dst)
-                       *dst++ = c;
-               length++;
-       } while(c & 0x80);
-       return length;
-}
-
-static void
-uleb128put(vlong v)
-{
-       char buf[10];
-       strnput(buf, uleb128enc(v, buf));
-}
-
-static void
-sleb128put(vlong v)
-{
-       char buf[10];
-       strnput(buf, sleb128enc(v, buf));
-}
-
-/*
- * Defining Abbrevs.  This is hardcoded, and there will be
- * only a handful of them.  The DWARF spec places no restriction on
- * the ordering of attributes in the Abbrevs and DIEs, and we will
- * always write them out in the order of declaration in the abbrev.
- */
-typedef struct DWAttrForm DWAttrForm;
-struct DWAttrForm {
-       uint16 attr;
-       uint8 form;
-};
-
-// Go-specific type attributes.
-enum {
-       DW_AT_go_kind = 0x2900,
-       DW_AT_go_key = 0x2901,
-       DW_AT_go_elem = 0x2902,
-
-       DW_AT_internal_location = 253,   // params and locals; not emitted
-};
-
-// Index into the abbrevs table below.
-// Keep in sync with ispubname() and ispubtype() below.
-// ispubtype considers >= NULLTYPE public
-enum
-{
-       DW_ABRV_NULL,
-       DW_ABRV_COMPUNIT,
-       DW_ABRV_FUNCTION,
-       DW_ABRV_VARIABLE,
-       DW_ABRV_AUTO,
-       DW_ABRV_PARAM,
-       DW_ABRV_STRUCTFIELD,
-       DW_ABRV_FUNCTYPEPARAM,
-       DW_ABRV_DOTDOTDOT,
-       DW_ABRV_ARRAYRANGE,
-       DW_ABRV_NULLTYPE,
-       DW_ABRV_BASETYPE,
-       DW_ABRV_ARRAYTYPE,
-       DW_ABRV_CHANTYPE,
-       DW_ABRV_FUNCTYPE,
-       DW_ABRV_IFACETYPE,
-       DW_ABRV_MAPTYPE,
-       DW_ABRV_PTRTYPE,
-       DW_ABRV_BARE_PTRTYPE, // only for void*, no DW_AT_type attr to please gdb 6.
-       DW_ABRV_SLICETYPE,
-       DW_ABRV_STRINGTYPE,
-       DW_ABRV_STRUCTTYPE,
-       DW_ABRV_TYPEDECL,
-       DW_NABRV
-};
-
-typedef struct DWAbbrev DWAbbrev;
-static struct DWAbbrev {
-       uint8 tag;
-       uint8 children;
-       DWAttrForm attr[30];
-} abbrevs[DW_NABRV] = {
-       /* The mandatory DW_ABRV_NULL entry. */
-       { 0 },
-       /* COMPUNIT */
-       {
-               DW_TAG_compile_unit, DW_CHILDREN_yes,
-               {{DW_AT_name,    DW_FORM_string},
-               {DW_AT_language,         DW_FORM_data1},
-               {DW_AT_low_pc,   DW_FORM_addr},
-               {DW_AT_high_pc,  DW_FORM_addr},
-               {DW_AT_stmt_list, DW_FORM_data4},
-               {0, 0}}
-       },
-       /* FUNCTION */
-       {
-               DW_TAG_subprogram, DW_CHILDREN_yes,
-               {{DW_AT_name,    DW_FORM_string},
-               {DW_AT_low_pc,   DW_FORM_addr},
-               {DW_AT_high_pc,  DW_FORM_addr},
-               {DW_AT_external,         DW_FORM_flag},
-               {0, 0}}
-       },
-       /* VARIABLE */
-       {
-               DW_TAG_variable, DW_CHILDREN_no,
-               {{DW_AT_name,    DW_FORM_string},
-               {DW_AT_location,         DW_FORM_block1},
-               {DW_AT_type,     DW_FORM_ref_addr},
-               {DW_AT_external,         DW_FORM_flag},
-               {0, 0}}
-       },
-       /* AUTO */
-       {
-               DW_TAG_variable, DW_CHILDREN_no,
-               {{DW_AT_name,    DW_FORM_string},
-               {DW_AT_location,         DW_FORM_block1},
-               {DW_AT_type,     DW_FORM_ref_addr},
-               {0, 0}}
-       },
-       /* PARAM */
-       {
-               DW_TAG_formal_parameter, DW_CHILDREN_no,
-               {{DW_AT_name,    DW_FORM_string},
-               {DW_AT_location,         DW_FORM_block1},
-               {DW_AT_type,     DW_FORM_ref_addr},
-               {0, 0}}
-       },
-       /* STRUCTFIELD */
-       {
-               DW_TAG_member,  DW_CHILDREN_no,
-               {{DW_AT_name,   DW_FORM_string},
-               {DW_AT_data_member_location, DW_FORM_block1},
-               {DW_AT_type,     DW_FORM_ref_addr},
-               {0, 0}}
-       },
-       /* FUNCTYPEPARAM */
-       {
-               DW_TAG_formal_parameter, DW_CHILDREN_no,
-               // No name!
-               {{DW_AT_type,    DW_FORM_ref_addr},
-               {0, 0}}
-       },
-
-       /* DOTDOTDOT */
-       {
-               DW_TAG_unspecified_parameters, DW_CHILDREN_no,
-               {{0, 0}}
-       },
-       /* ARRAYRANGE */
-       {
-               DW_TAG_subrange_type, DW_CHILDREN_no,
-               // No name!
-               {{DW_AT_type,    DW_FORM_ref_addr},
-               {DW_AT_count, DW_FORM_udata},
-               {0, 0}}
-       },
-
-       // Below here are the types considered public by ispubtype
-       /* NULLTYPE */
-       {
-               DW_TAG_unspecified_type, DW_CHILDREN_no,
-               {{DW_AT_name,   DW_FORM_string},
-               {0, 0}}
-       },
-       /* BASETYPE */
-       {
-               DW_TAG_base_type, DW_CHILDREN_no,
-               {{DW_AT_name,    DW_FORM_string},
-               {DW_AT_encoding,         DW_FORM_data1},
-               {DW_AT_byte_size, DW_FORM_data1},
-               {DW_AT_go_kind, DW_FORM_data1},
-               {0, 0}}
-       },
-       /* ARRAYTYPE */
-       // child is subrange with upper bound
-       {
-               DW_TAG_array_type, DW_CHILDREN_yes,
-               {{DW_AT_name,   DW_FORM_string},
-               {DW_AT_type,    DW_FORM_ref_addr},
-               {DW_AT_byte_size, DW_FORM_udata},
-               {DW_AT_go_kind, DW_FORM_data1},
-               {0, 0}}
-       },
-
-       /* CHANTYPE */
-       {
-               DW_TAG_typedef, DW_CHILDREN_no,
-               {{DW_AT_name,   DW_FORM_string},
-               {DW_AT_type,    DW_FORM_ref_addr},
-               {DW_AT_go_kind, DW_FORM_data1},
-               {DW_AT_go_elem, DW_FORM_ref_addr},
-               {0, 0}}
-       },
-
-       /* FUNCTYPE */
-       {
-               DW_TAG_subroutine_type, DW_CHILDREN_yes,
-               {{DW_AT_name,   DW_FORM_string},
-//             {DW_AT_type,    DW_FORM_ref_addr},
-               {DW_AT_go_kind, DW_FORM_data1},
-               {0, 0}}
-       },
-
-       /* IFACETYPE */
-       {
-               DW_TAG_typedef, DW_CHILDREN_yes,
-               {{DW_AT_name,    DW_FORM_string},
-               {DW_AT_type,    DW_FORM_ref_addr},
-               {DW_AT_go_kind, DW_FORM_data1},
-               {0, 0}}
-       },
-
-       /* MAPTYPE */
-       {
-               DW_TAG_typedef, DW_CHILDREN_no,
-               {{DW_AT_name,   DW_FORM_string},
-               {DW_AT_type,    DW_FORM_ref_addr},
-               {DW_AT_go_kind, DW_FORM_data1},
-               {DW_AT_go_key, DW_FORM_ref_addr},
-               {DW_AT_go_elem, DW_FORM_ref_addr},
-               {0, 0}}
-       },
-
-       /* PTRTYPE */
-       {
-               DW_TAG_pointer_type, DW_CHILDREN_no,
-               {{DW_AT_name,   DW_FORM_string},
-               {DW_AT_type,    DW_FORM_ref_addr},
-               {DW_AT_go_kind, DW_FORM_data1},
-               {0, 0}}
-       },
-       /* BARE_PTRTYPE */
-       {
-               DW_TAG_pointer_type, DW_CHILDREN_no,
-               {{DW_AT_name,   DW_FORM_string},
-               {0, 0}}
-       },
-
-       /* SLICETYPE */
-       {
-               DW_TAG_structure_type, DW_CHILDREN_yes,
-               {{DW_AT_name,   DW_FORM_string},
-               {DW_AT_byte_size, DW_FORM_udata},
-               {DW_AT_go_kind, DW_FORM_data1},
-               {DW_AT_go_elem, DW_FORM_ref_addr},
-               {0, 0}}
-       },
-
-       /* STRINGTYPE */
-       {
-               DW_TAG_structure_type, DW_CHILDREN_yes,
-               {{DW_AT_name,   DW_FORM_string},
-               {DW_AT_byte_size, DW_FORM_udata},
-               {DW_AT_go_kind, DW_FORM_data1},
-               {0, 0}}
-       },
-
-       /* STRUCTTYPE */
-       {
-               DW_TAG_structure_type, DW_CHILDREN_yes,
-               {{DW_AT_name,   DW_FORM_string},
-               {DW_AT_byte_size, DW_FORM_udata},
-               {DW_AT_go_kind, DW_FORM_data1},
-               {0, 0}}
-       },
-
-       /* TYPEDECL */
-       {
-               DW_TAG_typedef, DW_CHILDREN_no,
-               {{DW_AT_name,   DW_FORM_string},
-               {DW_AT_type,    DW_FORM_ref_addr},
-               {0, 0}}
-       },
-};
-
-static void
-writeabbrev(void)
-{
-       int i, j;
-       DWAttrForm *f;
-
-       abbrevo = cpos();
-       for (i = 1; i < DW_NABRV; i++) {
-               // See section 7.5.3
-               uleb128put(i);
-               uleb128put(abbrevs[i].tag);
-               cput(abbrevs[i].children);
-               for(j=0; j<nelem(abbrevs[i].attr); j++) {
-                       f = &abbrevs[i].attr[j];
-                       uleb128put(f->attr);
-                       uleb128put(f->form);
-                       if(f->attr == 0)
-                               break;
-               }
-       }
-       cput(0);
-       abbrevsize = cpos() - abbrevo;
-}
-
-/*
- * Debugging Information Entries and their attributes.
- */
-
-enum
-{
-       HASHSIZE = 107
-};
-
-static uint32
-dwarfhashstr(char* s)
-{
-       uint32 h;
-
-       h = 0;
-       while (*s)
-               h = h+h+h + *s++;
-       return h % HASHSIZE;
-}
-
-// For DW_CLS_string and _block, value should contain the length, and
-// data the data, for _reference, value is 0 and data is a DWDie* to
-// the referenced instance, for all others, value is the whole thing
-// and data is null.
-
-typedef struct DWAttr DWAttr;
-struct DWAttr {
-       DWAttr *link;
-       uint16 atr;  // DW_AT_
-       uint8 cls;  // DW_CLS_
-       vlong value;
-       void *data;
-};
-
-typedef struct DWDie DWDie;
-struct DWDie {
-       int abbrev;
-       DWDie *link;
-       DWDie *child;
-       DWAttr *attr;
-       // offset into .debug_info section, i.e relative to
-       // infoo. only valid after call to putdie()
-       vlong offs;
-       DWDie **hash;  // optional index of children by name, enabled by mkindex()
-       DWDie *hlink;  // bucket chain in parent's index
-};
-
-/*
- * Root DIEs for compilation units, types and global variables.
- */
-
-static DWDie dwroot;
-static DWDie dwtypes;
-static DWDie dwglobals;
-
-static DWAttr*
-newattr(DWDie *die, uint16 attr, int cls, vlong value, void *data)
-{
-       DWAttr *a;
-
-       a = mal(sizeof *a);
-       a->link = die->attr;
-       die->attr = a;
-       a->atr = attr;
-       a->cls = cls;
-       a->value = value;
-       a->data = data;
-       return a;
-}
-
-// Each DIE (except the root ones) has at least 1 attribute: its
-// name. getattr moves the desired one to the front so
-// frequently searched ones are found faster.
-static DWAttr*
-getattr(DWDie *die, uint16 attr)
-{
-       DWAttr *a, *b;
-
-       if (die->attr->atr == attr)
-               return die->attr;
-
-       a = die->attr;
-       b = a->link;
-       while (b != nil) {
-               if (b->atr == attr) {
-                       a->link = b->link;
-                       b->link = die->attr;
-                       die->attr = b;
-                       return b;
-               }
-               a = b;
-               b = b->link;
-       }
-       return nil;
-}
-
-// Every DIE has at least a DW_AT_name attribute (but it will only be
-// written out if it is listed in the abbrev). If its parent is
-// keeping an index, the new DIE will be inserted there.
-static DWDie*
-newdie(DWDie *parent, int abbrev, char *name)
-{
-       DWDie *die;
-       int h;
-
-       die = mal(sizeof *die);
-       die->abbrev = abbrev;
-       die->link = parent->child;
-       parent->child = die;
-
-       newattr(die, DW_AT_name, DW_CLS_STRING, strlen(name), name);
-
-       if (parent->hash) {
-               h = dwarfhashstr(name);
-               die->hlink = parent->hash[h];
-               parent->hash[h] = die;
-       }
-
-       return die;
-}
-
-static void
-mkindex(DWDie *die)
-{
-       die->hash = mal(HASHSIZE * sizeof(DWDie*));
-}
-
-static DWDie*
-walktypedef(DWDie *die)
-{
-       DWAttr *attr;
-
-       // Resolve typedef if present.
-       if (die->abbrev == DW_ABRV_TYPEDECL) {
-               for (attr = die->attr; attr; attr = attr->link) {
-                       if (attr->atr == DW_AT_type && attr->cls == DW_CLS_REFERENCE && attr->data != nil) {
-                               return (DWDie*)attr->data;
-                       }
-               }
-       }
-       return die;
-}
-
-// Find child by AT_name using hashtable if available or linear scan
-// if not.
-static DWDie*
-find(DWDie *die, char* name)
-{
-       DWDie *a, *b, *die2;
-       int h;
-
-top:
-       if (die->hash == nil) {
-               for (a = die->child; a != nil; a = a->link)
-                       if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
-                               return a;
-               goto notfound;
-       }
-
-       h = dwarfhashstr(name);
-       a = die->hash[h];
-
-       if (a == nil)
-               goto notfound;
-
-
-       if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
-               return a;
-
-       // Move found ones to head of the list.
-       b = a->hlink;
-       while (b != nil) {
-               if (strcmp(name, getattr(b, DW_AT_name)->data) == 0) {
-                       a->hlink = b->hlink;
-                       b->hlink = die->hash[h];
-                       die->hash[h] = b;
-                       return b;
-               }
-               a = b;
-               b = b->hlink;
-       }
-
-notfound:
-       die2 = walktypedef(die);
-       if(die2 != die) {
-               die = die2;
-               goto top;
-       }
-
-       return nil;
-}
-
-static DWDie*
-find_or_diag(DWDie *die, char* name)
-{
-       DWDie *r;
-       r = find(die, name);
-       if (r == nil) {
-               diag("dwarf find: %s %p has no %s", getattr(die, DW_AT_name)->data, die, name);
-               errorexit();
-       }
-       return r;
-}
-
-static void
-adddwarfrel(LSym* sec, LSym* sym, vlong offsetbase, int siz, vlong addend)
-{
-       Reloc *r;
-
-       r = addrel(sec);
-       r->sym = sym;
-       r->xsym = sym;
-       r->off = cpos() - offsetbase;
-       r->siz = siz;
-       r->type = R_ADDR;
-       r->add = addend;
-       r->xadd = addend;
-       if(iself && thearch.thechar == '6')
-               addend = 0;
-       switch(siz) {
-       case 4:
-               thearch.lput(addend);
-               break;
-       case 8:
-               thearch.vput(addend);
-               break;
-       default:
-               diag("bad size in adddwarfrel");
-               break;
-       }
-}
-
-static DWAttr*
-newrefattr(DWDie *die, uint16 attr, DWDie* ref)
-{
-       if (ref == nil)
-               return nil;
-       return newattr(die, attr, DW_CLS_REFERENCE, 0, ref);
-}
-
-static int fwdcount;
-
-static void
-putattr(int abbrev, int form, int cls, vlong value, void *data)
-{
-       vlong off;
-       uchar *p;
-       int i;
-
-       switch(form) {
-       case DW_FORM_addr:      // address
-               if(linkmode == LinkExternal) {
-                       value -= ((LSym*)data)->value;
-                       adddwarfrel(infosec, (LSym*)data, infoo, thearch.ptrsize, value);
-                       break;
-               }
-               addrput(value);
-               break;
-
-       case DW_FORM_block1:    // block
-               if(cls == DW_CLS_ADDRESS) {
-                       cput(1+thearch.ptrsize);
-                       cput(DW_OP_addr);
-                       if(linkmode == LinkExternal) {
-                               value -= ((LSym*)data)->value;
-                               adddwarfrel(infosec, (LSym*)data, infoo, thearch.ptrsize, value);
-                               break;
-                       }
-                       addrput(value);
-                       break;
-               }
-               value &= 0xff;
-               cput(value);
-               p = data;
-               for(i=0; i<value; i++)
-                       cput(p[i]);
-               break;
-
-       case DW_FORM_block2:    // block
-               value &= 0xffff;
-               thearch.wput(value);
-               p = data;
-               for(i=0; i<value; i++)
-                       cput(p[i]);
-               break;
-
-       case DW_FORM_block4:    // block
-               value &= 0xffffffff;
-               thearch.lput(value);
-               p = data;
-               for(i=0; i<value; i++)
-                       cput(p[i]);
-               break;
-
-       case DW_FORM_block:     // block
-               uleb128put(value);
-               p = data;
-               for(i=0; i<value; i++)
-                       cput(p[i]);
-               break;
-
-       case DW_FORM_data1:     // constant
-               cput(value);
-               break;
-
-       case DW_FORM_data2:     // constant
-               thearch.wput(value);
-               break;
-
-       case DW_FORM_data4:     // constant, {line,loclist,mac,rangelist}ptr
-               if(linkmode == LinkExternal && cls == DW_CLS_PTR) {
-                       adddwarfrel(infosec, linesym, infoo, 4, value);
-                       break;
-               }
-               thearch.lput(value);
-               break;
-
-       case DW_FORM_data8:     // constant, {line,loclist,mac,rangelist}ptr
-               thearch.vput(value);
-               break;
-
-       case DW_FORM_sdata:     // constant
-               sleb128put(value);
-               break;
-
-       case DW_FORM_udata:     // constant
-               uleb128put(value);
-               break;
-
-       case DW_FORM_string:    // string
-               strnput(data, value+1);
-               break;
-
-       case DW_FORM_flag:      // flag
-               if(value) {
-                       cput(1);
-               }else{
-                       cput(0);
-               }
-               break;
-
-       case DW_FORM_ref_addr:  // reference to a DIE in the .info section
-               // In DWARF 2 (which is what we claim to generate),
-               // the ref_addr is the same size as a normal address.
-               // In DWARF 3 it is always 32 bits, unless emitting a large
-               // (> 4 GB of debug info aka "64-bit") unit, which we don't implement.
-               if (data == nil) {
-                       diag("dwarf: null reference in %d", abbrev);
-                       if(thearch.ptrsize == 8)
-                               thearch.vput(0); // invalid dwarf, gdb will complain.
-                       else
-                               thearch.lput(0); // invalid dwarf, gdb will complain.
-               } else {
-                       off = ((DWDie*)data)->offs;
-                       if (off == 0)
-                               fwdcount++;
-                       if(linkmode == LinkExternal) {
-                               adddwarfrel(infosec, infosym, infoo, thearch.ptrsize, off);
-                               break;
-                       }
-                       addrput(off);
-               }
-               break;
-
-       case DW_FORM_ref1:      // reference within the compilation unit
-       case DW_FORM_ref2:      // reference
-       case DW_FORM_ref4:      // reference
-       case DW_FORM_ref8:      // reference
-       case DW_FORM_ref_udata: // reference
-
-       case DW_FORM_strp:      // string
-       case DW_FORM_indirect:  // (see Section 7.5.3)
-       default:
-               diag("dwarf: unsupported attribute form %d / class %d", form, cls);
-               errorexit();
-       }
-}
-
-// Note that we can (and do) add arbitrary attributes to a DIE, but
-// only the ones actually listed in the Abbrev will be written out.
-static void
-putattrs(int abbrev, DWAttr* attr)
-{
-       DWAttrForm* af;
-       DWAttr *ap;
-
-       for(af = abbrevs[abbrev].attr; af->attr; af++) {
-               for(ap=attr; ap; ap=ap->link) {
-                       if(ap->atr == af->attr) {
-                               putattr(abbrev, af->form,
-                                       ap->cls,
-                                       ap->value,
-                                       ap->data);
-                               goto done;
-                       }
-               }
-               putattr(abbrev, af->form, 0, 0, nil);
-       done:;
-       }
-}
-
-static void putdie(DWDie* die);
-
-static void
-putdies(DWDie* die)
-{
-       for(; die; die = die->link)
-               putdie(die);
-}
-
-static void
-putdie(DWDie* die)
-{
-       die->offs = cpos() - infoo;
-       uleb128put(die->abbrev);
-       putattrs(die->abbrev, die->attr);
-       if (abbrevs[die->abbrev].children) {
-               putdies(die->child);
-               cput(0);
-       }
-}
-
-static void
-reverselist(DWDie** list)
-{
-       DWDie *curr, *prev;
-
-       curr = *list;
-       prev = nil;
-       while(curr != nil) {
-               DWDie* next = curr->link;
-               curr->link = prev;
-               prev = curr;
-               curr = next;
-       }
-       *list = prev;
-}
-
-static void
-reversetree(DWDie** list)
-{
-        DWDie *die;
-
-        reverselist(list);
-        for (die = *list; die != nil; die = die->link)
-                if (abbrevs[die->abbrev].children)
-                        reversetree(&die->child);
-}
-
-static void
-newmemberoffsetattr(DWDie *die, int32 offs)
-{
-       char block[10];
-       int i;
-
-       i = 0;
-       block[i++] = DW_OP_plus_uconst;
-       i += uleb128enc(offs, block+i);
-       newattr(die, DW_AT_data_member_location, DW_CLS_BLOCK, i, mal(i));
-       memmove(die->attr->data, block, i);
-}
-
-// GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a
-// location expression that evals to a const.
-static void
-newabslocexprattr(DWDie *die, vlong addr, LSym *sym)
-{
-       newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, sym);
-}
-
-static DWDie* defptrto(DWDie *dwtype); // below
-
-// Lookup predefined types
-static LSym*
-lookup_or_diag(char *n)
-{
-       LSym *s;
-
-       s = linkrlookup(ctxt, n, 0);
-       if (s == nil || s->size == 0) {
-               diag("dwarf: missing type: %s", n);
-               errorexit();
-       }
-       return s;
-}
-
-static void
-dotypedef(DWDie *parent, char *name, DWDie *def)
-{
-       DWDie *die;
-
-       // Only emit typedefs for real names.
-       if(strncmp(name, "map[", 4) == 0)
-               return;
-       if(strncmp(name, "struct {", 8) == 0)
-               return;
-       if(strncmp(name, "chan ", 5) == 0)
-               return;
-       if(*name == '[' || *name == '*')
-               return;
-       if(def == nil)
-               diag("dwarf: bad def in dotypedef");
-
-       // The typedef entry must be created after the def,
-       // so that future lookups will find the typedef instead
-       // of the real definition. This hooks the typedef into any
-       // circular definition loops, so that gdb can understand them.
-       die = newdie(parent, DW_ABRV_TYPEDECL, name);
-       newrefattr(die, DW_AT_type, def);
-}
-
-// Define gotype, for composite ones recurse into constituents.
-static DWDie*
-defgotype(LSym *gotype)
-{
-       DWDie *die, *fld;
-       LSym *s;
-       char *name, *f;
-       uint8 kind;
-       vlong bytesize;
-       int i, nfields;
-
-       if (gotype == nil)
-               return find_or_diag(&dwtypes, "<unspecified>");
-
-       if (strncmp("type.", gotype->name, 5) != 0) {
-               diag("dwarf: type name doesn't start with \".type\": %s", gotype->name);
-               return find_or_diag(&dwtypes, "<unspecified>");
-       }
-       name = gotype->name + 5;  // could also decode from Type.string
-
-       die = find(&dwtypes, name);
-       if (die != nil)
-               return die;
-
-       if (0 && debug['v'] > 2)
-               print("new type: %Y\n", gotype);
-
-       kind = decodetype_kind(gotype);
-       bytesize = decodetype_size(gotype);
-
-       switch (kind) {
-       case KindBool:
-               die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
-               newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_boolean, 0);
-               newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
-               break;
-
-       case KindInt:
-       case KindInt8:
-       case KindInt16:
-       case KindInt32:
-       case KindInt64:
-               die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
-               newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_signed, 0);
-               newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
-               break;
-
-       case KindUint:
-       case KindUint8:
-       case KindUint16:
-       case KindUint32:
-       case KindUint64:
-       case KindUintptr:
-               die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
-               newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_unsigned, 0);
-               newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
-               break;
-
-       case KindFloat32:
-       case KindFloat64:
-               die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
-               newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_float, 0);
-               newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
-               break;
-
-       case KindComplex64:
-       case KindComplex128:
-               die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
-               newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_complex_float, 0);
-               newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
-               break;
-
-       case KindArray:
-               die = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, name);
-               dotypedef(&dwtypes, name, die);
-               newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
-               s = decodetype_arrayelem(gotype);
-               newrefattr(die, DW_AT_type, defgotype(s));
-               fld = newdie(die, DW_ABRV_ARRAYRANGE, "range");
-               // use actual length not upper bound; correct for 0-length arrays.
-               newattr(fld, DW_AT_count, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0);
-               newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
-               break;
-
-       case KindChan:
-               die = newdie(&dwtypes, DW_ABRV_CHANTYPE, name);
-               newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
-               s = decodetype_chanelem(gotype);
-               newrefattr(die, DW_AT_go_elem, defgotype(s));
-               break;
-
-       case KindFunc:
-               die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name);
-               dotypedef(&dwtypes, name, die);
-               newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "void"));
-               nfields = decodetype_funcincount(gotype);
-               for (i = 0; i < nfields; i++) {
-                       s = decodetype_funcintype(gotype, i);
-                       fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s->name+5);
-                       newrefattr(fld, DW_AT_type, defgotype(s));
-               }
-               if (decodetype_funcdotdotdot(gotype))
-                       newdie(die, DW_ABRV_DOTDOTDOT, "...");
-               nfields = decodetype_funcoutcount(gotype);
-               for (i = 0; i < nfields; i++) {
-                       s = decodetype_funcouttype(gotype, i);
-                       fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s->name+5);
-                       newrefattr(fld, DW_AT_type, defptrto(defgotype(s)));
-               }
-               break;
-
-       case KindInterface:
-               die = newdie(&dwtypes, DW_ABRV_IFACETYPE, name);
-               dotypedef(&dwtypes, name, die);
-               newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
-               nfields = decodetype_ifacemethodcount(gotype);
-               if (nfields == 0)
-                       s = lookup_or_diag("type.runtime.eface");
-               else
-                       s = lookup_or_diag("type.runtime.iface");
-               newrefattr(die, DW_AT_type, defgotype(s));
-               break;
-
-       case KindMap:
-               die = newdie(&dwtypes, DW_ABRV_MAPTYPE, name);
-               s = decodetype_mapkey(gotype);
-               newrefattr(die, DW_AT_go_key, defgotype(s));
-               s = decodetype_mapvalue(gotype);
-               newrefattr(die, DW_AT_go_elem, defgotype(s));
-               break;
-
-       case KindPtr:
-               die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name);
-               dotypedef(&dwtypes, name, die);
-               s = decodetype_ptrelem(gotype);
-               newrefattr(die, DW_AT_type, defgotype(s));
-               break;
-
-       case KindSlice:
-               die = newdie(&dwtypes, DW_ABRV_SLICETYPE, name);
-               dotypedef(&dwtypes, name, die);
-               newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
-               s = decodetype_arrayelem(gotype);
-               newrefattr(die, DW_AT_go_elem, defgotype(s));
-               break;
-
-       case KindString:
-               die = newdie(&dwtypes, DW_ABRV_STRINGTYPE, name);
-               newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
-               break;
-
-       case KindStruct:
-               die = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, name);
-               dotypedef(&dwtypes, name, die);
-               newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
-               nfields = decodetype_structfieldcount(gotype);
-               for (i = 0; i < nfields; i++) {
-                       f = decodetype_structfieldname(gotype, i);
-                       s = decodetype_structfieldtype(gotype, i);
-                       if (f == nil)
-                               f = s->name + 5;         // skip "type."
-                       fld = newdie(die, DW_ABRV_STRUCTFIELD, f);
-                       newrefattr(fld, DW_AT_type, defgotype(s));
-                       newmemberoffsetattr(fld, decodetype_structfieldoffs(gotype, i));
-               }
-               break;
-
-       case KindUnsafePointer:
-               die = newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, name);
-               break;
-
-       default:
-               diag("dwarf: definition of unknown kind %d: %s", kind, gotype->name);
-               die = newdie(&dwtypes, DW_ABRV_TYPEDECL, name);
-               newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "<unspecified>"));
-       }
-
-       newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, kind, 0);
-
-       return die;
-}
-
-// Find or construct *T given T.
-static DWDie*
-defptrto(DWDie *dwtype)
-{
-       char ptrname[1024];
-       DWDie *die;
-
-       snprint(ptrname, sizeof ptrname, "*%s", getattr(dwtype, DW_AT_name)->data);
-       die = find(&dwtypes, ptrname);
-       if (die == nil) {
-               die = newdie(&dwtypes, DW_ABRV_PTRTYPE,
-                            strcpy(mal(strlen(ptrname)+1), ptrname));
-               newrefattr(die, DW_AT_type, dwtype);
-       }
-       return die;
-}
-
-// Copies src's children into dst. Copies attributes by value.
-// DWAttr.data is copied as pointer only.  If except is one of
-// the top-level children, it will not be copied.
-static void
-copychildrenexcept(DWDie *dst, DWDie *src, DWDie *except)
-{
-       DWDie *c;
-       DWAttr *a;
-
-       for (src = src->child; src != nil; src = src->link) {
-               if(src == except)
-                       continue;
-               c = newdie(dst, src->abbrev, getattr(src, DW_AT_name)->data);
-               for (a = src->attr; a != nil; a = a->link)
-                       newattr(c, a->atr, a->cls, a->value, a->data);
-               copychildrenexcept(c, src, nil);
-       }
-       reverselist(&dst->child);
-}
-static void
-copychildren(DWDie *dst, DWDie *src)
-{
-       copychildrenexcept(dst, src, nil);
-}
-
-// Search children (assumed to have DW_TAG_member) for the one named
-// field and set its DW_AT_type to dwtype
-static void
-substitutetype(DWDie *structdie, char *field, DWDie* dwtype)
-{
-       DWDie *child;
-       DWAttr *a;
-
-       child = find_or_diag(structdie, field);
-       if (child == nil)
-               return;
-
-       a = getattr(child, DW_AT_type);
-       if (a != nil)
-               a->data = dwtype;
-       else
-               newrefattr(child, DW_AT_type, dwtype);
-}
-
-static void
-synthesizestringtypes(DWDie* die)
-{
-       DWDie *prototype;
-
-       prototype = walktypedef(defgotype(lookup_or_diag("type.runtime._string")));
-       if (prototype == nil)
-               return;
-
-       for (; die != nil; die = die->link) {
-               if (die->abbrev != DW_ABRV_STRINGTYPE)
-                       continue;
-               copychildren(die, prototype);
-       }
-}
-
-static void
-synthesizeslicetypes(DWDie *die)
-{
-       DWDie *prototype, *elem;
-
-       prototype = walktypedef(defgotype(lookup_or_diag("type.runtime.slice")));
-       if (prototype == nil)
-               return;
-
-       for (; die != nil; die = die->link) {
-               if (die->abbrev != DW_ABRV_SLICETYPE)
-                       continue;
-               copychildren(die, prototype);
-               elem = (DWDie*) getattr(die, DW_AT_go_elem)->data;
-               substitutetype(die, "array", defptrto(elem));
-       }
-}
-
-static char*
-mkinternaltypename(char *base, char *arg1, char *arg2)
-{
-       char buf[1024];
-       char *n;
-
-       if (arg2 == nil)
-               snprint(buf, sizeof buf, "%s<%s>", base, arg1);
-       else
-               snprint(buf, sizeof buf, "%s<%s,%s>", base, arg1, arg2);
-       n = mal(strlen(buf) + 1);
-       memmove(n, buf, strlen(buf));
-       return n;
-}
-
-// synthesizemaptypes is way too closely married to runtime/hashmap.c
-enum {
-       MaxKeySize = 128,
-       MaxValSize = 128,
-       BucketSize = 8,
-};
-
-static void
-synthesizemaptypes(DWDie *die)
-{
-
-       DWDie *hash, *bucket, *dwh, *dwhk, *dwhv, *dwhb, *keytype, *valtype, *fld, *t;
-       int indirect_key, indirect_val;
-       int keysize, valsize;
-       DWAttr *a;
-
-       hash            = walktypedef(defgotype(lookup_or_diag("type.runtime.hmap")));
-       bucket          = walktypedef(defgotype(lookup_or_diag("type.runtime.bmap")));
-
-       if (hash == nil)
-               return;
-
-       for (; die != nil; die = die->link) {
-               if (die->abbrev != DW_ABRV_MAPTYPE)
-                       continue;
-
-               keytype = walktypedef((DWDie*) getattr(die, DW_AT_go_key)->data);
-               valtype = walktypedef((DWDie*) getattr(die, DW_AT_go_elem)->data);
-
-               // compute size info like hashmap.c does.
-               a = getattr(keytype, DW_AT_byte_size);
-               if(a)
-                       keysize = a->value;
-               else
-                       keysize = thearch.ptrsize;
-               a = getattr(valtype, DW_AT_byte_size);
-               if(a)
-                       valsize = a->value;
-               else
-                       valsize = thearch.ptrsize;
-               indirect_key = 0;
-               indirect_val = 0;
-               if(keysize > MaxKeySize) {
-                       keysize = thearch.ptrsize;
-                       indirect_key = 1;
-               }
-               if(valsize > MaxValSize) {
-                       valsize = thearch.ptrsize;
-                       indirect_val = 1;
-               }
-
-               // Construct type to represent an array of BucketSize keys
-               dwhk = newdie(&dwtypes, DW_ABRV_ARRAYTYPE,
-                             mkinternaltypename("[]key",
-                                                getattr(keytype, DW_AT_name)->data, nil));
-               newattr(dwhk, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize * keysize, 0);
-               t = keytype;
-               if(indirect_key)
-                       t = defptrto(keytype);
-               newrefattr(dwhk, DW_AT_type, t);
-               fld = newdie(dwhk, DW_ABRV_ARRAYRANGE, "size");
-               newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0);
-               newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
-               
-               // Construct type to represent an array of BucketSize values
-               dwhv = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, 
-                             mkinternaltypename("[]val",
-                                                getattr(valtype, DW_AT_name)->data, nil));
-               newattr(dwhv, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize * valsize, 0);
-               t = valtype;
-               if(indirect_val)
-                       t = defptrto(valtype);
-               newrefattr(dwhv, DW_AT_type, t);
-               fld = newdie(dwhv, DW_ABRV_ARRAYRANGE, "size");
-               newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0);
-               newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
-
-               // Construct bucket<K,V>
-               dwhb = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
-                             mkinternaltypename("bucket",
-                                                getattr(keytype, DW_AT_name)->data,
-                                                getattr(valtype, DW_AT_name)->data));
-               // Copy over all fields except the field "data" from the generic bucket.
-               // "data" will be replaced with keys/values below.
-               copychildrenexcept(dwhb, bucket, find(bucket, "data"));
-               
-               fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "keys");
-               newrefattr(fld, DW_AT_type, dwhk);
-               newmemberoffsetattr(fld, BucketSize);
-               fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "values");
-               newrefattr(fld, DW_AT_type, dwhv);
-               newmemberoffsetattr(fld, BucketSize + BucketSize * keysize);
-               fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "overflow");
-               newrefattr(fld, DW_AT_type, defptrto(dwhb));
-               newmemberoffsetattr(fld, BucketSize + BucketSize * (keysize + valsize));
-               if(thearch.regsize > thearch.ptrsize) {
-                       fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "pad");
-                       newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
-                       newmemberoffsetattr(fld, BucketSize + BucketSize * (keysize + valsize) + thearch.ptrsize);
-               }
-               newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize + BucketSize * keysize + BucketSize * valsize + thearch.regsize, 0);
-
-               // Construct hash<K,V>
-               dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
-                       mkinternaltypename("hash",
-                               getattr(keytype, DW_AT_name)->data,
-                               getattr(valtype, DW_AT_name)->data));
-               copychildren(dwh, hash);
-               substitutetype(dwh, "buckets", defptrto(dwhb));
-               substitutetype(dwh, "oldbuckets", defptrto(dwhb));
-               newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT,
-                       getattr(hash, DW_AT_byte_size)->value, nil);
-
-               // make map type a pointer to hash<K,V>
-               newrefattr(die, DW_AT_type, defptrto(dwh));
-       }
-}
-
-static void
-synthesizechantypes(DWDie *die)
-{
-       DWDie *sudog, *waitq, *hchan,
-               *dws, *dww, *dwh, *elemtype;
-       DWAttr *a;
-       int elemsize, sudogsize;
-
-       sudog = walktypedef(defgotype(lookup_or_diag("type.runtime.sudog")));
-       waitq = walktypedef(defgotype(lookup_or_diag("type.runtime.waitq")));
-       hchan = walktypedef(defgotype(lookup_or_diag("type.runtime.hchan")));
-       if (sudog == nil || waitq == nil || hchan == nil)
-               return;
-
-       sudogsize = getattr(sudog, DW_AT_byte_size)->value;
-
-       for (; die != nil; die = die->link) {
-               if (die->abbrev != DW_ABRV_CHANTYPE)
-                       continue;
-               elemtype = (DWDie*) getattr(die, DW_AT_go_elem)->data;
-               a = getattr(elemtype, DW_AT_byte_size);
-               if(a)   
-                       elemsize = a->value;
-               else
-                       elemsize = thearch.ptrsize;
-
-               // sudog<T>
-               dws = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
-                       mkinternaltypename("sudog",
-                               getattr(elemtype, DW_AT_name)->data, nil));
-               copychildren(dws, sudog);
-               substitutetype(dws, "elem", elemtype);
-               if(elemsize > 8)
-                       elemsize -= 8;
-               else
-                       elemsize = 0;
-               newattr(dws, DW_AT_byte_size, DW_CLS_CONSTANT, sudogsize + elemsize, nil);
-
-               // waitq<T>
-               dww = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
-                       mkinternaltypename("waitq", getattr(elemtype, DW_AT_name)->data, nil));
-               copychildren(dww, waitq);
-               substitutetype(dww, "first", defptrto(dws));
-               substitutetype(dww, "last",  defptrto(dws));
-               newattr(dww, DW_AT_byte_size, DW_CLS_CONSTANT,
-                       getattr(waitq, DW_AT_byte_size)->value, nil);
-
-               // hchan<T>
-               dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
-                       mkinternaltypename("hchan", getattr(elemtype, DW_AT_name)->data, nil));
-               copychildren(dwh, hchan);
-               substitutetype(dwh, "recvq", dww);
-               substitutetype(dwh, "sendq", dww);
-               newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT,
-                       getattr(hchan, DW_AT_byte_size)->value, nil);
-
-               newrefattr(die, DW_AT_type, defptrto(dwh));
-       }
-}
-
-// For use with pass.c::genasmsym
-static void
-defdwsymb(LSym* sym, char *s, int t, vlong v, vlong size, int ver, LSym *gotype)
-{
-       DWDie *dv, *dt;
-
-       USED(size);
-       if (strncmp(s, "go.string.", 10) == 0)
-               return;
-
-       if (strncmp(s, "type.", 5) == 0 && strcmp(s, "type.*") != 0 && strncmp(s, "type..", 6) != 0) {
-               defgotype(sym);
-               return;
-       }
-
-       dv = nil;
-
-       switch (t) {
-       default:
-               return;
-       case 'd':
-       case 'b':
-       case 'D':
-       case 'B':
-               dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s);
-               newabslocexprattr(dv, v, sym);
-               if (ver == 0)
-                       newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0);
-               // fallthrough
-       case 'a':
-       case 'p':
-               dt = defgotype(gotype);
-       }
-
-       if (dv != nil)
-               newrefattr(dv, DW_AT_type, dt);
-}
-
-static void
-movetomodule(DWDie *parent)
-{
-       DWDie *die;
-
-       die = dwroot.child->child;
-       while(die->link != nil)
-               die = die->link;
-       die->link = parent->child;
-}
-
-// If the pcln table contains runtime/runtime.go, use that to set gdbscript path.
-static void
-finddebugruntimepath(LSym *s)
-{
-       int i;
-       char *p;
-       LSym *f;
-       
-       if(gdbscript[0] != '\x00')
-               return;
-
-       for(i=0; i<s->pcln->nfile; i++) {
-               f = s->pcln->file[i];
-               if((p = strstr(f->name, "runtime/runtime.go")) != nil) {
-                       *p = '\x00';
-                       snprint(gdbscript, sizeof gdbscript, "%sruntime/runtime-gdb.py", f->name);
-                       *p = 'r';
-                       break;
-               }
-       }
-}
-
-/*
- * Generate short opcodes when possible, long ones when necessary.
- * See section 6.2.5
- */
-
-enum {
-       LINE_BASE = -1,
-       LINE_RANGE = 4,
-       OPCODE_BASE = 10
-};
-
-static void
-putpclcdelta(vlong delta_pc, vlong delta_lc)
-{
-       if (LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE) {
-               vlong opcode = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc);
-               if (OPCODE_BASE <= opcode && opcode < 256) {
-                       cput(opcode);
-                       return;
-               }
-       }
-
-       if (delta_pc) {
-               cput(DW_LNS_advance_pc);
-               sleb128put(delta_pc);
-       }
-
-       cput(DW_LNS_advance_line);
-       sleb128put(delta_lc);
-       cput(DW_LNS_copy);
-}
-
-static void
-newcfaoffsetattr(DWDie *die, int32 offs)
-{
-       char block[10];
-       int i;
-
-       i = 0;
-
-       block[i++] = DW_OP_call_frame_cfa;
-       if (offs != 0) {
-               block[i++] = DW_OP_consts;
-               i += sleb128enc(offs, block+i);
-               block[i++] = DW_OP_plus;
-       }
-       newattr(die, DW_AT_location, DW_CLS_BLOCK, i, mal(i));
-       memmove(die->attr->data, block, i);
-}
-
-static char*
-mkvarname(char* name, int da)
-{
-       char buf[1024];
-       char *n;
-
-       snprint(buf, sizeof buf, "%s#%d", name, da);
-       n = mal(strlen(buf) + 1);
-       memmove(n, buf, strlen(buf));
-       return n;
-}
-
-/*
- * Walk prog table, emit line program and build DIE tree.
- */
-
-// flush previous compilation unit.
-static void
-flushunit(DWDie *dwinfo, vlong pc, LSym *pcsym, vlong unitstart, int32 header_length)
-{
-       vlong here;
-
-       if (dwinfo != nil && pc != 0) {
-               newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, pcsym);
-       }
-
-       if (unitstart >= 0) {
-               cput(0);  // start extended opcode
-               uleb128put(1);
-               cput(DW_LNE_end_sequence);
-
-               here = cpos();
-               cseek(unitstart);
-               thearch.lput(here - unitstart - 4);      // unit_length
-               thearch.wput(2);  // dwarf version
-               thearch.lput(header_length); // header length starting here
-               cseek(here);
-       }
-}
-
-static void
-writelines(void)
-{
-       LSym *s, *epcs;
-       Auto *a;
-       vlong unitstart, headerend, offs;
-       vlong pc, epc;
-       int i, lang, da, dt, line, file;
-       DWDie *dwinfo, *dwfunc, *dwvar, **dws;
-       DWDie *varhash[HASHSIZE];
-       char *n, *nn;
-       Pciter pcfile, pcline;
-       LSym **files, *f;
-
-       if(linesec == nil)
-               linesec = linklookup(ctxt, ".dwarfline", 0);
-       linesec->nr = 0;
-
-       unitstart = -1;
-       headerend = -1;
-       epc = 0;
-       epcs = nil;
-       lineo = cpos();
-       dwinfo = nil;
-       
-       flushunit(dwinfo, epc, epcs, unitstart, headerend - unitstart - 10);
-       unitstart = cpos();
-       
-       lang = DW_LANG_Go;
-       
-       s = ctxt->textp;
-
-       dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, estrdup("go"));
-       newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT,lang, 0);
-       newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart - lineo, 0);
-       newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s->value, s);
-
-       // Write .debug_line Line Number Program Header (sec 6.2.4)
-       // Fields marked with (*) must be changed for 64-bit dwarf
-       thearch.lput(0);   // unit_length (*), will be filled in by flushunit.
-       thearch.wput(2);   // dwarf version (appendix F)
-       thearch.lput(0);   // header_length (*), filled in by flushunit.
-       // cpos == unitstart + 4 + 2 + 4
-       cput(1);   // minimum_instruction_length
-       cput(1);   // default_is_stmt
-       cput(LINE_BASE);     // line_base
-       cput(LINE_RANGE);    // line_range
-       cput(OPCODE_BASE);   // opcode_base
-       cput(0);   // standard_opcode_lengths[1]
-       cput(1);   // standard_opcode_lengths[2]
-       cput(1);   // standard_opcode_lengths[3]
-       cput(1);   // standard_opcode_lengths[4]
-       cput(1);   // standard_opcode_lengths[5]
-       cput(0);   // standard_opcode_lengths[6]
-       cput(0);   // standard_opcode_lengths[7]
-       cput(0);   // standard_opcode_lengths[8]
-       cput(1);   // standard_opcode_lengths[9]
-       cput(0);   // include_directories  (empty)
-
-       files = emallocz(ctxt->nhistfile*sizeof files[0]);
-       for(f = ctxt->filesyms; f != nil; f = f->next)
-               files[f->value-1] = f;
-
-       for(i=0; i<ctxt->nhistfile; i++) {
-               strnput(files[i]->name, strlen(files[i]->name) + 4);
-               // 4 zeros: the string termination + 3 fields.
-       }
-
-       cput(0);   // terminate file_names.
-       headerend = cpos();
-
-       cput(0);  // start extended opcode
-       uleb128put(1 + thearch.ptrsize);
-       cput(DW_LNE_set_address);
-
-       pc = s->value;
-       line = 1;
-       file = 1;
-       if(linkmode == LinkExternal)
-               adddwarfrel(linesec, s, lineo, thearch.ptrsize, 0);
-       else
-               addrput(pc);
-
-       for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next) {
-               s = ctxt->cursym;
-
-               dwfunc = newdie(dwinfo, DW_ABRV_FUNCTION, s->name);
-               newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s->value, s);
-               epc = s->value + s->size;
-               epcs = s;
-               newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, s);
-               if (s->version == 0)
-                       newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0);
-
-               if(s->pcln == nil)
-                       continue;
-
-               finddebugruntimepath(s);
-
-               pciterinit(ctxt, &pcfile, &s->pcln->pcfile);
-               pciterinit(ctxt, &pcline, &s->pcln->pcline);
-               epc = pc;
-               while(!pcfile.done && !pcline.done) {
-                       if(epc - s->value >= pcfile.nextpc) {
-                               pciternext(&pcfile);
-                               continue;
-                       }
-                       if(epc - s->value >= pcline.nextpc) {
-                               pciternext(&pcline);
-                               continue;
-                       }
-
-                       if(file != pcfile.value) {
-                               cput(DW_LNS_set_file);
-                               uleb128put(pcfile.value);
-                               file = pcfile.value;
-                       }
-                       putpclcdelta(s->value + pcline.pc - pc, pcline.value - line);
-
-                       pc = s->value + pcline.pc;
-                       line = pcline.value;
-                       if(pcfile.nextpc < pcline.nextpc)
-                               epc = pcfile.nextpc;
-                       else
-                               epc = pcline.nextpc;
-                       epc += s->value;
-               }
-
-               da = 0;
-               dwfunc->hash = varhash;  // enable indexing of children by name
-               memset(varhash, 0, sizeof varhash);
-               for(a = s->autom; a; a = a->link) {
-                       switch (a->name) {
-                       case A_AUTO:
-                               dt = DW_ABRV_AUTO;
-                               offs = a->aoffset - thearch.ptrsize;
-                               break;
-                       case A_PARAM:
-                               dt = DW_ABRV_PARAM;
-                               offs = a->aoffset;
-                               break;
-                       default:
-                               continue;
-                       }
-                       if (strstr(a->asym->name, ".autotmp_"))
-                               continue;
-                       if (find(dwfunc, a->asym->name) != nil)
-                               n = mkvarname(a->asym->name, da);
-                       else
-                               n = a->asym->name;
-                       // Drop the package prefix from locals and arguments.
-                       nn = strrchr(n, '.');
-                       if (nn)
-                               n = nn + 1;
-
-                       dwvar = newdie(dwfunc, dt, n);
-                       newcfaoffsetattr(dwvar, offs);
-                       newrefattr(dwvar, DW_AT_type, defgotype(a->gotype));
-
-                       // push dwvar down dwfunc->child to preserve order
-                       newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, nil);
-                       dwfunc->child = dwvar->link;  // take dwvar out from the top of the list
-                       for (dws = &dwfunc->child; *dws != nil; dws = &(*dws)->link)
-                               if (offs > getattr(*dws, DW_AT_internal_location)->value)
-                                       break;
-                       dwvar->link = *dws;
-                       *dws = dwvar;
-
-                       da++;
-               }
-
-               dwfunc->hash = nil;
-       }
-
-       flushunit(dwinfo, epc, epcs, unitstart, headerend - unitstart - 10);
-       linesize = cpos() - lineo;
-}
-
-/*
- *  Emit .debug_frame
- */
-enum
-{
-       CIERESERVE = 16,
-       DATAALIGNMENTFACTOR = -4,       // TODO -thearch.ptrsize?
-       FAKERETURNCOLUMN = 16           // TODO gdb6 doesn't like > 15?
-};
-
-static void
-putpccfadelta(vlong deltapc, vlong cfa)
-{
-       cput(DW_CFA_def_cfa_offset_sf);
-       sleb128put(cfa / DATAALIGNMENTFACTOR);
-
-       if (deltapc < 0x40) {
-               cput(DW_CFA_advance_loc + deltapc);
-       } else if (deltapc < 0x100) {
-               cput(DW_CFA_advance_loc1);
-               cput(deltapc);
-       } else if (deltapc < 0x10000) {
-               cput(DW_CFA_advance_loc2);
-               thearch.wput(deltapc);
-       } else {
-               cput(DW_CFA_advance_loc4);
-               thearch.lput(deltapc);
-       }
-}
-
-static void
-writeframes(void)
-{
-       LSym *s;
-       vlong fdeo, fdesize, pad;
-       Pciter pcsp;
-       uint32 nextpc;
-
-       if(framesec == nil)
-               framesec = linklookup(ctxt, ".dwarfframe", 0);
-       framesec->nr = 0;
-       frameo = cpos();
-
-       // Emit the CIE, Section 6.4.1
-       thearch.lput(CIERESERVE);       // initial length, must be multiple of thearch.ptrsize
-       thearch.lput(0xffffffff);       // cid.
-       cput(3);                // dwarf version (appendix F)
-       cput(0);                // augmentation ""
-       uleb128put(1);          // code_alignment_factor
-       sleb128put(DATAALIGNMENTFACTOR); // guess
-       uleb128put(FAKERETURNCOLUMN);   // return_address_register
-
-       cput(DW_CFA_def_cfa);
-       uleb128put(thearch.dwarfregsp); // register SP (**ABI-dependent, defined in l.h)
-       uleb128put(thearch.ptrsize);    // offset
-
-       cput(DW_CFA_offset + FAKERETURNCOLUMN);  // return address
-       uleb128put(-thearch.ptrsize / DATAALIGNMENTFACTOR);  // at cfa - x*4
-
-       // 4 is to exclude the length field.
-       pad = CIERESERVE + frameo + 4 - cpos();
-       if (pad < 0) {
-               diag("dwarf: CIERESERVE too small by %lld bytes.", -pad);
-               errorexit();
-       }
-       strnput("", pad);
-
-       for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next) {
-               s = ctxt->cursym;
-               if(s->pcln == nil)
-                       continue;
-
-               fdeo = cpos();
-               // Emit a FDE, Section 6.4.1, starting wit a placeholder.
-               thearch.lput(0);        // length, must be multiple of thearch.ptrsize
-               thearch.lput(0);        // Pointer to the CIE above, at offset 0
-               addrput(0);     // initial location
-               addrput(0);     // address range
-
-               for(pciterinit(ctxt, &pcsp, &s->pcln->pcsp); !pcsp.done; pciternext(&pcsp)) {
-                       nextpc = pcsp.nextpc;
-                       // pciterinit goes up to the end of the function,
-                       // but DWARF expects us to stop just before the end.
-                       if(nextpc == s->size) {
-                               nextpc--;
-                               if(nextpc < pcsp.pc)
-                                       continue;
-                       }
-                       putpccfadelta(nextpc - pcsp.pc, thearch.ptrsize + pcsp.value);
-               }
-
-               fdesize = cpos() - fdeo - 4;    // exclude the length field.
-               pad = rnd(fdesize, thearch.ptrsize) - fdesize;
-               strnput("", pad);
-               fdesize += pad;
-
-               // Emit the FDE header for real, Section 6.4.1.
-               cseek(fdeo);
-               thearch.lput(fdesize);
-               if(linkmode == LinkExternal) {
-                       adddwarfrel(framesec, framesym, frameo, 4, 0);
-                       adddwarfrel(framesec, s, frameo, thearch.ptrsize, 0);
-               }
-               else {
-                       thearch.lput(0);
-                       addrput(s->value);
-               }
-               addrput(s->size);
-               cseek(fdeo + 4 + fdesize);
-       }
-
-       cflush();
-       framesize = cpos() - frameo;
-}
-
-/*
- *  Walk DWarfDebugInfoEntries, and emit .debug_info
- */
-enum
-{
-       COMPUNITHEADERSIZE = 4+2+4+1
-};
-
-static void
-writeinfo(void)
-{
-       DWDie *compunit;
-       vlong unitstart, here;
-
-       fwdcount = 0;
-       if (infosec == nil)
-               infosec = linklookup(ctxt, ".dwarfinfo", 0);
-       infosec->nr = 0;
-
-       if(arangessec == nil)
-               arangessec = linklookup(ctxt, ".dwarfaranges", 0);
-       arangessec->nr = 0;
-
-       for (compunit = dwroot.child; compunit; compunit = compunit->link) {
-               unitstart = cpos();
-
-               // Write .debug_info Compilation Unit Header (sec 7.5.1)
-               // Fields marked with (*) must be changed for 64-bit dwarf
-               // This must match COMPUNITHEADERSIZE above.
-               thearch.lput(0);        // unit_length (*), will be filled in later.
-               thearch.wput(2);        // dwarf version (appendix F)
-
-               // debug_abbrev_offset (*)
-               if(linkmode == LinkExternal)
-                       adddwarfrel(infosec, abbrevsym, infoo, 4, 0);
-               else
-                       thearch.lput(0);
-
-               cput(thearch.ptrsize);  // address_size
-
-               putdie(compunit);
-
-               here = cpos();
-               cseek(unitstart);
-               thearch.lput(here - unitstart - 4);     // exclude the length field.
-               cseek(here);
-       }
-       cflush();
-}
-
-/*
- *  Emit .debug_pubnames/_types.  _info must have been written before,
- *  because we need die->offs and infoo/infosize;
- */
-static int
-ispubname(DWDie *die)
-{
-       DWAttr *a;
-
-       switch(die->abbrev) {
-       case DW_ABRV_FUNCTION:
-       case DW_ABRV_VARIABLE:
-               a = getattr(die, DW_AT_external);
-               return a && a->value;
-       }
-       return 0;
-}
-
-static int
-ispubtype(DWDie *die)
-{
-       return die->abbrev >= DW_ABRV_NULLTYPE;
-}
-
-static vlong
-writepub(int (*ispub)(DWDie*))
-{
-       DWDie *compunit, *die;
-       DWAttr *dwa;
-       vlong unitstart, unitend, sectionstart, here;
-
-       sectionstart = cpos();
-
-       for (compunit = dwroot.child; compunit != nil; compunit = compunit->link) {
-               unitstart = compunit->offs - COMPUNITHEADERSIZE;
-               if (compunit->link != nil)
-                       unitend = compunit->link->offs - COMPUNITHEADERSIZE;
-               else
-                       unitend = infoo + infosize;
-
-               // Write .debug_pubnames/types  Header (sec 6.1.1)
-               thearch.lput(0);                        // unit_length (*), will be filled in later.
-               thearch.wput(2);                        // dwarf version (appendix F)
-               thearch.lput(unitstart);                // debug_info_offset (of the Comp unit Header)
-               thearch.lput(unitend - unitstart);      // debug_info_length
-
-               for (die = compunit->child; die != nil; die = die->link) {
-                       if (!ispub(die)) continue;
-                       thearch.lput(die->offs - unitstart);
-                       dwa = getattr(die, DW_AT_name);
-                       strnput(dwa->data, dwa->value + 1);
-               }
-               thearch.lput(0);
-
-               here = cpos();
-               cseek(sectionstart);
-               thearch.lput(here - sectionstart - 4);  // exclude the length field.
-               cseek(here);
-
-       }
-
-       return sectionstart;
-}
-
-/*
- *  emit .debug_aranges.  _info must have been written before,
- *  because we need die->offs of dw_globals.
- */
-static vlong
-writearanges(void)
-{
-       DWDie *compunit;
-       DWAttr *b, *e;
-       int headersize;
-       vlong sectionstart;
-       vlong value;
-
-       sectionstart = cpos();
-       headersize = rnd(4+2+4+1+1, thearch.ptrsize);  // don't count unit_length field itself
-
-       for (compunit = dwroot.child; compunit != nil; compunit = compunit->link) {
-               b = getattr(compunit,  DW_AT_low_pc);
-               if (b == nil)
-                       continue;
-               e = getattr(compunit,  DW_AT_high_pc);
-               if (e == nil)
-                       continue;
-
-               // Write .debug_aranges  Header + entry  (sec 6.1.2)
-               thearch.lput(headersize + 4*thearch.ptrsize - 4);       // unit_length (*)
-               thearch.wput(2);        // dwarf version (appendix F)
-
-               value = compunit->offs - COMPUNITHEADERSIZE;    // debug_info_offset
-               if(linkmode == LinkExternal)
-                       adddwarfrel(arangessec, infosym, sectionstart, 4, value);
-               else
-                       thearch.lput(value);
-
-               cput(thearch.ptrsize);  // address_size
-               cput(0);        // segment_size
-               strnput("", headersize - (4+2+4+1+1));  // align to thearch.ptrsize
-
-               if(linkmode == LinkExternal)
-                       adddwarfrel(arangessec, (LSym*)b->data, sectionstart, thearch.ptrsize, b->value-((LSym*)b->data)->value);
-               else
-                       addrput(b->value);
-
-               addrput(e->value - b->value);
-               addrput(0);
-               addrput(0);
-       }
-       cflush();
-       return sectionstart;
-}
-
-static vlong
-writegdbscript(void)
-{
-       vlong sectionstart;
-
-       sectionstart = cpos();
-
-       if (gdbscript[0]) {
-               cput(1);  // magic 1 byte?
-               strnput(gdbscript, strlen(gdbscript)+1);
-               cflush();
-       }
-       return sectionstart;
-}
-
-static void
-align(vlong size)
-{
-       if(HEADTYPE == Hwindows) // Only Windows PE need section align.
-               strnput("", rnd(size, PEFILEALIGN) - size);
-}
-
-static vlong
-writedwarfreloc(LSym* s)
-{
-       int i, ri;
-       vlong start;
-       Reloc *r;
-       
-       start = cpos();
-       for(ri=0; ri<s->nr; ri++) {
-               r = &s->r[ri];
-               if(iself)
-                       i = thearch.elfreloc1(r, r->off);
-               else if(HEADTYPE == Hdarwin)
-                       i = thearch.machoreloc1(r, r->off);
-               else
-                       i = -1;
-               if(i < 0)
-                       diag("unsupported obj reloc %d/%d to %s", r->type, r->siz, r->sym->name);
-       }
-       return start;
-}
-
-/*
- * This is the main entry point for generating dwarf.  After emitting
- * the mandatory debug_abbrev section, it calls writelines() to set up
- * the per-compilation unit part of the DIE tree, while simultaneously
- * emitting the debug_line section.  When the final tree contains
- * forward references, it will write the debug_info section in 2
- * passes.
- *
- */
-void
-dwarfemitdebugsections(void)
-{
-       vlong infoe;
-       DWDie* die;
-
-       if(debug['w'])  // disable dwarf
-               return;
-
-       if(linkmode == LinkExternal && !iself)
-               return;
-
-       // For diagnostic messages.
-       newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, strlen("dwtypes"), "dwtypes");
-
-       mkindex(&dwroot);
-       mkindex(&dwtypes);
-       mkindex(&dwglobals);
-
-       // Some types that must exist to define other ones.
-       newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>");
-       newdie(&dwtypes, DW_ABRV_NULLTYPE, "void");
-       newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer");
-
-       die = newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr");  // needed for array size
-       newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_unsigned, 0);
-       newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, thearch.ptrsize, 0);
-       newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, KindUintptr, 0);
-
-       // Needed by the prettyprinter code for interface inspection.
-       defgotype(lookup_or_diag("type.runtime._type"));
-       defgotype(lookup_or_diag("type.runtime.interfacetype"));
-       defgotype(lookup_or_diag("type.runtime.itab"));
-
-       genasmsym(defdwsymb);
-
-       writeabbrev();
-       align(abbrevsize);
-       writelines();
-       align(linesize);
-       writeframes();
-       align(framesize);
-
-       synthesizestringtypes(dwtypes.child);
-       synthesizeslicetypes(dwtypes.child);
-       synthesizemaptypes(dwtypes.child);
-       synthesizechantypes(dwtypes.child);
-
-       reversetree(&dwroot.child);
-       reversetree(&dwtypes.child);
-       reversetree(&dwglobals.child);
-
-       movetomodule(&dwtypes);
-       movetomodule(&dwglobals);
-
-       infoo = cpos();
-       writeinfo();
-       infoe = cpos();
-       pubnameso = infoe;
-       pubtypeso = infoe;
-       arangeso = infoe;
-       gdbscripto = infoe;
-
-       if (fwdcount > 0) {
-               if (debug['v'])
-                       Bprint(&bso, "%5.2f dwarf pass 2.\n", cputime());
-               cseek(infoo);
-               writeinfo();
-               if (fwdcount > 0) {
-                       diag("dwarf: unresolved references after first dwarf info pass");
-                       errorexit();
-               }
-               if (infoe != cpos()) {
-                       diag("dwarf: inconsistent second dwarf info pass");
-                       errorexit();
-               }
-       }
-       infosize = infoe - infoo;
-       align(infosize);
-
-       pubnameso  = writepub(ispubname);
-       pubnamessize  = cpos() - pubnameso;
-       align(pubnamessize);
-
-       pubtypeso  = writepub(ispubtype);
-       pubtypessize  = cpos() - pubtypeso;
-       align(pubtypessize);
-
-       arangeso   = writearanges();
-       arangessize   = cpos() - arangeso;
-       align(arangessize);
-
-       gdbscripto = writegdbscript();
-       gdbscriptsize = cpos() - gdbscripto;
-       align(gdbscriptsize);
-
-       while(cpos()&7)
-               cput(0);
-       inforeloco = writedwarfreloc(infosec);
-       inforelocsize = cpos() - inforeloco;
-       align(inforelocsize);
-
-       arangesreloco = writedwarfreloc(arangessec);
-       arangesrelocsize = cpos() - arangesreloco;
-       align(arangesrelocsize);
-
-       linereloco = writedwarfreloc(linesec);
-       linerelocsize = cpos() - linereloco;
-       align(linerelocsize);
-
-       framereloco = writedwarfreloc(framesec);
-       framerelocsize = cpos() - framereloco;
-       align(framerelocsize);
-}
-
-/*
- *  Elf.
- */
-enum
-{
-       ElfStrDebugAbbrev,
-       ElfStrDebugAranges,
-       ElfStrDebugFrame,
-       ElfStrDebugInfo,
-       ElfStrDebugLine,
-       ElfStrDebugLoc,
-       ElfStrDebugMacinfo,
-       ElfStrDebugPubNames,
-       ElfStrDebugPubTypes,
-       ElfStrDebugRanges,
-       ElfStrDebugStr,
-       ElfStrGDBScripts,
-       ElfStrRelDebugInfo,
-       ElfStrRelDebugAranges,
-       ElfStrRelDebugLine,
-       ElfStrRelDebugFrame,
-       NElfStrDbg
-};
-
-vlong elfstrdbg[NElfStrDbg];
-
-void
-dwarfaddshstrings(LSym *shstrtab)
-{
-       if(debug['w'])  // disable dwarf
-               return;
-
-       elfstrdbg[ElfStrDebugAbbrev]   = addstring(shstrtab, ".debug_abbrev");
-       elfstrdbg[ElfStrDebugAranges]  = addstring(shstrtab, ".debug_aranges");
-       elfstrdbg[ElfStrDebugFrame]    = addstring(shstrtab, ".debug_frame");
-       elfstrdbg[ElfStrDebugInfo]     = addstring(shstrtab, ".debug_info");
-       elfstrdbg[ElfStrDebugLine]     = addstring(shstrtab, ".debug_line");
-       elfstrdbg[ElfStrDebugLoc]      = addstring(shstrtab, ".debug_loc");
-       elfstrdbg[ElfStrDebugMacinfo]  = addstring(shstrtab, ".debug_macinfo");
-       elfstrdbg[ElfStrDebugPubNames] = addstring(shstrtab, ".debug_pubnames");
-       elfstrdbg[ElfStrDebugPubTypes] = addstring(shstrtab, ".debug_pubtypes");
-       elfstrdbg[ElfStrDebugRanges]   = addstring(shstrtab, ".debug_ranges");
-       elfstrdbg[ElfStrDebugStr]      = addstring(shstrtab, ".debug_str");
-       elfstrdbg[ElfStrGDBScripts]    = addstring(shstrtab, ".debug_gdb_scripts");
-       if(linkmode == LinkExternal) {
-               if(thearch.thechar == '6' || thearch.thechar == '9') {
-                       elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rela.debug_info");
-                       elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rela.debug_aranges");
-                       elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rela.debug_line");
-                       elfstrdbg[ElfStrRelDebugFrame] = addstring(shstrtab, ".rela.debug_frame");
-               } else {
-                       elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rel.debug_info");
-                       elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rel.debug_aranges");
-                       elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rel.debug_line");
-                       elfstrdbg[ElfStrRelDebugFrame] = addstring(shstrtab, ".rel.debug_frame");
-               }
-
-               infosym = linklookup(ctxt, ".debug_info", 0);
-               infosym->hide = 1;
-
-               abbrevsym = linklookup(ctxt, ".debug_abbrev", 0);
-               abbrevsym->hide = 1;
-
-               linesym = linklookup(ctxt, ".debug_line", 0);
-               linesym->hide = 1;
-
-               framesym = linklookup(ctxt, ".debug_frame", 0);
-               framesym->hide = 1;
-       }
-}
-
-// Add section symbols for DWARF debug info.  This is called before
-// dwarfaddelfheaders.
-void
-dwarfaddelfsectionsyms(void)
-{
-       if(infosym != nil) {
-               infosympos = cpos();
-               putelfsectionsym(infosym, 0);
-       }
-       if(abbrevsym != nil) {
-               abbrevsympos = cpos();
-               putelfsectionsym(abbrevsym, 0);
-       }
-       if(linesym != nil) {
-               linesympos = cpos();
-               putelfsectionsym(linesym, 0);
-       }
-       if(framesym != nil) {
-               framesympos = cpos();
-               putelfsectionsym(framesym, 0);
-       }
-}
-
-static void
-dwarfaddelfrelocheader(int elfstr, ElfShdr *shdata, vlong off, vlong size)
-{
-       ElfShdr *sh;
-
-       sh = newElfShdr(elfstrdbg[elfstr]);
-       if(thearch.thechar == '6' || thearch.thechar == '9') {
-               sh->type = SHT_RELA;
-       } else {
-               sh->type = SHT_REL;
-       }
-       sh->entsize = thearch.ptrsize*(2+(sh->type==SHT_RELA));
-       sh->link = elfshname(".symtab")->shnum;
-       sh->info = shdata->shnum;
-       sh->off = off;
-       sh->size = size;
-       sh->addralign = thearch.ptrsize;
-       
-}
-
-void
-dwarfaddelfheaders(void)
-{
-       ElfShdr *sh, *shinfo, *sharanges, *shline, *shframe;
-
-       if(debug['w'])  // disable dwarf
-               return;
-
-       sh = newElfShdr(elfstrdbg[ElfStrDebugAbbrev]);
-       sh->type = SHT_PROGBITS;
-       sh->off = abbrevo;
-       sh->size = abbrevsize;
-       sh->addralign = 1;
-       if(abbrevsympos > 0)
-               putelfsymshndx(abbrevsympos, sh->shnum);
-
-       sh = newElfShdr(elfstrdbg[ElfStrDebugLine]);
-       sh->type = SHT_PROGBITS;
-       sh->off = lineo;
-       sh->size = linesize;
-       sh->addralign = 1;
-       if(linesympos > 0)
-               putelfsymshndx(linesympos, sh->shnum);
-       shline = sh;
-
-       sh = newElfShdr(elfstrdbg[ElfStrDebugFrame]);
-       sh->type = SHT_PROGBITS;
-       sh->off = frameo;
-       sh->size = framesize;
-       sh->addralign = 1;
-       if(framesympos > 0)
-               putelfsymshndx(framesympos, sh->shnum);
-       shframe = sh;
-
-       sh = newElfShdr(elfstrdbg[ElfStrDebugInfo]);
-       sh->type = SHT_PROGBITS;
-       sh->off = infoo;
-       sh->size = infosize;
-       sh->addralign = 1;
-       if(infosympos > 0)
-               putelfsymshndx(infosympos, sh->shnum);
-       shinfo = sh;
-
-       if (pubnamessize > 0) {
-               sh = newElfShdr(elfstrdbg[ElfStrDebugPubNames]);
-               sh->type = SHT_PROGBITS;
-               sh->off = pubnameso;
-               sh->size = pubnamessize;
-               sh->addralign = 1;
-       }
-
-       if (pubtypessize > 0) {
-               sh = newElfShdr(elfstrdbg[ElfStrDebugPubTypes]);
-               sh->type = SHT_PROGBITS;
-               sh->off = pubtypeso;
-               sh->size = pubtypessize;
-               sh->addralign = 1;
-       }
-
-       sharanges = nil;
-       if (arangessize) {
-               sh = newElfShdr(elfstrdbg[ElfStrDebugAranges]);
-               sh->type = SHT_PROGBITS;
-               sh->off = arangeso;
-               sh->size = arangessize;
-               sh->addralign = 1;
-               sharanges = sh;
-       }
-
-       if (gdbscriptsize) {
-               sh = newElfShdr(elfstrdbg[ElfStrGDBScripts]);
-               sh->type = SHT_PROGBITS;
-               sh->off = gdbscripto;
-               sh->size = gdbscriptsize;
-               sh->addralign = 1;
-       }
-
-       if(inforelocsize)
-               dwarfaddelfrelocheader(ElfStrRelDebugInfo, shinfo, inforeloco, inforelocsize);
-
-       if(arangesrelocsize)
-               dwarfaddelfrelocheader(ElfStrRelDebugAranges, sharanges, arangesreloco, arangesrelocsize);
-
-       if(linerelocsize)
-               dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize);
-
-       if(framerelocsize)
-               dwarfaddelfrelocheader(ElfStrRelDebugFrame, shframe, framereloco, framerelocsize);
-}
-
-/*
- * Macho
- */
-void
-dwarfaddmachoheaders(void)
-{
-       MachoSect *msect;
-       MachoSeg *ms;
-       vlong fakestart;
-       int nsect;
-
-       if(debug['w'])  // disable dwarf
-               return;
-
-       // Zero vsize segments won't be loaded in memory, even so they
-       // have to be page aligned in the file.
-       fakestart = abbrevo & ~0xfff;
-
-       nsect = 4;
-       if (pubnamessize  > 0)
-               nsect++;
-       if (pubtypessize  > 0)
-               nsect++;
-       if (arangessize   > 0)
-               nsect++;
-       if (gdbscriptsize > 0)
-               nsect++;
-
-       ms = newMachoSeg("__DWARF", nsect);
-       ms->fileoffset = fakestart;
-       ms->filesize = abbrevo-fakestart;
-       ms->vaddr = ms->fileoffset + segdata.vaddr - segdata.fileoff;
-
-       msect = newMachoSect(ms, "__debug_abbrev", "__DWARF");
-       msect->off = abbrevo;
-       msect->size = abbrevsize;
-       msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
-       ms->filesize += msect->size;
-
-       msect = newMachoSect(ms, "__debug_line", "__DWARF");
-       msect->off = lineo;
-       msect->size = linesize;
-       msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
-       ms->filesize += msect->size;
-
-       msect = newMachoSect(ms, "__debug_frame", "__DWARF");
-       msect->off = frameo;
-       msect->size = framesize;
-       msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
-       ms->filesize += msect->size;
-
-       msect = newMachoSect(ms, "__debug_info", "__DWARF");
-       msect->off = infoo;
-       msect->size = infosize;
-       msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
-       ms->filesize += msect->size;
-
-       if (pubnamessize > 0) {
-               msect = newMachoSect(ms, "__debug_pubnames", "__DWARF");
-               msect->off = pubnameso;
-               msect->size = pubnamessize;
-               msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
-               ms->filesize += msect->size;
-       }
-
-       if (pubtypessize > 0) {
-               msect = newMachoSect(ms, "__debug_pubtypes", "__DWARF");
-               msect->off = pubtypeso;
-               msect->size = pubtypessize;
-               msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
-               ms->filesize += msect->size;
-       }
-
-       if (arangessize > 0) {
-               msect = newMachoSect(ms, "__debug_aranges", "__DWARF");
-               msect->off = arangeso;
-               msect->size = arangessize;
-               msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
-               ms->filesize += msect->size;
-       }
-
-       // TODO(lvd) fix gdb/python to load MachO (16 char section name limit)
-       if (gdbscriptsize > 0) {
-               msect = newMachoSect(ms, "__debug_gdb_scripts", "__DWARF");
-               msect->off = gdbscripto;
-               msect->size = gdbscriptsize;
-               msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
-               ms->filesize += msect->size;
-       }
-}
-
-/*
- * Windows PE
- */
-void
-dwarfaddpeheaders(void)
-{
-       if(debug['w'])  // disable dwarf
-               return;
-
-       newPEDWARFSection(".debug_abbrev", abbrevsize);
-       newPEDWARFSection(".debug_line", linesize);
-       newPEDWARFSection(".debug_frame", framesize);
-       newPEDWARFSection(".debug_info", infosize);
-       newPEDWARFSection(".debug_pubnames", pubnamessize);
-       newPEDWARFSection(".debug_pubtypes", pubtypessize);
-       newPEDWARFSection(".debug_aranges", arangessize);
-       newPEDWARFSection(".debug_gdb_scripts", gdbscriptsize);
-}
diff --git a/src/cmd/ld/dwarf.h b/src/cmd/ld/dwarf.h
deleted file mode 100644 (file)
index b2218c1..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2010 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.
-
-/*
- * Emit debug_abbrevs, debug_info and debug_line sections to current
- * offset in cout.
- */
-void dwarfemitdebugsections(void);
-
-/*
- * Add the dwarf section names to the ELF
- * s[ection]h[eader]str[ing]tab.  Prerequisite for
- * dwarfaddelfheaders().
- */
-void dwarfaddshstrings(LSym *shstrtab);
-
-/*
- * Add section headers pointing to the sections emitted in
- * dwarfemitdebugsections.
- */
-void dwarfaddelfheaders(void);
-void dwarfaddmachoheaders(void);
-void dwarfaddpeheaders(void);
-void dwarfaddelfsectionsyms(void);
diff --git a/src/cmd/ld/dwarf_defs.h b/src/cmd/ld/dwarf_defs.h
deleted file mode 100644 (file)
index 93e99ff..0000000
+++ /dev/null
@@ -1,504 +0,0 @@
-// Copyright 2010 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.
-
-// Cut, pasted, tr-and-awk'ed from tables in
-// http://dwarfstd.org/doc/Dwarf3.pdf
-
-// Table 18
-enum
-{
-       DW_TAG_array_type = 0x01,
-       DW_TAG_class_type = 0x02,
-       DW_TAG_entry_point = 0x03,
-       DW_TAG_enumeration_type = 0x04,
-       DW_TAG_formal_parameter = 0x05,
-       DW_TAG_imported_declaration = 0x08,
-       DW_TAG_label = 0x0a,
-       DW_TAG_lexical_block = 0x0b,
-       DW_TAG_member = 0x0d,
-       DW_TAG_pointer_type = 0x0f,
-       DW_TAG_reference_type = 0x10,
-       DW_TAG_compile_unit = 0x11,
-       DW_TAG_string_type = 0x12,
-       DW_TAG_structure_type = 0x13,
-       DW_TAG_subroutine_type = 0x15,
-       DW_TAG_typedef = 0x16,
-       DW_TAG_union_type = 0x17,
-       DW_TAG_unspecified_parameters = 0x18,
-       DW_TAG_variant = 0x19,
-       DW_TAG_common_block = 0x1a,
-       DW_TAG_common_inclusion = 0x1b,
-       DW_TAG_inheritance = 0x1c,
-       DW_TAG_inlined_subroutine = 0x1d,
-       DW_TAG_module = 0x1e,
-       DW_TAG_ptr_to_member_type = 0x1f,
-       DW_TAG_set_type = 0x20,
-       DW_TAG_subrange_type = 0x21,
-       DW_TAG_with_stmt = 0x22,
-       DW_TAG_access_declaration = 0x23,
-       DW_TAG_base_type = 0x24,
-       DW_TAG_catch_block = 0x25,
-       DW_TAG_const_type = 0x26,
-       DW_TAG_constant = 0x27,
-       DW_TAG_enumerator = 0x28,
-       DW_TAG_file_type = 0x29,
-       DW_TAG_friend = 0x2a,
-       DW_TAG_namelist = 0x2b,
-       DW_TAG_namelist_item = 0x2c,
-       DW_TAG_packed_type = 0x2d,
-       DW_TAG_subprogram = 0x2e,
-       DW_TAG_template_type_parameter = 0x2f,
-       DW_TAG_template_value_parameter = 0x30,
-       DW_TAG_thrown_type = 0x31,
-       DW_TAG_try_block = 0x32,
-       DW_TAG_variant_part = 0x33,
-       DW_TAG_variable = 0x34,
-       DW_TAG_volatile_type = 0x35,
-       // Dwarf3
-       DW_TAG_dwarf_procedure = 0x36,
-       DW_TAG_restrict_type = 0x37,
-       DW_TAG_interface_type = 0x38,
-       DW_TAG_namespace = 0x39,
-       DW_TAG_imported_module = 0x3a,
-       DW_TAG_unspecified_type = 0x3b,
-       DW_TAG_partial_unit = 0x3c,
-       DW_TAG_imported_unit = 0x3d,
-       DW_TAG_condition = 0x3f,
-       DW_TAG_shared_type = 0x40,
-       // Dwarf4
-       DW_TAG_type_unit = 0x41,
-       DW_TAG_rvalue_reference_type = 0x42,
-       DW_TAG_template_alias = 0x43,
-
-       // User defined
-       DW_TAG_lo_user = 0x4080,
-       DW_TAG_hi_user = 0xffff,
-
-};
-
-// Table 19
-enum
-{
-       DW_CHILDREN_no = 0x00,
-       DW_CHILDREN_yes = 0x01,
-};
-
-// Not from the spec, but logicaly belongs here
-enum
-{
-       DW_CLS_ADDRESS = 0x01,
-       DW_CLS_BLOCK,
-       DW_CLS_CONSTANT,
-       DW_CLS_FLAG,
-       DW_CLS_PTR,     // lineptr, loclistptr, macptr, rangelistptr
-       DW_CLS_REFERENCE,
-       DW_CLS_ADDRLOC,
-       DW_CLS_STRING
-};
-
-// Table 20
-enum
-{
-       DW_AT_sibling = 0x01,   // reference
-       DW_AT_location = 0x02,  // block, loclistptr
-       DW_AT_name = 0x03,      // string
-       DW_AT_ordering = 0x09,  // constant
-       DW_AT_byte_size = 0x0b, // block, constant, reference
-       DW_AT_bit_offset = 0x0c,        // block, constant, reference
-       DW_AT_bit_size = 0x0d,  // block, constant, reference
-       DW_AT_stmt_list = 0x10, // lineptr
-       DW_AT_low_pc = 0x11,    // address
-       DW_AT_high_pc = 0x12,   // address
-       DW_AT_language = 0x13,  // constant
-       DW_AT_discr = 0x15,     // reference
-       DW_AT_discr_value = 0x16,       // constant
-       DW_AT_visibility = 0x17,        // constant
-       DW_AT_import = 0x18,    // reference
-       DW_AT_string_length = 0x19,     // block, loclistptr
-       DW_AT_common_reference = 0x1a,  // reference
-       DW_AT_comp_dir = 0x1b,  // string
-       DW_AT_const_value = 0x1c,       // block, constant, string
-       DW_AT_containing_type = 0x1d,   // reference
-       DW_AT_default_value = 0x1e,     // reference
-       DW_AT_inline = 0x20,    // constant
-       DW_AT_is_optional = 0x21,       // flag
-       DW_AT_lower_bound = 0x22,       // block, constant, reference
-       DW_AT_producer = 0x25,  // string
-       DW_AT_prototyped = 0x27,        // flag
-       DW_AT_return_addr = 0x2a,       // block, loclistptr
-       DW_AT_start_scope = 0x2c,       // constant
-       DW_AT_bit_stride = 0x2e,        // constant
-       DW_AT_upper_bound = 0x2f,       // block, constant, reference
-       DW_AT_abstract_origin = 0x31,   // reference
-       DW_AT_accessibility = 0x32,     // constant
-       DW_AT_address_class = 0x33,     // constant
-       DW_AT_artificial = 0x34,        // flag
-       DW_AT_base_types = 0x35,        // reference
-       DW_AT_calling_convention = 0x36,        // constant
-       DW_AT_count = 0x37,     // block, constant, reference
-       DW_AT_data_member_location = 0x38,      // block, constant, loclistptr
-       DW_AT_decl_column = 0x39,       // constant
-       DW_AT_decl_file = 0x3a, // constant
-       DW_AT_decl_line = 0x3b, // constant
-       DW_AT_declaration = 0x3c,       // flag
-       DW_AT_discr_list = 0x3d,        // block
-       DW_AT_encoding = 0x3e,  // constant
-       DW_AT_external = 0x3f,  // flag
-       DW_AT_frame_base = 0x40,        // block, loclistptr
-       DW_AT_friend = 0x41,    // reference
-       DW_AT_identifier_case = 0x42,   // constant
-       DW_AT_macro_info = 0x43,        // macptr
-       DW_AT_namelist_item = 0x44,     // block
-       DW_AT_priority = 0x45,  // reference
-       DW_AT_segment = 0x46,   // block, loclistptr
-       DW_AT_specification = 0x47,     // reference
-       DW_AT_static_link = 0x48,       // block, loclistptr
-       DW_AT_type = 0x49,      // reference
-       DW_AT_use_location = 0x4a,      // block, loclistptr
-       DW_AT_variable_parameter = 0x4b,        // flag
-       DW_AT_virtuality = 0x4c,        // constant
-       DW_AT_vtable_elem_location = 0x4d,      // block, loclistptr
-       // Dwarf3
-       DW_AT_allocated = 0x4e, // block, constant, reference
-       DW_AT_associated = 0x4f,        // block, constant, reference
-       DW_AT_data_location = 0x50,     // block
-       DW_AT_byte_stride = 0x51,       // block, constant, reference
-       DW_AT_entry_pc = 0x52,  // address
-       DW_AT_use_UTF8 = 0x53,  // flag
-       DW_AT_extension = 0x54, // reference
-       DW_AT_ranges = 0x55,    // rangelistptr
-       DW_AT_trampoline = 0x56,        // address, flag, reference, string
-       DW_AT_call_column = 0x57,       // constant
-       DW_AT_call_file = 0x58, // constant
-       DW_AT_call_line = 0x59, // constant
-       DW_AT_description = 0x5a,       // string
-       DW_AT_binary_scale = 0x5b,      // constant
-       DW_AT_decimal_scale = 0x5c,     // constant
-       DW_AT_small = 0x5d,     // reference
-       DW_AT_decimal_sign = 0x5e,      // constant
-       DW_AT_digit_count = 0x5f,       // constant
-       DW_AT_picture_string = 0x60,    // string
-       DW_AT_mutable = 0x61,   // flag
-       DW_AT_threads_scaled = 0x62,    // flag
-       DW_AT_explicit = 0x63,  // flag
-       DW_AT_object_pointer = 0x64,    // reference
-       DW_AT_endianity = 0x65, // constant
-       DW_AT_elemental = 0x66, // flag
-       DW_AT_pure = 0x67,      // flag
-       DW_AT_recursive = 0x68, // flag
-
-       DW_AT_lo_user = 0x2000, // ---
-       DW_AT_hi_user = 0x3fff, // ---
-
-};
-
-// Table 21
-enum
-{
-       DW_FORM_addr = 0x01,    // address
-       DW_FORM_block2 = 0x03,  // block
-       DW_FORM_block4 = 0x04,  // block
-       DW_FORM_data2 = 0x05,   // constant
-       DW_FORM_data4 = 0x06,   // constant, lineptr, loclistptr, macptr, rangelistptr
-       DW_FORM_data8 = 0x07,   // constant, lineptr, loclistptr, macptr, rangelistptr
-       DW_FORM_string = 0x08,  // string
-       DW_FORM_block = 0x09,   // block
-       DW_FORM_block1 = 0x0a,  // block
-       DW_FORM_data1 = 0x0b,   // constant
-       DW_FORM_flag = 0x0c,    // flag
-       DW_FORM_sdata = 0x0d,   // constant
-       DW_FORM_strp = 0x0e,    // string
-       DW_FORM_udata = 0x0f,   // constant
-       DW_FORM_ref_addr = 0x10,        // reference
-       DW_FORM_ref1 = 0x11,    // reference
-       DW_FORM_ref2 = 0x12,    // reference
-       DW_FORM_ref4 = 0x13,    // reference
-       DW_FORM_ref8 = 0x14,    // reference
-       DW_FORM_ref_udata = 0x15,       // reference
-       DW_FORM_indirect = 0x16,        // (see Section 7.5.3)
-};
-
-// Table 24 (#operands, notes)
-enum
-{
-       DW_OP_addr = 0x03,      // 1 constant address (size target specific)
-       DW_OP_deref = 0x06,     // 0
-       DW_OP_const1u = 0x08,   // 1 1-byte constant
-       DW_OP_const1s = 0x09,   // 1 1-byte constant
-       DW_OP_const2u = 0x0a,   // 1 2-byte constant
-       DW_OP_const2s = 0x0b,   // 1 2-byte constant
-       DW_OP_const4u = 0x0c,   // 1 4-byte constant
-       DW_OP_const4s = 0x0d,   // 1 4-byte constant
-       DW_OP_const8u = 0x0e,   // 1 8-byte constant
-       DW_OP_const8s = 0x0f,   // 1 8-byte constant
-       DW_OP_constu = 0x10,    // 1 ULEB128 constant
-       DW_OP_consts = 0x11,    // 1 SLEB128 constant
-       DW_OP_dup = 0x12,       // 0
-       DW_OP_drop = 0x13,      // 0
-       DW_OP_over = 0x14,      // 0
-       DW_OP_pick = 0x15,      // 1 1-byte stack index
-       DW_OP_swap = 0x16,      // 0
-       DW_OP_rot = 0x17,       // 0
-       DW_OP_xderef = 0x18,    // 0
-       DW_OP_abs = 0x19,       // 0
-       DW_OP_and = 0x1a,       // 0
-       DW_OP_div = 0x1b,       // 0
-       DW_OP_minus = 0x1c,     // 0
-       DW_OP_mod = 0x1d,       // 0
-       DW_OP_mul = 0x1e,       // 0
-       DW_OP_neg = 0x1f,       // 0
-       DW_OP_not = 0x20,       // 0
-       DW_OP_or = 0x21,        // 0
-       DW_OP_plus = 0x22,      // 0
-       DW_OP_plus_uconst = 0x23,       // 1 ULEB128 addend
-       DW_OP_shl = 0x24,       // 0
-       DW_OP_shr = 0x25,       // 0
-       DW_OP_shra = 0x26,      // 0
-       DW_OP_xor = 0x27,       // 0
-       DW_OP_skip = 0x2f,      // 1 signed 2-byte constant
-       DW_OP_bra = 0x28,       // 1 signed 2-byte constant
-       DW_OP_eq = 0x29,        // 0
-       DW_OP_ge = 0x2a,        // 0
-       DW_OP_gt = 0x2b,        // 0
-       DW_OP_le = 0x2c,        // 0
-       DW_OP_lt = 0x2d,        // 0
-       DW_OP_ne = 0x2e,        // 0
-       DW_OP_lit0 = 0x30,      // 0 ...
-       DW_OP_lit31 = 0x4f,     // 0 literals 0..31 = (DW_OP_lit0 +
-       // literal)
-       DW_OP_reg0 = 0x50,      // 0 ..
-       DW_OP_reg31 = 0x6f,     // 0 reg 0..31 = (DW_OP_reg0 + regnum)
-       DW_OP_breg0 = 0x70,     // 1 ...
-       DW_OP_breg31 = 0x8f,    // 1 SLEB128 offset base register 0..31 = (DW_OP_breg0 + regnum)
-       DW_OP_regx = 0x90,      // 1 ULEB128 register
-       DW_OP_fbreg = 0x91,     // 1 SLEB128 offset
-       DW_OP_bregx = 0x92,     // 2 ULEB128 register followed by SLEB128 offset
-       DW_OP_piece = 0x93,     // 1 ULEB128 size of piece addressed
-       DW_OP_deref_size = 0x94,        // 1 1-byte size of data retrieved
-       DW_OP_xderef_size = 0x95,       // 1 1-byte size of data retrieved
-       DW_OP_nop = 0x96,       // 0
-       DW_OP_push_object_address = 0x97,       // 0
-       DW_OP_call2 = 0x98,     // 1 2-byte offset of DIE
-       DW_OP_call4 = 0x99,     // 1 4-byte offset of DIE
-       DW_OP_call_ref = 0x9a,  // 1 4- or 8-byte offset of DIE
-       DW_OP_form_tls_address = 0x9b,  // 0
-       DW_OP_call_frame_cfa = 0x9c,    // 0
-       DW_OP_bit_piece = 0x9d, // 2
-       DW_OP_lo_user = 0xe0,
-       DW_OP_hi_user = 0xff,
-};
-
-// Table 25
-enum
-{
-       DW_ATE_address = 0x01,
-       DW_ATE_boolean = 0x02,
-       DW_ATE_complex_float = 0x03,
-       DW_ATE_float = 0x04,
-       DW_ATE_signed = 0x05,
-       DW_ATE_signed_char = 0x06,
-       DW_ATE_unsigned = 0x07,
-       DW_ATE_unsigned_char = 0x08,
-       DW_ATE_imaginary_float = 0x09,
-       DW_ATE_packed_decimal = 0x0a,
-       DW_ATE_numeric_string = 0x0b,
-       DW_ATE_edited = 0x0c,
-       DW_ATE_signed_fixed = 0x0d,
-       DW_ATE_unsigned_fixed = 0x0e,
-       DW_ATE_decimal_float = 0x0f,
-       DW_ATE_lo_user = 0x80,
-       DW_ATE_hi_user = 0xff,
-};
-
-// Table 26
-enum
-{
-       DW_DS_unsigned = 0x01,
-       DW_DS_leading_overpunch = 0x02,
-       DW_DS_trailing_overpunch = 0x03,
-       DW_DS_leading_separate = 0x04,
-       DW_DS_trailing_separate = 0x05,
-};
-
-// Table 27
-enum
-{
-       DW_END_default = 0x00,
-       DW_END_big = 0x01,
-       DW_END_little = 0x02,
-       DW_END_lo_user = 0x40,
-       DW_END_hi_user = 0xff,
-};
-
-// Table 28
-enum
-{
-       DW_ACCESS_public = 0x01,
-       DW_ACCESS_protected = 0x02,
-       DW_ACCESS_private = 0x03,
-};
-
-// Table 29
-enum
-{
-       DW_VIS_local = 0x01,
-       DW_VIS_exported = 0x02,
-       DW_VIS_qualified = 0x03,
-};
-
-// Table 30
-enum
-{
-       DW_VIRTUALITY_none = 0x00,
-       DW_VIRTUALITY_virtual = 0x01,
-       DW_VIRTUALITY_pure_virtual = 0x02,
-};
-
-// Table 31
-enum
-{
-       DW_LANG_C89 = 0x0001,
-       DW_LANG_C = 0x0002,
-       DW_LANG_Ada83 = 0x0003,
-       DW_LANG_C_plus_plus = 0x0004,
-       DW_LANG_Cobol74 = 0x0005,
-       DW_LANG_Cobol85 = 0x0006,
-       DW_LANG_Fortran77 = 0x0007,
-       DW_LANG_Fortran90 = 0x0008,
-       DW_LANG_Pascal83 = 0x0009,
-       DW_LANG_Modula2 = 0x000a,
-       // Dwarf3
-       DW_LANG_Java = 0x000b,
-       DW_LANG_C99 = 0x000c,
-       DW_LANG_Ada95 = 0x000d,
-       DW_LANG_Fortran95 = 0x000e,
-       DW_LANG_PLI = 0x000f,
-       DW_LANG_ObjC = 0x0010,
-       DW_LANG_ObjC_plus_plus = 0x0011,
-       DW_LANG_UPC = 0x0012,
-       DW_LANG_D = 0x0013,
-       // Dwarf4
-       DW_LANG_Python = 0x0014,
-       // Dwarf5
-       DW_LANG_Go = 0x0016,
-
-       DW_LANG_lo_user = 0x8000,
-       DW_LANG_hi_user = 0xffff,
-};
-
-// Table 32
-enum
-{
-       DW_ID_case_sensitive = 0x00,
-       DW_ID_up_case = 0x01,
-       DW_ID_down_case = 0x02,
-       DW_ID_case_insensitive = 0x03,
-};
-
-// Table 33
-enum
-{
-       DW_CC_normal = 0x01,
-       DW_CC_program = 0x02,
-       DW_CC_nocall = 0x03,
-       DW_CC_lo_user = 0x40,
-       DW_CC_hi_user = 0xff,
-};
-
-// Table 34
-enum
-{
-       DW_INL_not_inlined = 0x00,
-       DW_INL_inlined = 0x01,
-       DW_INL_declared_not_inlined = 0x02,
-       DW_INL_declared_inlined = 0x03,
-};
-
-// Table 35
-enum
-{
-       DW_ORD_row_major = 0x00,
-       DW_ORD_col_major = 0x01,
-};
-
-// Table 36
-enum
-{
-       DW_DSC_label = 0x00,
-       DW_DSC_range = 0x01,
-};
-
-// Table 37
-enum
-{
-       DW_LNS_copy = 0x01,
-       DW_LNS_advance_pc = 0x02,
-       DW_LNS_advance_line = 0x03,
-       DW_LNS_set_file = 0x04,
-       DW_LNS_set_column = 0x05,
-       DW_LNS_negate_stmt = 0x06,
-       DW_LNS_set_basic_block = 0x07,
-       DW_LNS_const_add_pc = 0x08,
-       DW_LNS_fixed_advance_pc = 0x09,
-       // Dwarf3
-       DW_LNS_set_prologue_end = 0x0a,
-       DW_LNS_set_epilogue_begin = 0x0b,
-       DW_LNS_set_isa = 0x0c,
-};
-
-// Table 38
-enum
-{
-       DW_LNE_end_sequence = 0x01,
-       DW_LNE_set_address = 0x02,
-       DW_LNE_define_file = 0x03,
-       DW_LNE_lo_user = 0x80,
-       DW_LNE_hi_user = 0xff,
-};
-
-// Table 39
-enum
-{
-       DW_MACINFO_define = 0x01,
-       DW_MACINFO_undef = 0x02,
-       DW_MACINFO_start_file = 0x03,
-       DW_MACINFO_end_file = 0x04,
-       DW_MACINFO_vendor_ext = 0xff,
-};
-
-// Table 40.
-enum
-{                                      // operand,...
-       DW_CFA_nop = 0x00,
-       DW_CFA_set_loc = 0x01,          // address
-       DW_CFA_advance_loc1 = 0x02,     // 1-byte delta
-       DW_CFA_advance_loc2 = 0x03,     // 2-byte delta
-       DW_CFA_advance_loc4 = 0x04,     // 4-byte delta
-       DW_CFA_offset_extended = 0x05,  // ULEB128 register, ULEB128 offset
-       DW_CFA_restore_extended = 0x06, // ULEB128 register
-       DW_CFA_undefined = 0x07,        // ULEB128 register
-       DW_CFA_same_value = 0x08,       // ULEB128 register
-       DW_CFA_register = 0x09,         // ULEB128 register, ULEB128 register
-       DW_CFA_remember_state = 0x0a,
-       DW_CFA_restore_state = 0x0b,
-       DW_CFA_def_cfa = 0x0c,          // ULEB128 register, ULEB128 offset
-       DW_CFA_def_cfa_register = 0x0d, // ULEB128 register
-       DW_CFA_def_cfa_offset = 0x0e,   // ULEB128 offset
-       DW_CFA_def_cfa_expression = 0x0f, // BLOCK
-       DW_CFA_expression = 0x10,       // ULEB128 register, BLOCK
-       DW_CFA_offset_extended_sf = 0x11, // ULEB128 register, SLEB128 offset
-       DW_CFA_def_cfa_sf = 0x12,       // ULEB128 register, SLEB128 offset
-       DW_CFA_def_cfa_offset_sf = 0x13, // SLEB128 offset
-       DW_CFA_val_offset = 0x14,       // ULEB128, ULEB128
-       DW_CFA_val_offset_sf = 0x15,    // ULEB128, SLEB128
-       DW_CFA_val_expression = 0x16,   // ULEB128, BLOCK
-
-       DW_CFA_lo_user = 0x1c,
-       DW_CFA_hi_user = 0x3f,
-
-       // Opcodes that take an addend operand.
-       DW_CFA_advance_loc = 0x1<<6, // +delta
-       DW_CFA_offset      = 0x2<<6, // +register (ULEB128 offset)
-       DW_CFA_restore     = 0x3<<6, // +register
-};
diff --git a/src/cmd/ld/elf.c b/src/cmd/ld/elf.c
deleted file mode 100644 (file)
index cd7667b..0000000
+++ /dev/null
@@ -1,1685 +0,0 @@
-// 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       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-#include       "lib.h"
-#include       "elf.h"
-#include       "dwarf.h"
-
-/*
- * We use the 64-bit data structures on both 32- and 64-bit machines
- * in order to write the code just once.  The 64-bit data structure is
- * written in the 32-bit format on the 32-bit machines.
- */
-enum {
-       NSECT = 48,
-};
-
-int    iself;
-
-int    nelfsym = 1;
-
-static int     elf64;
-static ElfEhdr ehdr;
-static ElfPhdr *phdr[NSECT];
-static ElfShdr *shdr[NSECT];
-static char    *interp;
-
-typedef struct Elfstring Elfstring;
-struct Elfstring
-{
-       char *s;
-       int off;
-};
-
-static Elfstring elfstr[100];
-static int nelfstr;
-
-static uchar buildinfo[32];
-
-/*
- Initialize the global variable that describes the ELF header. It will be updated as
- we write section and prog headers.
- */
-void
-elfinit(void)
-{
-       iself = 1;
-
-       switch(thearch.thechar) {
-       // 64-bit architectures
-       case '9':
-               if(ctxt->arch->endian == BigEndian)
-                       ehdr.flags = 1;         /* Version 1 ABI */
-               else
-                       ehdr.flags = 2;         /* Version 2 ABI */
-               // fallthrough
-       case '6':
-               elf64 = 1;
-               ehdr.phoff = ELF64HDRSIZE;      /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */
-               ehdr.shoff = ELF64HDRSIZE;      /* Will move as we add PHeaders */
-               ehdr.ehsize = ELF64HDRSIZE;     /* Must be ELF64HDRSIZE */
-               ehdr.phentsize = ELF64PHDRSIZE; /* Must be ELF64PHDRSIZE */
-               ehdr.shentsize = ELF64SHDRSIZE; /* Must be ELF64SHDRSIZE */
-               break;
-
-       // 32-bit architectures
-       case '5':
-               // we use EABI on both linux/arm and freebsd/arm.
-               if(HEADTYPE == Hlinux || HEADTYPE == Hfreebsd)
-                       ehdr.flags = 0x5000002; // has entry point, Version5 EABI
-               // fallthrough
-       default:
-               ehdr.phoff = ELF32HDRSIZE;      /* Must be be ELF32HDRSIZE: first PHdr must follow ELF header */
-               ehdr.shoff = ELF32HDRSIZE;      /* Will move as we add PHeaders */
-               ehdr.ehsize = ELF32HDRSIZE;     /* Must be ELF32HDRSIZE */
-               ehdr.phentsize = ELF32PHDRSIZE; /* Must be ELF32PHDRSIZE */
-               ehdr.shentsize = ELF32SHDRSIZE; /* Must be ELF32SHDRSIZE */
-       }
-}
-
-void
-elf64phdr(ElfPhdr *e)
-{
-       thearch.lput(e->type);
-       thearch.lput(e->flags);
-       thearch.vput(e->off);
-       thearch.vput(e->vaddr);
-       thearch.vput(e->paddr);
-       thearch.vput(e->filesz);
-       thearch.vput(e->memsz);
-       thearch.vput(e->align);
-}
-
-void
-elf32phdr(ElfPhdr *e)
-{
-       int frag;
-       
-       if(e->type == PT_LOAD) {
-               // Correct ELF loaders will do this implicitly,
-               // but buggy ELF loaders like the one in some
-               // versions of QEMU won't.
-               frag = e->vaddr&(e->align-1);
-               e->off -= frag;
-               e->vaddr -= frag;
-               e->paddr -= frag;
-               e->filesz += frag;
-               e->memsz += frag;
-       }
-       thearch.lput(e->type);
-       thearch.lput(e->off);
-       thearch.lput(e->vaddr);
-       thearch.lput(e->paddr);
-       thearch.lput(e->filesz);
-       thearch.lput(e->memsz);
-       thearch.lput(e->flags);
-       thearch.lput(e->align);
-}
-
-void
-elf64shdr(ElfShdr *e)
-{
-       thearch.lput(e->name);
-       thearch.lput(e->type);
-       thearch.vput(e->flags);
-       thearch.vput(e->addr);
-       thearch.vput(e->off);
-       thearch.vput(e->size);
-       thearch.lput(e->link);
-       thearch.lput(e->info);
-       thearch.vput(e->addralign);
-       thearch.vput(e->entsize);
-}
-
-void
-elf32shdr(ElfShdr *e)
-{
-       thearch.lput(e->name);
-       thearch.lput(e->type);
-       thearch.lput(e->flags);
-       thearch.lput(e->addr);
-       thearch.lput(e->off);
-       thearch.lput(e->size);
-       thearch.lput(e->link);
-       thearch.lput(e->info);
-       thearch.lput(e->addralign);
-       thearch.lput(e->entsize);
-}
-
-uint32
-elfwriteshdrs(void)
-{
-       int i;
-
-       if (elf64) {
-               for (i = 0; i < ehdr.shnum; i++)
-                       elf64shdr(shdr[i]);
-               return ehdr.shnum * ELF64SHDRSIZE;
-       }
-       for (i = 0; i < ehdr.shnum; i++)
-               elf32shdr(shdr[i]);
-       return ehdr.shnum * ELF32SHDRSIZE;
-}
-
-void
-elfsetstring(char *s, int off)
-{
-       if(nelfstr >= nelem(elfstr)) {
-               diag("too many elf strings");
-               errorexit();
-       }
-       elfstr[nelfstr].s = s;
-       elfstr[nelfstr].off = off;
-       nelfstr++;
-}
-
-uint32
-elfwritephdrs(void)
-{
-       int i;
-
-       if (elf64) {
-               for (i = 0; i < ehdr.phnum; i++)
-                       elf64phdr(phdr[i]);
-               return ehdr.phnum * ELF64PHDRSIZE;
-       }
-       for (i = 0; i < ehdr.phnum; i++)
-               elf32phdr(phdr[i]);
-       return ehdr.phnum * ELF32PHDRSIZE;
-}
-
-ElfPhdr*
-newElfPhdr(void)
-{
-       ElfPhdr *e;
-
-       e = mal(sizeof *e);
-       if (ehdr.phnum >= NSECT)
-               diag("too many phdrs");
-       else
-               phdr[ehdr.phnum++] = e;
-       if (elf64)
-               ehdr.shoff += ELF64PHDRSIZE;
-       else
-               ehdr.shoff += ELF32PHDRSIZE;
-       return e;
-}
-
-ElfShdr*
-newElfShdr(vlong name)
-{
-       ElfShdr *e;
-
-       e = mal(sizeof *e);
-       e->name = name;
-       e->shnum = ehdr.shnum;
-       if (ehdr.shnum >= NSECT) {
-               diag("too many shdrs");
-       } else {
-               shdr[ehdr.shnum++] = e;
-       }
-       return e;
-}
-
-ElfEhdr*
-getElfEhdr(void)
-{
-       return &ehdr;
-}
-
-uint32
-elf64writehdr(void)
-{
-       int i;
-
-       for (i = 0; i < EI_NIDENT; i++)
-               cput(ehdr.ident[i]);
-       thearch.wput(ehdr.type);
-       thearch.wput(ehdr.machine);
-       thearch.lput(ehdr.version);
-       thearch.vput(ehdr.entry);
-       thearch.vput(ehdr.phoff);
-       thearch.vput(ehdr.shoff);
-       thearch.lput(ehdr.flags);
-       thearch.wput(ehdr.ehsize);
-       thearch.wput(ehdr.phentsize);
-       thearch.wput(ehdr.phnum);
-       thearch.wput(ehdr.shentsize);
-       thearch.wput(ehdr.shnum);
-       thearch.wput(ehdr.shstrndx);
-       return ELF64HDRSIZE;
-}
-
-uint32
-elf32writehdr(void)
-{
-       int i;
-
-       for (i = 0; i < EI_NIDENT; i++)
-               cput(ehdr.ident[i]);
-       thearch.wput(ehdr.type);
-       thearch.wput(ehdr.machine);
-       thearch.lput(ehdr.version);
-       thearch.lput(ehdr.entry);
-       thearch.lput(ehdr.phoff);
-       thearch.lput(ehdr.shoff);
-       thearch.lput(ehdr.flags);
-       thearch.wput(ehdr.ehsize);
-       thearch.wput(ehdr.phentsize);
-       thearch.wput(ehdr.phnum);
-       thearch.wput(ehdr.shentsize);
-       thearch.wput(ehdr.shnum);
-       thearch.wput(ehdr.shstrndx);
-       return ELF32HDRSIZE;
-}
-
-uint32
-elfwritehdr(void)
-{
-       if(elf64)
-               return elf64writehdr();
-       return elf32writehdr();
-}
-
-/* Taken directly from the definition document for ELF64 */
-uint32
-elfhash(uchar *name)
-{
-       uint32 h = 0, g;
-       while (*name) {
-               h = (h << 4) + *name++;
-               if (g = h & 0xf0000000)
-                       h ^= g >> 24;
-               h &= 0x0fffffff;
-       }
-       return h;
-}
-
-void
-elfwritedynent(LSym *s, int tag, uint64 val)
-{
-       if(elf64) {
-               adduint64(ctxt, s, tag);
-               adduint64(ctxt, s, val);
-       } else {
-               adduint32(ctxt, s, tag);
-               adduint32(ctxt, s, val);
-       }
-}
-
-void
-elfwritedynentsym(LSym *s, int tag, LSym *t)
-{
-       elfwritedynentsymplus(s, tag, t, 0);
-}
-
-void
-elfwritedynentsymplus(LSym *s, int tag, LSym *t, vlong add)
-{
-       if(elf64)
-               adduint64(ctxt, s, tag);
-       else
-               adduint32(ctxt, s, tag);
-       addaddrplus(ctxt, s, t, add);
-}
-
-void
-elfwritedynentsymsize(LSym *s, int tag, LSym *t)
-{
-       if(elf64)
-               adduint64(ctxt, s, tag);
-       else
-               adduint32(ctxt, s, tag);
-       addsize(ctxt, s, t);
-}
-
-int
-elfinterp(ElfShdr *sh, uint64 startva, uint64 resoff, char *p)
-{
-       int n;
-
-       interp = p;
-       n = strlen(interp)+1;
-       sh->addr = startva + resoff - n;
-       sh->off = resoff - n;
-       sh->size = n;
-
-       return n;
-}
-
-int
-elfwriteinterp(void)
-{
-       ElfShdr *sh;
-       
-       sh = elfshname(".interp");
-       cseek(sh->off);
-       cwrite(interp, sh->size);
-       return sh->size;
-}
-
-int
-elfnote(ElfShdr *sh, uint64 startva, uint64 resoff, int sz)
-{
-       uint64 n;
-
-       n = sizeof(Elf_Note) + sz + resoff % 4;
-
-       sh->type = SHT_NOTE;
-       sh->flags = SHF_ALLOC;
-       sh->addralign = 4;
-       sh->addr = startva + resoff - n;
-       sh->off = resoff - n;
-       sh->size = n - resoff % 4;
-
-       return n;
-}
-
-ElfShdr *
-elfwritenotehdr(char *str, uint32 namesz, uint32 descsz, uint32 tag)
-{
-       ElfShdr *sh;
-       
-       sh = elfshname(str);
-
-       // Write Elf_Note header.
-       cseek(sh->off);
-       thearch.lput(namesz);
-       thearch.lput(descsz);
-       thearch.lput(tag);
-
-       return sh;
-}
-
-// NetBSD Signature (as per sys/exec_elf.h)
-enum {
-       ELF_NOTE_NETBSD_NAMESZ = 7,
-       ELF_NOTE_NETBSD_DESCSZ = 4,
-       ELF_NOTE_NETBSD_TAG = 1,
-       ELF_NOTE_NETBSD_VERSION = 599000000,    /* NetBSD 5.99 */
-};
-
-char ELF_NOTE_NETBSD_NAME[] = "NetBSD\x00\x00";
-
-int
-elfnetbsdsig(ElfShdr *sh, uint64 startva, uint64 resoff)
-{
-       int n;
-
-       n = rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + rnd(ELF_NOTE_NETBSD_DESCSZ, 4);
-       return elfnote(sh, startva, resoff, n);
-}
-
-int
-elfwritenetbsdsig(void)
-{
-       ElfShdr *sh;
-
-       // Write Elf_Note header.
-       sh = elfwritenotehdr(".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG);
-       if(sh == nil)
-               return 0;
-
-       // Followed by NetBSD string and version.
-       cwrite(ELF_NOTE_NETBSD_NAME, ELF_NOTE_NETBSD_NAMESZ + 1);
-       thearch.lput(ELF_NOTE_NETBSD_VERSION);
-
-       return sh->size;
-}
-
-// OpenBSD Signature
-enum {
-       ELF_NOTE_OPENBSD_NAMESZ = 8,
-       ELF_NOTE_OPENBSD_DESCSZ = 4,
-       ELF_NOTE_OPENBSD_TAG = 1,
-       ELF_NOTE_OPENBSD_VERSION = 0,
-};
-char ELF_NOTE_OPENBSD_NAME[] = "OpenBSD\x00";
-
-int
-elfopenbsdsig(ElfShdr *sh, uint64 startva, uint64 resoff)
-{
-       int n;
-
-       n = ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ;
-       return elfnote(sh, startva, resoff, n);
-}
-
-int
-elfwriteopenbsdsig(void)
-{
-       ElfShdr *sh;
-
-       // Write Elf_Note header.
-       sh = elfwritenotehdr(".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG);
-       if(sh == nil)
-               return 0;
-
-       // Followed by OpenBSD string and version.
-       cwrite(ELF_NOTE_OPENBSD_NAME, ELF_NOTE_OPENBSD_NAMESZ);
-       thearch.lput(ELF_NOTE_OPENBSD_VERSION);
-
-       return sh->size;
-}
-
-void
-addbuildinfo(char *val)
-{
-       char *ov;
-       int i, b, j;
-
-       if(val[0] != '0' || val[1] != 'x') {
-               fprint(2, "%s: -B argument must start with 0x: %s\n", argv0, val);
-               exits("usage");
-       }
-       ov = val;
-       val += 2;
-       i = 0;
-       while(*val != '\x00') {
-               if(val[1] == '\x00') {
-                       fprint(2, "%s: -B argument must have even number of digits: %s\n", argv0, ov);
-                       exits("usage");
-               }
-               b = 0;
-               for(j = 0; j < 2; j++, val++) {
-                       b *= 16;
-                       if(*val >= '0' && *val <= '9')
-                               b += *val - '0';
-                       else if(*val >= 'a' && *val <= 'f')
-                               b += *val - 'a' + 10;
-                       else if(*val >= 'A' && *val <= 'F')
-                               b += *val - 'A' + 10;
-                       else {
-                               fprint(2, "%s: -B argument contains invalid hex digit %c: %s\n", argv0, *val, ov);
-                               exits("usage");
-                       }
-               }
-               if(i >= nelem(buildinfo)) {
-                       fprint(2, "%s: -B option too long (max %d digits): %s\n", argv0, (int)nelem(buildinfo), ov);
-                       exits("usage");
-               }
-               buildinfo[i++] = b;
-       }
-       buildinfolen = i;
-}
-
-// Build info note
-enum {
-       ELF_NOTE_BUILDINFO_NAMESZ = 4,
-       ELF_NOTE_BUILDINFO_TAG = 3,
-};
-
-char ELF_NOTE_BUILDINFO_NAME[] = "GNU\x00";
-
-int
-elfbuildinfo(ElfShdr *sh, uint64 startva, uint64 resoff)
-{
-       int n;
-
-       n = ELF_NOTE_BUILDINFO_NAMESZ + rnd(buildinfolen, 4);
-       return elfnote(sh, startva, resoff, n);
-}
-
-int
-elfwritebuildinfo(void)
-{
-       ElfShdr *sh;
-
-       sh = elfwritenotehdr(".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, buildinfolen, ELF_NOTE_BUILDINFO_TAG);
-       if(sh == nil)
-               return 0;
-
-       cwrite(ELF_NOTE_BUILDINFO_NAME, ELF_NOTE_BUILDINFO_NAMESZ);
-       cwrite(buildinfo, buildinfolen);
-       cwrite("\x00\x00\x00", rnd(buildinfolen, 4) - buildinfolen);
-
-       return sh->size;
-}
-
-int elfverneed;
-
-typedef struct Elfaux Elfaux;
-typedef struct Elflib Elflib;
-
-struct Elflib
-{
-       Elflib *next;
-       Elfaux *aux;
-       char *file;
-};
-
-struct Elfaux
-{
-       Elfaux *next;
-       int num;
-       char *vers;
-};
-
-Elfaux*
-addelflib(Elflib **list, char *file, char *vers)
-{
-       Elflib *lib;
-       Elfaux *aux;
-       
-       for(lib=*list; lib; lib=lib->next)
-               if(strcmp(lib->file, file) == 0)
-                       goto havelib;
-       lib = mal(sizeof *lib);
-       lib->next = *list;
-       lib->file = file;
-       *list = lib;
-havelib:
-       for(aux=lib->aux; aux; aux=aux->next)
-               if(strcmp(aux->vers, vers) == 0)
-                       goto haveaux;
-       aux = mal(sizeof *aux);
-       aux->next = lib->aux;
-       aux->vers = vers;
-       lib->aux = aux;
-haveaux:
-       return aux;
-}
-
-void
-elfdynhash(void)
-{
-       LSym *s, *sy, *dynstr;
-       int i, j, nbucket, b, nfile;
-       uint32 hc, *chain, *buckets;
-       int nsym;
-       char *name;
-       Elfaux **need;
-       Elflib *needlib;
-       Elflib *l;
-       Elfaux *x;
-       
-       if(!iself)
-               return;
-
-       nsym = nelfsym;
-       s = linklookup(ctxt, ".hash", 0);
-       s->type = SELFROSECT;
-       s->reachable = 1;
-
-       i = nsym;
-       nbucket = 1;
-       while(i > 0) {
-               ++nbucket;
-               i >>= 1;
-       }
-
-       needlib = nil;
-       need = malloc(nsym * sizeof need[0]);
-       chain = malloc(nsym * sizeof chain[0]);
-       buckets = malloc(nbucket * sizeof buckets[0]);
-       if(need == nil || chain == nil || buckets == nil) {
-               ctxt->cursym = nil;
-               diag("out of memory");
-               errorexit();
-       }
-       memset(need, 0, nsym * sizeof need[0]);
-       memset(chain, 0, nsym * sizeof chain[0]);
-       memset(buckets, 0, nbucket * sizeof buckets[0]);
-       for(sy=ctxt->allsym; sy!=nil; sy=sy->allsym) {
-               if (sy->dynid <= 0)
-                       continue;
-
-               if(sy->dynimpvers)
-                       need[sy->dynid] = addelflib(&needlib, sy->dynimplib, sy->dynimpvers);
-
-               name = sy->extname;
-               hc = elfhash((uchar*)name);
-
-               b = hc % nbucket;
-               chain[sy->dynid] = buckets[b];
-               buckets[b] = sy->dynid;
-       }
-
-       adduint32(ctxt, s, nbucket);
-       adduint32(ctxt, s, nsym);
-       for(i = 0; i<nbucket; i++)
-               adduint32(ctxt, s, buckets[i]);
-       for(i = 0; i<nsym; i++)
-               adduint32(ctxt, s, chain[i]);
-
-       free(chain);
-       free(buckets);
-       
-       // version symbols
-       dynstr = linklookup(ctxt, ".dynstr", 0);
-       s = linklookup(ctxt, ".gnu.version_r", 0);
-       i = 2;
-       nfile = 0;
-       for(l=needlib; l; l=l->next) {
-               nfile++;
-               // header
-               adduint16(ctxt, s, 1);  // table version
-               j = 0;
-               for(x=l->aux; x; x=x->next)
-                       j++;
-               adduint16(ctxt, s, j);  // aux count
-               adduint32(ctxt, s, addstring(dynstr, l->file));  // file string offset
-               adduint32(ctxt, s, 16);  // offset from header to first aux
-               if(l->next)
-                       adduint32(ctxt, s, 16+j*16);  // offset from this header to next
-               else
-                       adduint32(ctxt, s, 0);
-               
-               for(x=l->aux; x; x=x->next) {
-                       x->num = i++;
-                       // aux struct
-                       adduint32(ctxt, s, elfhash((uchar*)x->vers));  // hash
-                       adduint16(ctxt, s, 0);  // flags
-                       adduint16(ctxt, s, x->num);  // other - index we refer to this by
-                       adduint32(ctxt, s, addstring(dynstr, x->vers));  // version string offset
-                       if(x->next)
-                               adduint32(ctxt, s, 16);  // offset from this aux to next
-                       else
-                               adduint32(ctxt, s, 0);
-               }
-       }
-
-       // version references
-       s = linklookup(ctxt, ".gnu.version", 0);
-       for(i=0; i<nsym; i++) {
-               if(i == 0)
-                       adduint16(ctxt, s, 0); // first entry - no symbol
-               else if(need[i] == nil)
-                       adduint16(ctxt, s, 1); // global
-               else
-                       adduint16(ctxt, s, need[i]->num);
-       }
-
-       free(need);
-
-       s = linklookup(ctxt, ".dynamic", 0);
-       elfverneed = nfile;
-       if(elfverneed) {
-               elfwritedynentsym(s, DT_VERNEED, linklookup(ctxt, ".gnu.version_r", 0));
-               elfwritedynent(s, DT_VERNEEDNUM, nfile);
-               elfwritedynentsym(s, DT_VERSYM, linklookup(ctxt, ".gnu.version", 0));
-       }
-
-       if(thearch.thechar == '6' || thearch.thechar == '9') {
-               sy = linklookup(ctxt, ".rela.plt", 0);
-               if(sy->size > 0) {
-                       elfwritedynent(s, DT_PLTREL, DT_RELA);
-                       elfwritedynentsymsize(s, DT_PLTRELSZ, sy);
-                       elfwritedynentsym(s, DT_JMPREL, sy);
-               }
-       } else {
-               sy = linklookup(ctxt, ".rel.plt", 0);
-               if(sy->size > 0) {
-                       elfwritedynent(s, DT_PLTREL, DT_REL);
-                       elfwritedynentsymsize(s, DT_PLTRELSZ, sy);
-                       elfwritedynentsym(s, DT_JMPREL, sy);
-               }
-       }
-
-       elfwritedynent(s, DT_NULL, 0);
-}
-
-ElfPhdr*
-elfphload(Segment *seg)
-{
-       ElfPhdr *ph;
-       
-       ph = newElfPhdr();
-       ph->type = PT_LOAD;
-       if(seg->rwx & 4)
-               ph->flags |= PF_R;
-       if(seg->rwx & 2)
-               ph->flags |= PF_W;
-       if(seg->rwx & 1)
-               ph->flags |= PF_X;
-       ph->vaddr = seg->vaddr;
-       ph->paddr = seg->vaddr;
-       ph->memsz = seg->length;
-       ph->off = seg->fileoff;
-       ph->filesz = seg->filelen;
-       ph->align = INITRND;
-       
-       return ph;
-}
-
-ElfShdr*
-elfshname(char *name)
-{
-       int i, off;
-       ElfShdr *sh;
-       
-       for(i=0; i<nelfstr; i++) {
-               if(strcmp(name, elfstr[i].s) == 0) {
-                       off = elfstr[i].off;
-                       goto found;
-               }
-       }
-       diag("cannot find elf name %s", name);
-       errorexit();
-       return nil;
-
-found:
-       for(i=0; i<ehdr.shnum; i++) {
-               sh = shdr[i];
-               if(sh->name == off)
-                       return sh;
-       }
-       
-       sh = newElfShdr(off);
-       return sh;
-}
-
-ElfShdr*
-elfshalloc(Section *sect)
-{
-       ElfShdr *sh;
-       
-       sh = elfshname(sect->name);
-       sect->elfsect = sh;
-       return sh;
-}
-
-ElfShdr*
-elfshbits(Section *sect)
-{
-       ElfShdr *sh;
-       
-       sh = elfshalloc(sect);
-       if(sh->type > 0)
-               return sh;
-
-       if(sect->vaddr < sect->seg->vaddr + sect->seg->filelen)
-               sh->type = SHT_PROGBITS;
-       else
-               sh->type = SHT_NOBITS;
-       sh->flags = SHF_ALLOC;
-       if(sect->rwx & 1)
-               sh->flags |= SHF_EXECINSTR;
-       if(sect->rwx & 2)
-               sh->flags |= SHF_WRITE;
-       if(strcmp(sect->name, ".tbss") == 0) {
-               if(strcmp(goos, "android") != 0)
-                       sh->flags |= SHF_TLS; // no TLS on android
-               sh->type = SHT_NOBITS;
-       }
-       if(linkmode != LinkExternal)
-               sh->addr = sect->vaddr;
-       sh->addralign = sect->align;
-       sh->size = sect->length;
-       sh->off = sect->seg->fileoff + sect->vaddr - sect->seg->vaddr;
-
-       return sh;
-}
-
-ElfShdr*
-elfshreloc(Section *sect)
-{
-       int typ;
-       ElfShdr *sh;
-       char *prefix;
-       char buf[100];
-       
-       // If main section is SHT_NOBITS, nothing to relocate.
-       // Also nothing to relocate in .shstrtab.
-       if(sect->vaddr >= sect->seg->vaddr + sect->seg->filelen)
-               return nil;
-       if(strcmp(sect->name, ".shstrtab") == 0 || strcmp(sect->name, ".tbss") == 0)
-               return nil;
-
-       if(thearch.thechar == '6' || thearch.thechar == '9') {
-               prefix = ".rela";
-               typ = SHT_RELA;
-       } else {
-               prefix = ".rel";
-               typ = SHT_REL;
-       }
-
-       snprint(buf, sizeof buf, "%s%s", prefix, sect->name);
-       sh = elfshname(buf);
-       sh->type = typ;
-       sh->entsize = thearch.regsize*(2+(typ==SHT_RELA));
-       sh->link = elfshname(".symtab")->shnum;
-       sh->info = ((ElfShdr*)sect->elfsect)->shnum;
-       sh->off = sect->reloff;
-       sh->size = sect->rellen;
-       sh->addralign = thearch.regsize;
-       return sh;
-}
-
-void
-elfrelocsect(Section *sect, LSym *first)
-{
-       int ri;
-       LSym *sym;
-       int32 eaddr;
-       Reloc *r;
-
-       // If main section is SHT_NOBITS, nothing to relocate.
-       // Also nothing to relocate in .shstrtab.
-       if(sect->vaddr >= sect->seg->vaddr + sect->seg->filelen)
-               return;
-       if(strcmp(sect->name, ".shstrtab") == 0)
-               return;
-
-       sect->reloff = cpos();
-       for(sym = first; sym != nil; sym = sym->next) {
-               if(!sym->reachable)
-                       continue;
-               if(sym->value >= sect->vaddr)
-                       break;
-       }
-       
-       eaddr = sect->vaddr + sect->length;
-       for(; sym != nil; sym = sym->next) {
-               if(!sym->reachable)
-                       continue;
-               if(sym->value >= eaddr)
-                       break;
-               ctxt->cursym = sym;
-               
-               for(ri=0; ri<sym->nr; ri++) {
-                       r = &sym->r[ri];
-                       if(r->done)
-                               continue;
-                       if(r->xsym == nil) {
-                               diag("missing xsym in relocation");
-                               continue;
-                       }
-                       if(r->xsym->elfsym == 0)
-                               diag("reloc %d to non-elf symbol %s (outer=%s) %d", r->type, r->sym->name, r->xsym->name, r->sym->type);
-                       if(thearch.elfreloc1(r, sym->value+r->off - sect->vaddr) < 0)
-                               diag("unsupported obj reloc %d/%d to %s", r->type, r->siz, r->sym->name);
-               }
-       }
-               
-       sect->rellen = cpos() - sect->reloff;
-}      
-       
-void
-elfemitreloc(void)
-{
-       Section *sect;
-
-       while(cpos()&7)
-               cput(0);
-
-       elfrelocsect(segtext.sect, ctxt->textp);
-       for(sect=segtext.sect->next; sect!=nil; sect=sect->next)
-               elfrelocsect(sect, datap);      
-       for(sect=segrodata.sect; sect!=nil; sect=sect->next)
-               elfrelocsect(sect, datap);      
-       for(sect=segdata.sect; sect!=nil; sect=sect->next)
-               elfrelocsect(sect, datap);      
-}
-
-void
-doelf(void)
-{
-       LSym *s, *shstrtab, *dynstr;
-
-       if(!iself)
-               return;
-
-       /* predefine strings we need for section headers */
-       shstrtab = linklookup(ctxt, ".shstrtab", 0);
-       shstrtab->type = SELFROSECT;
-       shstrtab->reachable = 1;
-
-       addstring(shstrtab, "");
-       addstring(shstrtab, ".text");
-       addstring(shstrtab, ".noptrdata");
-       addstring(shstrtab, ".data");
-       addstring(shstrtab, ".bss");
-       addstring(shstrtab, ".noptrbss");
-       // generate .tbss section (except for OpenBSD where it's not supported)
-       // for dynamic internal linker or external linking, so that various
-       // binutils could correctly calculate PT_TLS size.
-       // see http://golang.org/issue/5200.
-       if(HEADTYPE != Hopenbsd)
-       if(!debug['d'] || linkmode == LinkExternal)
-               addstring(shstrtab, ".tbss");
-       if(HEADTYPE == Hnetbsd)
-               addstring(shstrtab, ".note.netbsd.ident");
-       if(HEADTYPE == Hopenbsd)
-               addstring(shstrtab, ".note.openbsd.ident");
-       if(buildinfolen > 0)
-               addstring(shstrtab, ".note.gnu.build-id");
-       addstring(shstrtab, ".elfdata");
-       addstring(shstrtab, ".rodata");
-       addstring(shstrtab, ".typelink");
-       addstring(shstrtab, ".gosymtab");
-       addstring(shstrtab, ".gopclntab");
-       
-       if(linkmode == LinkExternal) {
-               debug_s = debug['s'];
-               debug['s'] = 0;
-               debug['d'] = 1;
-
-               if(thearch.thechar == '6' || thearch.thechar == '9') {
-                       addstring(shstrtab, ".rela.text");
-                       addstring(shstrtab, ".rela.rodata");
-                       addstring(shstrtab, ".rela.typelink");
-                       addstring(shstrtab, ".rela.gosymtab");
-                       addstring(shstrtab, ".rela.gopclntab");
-                       addstring(shstrtab, ".rela.noptrdata");
-                       addstring(shstrtab, ".rela.data");
-               } else {
-                       addstring(shstrtab, ".rel.text");
-                       addstring(shstrtab, ".rel.rodata");
-                       addstring(shstrtab, ".rel.typelink");
-                       addstring(shstrtab, ".rel.gosymtab");
-                       addstring(shstrtab, ".rel.gopclntab");
-                       addstring(shstrtab, ".rel.noptrdata");
-                       addstring(shstrtab, ".rel.data");
-               }
-               // add a .note.GNU-stack section to mark the stack as non-executable
-               addstring(shstrtab, ".note.GNU-stack");
-       }
-
-       if(flag_shared) {
-               addstring(shstrtab, ".init_array");
-               if(thearch.thechar == '6' || thearch.thechar == '9')
-                       addstring(shstrtab, ".rela.init_array");
-               else
-                       addstring(shstrtab, ".rel.init_array");
-       }
-
-       if(!debug['s']) {
-               addstring(shstrtab, ".symtab");
-               addstring(shstrtab, ".strtab");
-               dwarfaddshstrings(shstrtab);
-       }
-       addstring(shstrtab, ".shstrtab");
-
-       if(!debug['d']) {       /* -d suppresses dynamic loader format */
-               addstring(shstrtab, ".interp");
-               addstring(shstrtab, ".hash");
-               addstring(shstrtab, ".got");
-               if(thearch.thechar == '9')
-                       addstring(shstrtab, ".glink");
-               addstring(shstrtab, ".got.plt");
-               addstring(shstrtab, ".dynamic");
-               addstring(shstrtab, ".dynsym");
-               addstring(shstrtab, ".dynstr");
-               if(thearch.thechar == '6' || thearch.thechar == '9') {
-                       addstring(shstrtab, ".rela");
-                       addstring(shstrtab, ".rela.plt");
-               } else {
-                       addstring(shstrtab, ".rel");
-                       addstring(shstrtab, ".rel.plt");
-               }
-               addstring(shstrtab, ".plt");
-               addstring(shstrtab, ".gnu.version");
-               addstring(shstrtab, ".gnu.version_r");
-
-               /* dynamic symbol table - first entry all zeros */
-               s = linklookup(ctxt, ".dynsym", 0);
-               s->type = SELFROSECT;
-               s->reachable = 1;
-               if(thearch.thechar == '6' || thearch.thechar == '9')
-                       s->size += ELF64SYMSIZE;
-               else
-                       s->size += ELF32SYMSIZE;
-
-               /* dynamic string table */
-               s = linklookup(ctxt, ".dynstr", 0);
-               s->type = SELFROSECT;
-               s->reachable = 1;
-               if(s->size == 0)
-                       addstring(s, "");
-               dynstr = s;
-
-               /* relocation table */
-               if(thearch.thechar == '6' || thearch.thechar == '9')
-                       s = linklookup(ctxt, ".rela", 0);
-               else
-                       s = linklookup(ctxt, ".rel", 0);
-               s->reachable = 1;
-               s->type = SELFROSECT;
-
-               /* global offset table */
-               s = linklookup(ctxt, ".got", 0);
-               s->reachable = 1;
-               s->type = SELFGOT; // writable
-
-               /* ppc64 glink resolver */
-               if(thearch.thechar == '9') {
-                       s = linklookup(ctxt, ".glink", 0);
-                       s->reachable = 1;
-                       s->type = SELFRXSECT;
-               }
-
-               /* hash */
-               s = linklookup(ctxt, ".hash", 0);
-               s->reachable = 1;
-               s->type = SELFROSECT;
-
-               s = linklookup(ctxt, ".got.plt", 0);
-               s->reachable = 1;
-               s->type = SELFSECT; // writable
-
-               s = linklookup(ctxt, ".plt", 0);
-               s->reachable = 1;
-               if(thearch.thechar == '9')
-                       // In the ppc64 ABI, .plt is a data section
-                       // written by the dynamic linker.
-                       s->type = SELFSECT;
-               else
-                       s->type = SELFRXSECT;
-               
-               thearch.elfsetupplt();
-               
-               if(thearch.thechar == '6' || thearch.thechar == '9')
-                       s = linklookup(ctxt, ".rela.plt", 0);
-               else
-                       s = linklookup(ctxt, ".rel.plt", 0);
-               s->reachable = 1;
-               s->type = SELFROSECT;
-               
-               s = linklookup(ctxt, ".gnu.version", 0);
-               s->reachable = 1;
-               s->type = SELFROSECT;
-               
-               s = linklookup(ctxt, ".gnu.version_r", 0);
-               s->reachable = 1;
-               s->type = SELFROSECT;
-
-               /* define dynamic elf table */
-               s = linklookup(ctxt, ".dynamic", 0);
-               s->reachable = 1;
-               s->type = SELFSECT; // writable
-
-               /*
-                * .dynamic table
-                */
-               elfwritedynentsym(s, DT_HASH, linklookup(ctxt, ".hash", 0));
-               elfwritedynentsym(s, DT_SYMTAB, linklookup(ctxt, ".dynsym", 0));
-               if(thearch.thechar == '6' || thearch.thechar == '9')
-                       elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE);
-               else
-                       elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE);
-               elfwritedynentsym(s, DT_STRTAB, linklookup(ctxt, ".dynstr", 0));
-               elfwritedynentsymsize(s, DT_STRSZ, linklookup(ctxt, ".dynstr", 0));
-               if(thearch.thechar == '6' || thearch.thechar == '9') {
-                       elfwritedynentsym(s, DT_RELA, linklookup(ctxt, ".rela", 0));
-                       elfwritedynentsymsize(s, DT_RELASZ, linklookup(ctxt, ".rela", 0));
-                       elfwritedynent(s, DT_RELAENT, ELF64RELASIZE);
-               } else {
-                       elfwritedynentsym(s, DT_REL, linklookup(ctxt, ".rel", 0));
-                       elfwritedynentsymsize(s, DT_RELSZ, linklookup(ctxt, ".rel", 0));
-                       elfwritedynent(s, DT_RELENT, ELF32RELSIZE);
-               }
-               if(rpath)
-                       elfwritedynent(s, DT_RUNPATH, addstring(dynstr, rpath));
-
-               if(thearch.thechar == '9')
-                       elfwritedynentsym(s, DT_PLTGOT, linklookup(ctxt, ".plt", 0));
-               else
-                       elfwritedynentsym(s, DT_PLTGOT, linklookup(ctxt, ".got.plt", 0));
-
-               if(thearch.thechar == '9')
-                       elfwritedynent(s, DT_PPC64_OPT, 0);
-
-               // Solaris dynamic linker can't handle an empty .rela.plt if
-               // DT_JMPREL is emitted so we have to defer generation of DT_PLTREL,
-               // DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the
-               // size of .rel(a).plt section.
-               elfwritedynent(s, DT_DEBUG, 0);
-
-               // Do not write DT_NULL.  elfdynhash will finish it.
-       }
-}
-
-void
-shsym(ElfShdr *sh, LSym *s)
-{
-       vlong addr;
-       addr = symaddr(s);
-       if(sh->flags&SHF_ALLOC)
-               sh->addr = addr;
-       sh->off = datoff(addr);
-       sh->size = s->size;
-}
-
-void
-phsh(ElfPhdr *ph, ElfShdr *sh)
-{
-       ph->vaddr = sh->addr;
-       ph->paddr = ph->vaddr;
-       ph->off = sh->off;
-       ph->filesz = sh->size;
-       ph->memsz = sh->size;
-       ph->align = sh->addralign;
-}
-
-void
-asmbelfsetup(void)
-{
-       Section *sect;
-
-       /* This null SHdr must appear before all others */
-       elfshname("");
-       
-       for(sect=segtext.sect; sect!=nil; sect=sect->next)
-               elfshalloc(sect);
-       for(sect=segrodata.sect; sect!=nil; sect=sect->next)
-               elfshalloc(sect);
-       for(sect=segdata.sect; sect!=nil; sect=sect->next)
-               elfshalloc(sect);
-}
-
-void
-asmbelf(vlong symo)
-{
-       vlong a, o;
-       vlong startva, resoff;
-       ElfEhdr *eh;
-       ElfPhdr *ph, *pph, *pnote;
-       ElfShdr *sh;
-       Section *sect;
-
-       eh = getElfEhdr();
-       switch(thearch.thechar) {
-       default:
-               diag("unknown architecture in asmbelf");
-               errorexit();
-       case '5':
-               eh->machine = EM_ARM;
-               break;
-       case '6':
-               eh->machine = EM_X86_64;
-               break;
-       case '8':
-               eh->machine = EM_386;
-               break;
-       case '9':
-               eh->machine = EM_PPC64;
-               break;
-       }
-
-       startva = INITTEXT - HEADR;
-       resoff = ELFRESERVE;
-       
-       pph = nil;
-       if(linkmode == LinkExternal) {
-               /* skip program headers */
-               eh->phoff = 0;
-               eh->phentsize = 0;
-               goto elfobj;
-       }
-
-       /* program header info */
-       pph = newElfPhdr();
-       pph->type = PT_PHDR;
-       pph->flags = PF_R;
-       pph->off = eh->ehsize;
-       pph->vaddr = INITTEXT - HEADR + pph->off;
-       pph->paddr = INITTEXT - HEADR + pph->off;
-       pph->align = INITRND;
-
-       /*
-        * PHDR must be in a loaded segment. Adjust the text
-        * segment boundaries downwards to include it.
-        * Except on NaCl where it must not be loaded.
-        */
-       if(HEADTYPE != Hnacl) {
-               o = segtext.vaddr - pph->vaddr;
-               segtext.vaddr -= o;
-               segtext.length += o;
-               o = segtext.fileoff - pph->off;
-               segtext.fileoff -= o;
-               segtext.filelen += o;
-       }
-
-       if(!debug['d']) {
-               /* interpreter */
-               sh = elfshname(".interp");
-               sh->type = SHT_PROGBITS;
-               sh->flags = SHF_ALLOC;
-               sh->addralign = 1;
-               if(interpreter == nil) {
-                       switch(HEADTYPE) {
-                       case Hlinux:
-                               interpreter = thearch.linuxdynld;
-                               break;
-                       case Hfreebsd:
-                               interpreter = thearch.freebsddynld;
-                               break;
-                       case Hnetbsd:
-                               interpreter = thearch.netbsddynld;
-                               break;
-                       case Hopenbsd:
-                               interpreter = thearch.openbsddynld;
-                               break;
-                       case Hdragonfly:
-                               interpreter = thearch.dragonflydynld;
-                               break;
-                       case Hsolaris:
-                               interpreter = thearch.solarisdynld;
-                               break;
-                       }
-               }
-               resoff -= elfinterp(sh, startva, resoff, interpreter);
-
-               ph = newElfPhdr();
-               ph->type = PT_INTERP;
-               ph->flags = PF_R;
-               phsh(ph, sh);
-       }
-
-       pnote = nil;
-       if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd) {
-               sh = nil;
-               switch(HEADTYPE) {
-               case Hnetbsd:
-                       sh = elfshname(".note.netbsd.ident");
-                       resoff -= elfnetbsdsig(sh, startva, resoff);
-                       break;
-               case Hopenbsd:
-                       sh = elfshname(".note.openbsd.ident");
-                       resoff -= elfopenbsdsig(sh, startva, resoff);
-                       break;
-               }
-
-               pnote = newElfPhdr();
-               pnote->type = PT_NOTE;
-               pnote->flags = PF_R;
-               phsh(pnote, sh);
-       }
-
-       if(buildinfolen > 0) {
-               sh = elfshname(".note.gnu.build-id");
-               resoff -= elfbuildinfo(sh, startva, resoff);
-
-               if(pnote == nil) {
-                       pnote = newElfPhdr();
-                       pnote->type = PT_NOTE;
-                       pnote->flags = PF_R;
-               }
-               phsh(pnote, sh);
-       }
-
-       // Additions to the reserved area must be above this line.
-       USED(resoff);
-
-       elfphload(&segtext);
-       if(segrodata.sect != nil)
-               elfphload(&segrodata);
-       elfphload(&segdata);
-
-       /* Dynamic linking sections */
-       if(!debug['d']) {       /* -d suppresses dynamic loader format */
-               sh = elfshname(".dynsym");
-               sh->type = SHT_DYNSYM;
-               sh->flags = SHF_ALLOC;
-               if(elf64)
-                       sh->entsize = ELF64SYMSIZE;
-               else
-                       sh->entsize = ELF32SYMSIZE;
-               sh->addralign = thearch.regsize;
-               sh->link = elfshname(".dynstr")->shnum;
-               // sh->info = index of first non-local symbol (number of local symbols)
-               shsym(sh, linklookup(ctxt, ".dynsym", 0));
-
-               sh = elfshname(".dynstr");
-               sh->type = SHT_STRTAB;
-               sh->flags = SHF_ALLOC;
-               sh->addralign = 1;
-               shsym(sh, linklookup(ctxt, ".dynstr", 0));
-
-               if(elfverneed) {
-                       sh = elfshname(".gnu.version");
-                       sh->type = SHT_GNU_VERSYM;
-                       sh->flags = SHF_ALLOC;
-                       sh->addralign = 2;
-                       sh->link = elfshname(".dynsym")->shnum;
-                       sh->entsize = 2;
-                       shsym(sh, linklookup(ctxt, ".gnu.version", 0));
-                       
-                       sh = elfshname(".gnu.version_r");
-                       sh->type = SHT_GNU_VERNEED;
-                       sh->flags = SHF_ALLOC;
-                       sh->addralign = thearch.regsize;
-                       sh->info = elfverneed;
-                       sh->link = elfshname(".dynstr")->shnum;
-                       shsym(sh, linklookup(ctxt, ".gnu.version_r", 0));
-               }
-
-               switch(eh->machine) {
-               case EM_X86_64:
-               case EM_PPC64:
-                       sh = elfshname(".rela.plt");
-                       sh->type = SHT_RELA;
-                       sh->flags = SHF_ALLOC;
-                       sh->entsize = ELF64RELASIZE;
-                       sh->addralign = thearch.regsize;
-                       sh->link = elfshname(".dynsym")->shnum;
-                       sh->info = elfshname(".plt")->shnum;
-                       shsym(sh, linklookup(ctxt, ".rela.plt", 0));
-
-                       sh = elfshname(".rela");
-                       sh->type = SHT_RELA;
-                       sh->flags = SHF_ALLOC;
-                       sh->entsize = ELF64RELASIZE;
-                       sh->addralign = 8;
-                       sh->link = elfshname(".dynsym")->shnum;
-                       shsym(sh, linklookup(ctxt, ".rela", 0));
-                       break;
-               
-               default:
-                       sh = elfshname(".rel.plt");
-                       sh->type = SHT_REL;
-                       sh->flags = SHF_ALLOC;
-                       sh->entsize = ELF32RELSIZE;
-                       sh->addralign = 4;
-                       sh->link = elfshname(".dynsym")->shnum;
-                       shsym(sh, linklookup(ctxt, ".rel.plt", 0));
-
-                       sh = elfshname(".rel");
-                       sh->type = SHT_REL;
-                       sh->flags = SHF_ALLOC;
-                       sh->entsize = ELF32RELSIZE;
-                       sh->addralign = 4;
-                       sh->link = elfshname(".dynsym")->shnum;
-                       shsym(sh, linklookup(ctxt, ".rel", 0));
-                       break;
-               }
-
-               if(eh->machine == EM_PPC64) {
-                       sh = elfshname(".glink");
-                       sh->type = SHT_PROGBITS;
-                       sh->flags = SHF_ALLOC+SHF_EXECINSTR;
-                       sh->addralign = 4;
-                       shsym(sh, linklookup(ctxt, ".glink", 0));
-               }
-
-               sh = elfshname(".plt");
-               sh->type = SHT_PROGBITS;
-               sh->flags = SHF_ALLOC+SHF_EXECINSTR;
-               if(eh->machine == EM_X86_64)
-                       sh->entsize = 16;
-               else if(eh->machine == EM_PPC64) {
-                       // On ppc64, this is just a table of addresses
-                       // filled by the dynamic linker
-                       sh->type = SHT_NOBITS;
-                       sh->flags = SHF_ALLOC+SHF_WRITE;
-                       sh->entsize = 8;
-               } else
-                       sh->entsize = 4;
-               sh->addralign = sh->entsize;
-               shsym(sh, linklookup(ctxt, ".plt", 0));
-
-               // On ppc64, .got comes from the input files, so don't
-               // create it here, and .got.plt is not used.
-               if(eh->machine != EM_PPC64) {
-                       sh = elfshname(".got");
-                       sh->type = SHT_PROGBITS;
-                       sh->flags = SHF_ALLOC+SHF_WRITE;
-                       sh->entsize = thearch.regsize;
-                       sh->addralign = thearch.regsize;
-                       shsym(sh, linklookup(ctxt, ".got", 0));
-
-                       sh = elfshname(".got.plt");
-                       sh->type = SHT_PROGBITS;
-                       sh->flags = SHF_ALLOC+SHF_WRITE;
-                       sh->entsize = thearch.regsize;
-                       sh->addralign = thearch.regsize;
-                       shsym(sh, linklookup(ctxt, ".got.plt", 0));
-               }
-               
-               sh = elfshname(".hash");
-               sh->type = SHT_HASH;
-               sh->flags = SHF_ALLOC;
-               sh->entsize = 4;
-               sh->addralign = thearch.regsize;
-               sh->link = elfshname(".dynsym")->shnum;
-               shsym(sh, linklookup(ctxt, ".hash", 0));
-
-               /* sh and PT_DYNAMIC for .dynamic section */
-               sh = elfshname(".dynamic");
-               sh->type = SHT_DYNAMIC;
-               sh->flags = SHF_ALLOC+SHF_WRITE;
-               sh->entsize = 2*thearch.regsize;
-               sh->addralign = thearch.regsize;
-               sh->link = elfshname(".dynstr")->shnum;
-               shsym(sh, linklookup(ctxt, ".dynamic", 0));
-               ph = newElfPhdr();
-               ph->type = PT_DYNAMIC;
-               ph->flags = PF_R + PF_W;
-               phsh(ph, sh);
-               
-               /*
-                * Thread-local storage segment (really just size).
-                */
-               // Do not emit PT_TLS for OpenBSD since ld.so(1) does
-               // not currently support it. This is handled
-               // appropriately in runtime/cgo.
-               if(ctxt->tlsoffset != 0 && HEADTYPE != Hopenbsd) {
-                       ph = newElfPhdr();
-                       ph->type = PT_TLS;
-                       ph->flags = PF_R;
-                       ph->memsz = -ctxt->tlsoffset;
-                       ph->align = thearch.regsize;
-               }
-       }
-
-       if(HEADTYPE == Hlinux) {
-               ph = newElfPhdr();
-               ph->type = PT_GNU_STACK;
-               ph->flags = PF_W+PF_R;
-               ph->align = thearch.regsize;
-               
-               ph = newElfPhdr();
-               ph->type = PT_PAX_FLAGS;
-               ph->flags = 0x2a00; // mprotect, randexec, emutramp disabled
-               ph->align = thearch.regsize;
-       }
-
-elfobj:
-       sh = elfshname(".shstrtab");
-       sh->type = SHT_STRTAB;
-       sh->addralign = 1;
-       shsym(sh, linklookup(ctxt, ".shstrtab", 0));
-       eh->shstrndx = sh->shnum;
-
-       // put these sections early in the list
-       if(!debug['s']) {
-               elfshname(".symtab");
-               elfshname(".strtab");
-       }
-
-       for(sect=segtext.sect; sect!=nil; sect=sect->next)
-               elfshbits(sect);
-       for(sect=segrodata.sect; sect!=nil; sect=sect->next)
-               elfshbits(sect);
-       for(sect=segdata.sect; sect!=nil; sect=sect->next)
-               elfshbits(sect);
-
-       if(linkmode == LinkExternal) {
-               for(sect=segtext.sect; sect!=nil; sect=sect->next)
-                       elfshreloc(sect);
-               for(sect=segrodata.sect; sect!=nil; sect=sect->next)
-                       elfshreloc(sect);
-               for(sect=segdata.sect; sect!=nil; sect=sect->next)
-                       elfshreloc(sect);
-               // add a .note.GNU-stack section to mark the stack as non-executable
-               sh = elfshname(".note.GNU-stack");
-               sh->type = SHT_PROGBITS;
-               sh->addralign = 1;
-               sh->flags = 0;
-       }
-
-       // generate .tbss section for dynamic internal linking (except for OpenBSD)
-       // external linking generates .tbss in data.c
-       if(linkmode == LinkInternal && !debug['d'] && HEADTYPE != Hopenbsd) {
-               sh = elfshname(".tbss");
-               sh->type = SHT_NOBITS;
-               sh->addralign = thearch.regsize;
-               sh->size = -ctxt->tlsoffset;
-               sh->flags = SHF_ALLOC | SHF_TLS | SHF_WRITE;
-       }
-
-       if(!debug['s']) {
-               sh = elfshname(".symtab");
-               sh->type = SHT_SYMTAB;
-               sh->off = symo;
-               sh->size = symsize;
-               sh->addralign = thearch.regsize;
-               sh->entsize = 8+2*thearch.regsize;
-               sh->link = elfshname(".strtab")->shnum;
-               sh->info = elfglobalsymndx;
-
-               sh = elfshname(".strtab");
-               sh->type = SHT_STRTAB;
-               sh->off = symo+symsize;
-               sh->size = elfstrsize;
-               sh->addralign = 1;
-
-               dwarfaddelfheaders();
-       }
-
-       /* Main header */
-       eh->ident[EI_MAG0] = '\177';
-       eh->ident[EI_MAG1] = 'E';
-       eh->ident[EI_MAG2] = 'L';
-       eh->ident[EI_MAG3] = 'F';
-       if(HEADTYPE == Hfreebsd)
-               eh->ident[EI_OSABI] = ELFOSABI_FREEBSD;
-       else if(HEADTYPE == Hnetbsd)
-               eh->ident[EI_OSABI] = ELFOSABI_NETBSD;
-       else if(HEADTYPE == Hopenbsd)
-               eh->ident[EI_OSABI] = ELFOSABI_OPENBSD;
-       else if(HEADTYPE == Hdragonfly)
-               eh->ident[EI_OSABI] = ELFOSABI_NONE;
-       if(elf64)
-               eh->ident[EI_CLASS] = ELFCLASS64;
-       else
-               eh->ident[EI_CLASS] = ELFCLASS32;
-       if(ctxt->arch->endian == BigEndian)
-               eh->ident[EI_DATA] = ELFDATA2MSB;
-       else
-               eh->ident[EI_DATA] = ELFDATA2LSB;
-       eh->ident[EI_VERSION] = EV_CURRENT;
-
-       if(linkmode == LinkExternal)
-               eh->type = ET_REL;
-       else
-               eh->type = ET_EXEC;
-
-       if(linkmode != LinkExternal)
-               eh->entry = entryvalue();
-
-       eh->version = EV_CURRENT;
-
-       if(pph != nil) {
-               pph->filesz = eh->phnum * eh->phentsize;
-               pph->memsz = pph->filesz;
-       }
-
-       cseek(0);
-       a = 0;
-       a += elfwritehdr();
-       a += elfwritephdrs();
-       a += elfwriteshdrs();
-       if(!debug['d'])
-               a += elfwriteinterp();
-       if(linkmode != LinkExternal) {
-               if(HEADTYPE == Hnetbsd)
-                       a += elfwritenetbsdsig();
-               if(HEADTYPE == Hopenbsd)
-                       a += elfwriteopenbsdsig();
-               if(buildinfolen > 0)
-                       a += elfwritebuildinfo();
-       }
-       if(a > ELFRESERVE)      
-               diag("ELFRESERVE too small: %lld > %d", a, ELFRESERVE);
-}
-
-uint32
-ELF32_R_SYM(uint32 info)
-{
-       return info>>8;
-}
-
-uint32
-ELF32_R_TYPE(uint32 info)
-{
-       return (uint8)info;
-}
-
-uint32
-ELF32_R_INFO(uint32 sym, uint32 type)
-{
-       return sym<<8 | type;
-}
-
-uint8
-ELF32_ST_BIND(uint8 info)
-{
-       return info>>4;
-}
-
-uint8
-ELF32_ST_TYPE(uint8 info)
-{
-       return info & 0xf;
-}
-
-uint8
-ELF32_ST_INFO(uint8 bind, uint8 type)
-{
-       return bind<<4 | type&0xf;
-}
-
-uint8
-ELF32_ST_VISIBILITY(uint8 oth)
-{
-       return oth & 3;
-}
-
-uint32
-ELF64_R_SYM(uint64 info)
-{
-       return info>>32;
-}
-
-uint32
-ELF64_R_TYPE(uint64 info)
-{
-       return info;
-}
-
-uint64
-ELF64_R_INFO(uint32 sym, uint32 type)
-{
-       return (uint64)sym<<32 | type;
-}
-
-uint8
-ELF64_ST_BIND(uint8 info)
-{
-       return info>>4;
-}
-
-uint8
-ELF64_ST_TYPE(uint8 info)
-{
-       return info & 0xf;
-}
-
-uint8
-ELF64_ST_INFO(uint8 bind, uint8 type)
-{
-       return bind<<4 | type&0xf;
-}
-
-uint8
-ELF64_ST_VISIBILITY(uint8 oth)
-{
-       return oth & 3;
-}
diff --git a/src/cmd/ld/elf.h b/src/cmd/ld/elf.h
deleted file mode 100644 (file)
index 378d246..0000000
+++ /dev/null
@@ -1,857 +0,0 @@
-/*
- * 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.
- *
- */
-
-/*
- * ELF definitions that are independent of architecture or word size.
- */
-
-/*
- * Note header.  The ".note" section contains an array of notes.  Each
- * begins with this header, aligned to a word boundary.  Immediately
- * following the note header is n_namesz bytes of name, padded to the
- * next word boundary.  Then comes n_descsz bytes of descriptor, again
- * padded to a word boundary.  The values of n_namesz and n_descsz do
- * not include the padding.
- */
-
-typedef struct Elf_Note Elf_Note;
-struct Elf_Note {
-       uint32  n_namesz;       /* Length of name. */
-       uint32  n_descsz;       /* Length of descriptor. */
-       uint32  n_type;         /* Type of this note. */
-};
-
-enum {
-/* Indexes into the e_ident array.  Keep synced with
-   http://www.sco.com/developer/gabi/ch4.eheader.html */
-       EI_MAG0 = 0, /* Magic number, byte 0. */
-       EI_MAG1 = 1, /* Magic number, byte 1. */
-       EI_MAG2 = 2, /* Magic number, byte 2. */
-       EI_MAG3 = 3, /* Magic number, byte 3. */
-       EI_CLASS = 4, /* Class of machine. */
-       EI_DATA = 5, /* Data format. */
-       EI_VERSION = 6, /* ELF format version. */
-       EI_OSABI = 7, /* Operating system / ABI identification */
-       EI_ABIVERSION = 8, /* ABI version */
-       OLD_EI_BRAND = 8, /* Start of architecture identification. */
-       EI_PAD = 9, /* Start of padding (per SVR4 ABI). */
-       EI_NIDENT = 16, /* Size of e_ident array. */
-
-/* Values for the magic number bytes. */
-       ELFMAG0 = 0x7f, 
-       ELFMAG1 = 'E', 
-       ELFMAG2 = 'L', 
-       ELFMAG3 = 'F', 
-       SELFMAG = 4, /* magic string size */
-
-/* Values for e_ident[EI_VERSION] and e_version. */
-       EV_NONE = 0, 
-       EV_CURRENT = 1, 
-
-/* Values for e_ident[EI_CLASS]. */
-       ELFCLASSNONE = 0, /* Unknown class. */
-       ELFCLASS32 = 1, /* 32-bit architecture. */
-       ELFCLASS64 = 2, /* 64-bit architecture. */
-
-/* Values for e_ident[EI_DATA]. */
-       ELFDATANONE = 0, /* Unknown data format. */
-       ELFDATA2LSB = 1, /* 2's complement little-endian. */
-       ELFDATA2MSB = 2, /* 2's complement big-endian. */
-
-/* Values for e_ident[EI_OSABI]. */
-       ELFOSABI_NONE = 0, /* UNIX System V ABI */
-       ELFOSABI_HPUX = 1, /* HP-UX operating system */
-       ELFOSABI_NETBSD = 2, /* NetBSD */
-       ELFOSABI_LINUX = 3, /* GNU/Linux */
-       ELFOSABI_HURD = 4, /* GNU/Hurd */
-       ELFOSABI_86OPEN = 5, /* 86Open common IA32 ABI */
-       ELFOSABI_SOLARIS = 6, /* Solaris */
-       ELFOSABI_AIX = 7, /* AIX */
-       ELFOSABI_IRIX = 8, /* IRIX */
-       ELFOSABI_FREEBSD = 9, /* FreeBSD */
-       ELFOSABI_TRU64 = 10, /* TRU64 UNIX */
-       ELFOSABI_MODESTO = 11, /* Novell Modesto */
-       ELFOSABI_OPENBSD = 12, /* OpenBSD */
-       ELFOSABI_OPENVMS = 13, /* Open VMS */
-       ELFOSABI_NSK = 14, /* HP Non-Stop Kernel */
-       ELFOSABI_ARM = 97, /* ARM */
-       ELFOSABI_STANDALONE = 255, /* Standalone (embedded) application */
-
-       ELFOSABI_SYSV = ELFOSABI_NONE, /* symbol used in old spec */
-       ELFOSABI_MONTEREY = ELFOSABI_AIX, /* Monterey */
-
-/* Values for e_type. */
-       ET_NONE = 0, /* Unknown type. */
-       ET_REL = 1, /* Relocatable. */
-       ET_EXEC = 2, /* Executable. */
-       ET_DYN = 3, /* Shared object. */
-       ET_CORE = 4, /* Core file. */
-       ET_LOOS = 0xfe00, /* First operating system specific. */
-       ET_HIOS = 0xfeff, /* Last operating system-specific. */
-       ET_LOPROC = 0xff00, /* First processor-specific. */
-       ET_HIPROC = 0xffff, /* Last processor-specific. */
-
-/* Values for e_machine. */
-       EM_NONE = 0, /* Unknown machine. */
-       EM_M32 = 1, /* AT&T WE32100. */
-       EM_SPARC = 2, /* Sun SPARC. */
-       EM_386 = 3, /* Intel i386. */
-       EM_68K = 4, /* Motorola 68000. */
-       EM_88K = 5, /* Motorola 88000. */
-       EM_860 = 7, /* Intel i860. */
-       EM_MIPS = 8, /* MIPS R3000 Big-Endian only. */
-       EM_S370 = 9, /* IBM System/370. */
-       EM_MIPS_RS3_LE = 10, /* MIPS R3000 Little-Endian. */
-       EM_PARISC = 15, /* HP PA-RISC. */
-       EM_VPP500 = 17, /* Fujitsu VPP500. */
-       EM_SPARC32PLUS = 18, /* SPARC v8plus. */
-       EM_960 = 19, /* Intel 80960. */
-       EM_PPC = 20, /* PowerPC 32-bit. */
-       EM_PPC64 = 21, /* PowerPC 64-bit. */
-       EM_S390 = 22, /* IBM System/390. */
-       EM_V800 = 36, /* NEC V800. */
-       EM_FR20 = 37, /* Fujitsu FR20. */
-       EM_RH32 = 38, /* TRW RH-32. */
-       EM_RCE = 39, /* Motorola RCE. */
-       EM_ARM = 40, /* ARM. */
-       EM_SH = 42, /* Hitachi SH. */
-       EM_SPARCV9 = 43, /* SPARC v9 64-bit. */
-       EM_TRICORE = 44, /* Siemens TriCore embedded processor. */
-       EM_ARC = 45, /* Argonaut RISC Core. */
-       EM_H8_300 = 46, /* Hitachi H8/300. */
-       EM_H8_300H = 47, /* Hitachi H8/300H. */
-       EM_H8S = 48, /* Hitachi H8S. */
-       EM_H8_500 = 49, /* Hitachi H8/500. */
-       EM_IA_64 = 50, /* Intel IA-64 Processor. */
-       EM_MIPS_X = 51, /* Stanford MIPS-X. */
-       EM_COLDFIRE = 52, /* Motorola ColdFire. */
-       EM_68HC12 = 53, /* Motorola M68HC12. */
-       EM_MMA = 54, /* Fujitsu MMA. */
-       EM_PCP = 55, /* Siemens PCP. */
-       EM_NCPU = 56, /* Sony nCPU. */
-       EM_NDR1 = 57, /* Denso NDR1 microprocessor. */
-       EM_STARCORE = 58, /* Motorola Star*Core processor. */
-       EM_ME16 = 59, /* Toyota ME16 processor. */
-       EM_ST100 = 60, /* STMicroelectronics ST100 processor. */
-       EM_TINYJ = 61, /* Advanced Logic Corp. TinyJ processor. */
-       EM_X86_64 = 62, /* Advanced Micro Devices x86-64 */
-
-/* Non-standard or deprecated. */
-       EM_486 = 6, /* Intel i486. */
-       EM_MIPS_RS4_BE = 10, /* MIPS R4000 Big-Endian */
-       EM_ALPHA_STD = 41, /* Digital Alpha (standard value). */
-       EM_ALPHA = 0x9026, /* Alpha (written in the absence of an ABI) */
-
-/* Special section indexes. */
-       SHN_UNDEF = 0, /* Undefined, missing, irrelevant. */
-       SHN_LORESERVE = 0xff00, /* First of reserved range. */
-       SHN_LOPROC = 0xff00, /* First processor-specific. */
-       SHN_HIPROC = 0xff1f, /* Last processor-specific. */
-       SHN_LOOS = 0xff20, /* First operating system-specific. */
-       SHN_HIOS = 0xff3f, /* Last operating system-specific. */
-       SHN_ABS = 0xfff1, /* Absolute values. */
-       SHN_COMMON = 0xfff2, /* Common data. */
-       SHN_XINDEX = 0xffff, /* Escape -- index stored elsewhere. */
-       SHN_HIRESERVE = 0xffff, /* Last of reserved range. */
-
-/* sh_type */
-       SHT_NULL = 0, /* inactive */
-       SHT_PROGBITS = 1, /* program defined information */
-       SHT_SYMTAB = 2, /* symbol table section */
-       SHT_STRTAB = 3, /* string table section */
-       SHT_RELA = 4, /* relocation section with addends */
-       SHT_HASH = 5, /* symbol hash table section */
-       SHT_DYNAMIC = 6, /* dynamic section */
-       SHT_NOTE = 7, /* note section */
-       SHT_NOBITS = 8, /* no space section */
-       SHT_REL = 9, /* relocation section - no addends */
-       SHT_SHLIB = 10, /* reserved - purpose unknown */
-       SHT_DYNSYM = 11, /* dynamic symbol table section */
-       SHT_INIT_ARRAY = 14, /* Initialization function pointers. */
-       SHT_FINI_ARRAY = 15, /* Termination function pointers. */
-       SHT_PREINIT_ARRAY = 16, /* Pre-initialization function ptrs. */
-       SHT_GROUP = 17, /* Section group. */
-       SHT_SYMTAB_SHNDX = 18, /* Section indexes (see SHN_XINDEX). */
-       SHT_LOOS = 0x60000000, /* First of OS specific semantics */
-       SHT_HIOS = 0x6fffffff, /* Last of OS specific semantics */
-       SHT_GNU_VERDEF = 0x6ffffffd, 
-       SHT_GNU_VERNEED = 0x6ffffffe, 
-       SHT_GNU_VERSYM = 0x6fffffff, 
-       SHT_LOPROC = 0x70000000, /* reserved range for processor */
-       SHT_HIPROC = 0x7fffffff, /* specific section header types */
-       SHT_LOUSER = 0x80000000, /* reserved range for application */
-       SHT_HIUSER = 0xffffffff, /* specific indexes */
-
-/* Flags for sh_flags. */
-       SHF_WRITE = 0x1, /* Section contains writable data. */
-       SHF_ALLOC = 0x2, /* Section occupies memory. */
-       SHF_EXECINSTR = 0x4, /* Section contains instructions. */
-       SHF_MERGE = 0x10, /* Section may be merged. */
-       SHF_STRINGS = 0x20, /* Section contains strings. */
-       SHF_INFO_LINK = 0x40, /* sh_info holds section index. */
-       SHF_LINK_ORDER = 0x80, /* Special ordering requirements. */
-       SHF_OS_NONCONFORMING = 0x100, /* OS-specific processing required. */
-       SHF_GROUP = 0x200, /* Member of section group. */
-       SHF_TLS = 0x400, /* Section contains TLS data. */
-       SHF_MASKOS = 0x0ff00000, /* OS-specific semantics. */
-       SHF_MASKPROC = 0xf0000000, /* Processor-specific semantics. */
-
-/* Values for p_type. */
-       PT_NULL = 0, /* Unused entry. */
-       PT_LOAD = 1, /* Loadable segment. */
-       PT_DYNAMIC = 2, /* Dynamic linking information segment. */
-       PT_INTERP = 3, /* Pathname of interpreter. */
-       PT_NOTE = 4, /* Auxiliary information. */
-       PT_SHLIB = 5, /* Reserved (not used). */
-       PT_PHDR = 6, /* Location of program header itself. */
-       PT_TLS = 7, /* Thread local storage segment */
-       PT_LOOS = 0x60000000, /* First OS-specific. */
-       PT_HIOS = 0x6fffffff, /* Last OS-specific. */
-       PT_LOPROC = 0x70000000, /* First processor-specific type. */
-       PT_HIPROC = 0x7fffffff, /* Last processor-specific type. */
-       PT_GNU_STACK = 0x6474e551, 
-       PT_PAX_FLAGS = 0x65041580, 
-
-/* Values for p_flags. */
-       PF_X = 0x1, /* Executable. */
-       PF_W = 0x2, /* Writable. */
-       PF_R = 0x4, /* Readable. */
-       PF_MASKOS = 0x0ff00000, /* Operating system-specific. */
-       PF_MASKPROC = 0xf0000000, /* Processor-specific. */
-
-/* Values for d_tag. */
-       DT_NULL = 0, /* Terminating entry. */
-/* String table offset of a needed shared library. */
-       DT_NEEDED = 1, 
-       DT_PLTRELSZ = 2, /* Total size in bytes of PLT relocations. */
-       DT_PLTGOT = 3, /* Processor-dependent address. */
-       DT_HASH = 4, /* Address of symbol hash table. */
-       DT_STRTAB = 5, /* Address of string table. */
-       DT_SYMTAB = 6, /* Address of symbol table. */
-       DT_RELA = 7, /* Address of ElfNN_Rela relocations. */
-       DT_RELASZ = 8, /* Total size of ElfNN_Rela relocations. */
-       DT_RELAENT = 9, /* Size of each ElfNN_Rela relocation entry. */
-       DT_STRSZ = 10, /* Size of string table. */
-       DT_SYMENT = 11, /* Size of each symbol table entry. */
-       DT_INIT = 12, /* Address of initialization function. */
-       DT_FINI = 13, /* Address of finalization function. */
-/* String table offset of shared object name. */
-       DT_SONAME = 14, 
-       DT_RPATH = 15, /* String table offset of library path. [sup] */
-       DT_SYMBOLIC = 16, /* Indicates "symbolic" linking. [sup] */
-       DT_REL = 17, /* Address of ElfNN_Rel relocations. */
-       DT_RELSZ = 18, /* Total size of ElfNN_Rel relocations. */
-       DT_RELENT = 19, /* Size of each ElfNN_Rel relocation. */
-       DT_PLTREL = 20, /* Type of relocation used for PLT. */
-       DT_DEBUG = 21, /* Reserved (not used). */
-/* Indicates there may be relocations in non-writable segments. [sup] */
-       DT_TEXTREL = 22, 
-       DT_JMPREL = 23, /* Address of PLT relocations. */
-       DT_BIND_NOW = 24, /* [sup] */
-/* Address of the array of pointers to initialization functions */
-       DT_INIT_ARRAY = 25, 
-/* Address of the array of pointers to termination functions */
-       DT_FINI_ARRAY = 26, 
-/* Size in bytes of the array of initialization functions. */
-       DT_INIT_ARRAYSZ = 27, 
-/* Size in bytes of the array of terminationfunctions. */
-       DT_FINI_ARRAYSZ = 28, 
-/* String table offset of a null-terminated library search path string. */
-       DT_RUNPATH = 29, 
-       DT_FLAGS = 30, /* Object specific flag values. */
-/*     Values greater than or equal to DT_ENCODING and less than
-       DT_LOOS follow the rules for the interpretation of the d_un
-       union as follows: even == 'd_ptr', even == 'd_val' or none */
-       DT_ENCODING = 32, 
-/* Address of the array of pointers to pre-initialization functions. */
-       DT_PREINIT_ARRAY = 32, 
-/* Size in bytes of the array of pre-initialization functions. */
-       DT_PREINIT_ARRAYSZ = 33, 
-       DT_LOOS = 0x6000000d, /* First OS-specific */
-       DT_HIOS = 0x6ffff000, /* Last OS-specific */
-       DT_LOPROC = 0x70000000, /* First processor-specific type. */
-       DT_HIPROC = 0x7fffffff, /* Last processor-specific type. */
-
-       DT_VERNEED = 0x6ffffffe, 
-       DT_VERNEEDNUM = 0x6fffffff, 
-       DT_VERSYM = 0x6ffffff0, 
-
-       DT_PPC64_GLINK = (DT_LOPROC + 0),
-       DT_PPC64_OPT = (DT_LOPROC + 3),
-
-/* Values for DT_FLAGS */
-/*     Indicates that the object being loaded may make reference to
-       the $ORIGIN substitution string */
-       DF_ORIGIN = 0x0001, 
-       DF_SYMBOLIC = 0x0002, /* Indicates "symbolic" linking. */
-/* Indicates there may be relocations in non-writable segments. */
-       DF_TEXTREL = 0x0004, 
-/*     Indicates that the dynamic linker should process all
-       relocations for the object containing this entry before
-       transferring control to the program.  */
-       DF_BIND_NOW = 0x0008, 
-/*     Indicates that the shared object or executable contains code
-       using a static thread-local storage scheme.  */
-       DF_STATIC_TLS = 0x0010, 
-
-/* Values for n_type.  Used in core files. */
-       NT_PRSTATUS = 1, /* Process status. */
-       NT_FPREGSET = 2, /* Floating point registers. */
-       NT_PRPSINFO = 3, /* Process state info. */
-
-/* Symbol Binding - ELFNN_ST_BIND - st_info */
-       STB_LOCAL = 0, /* Local symbol */
-       STB_GLOBAL = 1, /* Global symbol */
-       STB_WEAK = 2, /* like global - lower precedence */
-       STB_LOOS = 10, /* Reserved range for operating system */
-       STB_HIOS = 12, /*   specific semantics. */
-       STB_LOPROC = 13, /* reserved range for processor */
-       STB_HIPROC = 15, /*   specific semantics. */
-
-/* Symbol type - ELFNN_ST_TYPE - st_info */
-       STT_NOTYPE = 0, /* Unspecified type. */
-       STT_OBJECT = 1, /* Data object. */
-       STT_FUNC = 2, /* Function. */
-       STT_SECTION = 3, /* Section. */
-       STT_FILE = 4, /* Source file. */
-       STT_COMMON = 5, /* Uninitialized common block. */
-       STT_TLS = 6, /* TLS object. */
-       STT_LOOS = 10, /* Reserved range for operating system */
-       STT_HIOS = 12, /*   specific semantics. */
-       STT_LOPROC = 13, /* reserved range for processor */
-       STT_HIPROC = 15, /*   specific semantics. */
-
-/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
-       STV_DEFAULT = 0x0, /* Default visibility (see binding). */
-       STV_INTERNAL = 0x1, /* Special meaning in relocatable objects. */
-       STV_HIDDEN = 0x2, /* Not visible. */
-       STV_PROTECTED = 0x3, /* Visible but not preemptible. */
-
-/* Special symbol table indexes. */
-       STN_UNDEF = 0, /* Undefined symbol index. */
-};
-
-
-/* For accessing the fields of r_info. */
-uint32 ELF32_R_SYM(uint32 info);
-uint32 ELF32_R_TYPE(uint32 info);
-
-/* For constructing r_info from field values. */
-uint32 ELF32_R_INFO(uint32 sym, uint32 type);
-
-/*
- * Relocation types.
- */
-
-enum {
-       R_X86_64_NONE = 0, /* No relocation. */
-       R_X86_64_64 = 1, /* Add 64 bit symbol value. */
-       R_X86_64_PC32 = 2, /* PC-relative 32 bit signed sym value. */
-       R_X86_64_GOT32 = 3, /* PC-relative 32 bit GOT offset. */
-       R_X86_64_PLT32 = 4, /* PC-relative 32 bit PLT offset. */
-       R_X86_64_COPY = 5, /* Copy data from shared object. */
-       R_X86_64_GLOB_DAT = 6, /* Set GOT entry to data address. */
-       R_X86_64_JMP_SLOT = 7, /* Set GOT entry to code address. */
-       R_X86_64_RELATIVE = 8, /* Add load address of shared object. */
-       R_X86_64_GOTPCREL = 9, /* Add 32 bit signed pcrel offset to GOT. */
-       R_X86_64_32 = 10, /* Add 32 bit zero extended symbol value */
-       R_X86_64_32S = 11, /* Add 32 bit sign extended symbol value */
-       R_X86_64_16 = 12, /* Add 16 bit zero extended symbol value */
-       R_X86_64_PC16 = 13, /* Add 16 bit signed extended pc relative symbol value */
-       R_X86_64_8 = 14, /* Add 8 bit zero extended symbol value */
-       R_X86_64_PC8 = 15, /* Add 8 bit signed extended pc relative symbol value */
-       R_X86_64_DTPMOD64 = 16, /* ID of module containing symbol */
-       R_X86_64_DTPOFF64 = 17, /* Offset in TLS block */
-       R_X86_64_TPOFF64 = 18, /* Offset in static TLS block */
-       R_X86_64_TLSGD = 19, /* PC relative offset to GD GOT entry */
-       R_X86_64_TLSLD = 20, /* PC relative offset to LD GOT entry */
-       R_X86_64_DTPOFF32 = 21, /* Offset in TLS block */
-       R_X86_64_GOTTPOFF = 22, /* PC relative offset to IE GOT entry */
-       R_X86_64_TPOFF32 = 23, /* Offset in static TLS block */
-
-       R_X86_64_COUNT = 24, /* Count of defined relocation types. */
-
-
-       R_ALPHA_NONE = 0, /* No reloc */
-       R_ALPHA_REFLONG = 1, /* Direct 32 bit */
-       R_ALPHA_REFQUAD = 2, /* Direct 64 bit */
-       R_ALPHA_GPREL32 = 3, /* GP relative 32 bit */
-       R_ALPHA_LITERAL = 4, /* GP relative 16 bit w/optimization */
-       R_ALPHA_LITUSE = 5, /* Optimization hint for LITERAL */
-       R_ALPHA_GPDISP = 6, /* Add displacement to GP */
-       R_ALPHA_BRADDR = 7, /* PC+4 relative 23 bit shifted */
-       R_ALPHA_HINT = 8, /* PC+4 relative 16 bit shifted */
-       R_ALPHA_SREL16 = 9, /* PC relative 16 bit */
-       R_ALPHA_SREL32 = 10, /* PC relative 32 bit */
-       R_ALPHA_SREL64 = 11, /* PC relative 64 bit */
-       R_ALPHA_OP_PUSH = 12, /* OP stack push */
-       R_ALPHA_OP_STORE = 13, /* OP stack pop and store */
-       R_ALPHA_OP_PSUB = 14, /* OP stack subtract */
-       R_ALPHA_OP_PRSHIFT = 15, /* OP stack right shift */
-       R_ALPHA_GPVALUE = 16, 
-       R_ALPHA_GPRELHIGH = 17, 
-       R_ALPHA_GPRELLOW = 18, 
-       R_ALPHA_IMMED_GP_16 = 19, 
-       R_ALPHA_IMMED_GP_HI32 = 20, 
-       R_ALPHA_IMMED_SCN_HI32 = 21, 
-       R_ALPHA_IMMED_BR_HI32 = 22, 
-       R_ALPHA_IMMED_LO32 = 23, 
-       R_ALPHA_COPY = 24, /* Copy symbol at runtime */
-       R_ALPHA_GLOB_DAT = 25, /* Create GOT entry */
-       R_ALPHA_JMP_SLOT = 26, /* Create PLT entry */
-       R_ALPHA_RELATIVE = 27, /* Adjust by program base */
-
-       R_ALPHA_COUNT = 28, 
-
-
-       R_ARM_NONE = 0, /* No relocation. */
-       R_ARM_PC24 = 1, 
-       R_ARM_ABS32 = 2, 
-       R_ARM_REL32 = 3, 
-       R_ARM_PC13 = 4, 
-       R_ARM_ABS16 = 5, 
-       R_ARM_ABS12 = 6, 
-       R_ARM_THM_ABS5 = 7, 
-       R_ARM_ABS8 = 8, 
-       R_ARM_SBREL32 = 9, 
-       R_ARM_THM_PC22 = 10, 
-       R_ARM_THM_PC8 = 11, 
-       R_ARM_AMP_VCALL9 = 12, 
-       R_ARM_SWI24 = 13, 
-       R_ARM_THM_SWI8 = 14, 
-       R_ARM_XPC25 = 15, 
-       R_ARM_THM_XPC22 = 16, 
-       R_ARM_COPY = 20, /* Copy data from shared object. */
-       R_ARM_GLOB_DAT = 21, /* Set GOT entry to data address. */
-       R_ARM_JUMP_SLOT = 22, /* Set GOT entry to code address. */
-       R_ARM_RELATIVE = 23, /* Add load address of shared object. */
-       R_ARM_GOTOFF = 24, /* Add GOT-relative symbol address. */
-       R_ARM_GOTPC = 25, /* Add PC-relative GOT table address. */
-       R_ARM_GOT32 = 26, /* Add PC-relative GOT offset. */
-       R_ARM_PLT32 = 27, /* Add PC-relative PLT offset. */
-       R_ARM_CALL = 28, 
-       R_ARM_JUMP24 = 29, 
-       R_ARM_V4BX = 40, 
-       R_ARM_GOT_PREL = 96, 
-       R_ARM_GNU_VTENTRY = 100, 
-       R_ARM_GNU_VTINHERIT = 101, 
-       R_ARM_TLS_IE32 = 107, 
-       R_ARM_TLS_LE32 = 108, 
-       R_ARM_RSBREL32 = 250, 
-       R_ARM_THM_RPC22 = 251, 
-       R_ARM_RREL32 = 252, 
-       R_ARM_RABS32 = 253, 
-       R_ARM_RPC24 = 254, 
-       R_ARM_RBASE = 255, 
-
-       R_ARM_COUNT = 38, /* Count of defined relocation types. */
-
-
-       R_386_NONE = 0, /* No relocation. */
-       R_386_32 = 1, /* Add symbol value. */
-       R_386_PC32 = 2, /* Add PC-relative symbol value. */
-       R_386_GOT32 = 3, /* Add PC-relative GOT offset. */
-       R_386_PLT32 = 4, /* Add PC-relative PLT offset. */
-       R_386_COPY = 5, /* Copy data from shared object. */
-       R_386_GLOB_DAT = 6, /* Set GOT entry to data address. */
-       R_386_JMP_SLOT = 7, /* Set GOT entry to code address. */
-       R_386_RELATIVE = 8, /* Add load address of shared object. */
-       R_386_GOTOFF = 9, /* Add GOT-relative symbol address. */
-       R_386_GOTPC = 10, /* Add PC-relative GOT table address. */
-       R_386_TLS_TPOFF = 14, /* Negative offset in static TLS block */
-       R_386_TLS_IE = 15, /* Absolute address of GOT for -ve static TLS */
-       R_386_TLS_GOTIE = 16, /* GOT entry for negative static TLS block */
-       R_386_TLS_LE = 17, /* Negative offset relative to static TLS */
-       R_386_TLS_GD = 18, /* 32 bit offset to GOT (index,off) pair */
-       R_386_TLS_LDM = 19, /* 32 bit offset to GOT (index,zero) pair */
-       R_386_TLS_GD_32 = 24, /* 32 bit offset to GOT (index,off) pair */
-       R_386_TLS_GD_PUSH = 25, /* pushl instruction for Sun ABI GD sequence */
-       R_386_TLS_GD_CALL = 26, /* call instruction for Sun ABI GD sequence */
-       R_386_TLS_GD_POP = 27, /* popl instruction for Sun ABI GD sequence */
-       R_386_TLS_LDM_32 = 28, /* 32 bit offset to GOT (index,zero) pair */
-       R_386_TLS_LDM_PUSH = 29, /* pushl instruction for Sun ABI LD sequence */
-       R_386_TLS_LDM_CALL = 30, /* call instruction for Sun ABI LD sequence */
-       R_386_TLS_LDM_POP = 31, /* popl instruction for Sun ABI LD sequence */
-       R_386_TLS_LDO_32 = 32, /* 32 bit offset from start of TLS block */
-       R_386_TLS_IE_32 = 33, /* 32 bit offset to GOT static TLS offset entry */
-       R_386_TLS_LE_32 = 34, /* 32 bit offset within static TLS block */
-       R_386_TLS_DTPMOD32 = 35, /* GOT entry containing TLS index */
-       R_386_TLS_DTPOFF32 = 36, /* GOT entry containing TLS offset */
-       R_386_TLS_TPOFF32 = 37, /* GOT entry of -ve static TLS offset */
-
-       R_386_COUNT = 38, /* Count of defined relocation types. */
-
-       R_PPC_NONE = 0, /* No relocation. */
-       R_PPC_ADDR32 = 1, 
-       R_PPC_ADDR24 = 2, 
-       R_PPC_ADDR16 = 3, 
-       R_PPC_ADDR16_LO = 4, 
-       R_PPC_ADDR16_HI = 5, 
-       R_PPC_ADDR16_HA = 6, 
-       R_PPC_ADDR14 = 7, 
-       R_PPC_ADDR14_BRTAKEN = 8, 
-       R_PPC_ADDR14_BRNTAKEN = 9, 
-       R_PPC_REL24 = 10, 
-       R_PPC_REL14 = 11, 
-       R_PPC_REL14_BRTAKEN = 12, 
-       R_PPC_REL14_BRNTAKEN = 13, 
-       R_PPC_GOT16 = 14, 
-       R_PPC_GOT16_LO = 15, 
-       R_PPC_GOT16_HI = 16, 
-       R_PPC_GOT16_HA = 17, 
-       R_PPC_PLTREL24 = 18, 
-       R_PPC_COPY = 19, 
-       R_PPC_GLOB_DAT = 20, 
-       R_PPC_JMP_SLOT = 21, 
-       R_PPC_RELATIVE = 22, 
-       R_PPC_LOCAL24PC = 23, 
-       R_PPC_UADDR32 = 24, 
-       R_PPC_UADDR16 = 25, 
-       R_PPC_REL32 = 26, 
-       R_PPC_PLT32 = 27, 
-       R_PPC_PLTREL32 = 28, 
-       R_PPC_PLT16_LO = 29, 
-       R_PPC_PLT16_HI = 30, 
-       R_PPC_PLT16_HA = 31, 
-       R_PPC_SDAREL16 = 32, 
-       R_PPC_SECTOFF = 33, 
-       R_PPC_SECTOFF_LO = 34, 
-       R_PPC_SECTOFF_HI = 35, 
-       R_PPC_SECTOFF_HA = 36, 
-
-       R_PPC_COUNT = 37, /* Count of defined relocation types. */
-
-       R_PPC_TLS = 67, 
-       R_PPC_DTPMOD32 = 68, 
-       R_PPC_TPREL16 = 69, 
-       R_PPC_TPREL16_LO = 70, 
-       R_PPC_TPREL16_HI = 71, 
-       R_PPC_TPREL16_HA = 72, 
-       R_PPC_TPREL32 = 73, 
-       R_PPC_DTPREL16 = 74, 
-       R_PPC_DTPREL16_LO = 75, 
-       R_PPC_DTPREL16_HI = 76, 
-       R_PPC_DTPREL16_HA = 77, 
-       R_PPC_DTPREL32 = 78, 
-       R_PPC_GOT_TLSGD16 = 79, 
-       R_PPC_GOT_TLSGD16_LO = 80, 
-       R_PPC_GOT_TLSGD16_HI = 81, 
-       R_PPC_GOT_TLSGD16_HA = 82, 
-       R_PPC_GOT_TLSLD16 = 83, 
-       R_PPC_GOT_TLSLD16_LO = 84, 
-       R_PPC_GOT_TLSLD16_HI = 85, 
-       R_PPC_GOT_TLSLD16_HA = 86, 
-       R_PPC_GOT_TPREL16 = 87, 
-       R_PPC_GOT_TPREL16_LO = 88, 
-       R_PPC_GOT_TPREL16_HI = 89, 
-       R_PPC_GOT_TPREL16_HA = 90, 
-
-       R_PPC_EMB_NADDR32 = 101, 
-       R_PPC_EMB_NADDR16 = 102, 
-       R_PPC_EMB_NADDR16_LO = 103, 
-       R_PPC_EMB_NADDR16_HI = 104, 
-       R_PPC_EMB_NADDR16_HA = 105, 
-       R_PPC_EMB_SDAI16 = 106, 
-       R_PPC_EMB_SDA2I16 = 107, 
-       R_PPC_EMB_SDA2REL = 108, 
-       R_PPC_EMB_SDA21 = 109, 
-       R_PPC_EMB_MRKREF = 110, 
-       R_PPC_EMB_RELSEC16 = 111, 
-       R_PPC_EMB_RELST_LO = 112, 
-       R_PPC_EMB_RELST_HI = 113, 
-       R_PPC_EMB_RELST_HA = 114, 
-       R_PPC_EMB_BIT_FLD = 115, 
-       R_PPC_EMB_RELSDA = 116, 
-
-                                       /* Count of defined relocation types. */
-       R_PPC_EMB_COUNT = (R_PPC_EMB_RELSDA - R_PPC_EMB_NADDR32 + 1),
-
-       R_PPC64_REL24 = R_PPC_REL24, 
-       R_PPC64_JMP_SLOT = R_PPC_JMP_SLOT, 
-       R_PPC64_ADDR64 = 38, 
-       R_PPC64_TOC16 = 47, 
-       R_PPC64_TOC16_LO = 48, 
-       R_PPC64_TOC16_HI = 49, 
-       R_PPC64_TOC16_HA = 50, 
-       R_PPC64_TOC16_DS = 63, 
-       R_PPC64_TOC16_LO_DS = 64, 
-       R_PPC64_REL16_LO = 250, 
-       R_PPC64_REL16_HI = 251, 
-       R_PPC64_REL16_HA = 252, 
-
-       R_SPARC_NONE = 0, 
-       R_SPARC_8 = 1, 
-       R_SPARC_16 = 2, 
-       R_SPARC_32 = 3, 
-       R_SPARC_DISP8 = 4, 
-       R_SPARC_DISP16 = 5, 
-       R_SPARC_DISP32 = 6, 
-       R_SPARC_WDISP30 = 7, 
-       R_SPARC_WDISP22 = 8, 
-       R_SPARC_HI22 = 9, 
-       R_SPARC_22 = 10, 
-       R_SPARC_13 = 11, 
-       R_SPARC_LO10 = 12, 
-       R_SPARC_GOT10 = 13, 
-       R_SPARC_GOT13 = 14, 
-       R_SPARC_GOT22 = 15, 
-       R_SPARC_PC10 = 16, 
-       R_SPARC_PC22 = 17, 
-       R_SPARC_WPLT30 = 18, 
-       R_SPARC_COPY = 19, 
-       R_SPARC_GLOB_DAT = 20, 
-       R_SPARC_JMP_SLOT = 21, 
-       R_SPARC_RELATIVE = 22, 
-       R_SPARC_UA32 = 23, 
-       R_SPARC_PLT32 = 24, 
-       R_SPARC_HIPLT22 = 25, 
-       R_SPARC_LOPLT10 = 26, 
-       R_SPARC_PCPLT32 = 27, 
-       R_SPARC_PCPLT22 = 28, 
-       R_SPARC_PCPLT10 = 29, 
-       R_SPARC_10 = 30, 
-       R_SPARC_11 = 31, 
-       R_SPARC_64 = 32, 
-       R_SPARC_OLO10 = 33, 
-       R_SPARC_HH22 = 34, 
-       R_SPARC_HM10 = 35, 
-       R_SPARC_LM22 = 36, 
-       R_SPARC_PC_HH22 = 37, 
-       R_SPARC_PC_HM10 = 38, 
-       R_SPARC_PC_LM22 = 39, 
-       R_SPARC_WDISP16 = 40, 
-       R_SPARC_WDISP19 = 41, 
-       R_SPARC_GLOB_JMP = 42, 
-       R_SPARC_7 = 43, 
-       R_SPARC_5 = 44, 
-       R_SPARC_6 = 45, 
-       R_SPARC_DISP64 = 46, 
-       R_SPARC_PLT64 = 47, 
-       R_SPARC_HIX22 = 48, 
-       R_SPARC_LOX10 = 49, 
-       R_SPARC_H44 = 50, 
-       R_SPARC_M44 = 51, 
-       R_SPARC_L44 = 52, 
-       R_SPARC_REGISTER = 53, 
-       R_SPARC_UA64 = 54, 
-       R_SPARC_UA16 = 55, 
-
-
-/*
- * Magic number for the elf trampoline, chosen wisely to be an immediate
- * value.
- */
-       ARM_MAGIC_TRAMP_NUMBER = 0x5c000003, 
-};
-
-/*
- * Symbol table entries.
- */
-
-/* For accessing the fields of st_info. */
-uint8 ELF32_ST_BIND(uint8);
-uint8 ELF32_ST_TYPE(uint8);
-
-/* For constructing st_info from field values. */
-uint8 ELF32_ST_INFO(uint8 bind, uint8 type);
-
-/* For accessing the fields of st_other. */
-uint8 ELF32_ST_VISIBILITY(uint8);
-
-/*
- * ELF header.
- */
-
-typedef struct ElfEhdr ElfEhdr;
-struct ElfEhdr {
-       uint8   ident[EI_NIDENT];       /* File identification. */
-       uint16  type;           /* File type. */
-       uint16  machine;        /* Machine architecture. */
-       uint32  version;        /* ELF format version. */
-       uint64  entry;  /* Entry point. */
-       uint64  phoff;  /* Program header file offset. */
-       uint64  shoff;  /* Section header file offset. */
-       uint32  flags;  /* Architecture-specific flags. */
-       uint16  ehsize; /* Size of ELF header in bytes. */
-       uint16  phentsize;      /* Size of program header entry. */
-       uint16  phnum;  /* Number of program header entries. */
-       uint16  shentsize;      /* Size of section header entry. */
-       uint16  shnum;  /* Number of section header entries. */
-       uint16  shstrndx;       /* Section name strings section. */
-};
-
-/*
- * Section header.
- */
-
-typedef struct ElfShdr ElfShdr;
-struct ElfShdr {
-       uint32  name;   /* Section name (index into the
-                                          section header string table). */
-       uint32  type;   /* Section type. */
-       uint64  flags;  /* Section flags. */
-       uint64  addr;   /* Address in memory image. */
-       uint64  off;    /* Offset in file. */
-       uint64  size;   /* Size in bytes. */
-       uint32  link;   /* Index of a related section. */
-       uint32  info;   /* Depends on section type. */
-       uint64  addralign;      /* Alignment in bytes. */
-       uint64  entsize;        /* Size of each entry in section. */
-       
-       int     shnum;  /* section number, not stored on disk */
-       LSym*   secsym; /* section symbol, if needed; not on disk */
-};
-
-/*
- * Program header.
- */
-
-typedef struct ElfPhdr ElfPhdr;
-struct ElfPhdr {
-       uint32  type;           /* Entry type. */
-       uint32  flags;  /* Access permission flags. */
-       uint64  off;    /* File offset of contents. */
-       uint64  vaddr;  /* Virtual address in memory image. */
-       uint64  paddr;  /* Physical address (not used). */
-       uint64  filesz; /* Size of contents in file. */
-       uint64  memsz;  /* Size of contents in memory. */
-       uint64  align;  /* Alignment in memory and file. */
-};
-
-/* For accessing the fields of r_info. */
-uint32 ELF64_R_SYM(uint64);
-uint32 ELF64_R_TYPE(uint64);
-
-/* For constructing r_info from field values. */
-uint64 ELF64_R_INFO(uint32, uint32);
-
-/*
- * Symbol table entries.
- */
-
-/* For accessing the fields of st_info. */
-uint8 ELF64_ST_BIND(uint8);
-uint8 ELF64_ST_TYPE(uint8);
-
-/* For constructing st_info from field values. */
-uint8 ELF64_ST_INFO(uint8 bind, uint8 type);
-
-/* For accessing the fields of st_other. */
-uint8 ELF64_ST_VISIBILITY(uint8);
-
-/*
- * Go linker interface
- */
-enum {
-       ELF64HDRSIZE = 64, 
-       ELF64PHDRSIZE = 56, 
-       ELF64SHDRSIZE = 64, 
-       ELF64RELSIZE = 16, 
-       ELF64RELASIZE = 24, 
-       ELF64SYMSIZE = 24,
-
-       ELF32HDRSIZE = 52,
-       ELF32PHDRSIZE = 32,
-       ELF32SHDRSIZE = 40,
-       ELF32SYMSIZE = 16,
-       ELF32RELSIZE = 8, 
-};
-
-/*
- * The interface uses the 64-bit structures always,
- * to avoid code duplication.  The writers know how to
- * marshal a 32-bit representation from the 64-bit structure.
- */
-
-void   elfinit(void);
-ElfEhdr        *getElfEhdr(void);
-ElfShdr        *newElfShdr(vlong);
-ElfPhdr        *newElfPhdr(void);
-uint32 elfwritehdr(void);
-uint32 elfwritephdrs(void);
-uint32 elfwriteshdrs(void);
-void   elfwritedynent(LSym*, int, uint64);
-void   elfwritedynentsym(LSym*, int, LSym*);
-void   elfwritedynentsymplus(LSym*, int, LSym*, vlong);
-void   elfwritedynentsymsize(LSym*, int, LSym*);
-uint32 elfhash(uint8*);
-uint64 startelf(void);
-uint64 endelf(void);
-extern int     numelfphdr;
-extern int     numelfshdr;
-extern int     iself;
-extern int     elfverneed;
-int    elfinterp(ElfShdr*, uint64, uint64, char*);
-int    elfwriteinterp(void);
-int    elfnetbsdsig(ElfShdr*, uint64, uint64);
-int    elfwritenetbsdsig(void);
-int    elfopenbsdsig(ElfShdr*, uint64, uint64);
-int    elfwriteopenbsdsig(void);
-void   addbuildinfo(char*);
-int    elfbuildinfo(ElfShdr*, uint64, uint64);
-int    elfwritebuildinfo(void);
-void   elfdynhash(void);
-ElfPhdr* elfphload(Segment*);
-ElfShdr* elfshbits(Section*);
-ElfShdr* elfshalloc(Section*);
-ElfShdr* elfshname(char*);
-ElfShdr* elfshreloc(Section*);
-void   elfsetstring(char*, int);
-void   elfaddverneed(LSym*);
-void   elfemitreloc(void);
-void   shsym(ElfShdr*, LSym*);
-void   phsh(ElfPhdr*, ElfShdr*);
-void   doelf(void);
-void   asmbelf(vlong symo);
-void   asmbelfsetup(void);
-void   putelfsectionsyms(void);
-
-EXTERN int     elfstrsize;
-EXTERN char*   elfstrdat;
-EXTERN int     buildinfolen;
-
-/*
- * Total amount of space to reserve at the start of the file
- * for Header, PHeaders, SHeaders, and interp.
- * May waste some.
- * On FreeBSD, cannot be larger than a page.
- */
-enum {
-       ELFRESERVE = 3072, 
-};
diff --git a/src/cmd/ld/go.c b/src/cmd/ld/go.c
deleted file mode 100644 (file)
index 3432d3b..0000000
+++ /dev/null
@@ -1,864 +0,0 @@
-// 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.
-
-// go-specific code shared across loaders (5l, 6l, 8l).
-
-#include       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-#include       "lib.h"
-
-// accumulate all type information from .6 files.
-// check for inconsistencies.
-
-// TODO:
-//     generate debugging section in binary.
-//     once the dust settles, try to move some code to
-//             libmach, so that other linkers and ar can share.
-
-/*
- *     package import data
- */
-typedef struct Import Import;
-struct Import
-{
-       Import *hash;   // next in hash table
-       char *prefix;   // "type", "var", "func", "const"
-       char *name;
-       char *def;
-       char *file;
-};
-enum {
-       NIHASH = 1024
-};
-static Import *ihash[NIHASH];
-static int nimport;
-static void imported(char *pkg, char *import);
-
-static int
-hashstr(char *name)
-{
-       uint32 h;
-       char *cp;
-
-       h = 0;
-       for(cp = name; *cp; h += *cp++)
-               h *= 1119;
-       h &= 0xffffff;
-       return h;
-}
-
-static Import *
-ilookup(char *name)
-{
-       int h;
-       Import *x;
-
-       h = hashstr(name) % NIHASH;
-       for(x=ihash[h]; x; x=x->hash)
-               if(x->name[0] == name[0] && strcmp(x->name, name) == 0)
-                       return x;
-       x = mal(sizeof *x);
-       x->name = estrdup(name);
-       x->hash = ihash[h];
-       ihash[h] = x;
-       nimport++;
-       return x;
-}
-
-static void loadpkgdata(char*, char*, char*, int);
-static void loadcgo(char*, char*, char*, int);
-static int parsemethod(char**, char*, char**);
-static int parsepkgdata(char*, char*, char**, char*, char**, char**, char**);
-
-void
-ldpkg(Biobuf *f, char *pkg, int64 length, char *filename, int whence)
-{
-       char *data, *p0, *p1, *name;
-
-       if(debug['g'])
-               return;
-
-       if((int)length != length) {
-               fprint(2, "%s: too much pkg data in %s\n", argv0, filename);
-               if(debug['u'])
-                       errorexit();
-               return;
-       }
-       data = mal(length+1);
-       if(Bread(f, data, length) != length) {
-               fprint(2, "%s: short pkg read %s\n", argv0, filename);
-               if(debug['u'])
-                       errorexit();
-               return;
-       }
-       data[length] = '\x00';
-
-       // first \n$$ marks beginning of exports - skip rest of line
-       p0 = strstr(data, "\n$$");
-       if(p0 == nil) {
-               if(debug['u'] && whence != ArchiveObj) {
-                       fprint(2, "%s: cannot find export data in %s\n", argv0, filename);
-                       errorexit();
-               }
-               return;
-       }
-       p0 += 3;
-       while(*p0 != '\n' && *p0 != '\x00')
-               p0++;
-
-       // second marks end of exports / beginning of local data
-       p1 = strstr(p0, "\n$$");
-       if(p1 == nil) {
-               fprint(2, "%s: cannot find end of exports in %s\n", argv0, filename);
-               if(debug['u'])
-                       errorexit();
-               return;
-       }
-       while(p0 < p1 && (*p0 == ' ' || *p0 == '\t' || *p0 == '\n'))
-               p0++;
-       if(p0 < p1) {
-               if(strncmp(p0, "package ", 8) != 0) {
-                       fprint(2, "%s: bad package section in %s - %s\n", argv0, filename, p0);
-                       if(debug['u'])
-                               errorexit();
-                       return;
-               }
-               p0 += 8;
-               while(p0 < p1 && (*p0 == ' ' || *p0 == '\t' || *p0 == '\n'))
-                       p0++;
-               name = p0;
-               while(p0 < p1 && *p0 != ' ' && *p0 != '\t' && *p0 != '\n')
-                       p0++;
-               if(debug['u'] && whence != ArchiveObj &&
-                  (p0+6 > p1 || memcmp(p0, " safe\n", 6) != 0)) {
-                       fprint(2, "%s: load of unsafe package %s\n", argv0, filename);
-                       nerrors++;
-                       errorexit();
-               }
-               if(p0 < p1) {
-                       if(*p0 == '\n')
-                               *p0++ = '\x00';
-                       else {
-                               *p0++ = '\x00';
-                               while(p0 < p1 && *p0 != '\n')
-                                       p0++;
-                       }
-               }
-               if(strcmp(pkg, "main") == 0 && strcmp(name, "main") != 0) {
-                       fprint(2, "%s: %s: not package main (package %s)\n", argv0, filename, name);
-                       nerrors++;
-                       errorexit();
-               }
-               loadpkgdata(filename, pkg, p0, p1 - p0);
-       }
-       
-       // __.PKGDEF has no cgo section - those are in the C compiler-generated object files.
-       if(whence == Pkgdef)
-               return;
-
-       // look for cgo section
-       p0 = strstr(p1, "\n$$  // cgo");
-       if(p0 != nil) {
-               p0 = strchr(p0+1, '\n');
-               if(p0 == nil) {
-                       fprint(2, "%s: found $$ // cgo but no newline in %s\n", argv0, filename);
-                       if(debug['u'])
-                               errorexit();
-                       return;
-               }
-               p1 = strstr(p0, "\n$$");
-               if(p1 == nil)
-                       p1 = strstr(p0, "\n!\n");
-               if(p1 == nil) {
-                       fprint(2, "%s: cannot find end of // cgo section in %s\n", argv0, filename);
-                       if(debug['u'])
-                               errorexit();
-                       return;
-               }
-               loadcgo(filename, pkg, p0 + 1, p1 - (p0+1));
-       }
-}
-
-static void
-loadpkgdata(char *file, char *pkg, char *data, int length)
-{
-       char *p, *ep, *prefix, *name, *def;
-       Import *x;
-
-       file = estrdup(file);
-       p = data;
-       ep = data + length;
-       while(parsepkgdata(file, pkg, &p, ep, &prefix, &name, &def) > 0) {
-               x = ilookup(name);
-               if(x->prefix == nil) {
-                       x->prefix = prefix;
-                       x->def = estrdup(def);
-                       x->file = file;
-               } else if(strcmp(x->prefix, prefix) != 0) {
-                       fprint(2, "%s: conflicting definitions for %s\n", argv0, name);
-                       fprint(2, "%s:\t%s %s ...\n", x->file, x->prefix, name);
-                       fprint(2, "%s:\t%s %s ...\n", file, prefix, name);
-                       nerrors++;
-               } else if(strcmp(x->def, def) != 0) {
-                       fprint(2, "%s: conflicting definitions for %s\n", argv0, name);
-                       fprint(2, "%s:\t%s %s %s\n", x->file, x->prefix, name, x->def);
-                       fprint(2, "%s:\t%s %s %s\n", file, prefix, name, def);
-                       nerrors++;
-               }
-               free(name);
-               free(def);
-       }
-       free(file);
-}
-
-static int
-parsepkgdata(char *file, char *pkg, char **pp, char *ep, char **prefixp, char **namep, char **defp)
-{
-       char *p, *prefix, *name, *def, *edef, *meth;
-       int n, inquote;
-
-       // skip white space
-       p = *pp;
-loop:
-       while(p < ep && (*p == ' ' || *p == '\t' || *p == '\n'))
-               p++;
-       if(p == ep || strncmp(p, "$$\n", 3) == 0)
-               return 0;
-
-       // prefix: (var|type|func|const)
-       prefix = p;
-       if(p + 7 > ep)
-               return -1;
-       if(strncmp(p, "var ", 4) == 0)
-               p += 4;
-       else if(strncmp(p, "type ", 5) == 0)
-               p += 5;
-       else if(strncmp(p, "func ", 5) == 0)
-               p += 5;
-       else if(strncmp(p, "const ", 6) == 0)
-               p += 6;
-       else if(strncmp(p, "import ", 7) == 0) {
-               p += 7;
-               while(p < ep && *p != ' ')
-                       p++;
-               p++;
-               name = p;
-               while(p < ep && *p != '\n')
-                       p++;
-               if(p >= ep) {
-                       fprint(2, "%s: %s: confused in import line\n", argv0, file);
-                       nerrors++;
-                       return -1;
-               }
-               *p++ = '\x00';
-               imported(pkg, name);
-               goto loop;
-       }
-       else {
-               fprint(2, "%s: %s: confused in pkg data near <<%.40s>>\n", argv0, file, prefix);
-               nerrors++;
-               return -1;
-       }
-       p[-1] = '\x00';
-
-       // name: a.b followed by space
-       name = p;
-       inquote = 0;
-       while(p < ep) {
-               if (*p == ' ' && !inquote)
-                       break;
-
-               if(*p == '\\')
-                       p++;
-               else if(*p == '"')
-                       inquote = !inquote;
-
-               p++;
-       }
-
-       if(p >= ep)
-               return -1;
-       *p++ = '\x00';
-
-       // def: free form to new line
-       def = p;
-       while(p < ep && *p != '\n')
-               p++;
-       if(p >= ep)
-               return -1;
-       edef = p;
-       *p++ = '\x00';
-
-       // include methods on successive lines in def of named type
-       while(parsemethod(&p, ep, &meth) > 0) {
-               *edef++ = '\n'; // overwrites '\x00'
-               if(edef+1 > meth) {
-                       // We want to indent methods with a single \t.
-                       // 6g puts at least one char of indent before all method defs,
-                       // so there will be room for the \t.  If the method def wasn't
-                       // indented we could do something more complicated,
-                       // but for now just diagnose the problem and assume
-                       // 6g will keep indenting for us.
-                       fprint(2, "%s: %s: expected methods to be indented %p %p %.10s\n", argv0,
-                               file, edef, meth, meth);
-                       nerrors++;
-                       return -1;
-               }
-               *edef++ = '\t';
-               n = strlen(meth);
-               memmove(edef, meth, n);
-               edef += n;
-       }
-
-       name = expandpkg(name, pkg);
-       def = expandpkg(def, pkg);
-
-       // done
-       *pp = p;
-       *prefixp = prefix;
-       *namep = name;
-       *defp = def;
-       return 1;
-}
-
-static int
-parsemethod(char **pp, char *ep, char **methp)
-{
-       char *p;
-
-       // skip white space
-       p = *pp;
-       while(p < ep && (*p == ' ' || *p == '\t'))
-               p++;
-       if(p == ep)
-               return 0;
-
-       // might be a comment about the method
-       if(p + 2 < ep && strncmp(p, "//", 2) == 0)
-               goto useline;
-       
-       // if it says "func (", it's a method
-       if(p + 6 < ep && strncmp(p, "func (", 6) == 0)
-               goto useline;
-       return 0;
-
-useline:
-       // definition to end of line
-       *methp = p;
-       while(p < ep && *p != '\n')
-               p++;
-       if(p >= ep) {
-               fprint(2, "%s: lost end of line in method definition\n", argv0);
-               *pp = ep;
-               return -1;
-       }
-       *p++ = '\x00';
-       *pp = p;
-       return 1;
-}
-
-static void
-loadcgo(char *file, char *pkg, char *p, int n)
-{
-       char *pend, *next, *p0, *q;
-       char *f[10], *local, *remote, *lib;
-       int nf;
-       LSym *s;
-
-       USED(file);
-       pend = p + n;
-       p0 = nil;
-       for(; p<pend; p=next) {
-               next = strchr(p, '\n');
-               if(next == nil)
-                       next = "";
-               else
-                       *next++ = '\x00';
-
-               free(p0);
-               p0 = estrdup(p); // save for error message
-               nf = tokenize(p, f, nelem(f));
-               
-               if(strcmp(f[0], "cgo_import_dynamic") == 0) {
-                       if(nf < 2 || nf > 4)
-                               goto err;
-                       
-                       local = f[1];
-                       remote = local;
-                       if(nf > 2)
-                               remote = f[2];
-                       lib = "";
-                       if(nf > 3)
-                               lib = f[3];
-                       
-                       if(debug['d']) {
-                               fprint(2, "%s: %s: cannot use dynamic imports with -d flag\n", argv0, file);
-                               nerrors++;
-                               return;
-                       }
-               
-                       if(strcmp(local, "_") == 0 && strcmp(remote, "_") == 0) {
-                               // allow #pragma dynimport _ _ "foo.so"
-                               // to force a link of foo.so.
-                               havedynamic = 1;
-                               thearch.adddynlib(lib);
-                               continue;
-                       }
-
-                       local = expandpkg(local, pkg);
-                       q = strchr(remote, '#');
-                       if(q)
-                               *q++ = '\x00';
-                       s = linklookup(ctxt, local, 0);
-                       if(local != f[1])
-                               free(local);
-                       if(s->type == 0 || s->type == SXREF || s->type == SHOSTOBJ) {
-                               s->dynimplib = lib;
-                               s->extname = remote;
-                               s->dynimpvers = q;
-                               if(s->type != SHOSTOBJ)
-                                       s->type = SDYNIMPORT;
-                               havedynamic = 1;
-                       }
-                       continue;
-               }
-               
-               if(strcmp(f[0], "cgo_import_static") == 0) {
-                       if(nf != 2)
-                               goto err;
-                       local = f[1];
-                       s = linklookup(ctxt, local, 0);
-                       s->type = SHOSTOBJ;
-                       s->size = 0;
-                       continue;
-               }
-
-               if(strcmp(f[0], "cgo_export_static") == 0 || strcmp(f[0], "cgo_export_dynamic") == 0) {
-                       // TODO: Remove once we know Windows is okay.
-                       if(strcmp(f[0], "cgo_export_static") == 0 && HEADTYPE == Hwindows)
-                               continue;
-
-                       if(nf < 2 || nf > 3)
-                               goto err;
-                       local = f[1];
-                       if(nf > 2)
-                               remote = f[2];
-                       else
-                               remote = local;
-                       local = expandpkg(local, pkg);
-                       s = linklookup(ctxt, local, 0);
-
-                       if(flag_shared && s == linklookup(ctxt, "main", 0))
-                               continue;
-
-                       // export overrides import, for openbsd/cgo.
-                       // see issue 4878.
-                       if(s->dynimplib != nil) {
-                               s->dynimplib = nil;
-                               s->extname = nil;
-                               s->dynimpvers = nil;
-                               s->type = 0;
-                       }
-
-                       if(s->cgoexport == 0) {
-                               s->extname = remote;
-                               if(ndynexp%32 == 0)
-                                       dynexp = erealloc(dynexp, (ndynexp+32)*sizeof dynexp[0]);
-                               dynexp[ndynexp++] = s;
-                       } else if(strcmp(s->extname, remote) != 0) {
-                               fprint(2, "%s: conflicting cgo_export directives: %s as %s and %s\n", argv0, s->name, s->extname, remote);
-                               nerrors++;
-                               return;
-                       }
-                       if(strcmp(f[0], "cgo_export_static") == 0)
-                               s->cgoexport |= CgoExportStatic;
-                       else
-                               s->cgoexport |= CgoExportDynamic;
-                       if(local != f[1])
-                               free(local);
-                       continue;
-               }
-               
-               if(strcmp(f[0], "cgo_dynamic_linker") == 0) {
-                       if(nf != 2)
-                               goto err;
-                       
-                       if(!debug['I']) { // not overridden by command line
-                               if(interpreter != nil && strcmp(interpreter, f[1]) != 0) {
-                                       fprint(2, "%s: conflict dynlinker: %s and %s\n", argv0, interpreter, f[1]);
-                                       nerrors++;
-                                       return;
-                               }
-                               free(interpreter);
-                               interpreter = estrdup(f[1]);
-                       }
-                       continue;
-               }
-               
-               if(strcmp(f[0], "cgo_ldflag") == 0) {
-                       if(nf != 2)
-                               goto err;
-                       if(nldflag%32 == 0)
-                               ldflag = erealloc(ldflag, (nldflag+32)*sizeof ldflag[0]);
-                       ldflag[nldflag++] = estrdup(f[1]);
-                       continue;
-               }
-       }
-       free(p0);
-       return;
-
-err:
-       fprint(2, "%s: %s: invalid dynimport line: %s\n", argv0, file, p0);
-       nerrors++;
-}
-
-static LSym *markq;
-static LSym *emarkq;
-
-static void
-mark1(LSym *s, LSym *parent)
-{
-       if(s == nil || s->reachable)
-               return;
-       if(strncmp(s->name, "go.weak.", 8) == 0)
-               return;
-       s->reachable = 1;
-       s->reachparent = parent;
-       if(markq == nil)
-               markq = s;
-       else
-               emarkq->queue = s;
-       emarkq = s;
-}
-
-void
-mark(LSym *s)
-{
-       mark1(s, nil);
-}
-
-static void
-markflood(void)
-{
-       Auto *a;
-       LSym *s;
-       int i;
-       
-       for(s=markq; s!=nil; s=s->queue) {
-               if(s->type == STEXT) {
-                       if(debug['v'] > 1)
-                               Bprint(&bso, "marktext %s\n", s->name);
-                       for(a=s->autom; a; a=a->link)
-                               mark1(a->gotype, s);
-               }
-               for(i=0; i<s->nr; i++)
-                       mark1(s->r[i].sym, s);
-               if(s->pcln) {
-                       for(i=0; i<s->pcln->nfuncdata; i++)
-                               mark1(s->pcln->funcdata[i], s);
-               }
-               mark1(s->gotype, s);
-               mark1(s->sub, s);
-               mark1(s->outer, s);
-       }
-}
-
-static char*
-markextra[] =
-{
-       "runtime.morestack",
-       "runtime.morestackx",
-
-       "runtime.morestack00",
-       "runtime.morestack10",
-       "runtime.morestack01",
-       "runtime.morestack11",
-
-       "runtime.morestack8",
-       "runtime.morestack16",
-       "runtime.morestack24",
-       "runtime.morestack32",
-       "runtime.morestack40",
-       "runtime.morestack48",
-       
-       // on arm, lock in the div/mod helpers too
-       "_div",
-       "_divu",
-       "_mod",
-       "_modu",
-};
-
-void
-deadcode(void)
-{
-       int i;
-       LSym *s, *last, *p;
-       Fmt fmt;
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f deadcode\n", cputime());
-
-       mark(linklookup(ctxt, INITENTRY, 0));
-       for(i=0; i<nelem(markextra); i++)
-               mark(linklookup(ctxt, markextra[i], 0));
-
-       for(i=0; i<ndynexp; i++)
-               mark(dynexp[i]);
-
-       markflood();
-       
-       // keep each beginning with 'typelink.' if the symbol it points at is being kept.
-       for(s = ctxt->allsym; s != nil; s = s->allsym) {
-               if(strncmp(s->name, "go.typelink.", 12) == 0)
-                       s->reachable = s->nr==1 && s->r[0].sym->reachable;
-       }
-
-       // remove dead text but keep file information (z symbols).
-       last = nil;
-       for(s = ctxt->textp; s != nil; s = s->next) {
-               if(!s->reachable)
-                       continue;
-               // NOTE: Removing s from old textp and adding to new, shorter textp.
-               if(last == nil)
-                       ctxt->textp = s;
-               else
-                       last->next = s;
-               last = s;
-       }
-       if(last == nil)
-               ctxt->textp = nil;
-       else
-               last->next = nil;
-       
-       for(s = ctxt->allsym; s != nil; s = s->allsym)
-               if(strncmp(s->name, "go.weak.", 8) == 0) {
-                       s->special = 1;  // do not lay out in data segment
-                       s->reachable = 1;
-                       s->hide = 1;
-               }
-       
-       // record field tracking references
-       fmtstrinit(&fmt);
-       for(s = ctxt->allsym; s != nil; s = s->allsym) {
-               if(strncmp(s->name, "go.track.", 9) == 0) {
-                       s->special = 1;  // do not lay out in data segment
-                       s->hide = 1;
-                       if(s->reachable) {
-                               fmtprint(&fmt, "%s", s->name+9);
-                               for(p=s->reachparent; p; p=p->reachparent)
-                                       fmtprint(&fmt, "\t%s", p->name);
-                               fmtprint(&fmt, "\n");
-                       }
-                       s->type = SCONST;
-                       s->value = 0;
-               }
-       }
-       if(tracksym == nil)
-               return;
-       s = linklookup(ctxt, tracksym, 0);
-       if(!s->reachable)
-               return;
-       addstrdata(tracksym, fmtstrflush(&fmt));
-}
-
-void
-doweak(void)
-{
-       LSym *s, *t;
-
-       // resolve weak references only if
-       // target symbol will be in binary anyway.
-       for(s = ctxt->allsym; s != nil; s = s->allsym) {
-               if(strncmp(s->name, "go.weak.", 8) == 0) {
-                       t = linkrlookup(ctxt, s->name+8, s->version);
-                       if(t && t->type != 0 && t->reachable) {
-                               s->value = t->value;
-                               s->type = t->type;
-                               s->outer = t;
-                       } else {
-                               s->type = SCONST;
-                               s->value = 0;
-                       }
-                       continue;
-               }
-       }
-}
-
-void
-addexport(void)
-{
-       int i;
-       
-       if(HEADTYPE == Hdarwin)
-               return;
-
-       for(i=0; i<ndynexp; i++)
-               thearch.adddynsym(ctxt, dynexp[i]);
-}
-
-/* %Z from gc, for quoting import paths */
-int
-Zconv(Fmt *fp)
-{
-       Rune r;
-       char *s, *se;
-       int n;
-
-       s = va_arg(fp->args, char*);
-       if(s == nil)
-               return fmtstrcpy(fp, "<nil>");
-
-       se = s + strlen(s);
-
-       // NOTE: Keep in sync with ../gc/go.c:/^Zconv.
-       while(s < se) {
-               n = chartorune(&r, s);
-               s += n;
-               switch(r) {
-               case Runeerror:
-                       if(n == 1) {
-                               fmtprint(fp, "\\x%02x", (uchar)*(s-1));
-                               break;
-                       }
-                       // fall through
-               default:
-                       if(r < ' ') {
-                               fmtprint(fp, "\\x%02x", r);
-                               break;
-                       }
-                       fmtrune(fp, r);
-                       break;
-               case '\t':
-                       fmtstrcpy(fp, "\\t");
-                       break;
-               case '\n':
-                       fmtstrcpy(fp, "\\n");
-                       break;
-               case '\"':
-               case '\\':
-                       fmtrune(fp, '\\');
-                       fmtrune(fp, r);
-                       break;
-               case 0xFEFF: // BOM, basically disallowed in source code
-                       fmtstrcpy(fp, "\\uFEFF");
-                       break;
-               }
-       }
-       return 0;
-}
-
-
-typedef struct Pkg Pkg;
-struct Pkg
-{
-       uchar mark;
-       uchar checked;
-       Pkg *next;
-       char *path;
-       Pkg **impby;
-       int nimpby;
-       int mimpby;
-       Pkg *all;
-};
-
-static Pkg *phash[1024];
-static Pkg *pkgall;
-
-static Pkg*
-getpkg(char *path)
-{
-       Pkg *p;
-       int h;
-       
-       h = hashstr(path) % nelem(phash);
-       for(p=phash[h]; p; p=p->next)
-               if(strcmp(p->path, path) == 0)
-                       return p;
-       p = mal(sizeof *p);
-       p->path = estrdup(path);
-       p->next = phash[h];
-       phash[h] = p;
-       p->all = pkgall;
-       pkgall = p;
-       return p;
-}
-
-static void
-imported(char *pkg, char *import)
-{
-       Pkg *p, *i;
-       
-       // everyone imports runtime, even runtime.
-       if(strcmp(import, "\"runtime\"") == 0)
-               return;
-
-       pkg = smprint("\"%Z\"", pkg);  // turn pkg path into quoted form, freed below
-       p = getpkg(pkg);
-       i = getpkg(import);
-       if(i->nimpby >= i->mimpby) {
-               i->mimpby *= 2;
-               if(i->mimpby == 0)
-                       i->mimpby = 16;
-               i->impby = erealloc(i->impby, i->mimpby*sizeof i->impby[0]);
-       }
-       i->impby[i->nimpby++] = p;
-       free(pkg);
-}
-
-static Pkg*
-cycle(Pkg *p)
-{
-       int i;
-       Pkg *bad;
-
-       if(p->checked)
-               return 0;
-
-       if(p->mark) {
-               nerrors++;
-               print("import cycle:\n");
-               print("\t%s\n", p->path);
-               return p;
-       }
-       p->mark = 1;
-       for(i=0; i<p->nimpby; i++) {
-               if((bad = cycle(p->impby[i])) != nil) {
-                       p->mark = 0;
-                       p->checked = 1;
-                       print("\timports %s\n", p->path);
-                       if(bad == p)
-                               return nil;
-                       return bad;
-               }
-       }
-       p->checked = 1;
-       p->mark = 0;
-       return 0;
-}
-
-void
-importcycles(void)
-{
-       Pkg *p;
-       
-       for(p=pkgall; p; p=p->all)
-               cycle(p);
-}
-
-void
-setlinkmode(char *arg)
-{
-       if(strcmp(arg, "internal") == 0)
-               linkmode = LinkInternal;
-       else if(strcmp(arg, "external") == 0)
-               linkmode = LinkExternal;
-       else if(strcmp(arg, "auto") == 0)
-               linkmode = LinkAuto;
-       else {
-               fprint(2, "unknown link mode -linkmode %s\n", arg);
-               errorexit();
-       }
-}
diff --git a/src/cmd/ld/ldelf.c b/src/cmd/ld/ldelf.c
deleted file mode 100644 (file)
index f4ddc2c..0000000
+++ /dev/null
@@ -1,958 +0,0 @@
-/*
-Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
-http://code.swtch.com/plan9port/src/tip/src/libmach/
-
-       Copyright © 2004 Russ Cox.
-       Portions Copyright © 2008-2010 Google Inc.
-       Portions Copyright © 2010 The Go Authors.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#include       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-#include       "lib.h"
-#include       "elf.h"
-
-enum
-{
-       ElfClassNone = 0,
-       ElfClass32,
-       ElfClass64,
-
-       ElfDataNone = 0,
-       ElfDataLsb,
-       ElfDataMsb,
-
-       ElfTypeNone = 0,
-       ElfTypeRelocatable,
-       ElfTypeExecutable,
-       ElfTypeSharedObject,
-       ElfTypeCore,
-       /* 0xFF00 - 0xFFFF reserved for processor-specific types */
-
-       ElfMachNone = 0,
-       ElfMach32100,           /* AT&T WE 32100 */
-       ElfMachSparc,           /* SPARC */
-       ElfMach386,             /* Intel 80386 */
-       ElfMach68000,           /* Motorola 68000 */
-       ElfMach88000,           /* Motorola 88000 */
-       ElfMach486,             /* Intel 80486, no longer used */
-       ElfMach860,             /* Intel 80860 */
-       ElfMachMips,            /* MIPS RS3000 */
-       ElfMachS370,            /* IBM System/370 */
-       ElfMachMipsLe,  /* MIPS RS3000 LE */
-       ElfMachParisc = 15,             /* HP PA RISC */
-       ElfMachVpp500 = 17,     /* Fujitsu VPP500 */
-       ElfMachSparc32Plus,     /* SPARC V8+ */
-       ElfMach960,             /* Intel 80960 */
-       ElfMachPower,           /* PowerPC */
-       ElfMachPower64, /* PowerPC 64-bit */
-       ElfMachS390,            /* IBM System/390 */
-       ElfMachV800 = 36,       /* NEC V800 */
-       ElfMachFr20,            /* Fujitsu FR20 */
-       ElfMachRh32,            /* TRW RH-32 */
-       ElfMachRce,             /* Motorola RCE */
-       ElfMachArm,             /* ARM */
-       ElfMachAlpha,           /* Digital Alpha */
-       ElfMachSH,              /* Hitachi SH */
-       ElfMachSparc9,          /* SPARC V9 */
-       ElfMachAmd64 = 62,
-       /* and the list goes on... */
-
-       ElfAbiNone = 0,
-       ElfAbiSystemV = 0,      /* [sic] */
-       ElfAbiHPUX,
-       ElfAbiNetBSD,
-       ElfAbiLinux,
-       ElfAbiSolaris = 6,
-       ElfAbiAix,
-       ElfAbiIrix,
-       ElfAbiFreeBSD,
-       ElfAbiTru64,
-       ElfAbiModesto,
-       ElfAbiOpenBSD,
-       ElfAbiARM = 97,
-       ElfAbiEmbedded = 255,
-
-       /* some of sections 0xFF00 - 0xFFFF reserved for various things */
-       ElfSectNone = 0,
-       ElfSectProgbits,
-       ElfSectSymtab,
-       ElfSectStrtab,
-       ElfSectRela,
-       ElfSectHash,
-       ElfSectDynamic,
-       ElfSectNote,
-       ElfSectNobits,
-       ElfSectRel,
-       ElfSectShlib,
-       ElfSectDynsym,
-
-       ElfSectFlagWrite = 0x1,
-       ElfSectFlagAlloc = 0x2,
-       ElfSectFlagExec = 0x4,
-       /* 0xF0000000 are reserved for processor specific */
-
-       ElfSymBindLocal = 0,
-       ElfSymBindGlobal,
-       ElfSymBindWeak,
-       /* 13-15 reserved */
-
-       ElfSymTypeNone = 0,
-       ElfSymTypeObject,
-       ElfSymTypeFunc,
-       ElfSymTypeSection,
-       ElfSymTypeFile,
-       /* 13-15 reserved */
-
-       ElfSymShnNone = 0,
-       ElfSymShnAbs = 0xFFF1,
-       ElfSymShnCommon = 0xFFF2,
-       /* 0xFF00-0xFF1F reserved for processors */
-       /* 0xFF20-0xFF3F reserved for operating systems */
-
-       ElfProgNone = 0,
-       ElfProgLoad,
-       ElfProgDynamic,
-       ElfProgInterp,
-       ElfProgNote,
-       ElfProgShlib,
-       ElfProgPhdr,
-
-       ElfProgFlagExec = 0x1,
-       ElfProgFlagWrite = 0x2,
-       ElfProgFlagRead = 0x4,
-
-       ElfNotePrStatus = 1,
-       ElfNotePrFpreg = 2,
-       ElfNotePrPsinfo = 3,
-       ElfNotePrTaskstruct = 4,
-       ElfNotePrAuxv = 6,
-       ElfNotePrXfpreg = 0x46e62b7f    /* for gdb/386 */
-};
-
-typedef struct ElfHdrBytes ElfHdrBytes;
-typedef struct ElfSectBytes ElfSectBytes;
-typedef struct ElfProgBytes ElfProgBytes;
-typedef struct ElfSymBytes ElfSymBytes;
-
-typedef struct ElfHdrBytes64 ElfHdrBytes64;
-typedef struct ElfSectBytes64 ElfSectBytes64;
-typedef struct ElfProgBytes64 ElfProgBytes64;
-typedef struct ElfSymBytes64 ElfSymBytes64;
-
-struct ElfHdrBytes
-{
-       uchar   ident[16];
-       uchar   type[2];
-       uchar   machine[2];
-       uchar   version[4];
-       uchar   entry[4];
-       uchar   phoff[4];
-       uchar   shoff[4];
-       uchar   flags[4];
-       uchar   ehsize[2];
-       uchar   phentsize[2];
-       uchar   phnum[2];
-       uchar   shentsize[2];
-       uchar   shnum[2];
-       uchar   shstrndx[2];
-};
-
-struct ElfHdrBytes64
-{
-       uchar   ident[16];
-       uchar   type[2];
-       uchar   machine[2];
-       uchar   version[4];
-       uchar   entry[8];
-       uchar   phoff[8];
-       uchar   shoff[8];
-       uchar   flags[4];
-       uchar   ehsize[2];
-       uchar   phentsize[2];
-       uchar   phnum[2];
-       uchar   shentsize[2];
-       uchar   shnum[2];
-       uchar   shstrndx[2];
-};
-
-struct ElfSectBytes
-{
-       uchar   name[4];
-       uchar   type[4];
-       uchar   flags[4];
-       uchar   addr[4];
-       uchar   off[4];
-       uchar   size[4];
-       uchar   link[4];
-       uchar   info[4];
-       uchar   align[4];
-       uchar   entsize[4];
-};
-
-struct ElfSectBytes64
-{
-       uchar   name[4];
-       uchar   type[4];
-       uchar   flags[8];
-       uchar   addr[8];
-       uchar   off[8];
-       uchar   size[8];
-       uchar   link[4];
-       uchar   info[4];
-       uchar   align[8];
-       uchar   entsize[8];
-};
-
-struct ElfSymBytes
-{
-       uchar   name[4];
-       uchar   value[4];
-       uchar   size[4];
-       uchar   info;   /* top4: bind, bottom4: type */
-       uchar   other;
-       uchar   shndx[2];
-};
-
-struct ElfSymBytes64
-{
-       uchar   name[4];
-       uchar   info;   /* top4: bind, bottom4: type */
-       uchar   other;
-       uchar   shndx[2];
-       uchar   value[8];
-       uchar   size[8];
-};
-
-typedef struct ElfSect ElfSect;
-typedef struct ElfObj ElfObj;
-typedef struct ElfSym ElfSym;
-
-struct ElfSect
-{
-       char            *name;
-       uint32  nameoff;
-       uint32  type;
-       uint64  flags;
-       uint64  addr;
-       uint64  off;
-       uint64  size;
-       uint32  link;
-       uint32  info;
-       uint64  align;
-       uint64  entsize;
-       uchar   *base;
-       LSym    *sym;
-};
-
-struct ElfObj
-{
-       Biobuf  *f;
-       int64   base;   // offset in f where ELF begins
-       int64   length;         // length of ELF
-       int     is64;
-       char    *name;
-
-       Endian  *e;
-       ElfSect *sect;
-       uint            nsect;
-       char            *shstrtab;
-       int             nsymtab;
-       ElfSect *symtab;
-       ElfSect *symstr;
-
-       uint32  type;
-       uint32  machine;
-       uint32  version;
-       uint64  entry;
-       uint64  phoff;
-       uint64  shoff;
-       uint32  flags;
-       uint32  ehsize;
-       uint32  phentsize;
-       uint32  phnum;
-       uint32  shentsize;
-       uint32  shnum;
-       uint32  shstrndx;
-};
-
-struct ElfSym
-{
-       char*   name;
-       uint64  value;
-       uint64  size;
-       uchar   bind;
-       uchar   type;
-       uchar   other;
-       uint16  shndx;
-       LSym*   sym;
-};
-
-uchar ElfMagic[4] = { 0x7F, 'E', 'L', 'F' };
-
-static ElfSect*        section(ElfObj*, char*);
-static int     elfmap(ElfObj*, ElfSect*);
-static int     readelfsym(ElfObj*, int i, ElfSym*, int);
-static int     reltype(char*, int, uchar*);
-
-int
-valuecmp(LSym *a, LSym *b)
-{
-       if(a->value < b->value)
-               return -1;
-       if(a->value > b->value)
-               return +1;
-       return 0;
-}
-
-void
-ldelf(Biobuf *f, char *pkg, int64 length, char *pn)
-{
-       int32 base;
-       uint64 add, info;
-       char *name;
-       int i, j, rela, is64, n, flag;
-       uchar hdrbuf[64];
-       uchar *p;
-       ElfHdrBytes *hdr;
-       ElfObj *elfobj;
-       ElfSect *sect, *rsect;
-       ElfSym sym;
-       Endian *e;
-       Reloc *r, *rp;
-       LSym *s;
-       LSym **symbols;
-
-       symbols = nil;
-
-       if(debug['v'])
-               Bprint(&bso, "%5.2f ldelf %s\n", cputime(), pn);
-
-       ctxt->version++;
-       base = Boffset(f);
-
-       if(Bread(f, hdrbuf, sizeof hdrbuf) != sizeof hdrbuf)
-               goto bad;
-       hdr = (ElfHdrBytes*)hdrbuf;
-       if(memcmp(hdr->ident, ElfMagic, 4) != 0)
-               goto bad;
-       switch(hdr->ident[5]) {
-       case ElfDataLsb:
-               e = &le;
-               break;
-       case ElfDataMsb:
-               e = &be;
-               break;
-       default:
-               goto bad;
-       }
-
-       // read header
-       elfobj = mal(sizeof *elfobj);
-       elfobj->e = e;
-       elfobj->f = f;
-       elfobj->base = base;
-       elfobj->length = length;
-       elfobj->name = pn;
-       
-       is64 = 0;
-       if(hdr->ident[4] == ElfClass64) {
-               ElfHdrBytes64* hdr;
-
-               is64 = 1;
-               hdr = (ElfHdrBytes64*)hdrbuf;
-               elfobj->type = e->e16(hdr->type);
-               elfobj->machine = e->e16(hdr->machine);
-               elfobj->version = e->e32(hdr->version);
-               elfobj->phoff = e->e64(hdr->phoff);
-               elfobj->shoff = e->e64(hdr->shoff);
-               elfobj->flags = e->e32(hdr->flags);
-               elfobj->ehsize = e->e16(hdr->ehsize);
-               elfobj->phentsize = e->e16(hdr->phentsize);
-               elfobj->phnum = e->e16(hdr->phnum);
-               elfobj->shentsize = e->e16(hdr->shentsize);
-               elfobj->shnum = e->e16(hdr->shnum);
-               elfobj->shstrndx = e->e16(hdr->shstrndx);
-       } else {
-               elfobj->type = e->e16(hdr->type);
-               elfobj->machine = e->e16(hdr->machine);
-               elfobj->version = e->e32(hdr->version);
-               elfobj->entry = e->e32(hdr->entry);
-               elfobj->phoff = e->e32(hdr->phoff);
-               elfobj->shoff = e->e32(hdr->shoff);
-               elfobj->flags = e->e32(hdr->flags);
-               elfobj->ehsize = e->e16(hdr->ehsize);
-               elfobj->phentsize = e->e16(hdr->phentsize);
-               elfobj->phnum = e->e16(hdr->phnum);
-               elfobj->shentsize = e->e16(hdr->shentsize);
-               elfobj->shnum = e->e16(hdr->shnum);
-               elfobj->shstrndx = e->e16(hdr->shstrndx);
-       }
-       elfobj->is64 = is64;
-       
-       if(hdr->ident[6] != elfobj->version)
-               goto bad;
-
-       if(e->e16(hdr->type) != ElfTypeRelocatable) {
-               diag("%s: elf but not elf relocatable object", pn);
-               return;
-       }
-
-       switch(thearch.thechar) {
-       default:
-               diag("%s: elf %s unimplemented", pn, thestring);
-               return;
-       case '5':
-               if(e != &le || elfobj->machine != ElfMachArm || hdr->ident[4] != ElfClass32) {
-                       diag("%s: elf object but not arm", pn);
-                       return;
-               }
-               break;
-       case '6':
-               if(e != &le || elfobj->machine != ElfMachAmd64 || hdr->ident[4] != ElfClass64) {
-                       diag("%s: elf object but not amd64", pn);
-                       return;
-               }
-               break;
-       case '8':
-               if(e != &le || elfobj->machine != ElfMach386 || hdr->ident[4] != ElfClass32) {
-                       diag("%s: elf object but not 386", pn);
-                       return;
-               }
-               break;
-       case '9':
-               if(elfobj->machine != ElfMachPower64 || hdr->ident[4] != ElfClass64) {
-                       diag("%s: elf object but not ppc64", pn);
-                       return;
-               }
-               break;
-       }
-
-       // load section list into memory.
-       elfobj->sect = mal(elfobj->shnum*sizeof elfobj->sect[0]);
-       elfobj->nsect = elfobj->shnum;
-       for(i=0; i<elfobj->nsect; i++) {
-               if(Bseek(f, base+elfobj->shoff+i*elfobj->shentsize, 0) < 0)
-                       goto bad;
-               sect = &elfobj->sect[i];
-               if(is64) {
-                       ElfSectBytes64 b;
-
-                       werrstr("short read");
-                       if(Bread(f, &b, sizeof b) != sizeof b)
-                               goto bad;
-
-                       sect->nameoff = (uintptr)e->e32(b.name);
-                       sect->type = e->e32(b.type);
-                       sect->flags = e->e64(b.flags);
-                       sect->addr = e->e64(b.addr);
-                       sect->off = e->e64(b.off);
-                       sect->size = e->e64(b.size);
-                       sect->link = e->e32(b.link);
-                       sect->info = e->e32(b.info);
-                       sect->align = e->e64(b.align);
-                       sect->entsize = e->e64(b.entsize);
-               } else {
-                       ElfSectBytes b;
-
-                       werrstr("short read");
-                       if(Bread(f, &b, sizeof b) != sizeof b)
-                               goto bad;
-               
-                       sect->nameoff = (uintptr)e->e32(b.name);
-                       sect->type = e->e32(b.type);
-                       sect->flags = e->e32(b.flags);
-                       sect->addr = e->e32(b.addr);
-                       sect->off = e->e32(b.off);
-                       sect->size = e->e32(b.size);
-                       sect->link = e->e32(b.link);
-                       sect->info = e->e32(b.info);
-                       sect->align = e->e32(b.align);
-                       sect->entsize = e->e32(b.entsize);
-               }
-       }
-
-       // read section string table and translate names
-       if(elfobj->shstrndx >= elfobj->nsect) {
-               werrstr("shstrndx out of range %d >= %d", elfobj->shstrndx, elfobj->nsect);
-               goto bad;
-       }
-       sect = &elfobj->sect[elfobj->shstrndx];
-       if(elfmap(elfobj, sect) < 0)
-               goto bad;
-       for(i=0; i<elfobj->nsect; i++)
-               if(elfobj->sect[i].nameoff != 0)
-                       elfobj->sect[i].name = (char*)sect->base + elfobj->sect[i].nameoff;
-       
-       // load string table for symbols into memory.
-       elfobj->symtab = section(elfobj, ".symtab");
-       if(elfobj->symtab == nil) {
-               // our work is done here - no symbols means nothing can refer to this file
-               return;
-       }
-       if(elfobj->symtab->link <= 0 || elfobj->symtab->link >= elfobj->nsect) {
-               diag("%s: elf object has symbol table with invalid string table link", pn);
-               return;
-       }
-       elfobj->symstr = &elfobj->sect[elfobj->symtab->link];
-       if(is64)
-               elfobj->nsymtab = elfobj->symtab->size / sizeof(ElfSymBytes64);
-       else
-               elfobj->nsymtab = elfobj->symtab->size / sizeof(ElfSymBytes);
-       
-       if(elfmap(elfobj, elfobj->symtab) < 0)
-               goto bad;
-       if(elfmap(elfobj, elfobj->symstr) < 0)
-               goto bad;
-
-       // load text and data segments into memory.
-       // they are not as small as the section lists, but we'll need
-       // the memory anyway for the symbol images, so we might
-       // as well use one large chunk.
-       
-       // create symbols for elfmapped sections
-       for(i=0; i<elfobj->nsect; i++) {
-               sect = &elfobj->sect[i];
-               if((sect->type != ElfSectProgbits && sect->type != ElfSectNobits) || !(sect->flags&ElfSectFlagAlloc))
-                       continue;
-               if(sect->type != ElfSectNobits && elfmap(elfobj, sect) < 0)
-                       goto bad;
-               
-               name = smprint("%s(%s)", pkg, sect->name);
-               s = linklookup(ctxt, name, ctxt->version);
-               free(name);
-               switch((int)sect->flags&(ElfSectFlagAlloc|ElfSectFlagWrite|ElfSectFlagExec)) {
-               default:
-                       werrstr("unexpected flags for ELF section %s", sect->name);
-                       goto bad;
-               case ElfSectFlagAlloc:
-                       s->type = SRODATA;
-                       break;
-               case ElfSectFlagAlloc + ElfSectFlagWrite:
-                       if(sect->type == ElfSectNobits)
-                               s->type = SNOPTRBSS;
-                       else
-                               s->type = SNOPTRDATA;
-                       break;
-               case ElfSectFlagAlloc + ElfSectFlagExec:
-                       s->type = STEXT;
-                       break;
-               }
-               if(strcmp(sect->name, ".got") == 0 ||
-                  strcmp(sect->name, ".toc") == 0)
-                       s->type = SELFGOT;
-               if(sect->type == ElfSectProgbits) {
-                       s->p = sect->base;
-                       s->np = sect->size;
-               }
-               s->size = sect->size;
-               s->align = sect->align;
-               sect->sym = s;
-       }
-
-       // enter sub-symbols into symbol table.
-       // symbol 0 is the null symbol.
-       symbols = malloc(elfobj->nsymtab * sizeof(symbols[0]));
-       if(symbols == nil) {
-               diag("out of memory");
-               errorexit();
-       }
-       for(i=1; i<elfobj->nsymtab; i++) {
-               if(readelfsym(elfobj, i, &sym, 1) < 0)
-                       goto bad;
-               symbols[i] = sym.sym;
-               if(sym.type != ElfSymTypeFunc && sym.type != ElfSymTypeObject && sym.type != ElfSymTypeNone)
-                       continue;
-               if(sym.shndx == ElfSymShnCommon) {
-                       s = sym.sym;
-                       if(s->size < sym.size)
-                               s->size = sym.size;
-                       if(s->type == 0 || s->type == SXREF)
-                               s->type = SNOPTRBSS;
-                       continue;
-               }
-               if(sym.shndx >= elfobj->nsect || sym.shndx == 0)
-                       continue;
-               // even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols
-               if(sym.sym == nil)
-                       continue;
-               sect = elfobj->sect+sym.shndx;
-               if(sect->sym == nil) {
-                       if(strncmp(sym.name, ".Linfo_string", 13) == 0) // clang does this
-                               continue;
-                       diag("%s: sym#%d: ignoring %s in section %d (type %d)", pn, i, sym.name, sym.shndx, sym.type);
-                       continue;
-               }
-               s = sym.sym;
-               if(s->outer != nil) {
-                       if(s->dupok)
-                               continue;
-                       diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s->name, s->outer->name, sect->sym->name);
-                       errorexit();
-               }
-               s->sub = sect->sym->sub;
-               sect->sym->sub = s;
-               s->type = sect->sym->type | (s->type&~SMASK) | SSUB;
-               if(!(s->cgoexport & CgoExportDynamic))
-                       s->dynimplib = nil;  // satisfy dynimport
-               s->value = sym.value;
-               s->size = sym.size;
-               s->outer = sect->sym;
-               if(sect->sym->type == STEXT) {
-                       if(s->external && !s->dupok)
-                                       diag("%s: duplicate definition of %s", pn, s->name);
-                       s->external = 1;
-               }
-               if(elfobj->machine == ElfMachPower64) {
-                       flag = sym.other >> 5;
-                       if(2 <= flag && flag <= 6)
-                               s->localentry = 1 << (flag - 2);
-                       else if(flag == 7)
-                               diag("%s: invalid sym.other 0x%x for %s", pn, sym.other, s->name);
-               }
-       }
-       
-       // Sort outer lists by address, adding to textp.
-       // This keeps textp in increasing address order.
-       for(i=0; i<elfobj->nsect; i++) {
-               s = elfobj->sect[i].sym;
-               if(s == nil)
-                       continue;
-               if(s->sub)
-                       s->sub = listsort(s->sub, valuecmp, listsubp);
-               if(s->type == STEXT) {
-                       if(s->onlist)
-                               sysfatal("symbol %s listed multiple times", s->name);
-                       s->onlist = 1;
-                       if(ctxt->etextp)
-                               ctxt->etextp->next = s;
-                       else
-                               ctxt->textp = s;
-                       ctxt->etextp = s;
-                       for(s = s->sub; s != nil; s = s->sub) {
-                               if(s->onlist)
-                                       sysfatal("symbol %s listed multiple times", s->name);
-                               s->onlist = 1;
-                               ctxt->etextp->next = s;
-                               ctxt->etextp = s;
-                       }
-               }
-       }
-
-       // load relocations
-       for(i=0; i<elfobj->nsect; i++) {
-               rsect = &elfobj->sect[i];
-               if(rsect->type != ElfSectRela && rsect->type != ElfSectRel)
-                       continue;
-               if(rsect->info >= elfobj->nsect || elfobj->sect[rsect->info].base == nil)
-                       continue;
-               sect = &elfobj->sect[rsect->info];
-               if(elfmap(elfobj, rsect) < 0)
-                       goto bad;
-               rela = rsect->type == ElfSectRela;
-               n = rsect->size/(4+4*is64)/(2+rela);
-               r = mal(n*sizeof r[0]);
-               p = rsect->base;
-               for(j=0; j<n; j++) {
-                       add = 0;
-                       rp = &r[j];
-                       if(is64) {
-                               // 64-bit rel/rela
-                               rp->off = e->e64(p);
-                               p += 8;
-                               info = e->e64(p);
-                               p += 8;
-                               if(rela) {
-                                       add = e->e64(p);
-                                       p += 8;
-                               }
-                       } else {
-                               // 32-bit rel/rela
-                               rp->off = e->e32(p);
-                               p += 4;
-                               info = e->e32(p);
-                               info = info>>8<<32 | (info&0xff);       // convert to 64-bit info
-                               p += 4;
-                               if(rela) {
-                                       add = e->e32(p);
-                                       p += 4;
-                               }
-                       }
-                       if((info & 0xffffffff) == 0) { // skip R_*_NONE relocation
-                               j--;
-                               n--;
-                               continue;
-                       }
-                       if((info >> 32) == 0) { // absolute relocation, don't bother reading the null symbol
-                               rp->sym = nil;
-                       } else {
-                               if(readelfsym(elfobj, info>>32, &sym, 0) < 0)
-                                       goto bad;
-                               sym.sym = symbols[info>>32];
-                               if(sym.sym == nil) {
-                                       werrstr("%s#%d: reloc of invalid sym #%d %s shndx=%d type=%d",
-                                               sect->sym->name, j, (int)(info>>32), sym.name, sym.shndx, sym.type);
-                                       goto bad;
-                               }
-                               rp->sym = sym.sym;
-                       }
-                       rp->type = reltype(pn, (uint32)info, &rp->siz);
-                       if(rela)
-                               rp->add = add;
-                       else {
-                               // load addend from image
-                               if(rp->siz == 4)
-                                       rp->add = e->e32(sect->base+rp->off);
-                               else if(rp->siz == 8)
-                                       rp->add = e->e64(sect->base+rp->off);
-                               else
-                                       diag("invalid rela size %d", rp->siz);
-                       }
-                       if(rp->siz == 2)
-                               rp->add = (int16)rp->add;
-                       if(rp->siz == 4)
-                               rp->add = (int32)rp->add;
-                       //print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add);
-               }
-               qsort(r, n, sizeof r[0], rbyoff);       // just in case
-               
-               s = sect->sym;
-               s->r = r;
-               s->nr = n;
-       }
-       free(symbols);
-
-       return;
-
-bad:
-       diag("%s: malformed elf file: %r", pn);
-       free(symbols);
-}
-
-static ElfSect*
-section(ElfObj *elfobj, char *name)
-{
-       int i;
-       
-       for(i=0; i<elfobj->nsect; i++)
-               if(elfobj->sect[i].name && name && strcmp(elfobj->sect[i].name, name) == 0)
-                       return &elfobj->sect[i];
-       return nil;
-}
-
-static int
-elfmap(ElfObj *elfobj, ElfSect *sect)
-{
-       if(sect->base != nil)
-               return 0;
-
-       if(sect->off+sect->size > elfobj->length) {
-               werrstr("elf section past end of file");
-               return -1;
-       }
-
-       sect->base = mal(sect->size);
-       werrstr("short read");
-       if(Bseek(elfobj->f, elfobj->base+sect->off, 0) < 0 || Bread(elfobj->f, sect->base, sect->size) != sect->size)
-               return -1;
-       
-       return 0;
-}
-
-static int
-readelfsym(ElfObj *elfobj, int i, ElfSym *sym, int needSym)
-{
-       LSym *s;
-
-       if(i >= elfobj->nsymtab || i < 0) {
-               werrstr("invalid elf symbol index");
-               return -1;
-       }
-       if(i == 0) {
-               diag("readym: read null symbol!");
-       }
-
-       if(elfobj->is64) {
-               ElfSymBytes64 *b;
-               
-               b = (ElfSymBytes64*)(elfobj->symtab->base + i*sizeof *b);
-               sym->name = (char*)elfobj->symstr->base + elfobj->e->e32(b->name);
-               sym->value = elfobj->e->e64(b->value);
-               sym->size = elfobj->e->e64(b->size);
-               sym->shndx = elfobj->e->e16(b->shndx);
-               sym->bind = b->info>>4;
-               sym->type = b->info&0xf;
-               sym->other = b->other;
-       } else {
-               ElfSymBytes *b;
-               
-               b = (ElfSymBytes*)(elfobj->symtab->base + i*sizeof *b);
-               sym->name = (char*)elfobj->symstr->base + elfobj->e->e32(b->name);
-               sym->value = elfobj->e->e32(b->value);
-               sym->size = elfobj->e->e32(b->size);
-               sym->shndx = elfobj->e->e16(b->shndx);
-               sym->bind = b->info>>4;
-               sym->type = b->info&0xf;
-               sym->other = b->other;
-       }
-
-       s = nil;
-       if(strcmp(sym->name, "_GLOBAL_OFFSET_TABLE_") == 0)
-               sym->name = ".got";
-       if(strcmp(sym->name, ".TOC.") == 0)
-               // Magic symbol on ppc64.  Will be set to this object
-               // file's .got+0x8000.
-               sym->bind = ElfSymBindLocal;
-       switch(sym->type) {
-       case ElfSymTypeSection:
-               s = elfobj->sect[sym->shndx].sym;
-               break;
-       case ElfSymTypeObject:
-       case ElfSymTypeFunc:
-       case ElfSymTypeNone:
-               switch(sym->bind) {
-               case ElfSymBindGlobal:
-                       if(needSym) {
-                               s = linklookup(ctxt, sym->name, 0);
-                               // for global scoped hidden symbols we should insert it into
-                               // symbol hash table, but mark them as hidden.
-                               // __i686.get_pc_thunk.bx is allowed to be duplicated, to
-                               // workaround that we set dupok.
-                               // TODO(minux): correctly handle __i686.get_pc_thunk.bx without
-                               // set dupok generally. See http://codereview.appspot.com/5823055/
-                               // comment #5 for details.
-                               if(s && sym->other == 2) {
-                                       s->type |= SHIDDEN;
-                                       s->dupok = 1;
-                               }
-                       }
-                       break;
-               case ElfSymBindLocal:
-                       if(thearch.thechar == '5' && (strncmp(sym->name, "$a", 2) == 0 || strncmp(sym->name, "$d", 2) == 0)) {
-                               // binutils for arm generate these elfmapping
-                               // symbols, ignore these
-                               break;
-                       }
-                       if(strcmp(sym->name, ".TOC.") == 0) {
-                               // We need to be able to look this up,
-                               // so put it in the hash table.
-                               if(needSym) {
-                                       s = linklookup(ctxt, sym->name, ctxt->version);
-                                       s->type |= SHIDDEN;
-                               }
-                               break;
-                       }
-                       if(needSym) {
-                               // local names and hidden visiblity global names are unique
-                               // and should only reference by its index, not name, so we
-                               // don't bother to add them into hash table
-                               s = linknewsym(ctxt, sym->name, ctxt->version);
-                               s->type |= SHIDDEN;
-                       }
-                       break;
-               case ElfSymBindWeak:
-                       if(needSym) {
-                               s = linknewsym(ctxt, sym->name, 0);
-                               if(sym->other == 2)
-                                       s->type |= SHIDDEN;
-                       }
-                       break;
-               default:
-                       werrstr("%s: invalid symbol binding %d", sym->name, sym->bind);
-                       return -1;
-               }
-               break;
-       }
-       if(s != nil && s->type == 0 && sym->type != ElfSymTypeSection)
-               s->type = SXREF;
-       sym->sym = s;
-
-       return 0;
-}
-
-int
-rbyoff(const void *va, const void *vb)
-{
-       Reloc *a, *b;
-       
-       a = (Reloc*)va;
-       b = (Reloc*)vb;
-       if(a->off < b->off)
-               return -1;
-       if(a->off > b->off)
-               return +1;
-       return 0;
-}
-
-#define R(x, y) ((x)|((y)<<24))
-/*c2go uint32 R(uint32, uint32); */
-
-static int
-reltype(char *pn, int elftype, uchar *siz)
-{
-       switch(R(thearch.thechar, elftype)) {
-       default:
-               diag("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype);
-       case R('9', R_PPC64_TOC16):
-       case R('9', R_PPC64_TOC16_LO):
-       case R('9', R_PPC64_TOC16_HI):
-       case R('9', R_PPC64_TOC16_HA):
-       case R('9', R_PPC64_TOC16_DS):
-       case R('9', R_PPC64_TOC16_LO_DS):
-       case R('9', R_PPC64_REL16_LO):
-       case R('9', R_PPC64_REL16_HI):
-       case R('9', R_PPC64_REL16_HA):
-               *siz = 2;
-               break;
-       case R('5', R_ARM_ABS32):
-       case R('5', R_ARM_GOT32):
-       case R('5', R_ARM_PLT32):
-       case R('5', R_ARM_GOTOFF):
-       case R('5', R_ARM_GOTPC):
-       case R('5', R_ARM_THM_PC22):
-       case R('5', R_ARM_REL32):
-       case R('5', R_ARM_CALL):
-       case R('5', R_ARM_V4BX):
-       case R('5', R_ARM_GOT_PREL):
-       case R('5', R_ARM_PC24):
-       case R('5', R_ARM_JUMP24):
-       case R('6', R_X86_64_PC32):
-       case R('6', R_X86_64_PLT32):
-       case R('6', R_X86_64_GOTPCREL):
-       case R('8', R_386_32):
-       case R('8', R_386_PC32):
-       case R('8', R_386_GOT32):
-       case R('8', R_386_PLT32):
-       case R('8', R_386_GOTOFF):
-       case R('8', R_386_GOTPC):
-       case R('9', R_PPC64_REL24):
-               *siz = 4;
-               break;
-       case R('6', R_X86_64_64):
-       case R('9', R_PPC64_ADDR64):
-               *siz = 8;
-               break;
-       }
-
-       return 256+elftype;
-}
diff --git a/src/cmd/ld/ldmacho.c b/src/cmd/ld/ldmacho.c
deleted file mode 100644 (file)
index 300f18a..0000000
+++ /dev/null
@@ -1,853 +0,0 @@
-/*
-Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c
-http://code.swtch.com/plan9port/src/tip/src/libmach/
-
-       Copyright © 2004 Russ Cox.
-       Portions Copyright © 2008-2010 Google Inc.
-       Portions Copyright © 2010 The Go Authors.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#include       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-#include       "lib.h"
-#include       "macho.h"
-
-enum { 
-       N_EXT = 0x01,
-       N_TYPE = 0x1e,
-       N_STAB = 0xe0,
-};
-
-typedef struct LdMachoObj LdMachoObj;
-typedef struct LdMachoCmd LdMachoCmd;
-typedef struct LdMachoSeg LdMachoSeg;
-typedef struct LdMachoSect LdMachoSect;
-typedef struct LdMachoRel LdMachoRel;
-typedef struct LdMachoSymtab LdMachoSymtab;
-typedef struct LdMachoSym LdMachoSym;
-typedef struct LdMachoDysymtab LdMachoDysymtab;
-
-enum
-{
-       LdMachoCpuVax = 1,
-       LdMachoCpu68000 = 6,
-       LdMachoCpu386 = 7,
-       LdMachoCpuAmd64 = 0x1000007,
-       LdMachoCpuMips = 8,
-       LdMachoCpu98000 = 10,
-       LdMachoCpuHppa = 11,
-       LdMachoCpuArm = 12,
-       LdMachoCpu88000 = 13,
-       LdMachoCpuSparc = 14,
-       LdMachoCpu860 = 15,
-       LdMachoCpuAlpha = 16,
-       LdMachoCpuPower = 18,
-
-       LdMachoCmdSegment = 1,
-       LdMachoCmdSymtab = 2,
-       LdMachoCmdSymseg = 3,
-       LdMachoCmdThread = 4,
-       LdMachoCmdDysymtab = 11,
-       LdMachoCmdSegment64 = 25,
-
-       LdMachoFileObject = 1,
-       LdMachoFileExecutable = 2,
-       LdMachoFileFvmlib = 3,
-       LdMachoFileCore = 4,
-       LdMachoFilePreload = 5,
-};
-
-struct LdMachoSeg
-{
-       char name[16+1];
-       uint64 vmaddr;
-       uint64 vmsize;
-       uint32 fileoff;
-       uint32 filesz;
-       uint32 maxprot;
-       uint32 initprot;
-       uint32 nsect;
-       uint32 flags;
-       LdMachoSect *sect;
-};
-
-struct LdMachoSect
-{
-       char    name[16+1];
-       char    segname[16+1];
-       uint64 addr;
-       uint64 size;
-       uint32 off;
-       uint32 align;
-       uint32 reloff;
-       uint32 nreloc;
-       uint32 flags;
-       uint32 res1;
-       uint32 res2;
-       LSym *sym;
-       
-       LdMachoRel *rel;
-};
-
-struct LdMachoRel
-{
-       uint32 addr;
-       uint32 symnum;
-       uint8 pcrel;
-       uint8 length;
-       uint8 extrn;
-       uint8 type;
-       uint8 scattered;
-       uint32 value;
-};
-
-struct LdMachoSymtab
-{
-       uint32 symoff;
-       uint32 nsym;
-       uint32 stroff;
-       uint32 strsize;
-       
-       char *str;
-       LdMachoSym *sym;
-};
-
-struct LdMachoSym
-{
-       char *name;
-       uint8 type;
-       uint8 sectnum;
-       uint16 desc;
-       char kind;
-       uint64 value;
-       LSym *sym;
-};
-
-struct LdMachoDysymtab
-{
-       uint32 ilocalsym;
-       uint32 nlocalsym;
-       uint32 iextdefsym;
-       uint32 nextdefsym;
-       uint32 iundefsym;
-       uint32 nundefsym;
-       uint32 tocoff;
-       uint32 ntoc;
-       uint32 modtaboff;
-       uint32 nmodtab;
-       uint32 extrefsymoff;
-       uint32 nextrefsyms;
-       uint32 indirectsymoff;
-       uint32 nindirectsyms;
-       uint32 extreloff;
-       uint32 nextrel;
-       uint32 locreloff;
-       uint32 nlocrel;
-       uint32 *indir;
-};
-
-struct LdMachoCmd
-{
-       int type;
-       uint32 off;
-       uint32 size;
-       LdMachoSeg seg;
-       LdMachoSymtab sym;
-       LdMachoDysymtab dsym;
-};
-
-struct LdMachoObj
-{
-       Biobuf  *f;
-       int64   base;   // off in f where Mach-O begins
-       int64   length;         // length of Mach-O
-       int is64;
-       char    *name;
-
-       Endian  *e;
-       uint cputype;
-       uint subcputype;
-       uint32 filetype;
-       uint32 flags;
-       LdMachoCmd *cmd;
-       uint ncmd;
-};
-
-static int
-unpackcmd(uchar *p, LdMachoObj *m, LdMachoCmd *c, uint type, uint sz)
-{
-       uint32 (*e4)(uchar*);
-       uint64 (*e8)(uchar*);
-       LdMachoSect *s;
-       int i;
-
-       e4 = m->e->e32;
-       e8 = m->e->e64;
-
-       c->type = type;
-       c->size = sz;
-       switch(type){
-       default:
-               return -1;
-       case LdMachoCmdSegment:
-               if(sz < 56)
-                       return -1;
-               strecpy(c->seg.name, c->seg.name+sizeof c->seg.name, (char*)p+8);
-               c->seg.vmaddr = e4(p+24);
-               c->seg.vmsize = e4(p+28);
-               c->seg.fileoff = e4(p+32);
-               c->seg.filesz = e4(p+36);
-               c->seg.maxprot = e4(p+40);
-               c->seg.initprot = e4(p+44);
-               c->seg.nsect = e4(p+48);
-               c->seg.flags = e4(p+52);
-               c->seg.sect = mal(c->seg.nsect * sizeof c->seg.sect[0]);
-               if(sz < 56+c->seg.nsect*68)
-                       return -1;
-               p += 56;
-               for(i=0; i<c->seg.nsect; i++) {
-                       s = &c->seg.sect[i];
-                       strecpy(s->name, s->name+sizeof s->name, (char*)p+0);
-                       strecpy(s->segname, s->segname+sizeof s->segname, (char*)p+16);
-                       s->addr = e4(p+32);
-                       s->size = e4(p+36);
-                       s->off = e4(p+40);
-                       s->align = e4(p+44);
-                       s->reloff = e4(p+48);
-                       s->nreloc = e4(p+52);
-                       s->flags = e4(p+56);
-                       s->res1 = e4(p+60);
-                       s->res2 = e4(p+64);
-                       p += 68;
-               }
-               break;
-       case LdMachoCmdSegment64:
-               if(sz < 72)
-                       return -1;
-               strecpy(c->seg.name, c->seg.name+sizeof c->seg.name, (char*)p+8);
-               c->seg.vmaddr = e8(p+24);
-               c->seg.vmsize = e8(p+32);
-               c->seg.fileoff = e8(p+40);
-               c->seg.filesz = e8(p+48);
-               c->seg.maxprot = e4(p+56);
-               c->seg.initprot = e4(p+60);
-               c->seg.nsect = e4(p+64);
-               c->seg.flags = e4(p+68);
-               c->seg.sect = mal(c->seg.nsect * sizeof c->seg.sect[0]);
-               if(sz < 72+c->seg.nsect*80)
-                       return -1;
-               p += 72;
-               for(i=0; i<c->seg.nsect; i++) {
-                       s = &c->seg.sect[i];
-                       strecpy(s->name, s->name+sizeof s->name, (char*)p+0);
-                       strecpy(s->segname, s->segname+sizeof s->segname, (char*)p+16);
-                       s->addr = e8(p+32);
-                       s->size = e8(p+40);
-                       s->off = e4(p+48);
-                       s->align = e4(p+52);
-                       s->reloff = e4(p+56);
-                       s->nreloc = e4(p+60);
-                       s->flags = e4(p+64);
-                       s->res1 = e4(p+68);
-                       s->res2 = e4(p+72);
-                       // p+76 is reserved
-                       p += 80;
-               }
-               break;
-       case LdMachoCmdSymtab:
-               if(sz < 24)
-                       return -1;
-               c->sym.symoff = e4(p+8);
-               c->sym.nsym = e4(p+12);
-               c->sym.stroff = e4(p+16);
-               c->sym.strsize = e4(p+20);
-               break;
-       case LdMachoCmdDysymtab:
-               if(sz < 80)
-                       return -1;
-               c->dsym.ilocalsym = e4(p+8);
-               c->dsym.nlocalsym = e4(p+12);
-               c->dsym.iextdefsym = e4(p+16);
-               c->dsym.nextdefsym = e4(p+20);
-               c->dsym.iundefsym = e4(p+24);
-               c->dsym.nundefsym = e4(p+28);
-               c->dsym.tocoff = e4(p+32);
-               c->dsym.ntoc = e4(p+36);
-               c->dsym.modtaboff = e4(p+40);
-               c->dsym.nmodtab = e4(p+44);
-               c->dsym.extrefsymoff = e4(p+48);
-               c->dsym.nextrefsyms = e4(p+52);
-               c->dsym.indirectsymoff = e4(p+56);
-               c->dsym.nindirectsyms = e4(p+60);
-               c->dsym.extreloff = e4(p+64);
-               c->dsym.nextrel = e4(p+68);
-               c->dsym.locreloff = e4(p+72);
-               c->dsym.nlocrel = e4(p+76);
-               break;
-       }
-       return 0;
-}
-
-static int
-macholoadrel(LdMachoObj *m, LdMachoSect *sect)
-{
-       LdMachoRel *rel, *r;
-       uchar *buf, *p;
-       int i, n;
-       uint32 v;
-       
-       if(sect->rel != nil || sect->nreloc == 0)
-               return 0;
-       rel = mal(sect->nreloc * sizeof r[0]);
-       n = sect->nreloc * 8;
-       buf = mal(n);
-       if(Bseek(m->f, m->base + sect->reloff, 0) < 0 || Bread(m->f, buf, n) != n)
-               return -1;
-       for(i=0; i<sect->nreloc; i++) {
-               r = &rel[i];
-               p = buf+i*8;
-               r->addr = m->e->e32(p);
-               
-               // TODO(rsc): Wrong interpretation for big-endian bitfields?
-               if(r->addr & 0x80000000) {
-                       // scatterbrained relocation
-                       r->scattered = 1;
-                       v = r->addr >> 24;
-                       r->addr &= 0xFFFFFF;
-                       r->type = v & 0xF;
-                       v >>= 4;
-                       r->length = 1<<(v&3);
-                       v >>= 2;
-                       r->pcrel = v & 1;
-                       r->value = m->e->e32(p+4);
-               } else {
-                       v = m->e->e32(p+4);
-                       r->symnum = v & 0xFFFFFF;
-                       v >>= 24;
-                       r->pcrel = v&1;
-                       v >>= 1;
-                       r->length = 1<<(v&3);
-                       v >>= 2;
-                       r->extrn = v&1;
-                       v >>= 1;
-                       r->type = v;
-               }
-       }
-       sect->rel = rel;
-       return 0;
-}
-
-static int
-macholoaddsym(LdMachoObj *m, LdMachoDysymtab *d)
-{
-       uchar *p;
-       int i, n;
-       
-       n = d->nindirectsyms;
-       
-       p = mal(n*4);
-       if(Bseek(m->f, m->base + d->indirectsymoff, 0) < 0 || Bread(m->f, p, n*4) != n*4)
-               return -1;
-       
-       d->indir = (uint32*)p;
-       for(i=0; i<n; i++)
-               d->indir[i] = m->e->e32(p+4*i);
-       return 0;
-}
-
-static int 
-macholoadsym(LdMachoObj *m, LdMachoSymtab *symtab)
-{
-       char *strbuf;
-       uchar *symbuf, *p;
-       int i, n, symsize;
-       LdMachoSym *sym, *s;
-       uint32 v;
-
-       if(symtab->sym != nil)
-               return 0;
-
-       strbuf = mal(symtab->strsize);
-       if(Bseek(m->f, m->base + symtab->stroff, 0) < 0 || Bread(m->f, strbuf, symtab->strsize) != symtab->strsize)
-               return -1;
-       
-       symsize = 12;
-       if(m->is64)
-               symsize = 16;
-       n = symtab->nsym * symsize;
-       symbuf = mal(n);
-       if(Bseek(m->f, m->base + symtab->symoff, 0) < 0 || Bread(m->f, symbuf, n) != n)
-               return -1;
-       sym = mal(symtab->nsym * sizeof sym[0]);
-       p = symbuf;
-       for(i=0; i<symtab->nsym; i++) {
-               s = &sym[i];
-               v = m->e->e32(p);
-               if(v >= symtab->strsize)
-                       return -1;
-               s->name = strbuf + v;
-               s->type = p[4];
-               s->sectnum = p[5];
-               s->desc = m->e->e16(p+6);
-               if(m->is64)
-                       s->value = m->e->e64(p+8);
-               else
-                       s->value = m->e->e32(p+8);
-               p += symsize;
-       }
-       symtab->str = strbuf;
-       symtab->sym = sym;
-       return 0;
-}
-
-void
-ldmacho(Biobuf *f, char *pkg, int64 length, char *pn)
-{
-       int i, j, is64;
-       uint64 secaddr;
-       uchar hdr[7*4], *cmdp;
-       uchar tmp[4];
-       uchar *dat;
-       ulong ncmd, cmdsz, ty, sz, off;
-       LdMachoObj *m;
-       Endian *e;
-       int64 base;
-       LdMachoSect *sect;
-       LdMachoRel *rel;
-       int rpi;
-       LSym *s, *s1, *outer;
-       LdMachoCmd *c;
-       LdMachoSymtab *symtab;
-       LdMachoDysymtab *dsymtab;
-       LdMachoSym *sym;
-       Reloc *r, *rp;
-       char *name;
-
-       ctxt->version++;
-       base = Boffset(f);
-       if(Bread(f, hdr, sizeof hdr) != sizeof hdr)
-               goto bad;
-
-       if((be.e32(hdr)&~1) == 0xFEEDFACE){
-               e = &be;
-       }else if((le.e32(hdr)&~1) == 0xFEEDFACE){
-               e = &le;
-       }else{
-               werrstr("bad magic - not mach-o file");
-               goto bad;
-       }
-
-       is64 = e->e32(hdr) == 0xFEEDFACF;
-       ncmd = e->e32(hdr+4*4);
-       cmdsz = e->e32(hdr+5*4);
-       if(ncmd > 0x10000 || cmdsz >= 0x01000000){
-               werrstr("implausible mach-o header ncmd=%lud cmdsz=%lud", ncmd, cmdsz);
-               goto bad;
-       }
-       if(is64)
-               Bread(f, tmp, 4);       // skip reserved word in header
-
-       m = mal(sizeof(*m)+ncmd*sizeof(LdMachoCmd)+cmdsz);
-       m->f = f;
-       m->e = e;
-       m->cputype = e->e32(hdr+1*4);
-       m->subcputype = e->e32(hdr+2*4);
-       m->filetype = e->e32(hdr+3*4);
-       m->ncmd = ncmd;
-       m->flags = e->e32(hdr+6*4);
-       m->is64 = is64;
-       m->base = base;
-       m->length = length;
-       m->name = pn;
-       
-       switch(thearch.thechar) {
-       default:
-               diag("%s: mach-o %s unimplemented", pn, thestring);
-               return;
-       case '6':
-               if(e != &le || m->cputype != LdMachoCpuAmd64) {
-                       diag("%s: mach-o object but not amd64", pn);
-                       return;
-               }
-               break;
-       case '8':
-               if(e != &le || m->cputype != LdMachoCpu386) {
-                       diag("%s: mach-o object but not 386", pn);
-                       return;
-               }
-               break;
-       }
-
-       m->cmd = (LdMachoCmd*)(m+1);
-       off = sizeof hdr;
-       cmdp = (uchar*)(m->cmd+ncmd);
-       if(Bread(f, cmdp, cmdsz) != cmdsz){
-               werrstr("reading cmds: %r");
-               goto bad;
-       }
-
-       // read and parse load commands
-       c = nil;
-       symtab = nil;
-       dsymtab = nil;
-       USED(dsymtab);
-       for(i=0; i<ncmd; i++){
-               ty = e->e32(cmdp);
-               sz = e->e32(cmdp+4);
-               m->cmd[i].off = off;
-               unpackcmd(cmdp, m, &m->cmd[i], ty, sz);
-               cmdp += sz;
-               off += sz;
-               if(ty == LdMachoCmdSymtab) {
-                       if(symtab != nil) {
-                               werrstr("multiple symbol tables");
-                               goto bad;
-                       }
-                       symtab = &m->cmd[i].sym;
-                       macholoadsym(m, symtab);
-               }
-               if(ty == LdMachoCmdDysymtab) {
-                       dsymtab = &m->cmd[i].dsym;
-                       macholoaddsym(m, dsymtab);
-               }
-               if((is64 && ty == LdMachoCmdSegment64) || (!is64 && ty == LdMachoCmdSegment)) {
-                       if(c != nil) {
-                               werrstr("multiple load commands");
-                               goto bad;
-                       }
-                       c = &m->cmd[i];
-               }
-       }
-
-       // load text and data segments into memory.
-       // they are not as small as the load commands, but we'll need
-       // the memory anyway for the symbol images, so we might
-       // as well use one large chunk.
-       if(c == nil) {
-               werrstr("no load command");
-               goto bad;
-       }
-       if(symtab == nil) {
-               // our work is done here - no symbols means nothing can refer to this file
-               return;
-       }
-
-       if(c->seg.fileoff+c->seg.filesz >= length) {
-               werrstr("load segment out of range");
-               goto bad;
-       }
-
-       dat = mal(c->seg.filesz);
-       if(Bseek(f, m->base + c->seg.fileoff, 0) < 0 || Bread(f, dat, c->seg.filesz) != c->seg.filesz) {
-               werrstr("cannot load object data: %r");
-               goto bad;
-       }
-       
-       for(i=0; i<c->seg.nsect; i++) {
-               sect = &c->seg.sect[i];
-               if(strcmp(sect->segname, "__TEXT") != 0 && strcmp(sect->segname, "__DATA") != 0)
-                       continue;
-               if(strcmp(sect->name, "__eh_frame") == 0)
-                       continue;
-               name = smprint("%s(%s/%s)", pkg, sect->segname, sect->name);
-               s = linklookup(ctxt, name, ctxt->version);
-               if(s->type != 0) {
-                       werrstr("duplicate %s/%s", sect->segname, sect->name);
-                       goto bad;
-               }
-               free(name);
-
-               s->np = sect->size;
-               s->size = s->np;
-               if((sect->flags & 0xff) == 1) // S_ZEROFILL
-                       s->p = mal(s->size);
-               else {
-                       s->p = dat + sect->addr - c->seg.vmaddr;
-               }
-               
-               if(strcmp(sect->segname, "__TEXT") == 0) {
-                       if(strcmp(sect->name, "__text") == 0)
-                               s->type = STEXT;
-                       else
-                               s->type = SRODATA;
-               } else {
-                       if (strcmp(sect->name, "__bss") == 0) {
-                               s->type = SNOPTRBSS;
-                               s->np = 0;
-                       } else
-                               s->type = SNOPTRDATA;
-               }
-               sect->sym = s;
-       }
-       
-       // enter sub-symbols into symbol table.
-       // have to guess sizes from next symbol.
-       for(i=0; i<symtab->nsym; i++) {
-               int v;
-               sym = &symtab->sym[i];
-               if(sym->type&N_STAB)
-                       continue;
-               // TODO: check sym->type against outer->type.
-               name = sym->name;
-               if(name[0] == '_' && name[1] != '\x00')
-                       name++;
-               v = 0;
-               if(!(sym->type&N_EXT))
-                       v = ctxt->version;
-               s = linklookup(ctxt, name, v);
-               if(!(sym->type&N_EXT))
-                       s->dupok = 1;
-               sym->sym = s;
-               if(sym->sectnum == 0)   // undefined
-                       continue;
-               if(sym->sectnum > c->seg.nsect) {
-                       werrstr("reference to invalid section %d", sym->sectnum);
-                       goto bad;
-               }
-               sect = &c->seg.sect[sym->sectnum-1];
-               outer = sect->sym;
-               if(outer == nil) {
-                       werrstr("reference to invalid section %s/%s", sect->segname, sect->name);
-                       continue;
-               }
-               if(s->outer != nil) {
-                       if(s->dupok)
-                               continue;
-                       diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s->name, s->outer->name, sect->sym->name);
-                       errorexit();
-               }
-               s->type = outer->type | SSUB;
-               s->sub = outer->sub;
-               outer->sub = s;
-               s->outer = outer;
-               s->value = sym->value - sect->addr;
-               if(!(s->cgoexport & CgoExportDynamic))
-                       s->dynimplib = nil;     // satisfy dynimport
-               if(outer->type == STEXT) {
-                       if(s->external && !s->dupok)
-                               diag("%s: duplicate definition of %s", pn, s->name);
-                       s->external = 1;
-               }
-               sym->sym = s;
-       }
-
-       // Sort outer lists by address, adding to textp.
-       // This keeps textp in increasing address order.
-       for(i=0; i<c->seg.nsect; i++) {
-               sect = &c->seg.sect[i];
-               if((s = sect->sym) == nil)
-                       continue;
-               if(s->sub) {
-                       s->sub = listsort(s->sub, valuecmp, listsubp);
-                       
-                       // assign sizes, now that we know symbols in sorted order.
-                       for(s1 = s->sub; s1 != nil; s1 = s1->sub) {
-                               if(s1->sub)
-                                       s1->size = s1->sub->value - s1->value;
-                               else
-                                       s1->size = s->value + s->size - s1->value;
-                       }
-               }
-               if(s->type == STEXT) {
-                       if(s->onlist)
-                               sysfatal("symbol %s listed multiple times", s->name);
-                       s->onlist = 1;
-                       if(ctxt->etextp)
-                               ctxt->etextp->next = s;
-                       else
-                               ctxt->textp = s;
-                       ctxt->etextp = s;
-                       for(s1 = s->sub; s1 != nil; s1 = s1->sub) {
-                               if(s1->onlist)
-                                       sysfatal("symbol %s listed multiple times", s1->name);
-                               s1->onlist = 1;
-                               ctxt->etextp->next = s1;
-                               ctxt->etextp = s1;
-                       }
-               }
-       }
-
-       // load relocations
-       for(i=0; i<c->seg.nsect; i++) {
-               sect = &c->seg.sect[i];
-               if((s = sect->sym) == nil)
-                       continue;
-               macholoadrel(m, sect);
-               if(sect->rel == nil)
-                       continue;
-               r = mal(sect->nreloc*sizeof r[0]);
-               rpi = 0;
-               for(j=0; j<sect->nreloc; j++) {
-                       rp = &r[rpi];
-                       rel = &sect->rel[j];
-                       if(rel->scattered) {
-                               int k;
-                               LdMachoSect *ks;
-
-                               if(thearch.thechar != '8') {
-                                       // mach-o only uses scattered relocation on 32-bit platforms
-                                       diag("unexpected scattered relocation");
-                                       continue;
-                               }
-
-                               // on 386, rewrite scattered 4/1 relocation and some
-                               // scattered 2/1 relocation into the pseudo-pc-relative
-                               // reference that it is.
-                               // assume that the second in the pair is in this section
-                               // and use that as the pc-relative base.
-                               if(j+1 >= sect->nreloc) {
-                                       werrstr("unsupported scattered relocation %d", (int)rel->type);
-                                       goto bad;
-                               }
-                               if(!sect->rel[j+1].scattered || sect->rel[j+1].type != 1 ||
-                                  (rel->type != 4 && rel->type != 2) ||
-                                  sect->rel[j+1].value < sect->addr || sect->rel[j+1].value >= sect->addr+sect->size) {
-                                       werrstr("unsupported scattered relocation %d/%d", (int)rel->type, (int)sect->rel[j+1].type);
-                                       goto bad;
-                               }
-
-                               rp->siz = rel->length;
-                               rp->off = rel->addr;
-                               
-                               // NOTE(rsc): I haven't worked out why (really when)
-                               // we should ignore the addend on a
-                               // scattered relocation, but it seems that the
-                               // common case is we ignore it.
-                               // It's likely that this is not strictly correct
-                               // and that the math should look something
-                               // like the non-scattered case below.
-                               rp->add = 0;
-                               
-                               // want to make it pc-relative aka relative to rp->off+4
-                               // but the scatter asks for relative to off = sect->rel[j+1].value - sect->addr.
-                               // adjust rp->add accordingly.
-                               rp->type = R_PCREL;
-                               rp->add += (rp->off+4) - (sect->rel[j+1].value - sect->addr);
-                               
-                               // now consider the desired symbol.
-                               // find the section where it lives.
-                               for(k=0; k<c->seg.nsect; k++) {
-                                       ks = &c->seg.sect[k];
-                                       if(ks->addr <= rel->value && rel->value < ks->addr+ks->size)
-                                               goto foundk;
-                               }
-                               werrstr("unsupported scattered relocation: invalid address %#ux", rel->addr);
-                               goto bad;
-                       foundk:
-                               if(ks->sym != nil) {
-                                       rp->sym = ks->sym;
-                                       rp->add += rel->value - ks->addr;
-                               } else if(strcmp(ks->segname, "__IMPORT") == 0 && strcmp(ks->name, "__pointers") == 0) {
-                                       // handle reference to __IMPORT/__pointers.
-                                       // how much worse can this get?
-                                       // why are we supporting 386 on the mac anyway?
-                                       rp->type = 512 + MACHO_FAKE_GOTPCREL;
-                                       // figure out which pointer this is a reference to.
-                                       k = ks->res1 + (rel->value - ks->addr) / 4;
-                                       // load indirect table for __pointers
-                                       // fetch symbol number
-                                       if(dsymtab == nil || k < 0 || k >= dsymtab->nindirectsyms || dsymtab->indir == nil) {
-                                               werrstr("invalid scattered relocation: indirect symbol reference out of range");
-                                               goto bad;
-                                       }
-                                       k = dsymtab->indir[k];
-                                       if(k < 0 || k >= symtab->nsym) {
-                                               werrstr("invalid scattered relocation: symbol reference out of range");
-                                               goto bad;
-                                       }
-                                       rp->sym = symtab->sym[k].sym;
-                               } else {
-                                       werrstr("unsupported scattered relocation: reference to %s/%s", ks->segname, ks->name);
-                                       goto bad;
-                               }
-                               rpi++;
-                               // skip #1 of 2 rel; continue skips #2 of 2.
-                               j++;
-                               continue;
-                       }
-
-                       rp->siz = rel->length;
-                       rp->type = 512 + (rel->type<<1) + rel->pcrel;
-                       rp->off = rel->addr;
-
-                       // Handle X86_64_RELOC_SIGNED referencing a section (rel->extrn == 0).
-                       if (thearch.thechar == '6' && rel->extrn == 0 && rel->type == 1) {
-                               // Calculate the addend as the offset into the section.
-                               //
-                               // The rip-relative offset stored in the object file is encoded
-                               // as follows:
-                               //    
-                               //    movsd     0x00000360(%rip),%xmm0
-                               //
-                               // To get the absolute address of the value this rip-relative address is pointing
-                               // to, we must add the address of the next instruction to it. This is done by
-                               // taking the address of the relocation and adding 4 to it (since the rip-relative
-                               // offset can at most be 32 bits long).  To calculate the offset into the section the
-                               // relocation is referencing, we subtract the vaddr of the start of the referenced
-                               // section found in the original object file.
-                               //
-                               // [For future reference, see Darwin's /usr/include/mach-o/x86_64/reloc.h]
-                               secaddr = c->seg.sect[rel->symnum-1].addr;
-                               rp->add = (int32)e->e32(s->p+rp->off) + rp->off + 4 - secaddr;
-                       } else
-                               rp->add = (int32)e->e32(s->p+rp->off);
-
-                       // For i386 Mach-O PC-relative, the addend is written such that
-                       // it *is* the PC being subtracted.  Use that to make
-                       // it match our version of PC-relative.
-                       if(rel->pcrel && thearch.thechar == '8')
-                               rp->add += rp->off+rp->siz;
-                       if(!rel->extrn) {
-                               if(rel->symnum < 1 || rel->symnum > c->seg.nsect) {
-                                       werrstr("invalid relocation: section reference out of range %d vs %d", rel->symnum, c->seg.nsect);
-                                       goto bad;
-                               }
-                               rp->sym = c->seg.sect[rel->symnum-1].sym;
-                               if(rp->sym == nil) {
-                                       werrstr("invalid relocation: %s", c->seg.sect[rel->symnum-1].name);
-                                       goto bad;
-                               }
-                               // References to symbols in other sections
-                               // include that information in the addend.
-                               // We only care about the delta from the 
-                               // section base.
-                               if(thearch.thechar == '8')
-                                       rp->add -= c->seg.sect[rel->symnum-1].addr;
-                       } else {
-                               if(rel->symnum >= symtab->nsym) {
-                                       werrstr("invalid relocation: symbol reference out of range");
-                                       goto bad;
-                               }
-                               rp->sym = symtab->sym[rel->symnum].sym;
-                       }
-                       rpi++;
-               }                       
-               qsort(r, rpi, sizeof r[0], rbyoff);
-               s->r = r;
-               s->nr = rpi;
-       }
-       return;
-
-bad:
-       diag("%s: malformed mach-o file: %r", pn);
-}
diff --git a/src/cmd/ld/ldpe.c b/src/cmd/ld/ldpe.c
deleted file mode 100644 (file)
index e67ad56..0000000
+++ /dev/null
@@ -1,504 +0,0 @@
-// Copyright 2010 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       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-#include       "lib.h"
-#include       "pe.h"
-
-enum {
-       IMAGE_SYM_UNDEFINED = 0,
-       IMAGE_SYM_ABSOLUTE = (-1),
-       IMAGE_SYM_DEBUG = (-2),
-       IMAGE_SYM_TYPE_NULL = 0,
-       IMAGE_SYM_TYPE_VOID = 1,
-       IMAGE_SYM_TYPE_CHAR = 2,
-       IMAGE_SYM_TYPE_SHORT = 3,
-       IMAGE_SYM_TYPE_INT = 4,
-       IMAGE_SYM_TYPE_LONG = 5,
-       IMAGE_SYM_TYPE_FLOAT = 6,
-       IMAGE_SYM_TYPE_DOUBLE = 7,
-       IMAGE_SYM_TYPE_STRUCT = 8,
-       IMAGE_SYM_TYPE_UNION = 9,
-       IMAGE_SYM_TYPE_ENUM = 10,
-       IMAGE_SYM_TYPE_MOE = 11,
-       IMAGE_SYM_TYPE_BYTE = 12,
-       IMAGE_SYM_TYPE_WORD = 13,
-       IMAGE_SYM_TYPE_UINT = 14,
-       IMAGE_SYM_TYPE_DWORD = 15,
-       IMAGE_SYM_TYPE_PCODE = 32768,
-       IMAGE_SYM_DTYPE_NULL = 0,
-       IMAGE_SYM_DTYPE_POINTER = 0x10,
-       IMAGE_SYM_DTYPE_FUNCTION = 0x20,
-       IMAGE_SYM_DTYPE_ARRAY = 0x30,
-       IMAGE_SYM_CLASS_END_OF_FUNCTION = (-1),
-       IMAGE_SYM_CLASS_NULL = 0,
-       IMAGE_SYM_CLASS_AUTOMATIC = 1,
-       IMAGE_SYM_CLASS_EXTERNAL = 2,
-       IMAGE_SYM_CLASS_STATIC = 3,
-       IMAGE_SYM_CLASS_REGISTER = 4,
-       IMAGE_SYM_CLASS_EXTERNAL_DEF = 5,
-       IMAGE_SYM_CLASS_LABEL = 6,
-       IMAGE_SYM_CLASS_UNDEFINED_LABEL = 7,
-       IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8,
-       IMAGE_SYM_CLASS_ARGUMENT = 9,
-       IMAGE_SYM_CLASS_STRUCT_TAG = 10,
-       IMAGE_SYM_CLASS_MEMBER_OF_UNION = 11,
-       IMAGE_SYM_CLASS_UNION_TAG = 12,
-       IMAGE_SYM_CLASS_TYPE_DEFINITION = 13,
-       IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14,
-       IMAGE_SYM_CLASS_ENUM_TAG = 15,
-       IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16,
-       IMAGE_SYM_CLASS_REGISTER_PARAM = 17,
-       IMAGE_SYM_CLASS_BIT_FIELD = 18,
-       IMAGE_SYM_CLASS_FAR_EXTERNAL = 68, /* Not in PECOFF v8 spec */
-       IMAGE_SYM_CLASS_BLOCK = 100,
-       IMAGE_SYM_CLASS_FUNCTION = 101,
-       IMAGE_SYM_CLASS_END_OF_STRUCT = 102,
-       IMAGE_SYM_CLASS_FILE = 103,
-       IMAGE_SYM_CLASS_SECTION = 104,
-       IMAGE_SYM_CLASS_WEAK_EXTERNAL = 105,
-       IMAGE_SYM_CLASS_CLR_TOKEN = 107,
-
-       IMAGE_REL_I386_ABSOLUTE = 0x0000,
-       IMAGE_REL_I386_DIR16 = 0x0001,
-       IMAGE_REL_I386_REL16 = 0x0002,
-       IMAGE_REL_I386_DIR32 = 0x0006,
-       IMAGE_REL_I386_DIR32NB = 0x0007,
-       IMAGE_REL_I386_SEG12 = 0x0009,
-       IMAGE_REL_I386_SECTION = 0x000A,
-       IMAGE_REL_I386_SECREL = 0x000B,
-       IMAGE_REL_I386_TOKEN = 0x000C,
-       IMAGE_REL_I386_SECREL7 = 0x000D,
-       IMAGE_REL_I386_REL32 = 0x0014,
-
-       IMAGE_REL_AMD64_ABSOLUTE = 0x0000,
-       IMAGE_REL_AMD64_ADDR64 = 0x0001, // R_X86_64_64
-       IMAGE_REL_AMD64_ADDR32 = 0x0002, // R_X86_64_PC32
-       IMAGE_REL_AMD64_ADDR32NB = 0x0003,
-       IMAGE_REL_AMD64_REL32 = 0x0004, 
-       IMAGE_REL_AMD64_REL32_1 = 0x0005,
-       IMAGE_REL_AMD64_REL32_2 = 0x0006,
-       IMAGE_REL_AMD64_REL32_3 = 0x0007,
-       IMAGE_REL_AMD64_REL32_4 = 0x0008,
-       IMAGE_REL_AMD64_REL32_5 = 0x0009,
-       IMAGE_REL_AMD64_SECTION = 0x000A,
-       IMAGE_REL_AMD64_SECREL = 0x000B,
-       IMAGE_REL_AMD64_SECREL7 = 0x000C,
-       IMAGE_REL_AMD64_TOKEN = 0x000D,
-       IMAGE_REL_AMD64_SREL32 = 0x000E,
-       IMAGE_REL_AMD64_PAIR = 0x000F,
-       IMAGE_REL_AMD64_SSPAN32 = 0x0010,
-};
-
-typedef struct PeSym PeSym;
-typedef struct PeSect PeSect;
-typedef struct PeObj PeObj;
-
-struct PeSym {
-       char* name;
-       uint32 value;
-       uint16 sectnum;
-       uint16 type;
-       uint8 sclass;
-       uint8 aux;
-       LSym* sym;
-};
-
-struct PeSect {
-       char* name;
-       uchar* base;
-       uint64 size;
-       LSym* sym;
-       IMAGE_SECTION_HEADER sh;
-};
-
-struct PeObj {
-       Biobuf  *f;
-       char    *name;
-       uint32 base;
-       
-       PeSect  *sect;
-       uint    nsect;
-       PeSym   *pesym;
-       uint npesym;
-       
-       IMAGE_FILE_HEADER fh;
-       char* snames;
-};
-
-static int pemap(PeObj *peobj, PeSect *sect);
-static int issect(PeSym *s);
-static int readpesym(PeObj *peobj, int i, PeSym **sym);
-
-void
-ldpe(Biobuf *f, char *pkg, int64 length, char *pn)
-{
-       char *name;
-       int32 base;
-       uint32 l;
-       int i, j, numaux;
-       PeObj *peobj;
-       PeSect *sect, *rsect;
-       IMAGE_SECTION_HEADER sh;
-       uchar symbuf[18];
-       LSym *s;
-       Reloc *r, *rp;
-       PeSym *sym;
-
-       USED(length);
-       if(debug['v'])
-               Bprint(&bso, "%5.2f ldpe %s\n", cputime(), pn);
-       
-       sect = nil;
-       ctxt->version++;
-       base = Boffset(f);
-       
-       peobj = mal(sizeof *peobj);
-       peobj->f = f;
-       peobj->base = base;
-       peobj->name = pn;
-       // read header
-       if(Bread(f, &peobj->fh, sizeof peobj->fh) != sizeof peobj->fh)
-               goto bad;
-       // load section list
-       peobj->sect = mal(peobj->fh.NumberOfSections*sizeof peobj->sect[0]);
-       peobj->nsect = peobj->fh.NumberOfSections;
-       for(i=0; i < peobj->fh.NumberOfSections; i++) {
-               if(Bread(f, &peobj->sect[i].sh, sizeof sh) != sizeof sh)
-                       goto bad;
-               peobj->sect[i].size = peobj->sect[i].sh.SizeOfRawData;
-               peobj->sect[i].name = (char*)peobj->sect[i].sh.Name;
-               // TODO return error if found .cormeta
-       }
-       // load string table
-       Bseek(f, base+peobj->fh.PointerToSymbolTable+sizeof(symbuf)*peobj->fh.NumberOfSymbols, 0);
-       if(Bread(f, symbuf, 4) != 4) 
-               goto bad;
-       l = le32(symbuf);
-       peobj->snames = mal(l);
-       Bseek(f, base+peobj->fh.PointerToSymbolTable+sizeof(symbuf)*peobj->fh.NumberOfSymbols, 0);
-       if(Bread(f, peobj->snames, l) != l)
-               goto bad;
-       // rewrite section names if they start with /
-       for(i=0; i < peobj->fh.NumberOfSections; i++) {
-               if(peobj->sect[i].name == nil)
-                       continue;
-               if(peobj->sect[i].name[0] != '/')
-                       continue;
-               l = atoi(peobj->sect[i].name + 1);
-               peobj->sect[i].name = (char*)&peobj->snames[l];
-       }
-       // read symbols
-       peobj->pesym = mal(peobj->fh.NumberOfSymbols*sizeof peobj->pesym[0]);
-       peobj->npesym = peobj->fh.NumberOfSymbols;
-       Bseek(f, base+peobj->fh.PointerToSymbolTable, 0);
-       for(i=0; i<peobj->fh.NumberOfSymbols; i+=numaux+1) {
-               Bseek(f, base+peobj->fh.PointerToSymbolTable+sizeof(symbuf)*i, 0);
-               if(Bread(f, symbuf, sizeof symbuf) != sizeof symbuf)
-                       goto bad;
-               
-               if((symbuf[0] == 0) && (symbuf[1] == 0) &&
-                        (symbuf[2] == 0) && (symbuf[3] == 0)) {
-                       l = le32(&symbuf[4]);
-                       peobj->pesym[i].name = (char*)&peobj->snames[l];
-               } else { // sym name length <= 8
-                       peobj->pesym[i].name = mal(9);
-                       strncpy(peobj->pesym[i].name, (char*)symbuf, 8);
-                       peobj->pesym[i].name[8] = 0;
-               }
-               peobj->pesym[i].value = le32(&symbuf[8]);
-               peobj->pesym[i].sectnum = le16(&symbuf[12]);
-               peobj->pesym[i].sclass = symbuf[16];
-               peobj->pesym[i].aux = symbuf[17];
-               peobj->pesym[i].type = le16(&symbuf[14]);
-               numaux = peobj->pesym[i].aux; 
-               if (numaux < 0) 
-                       numaux = 0;
-       }
-       // create symbols for mapped sections
-       for(i=0; i<peobj->nsect; i++) {
-               sect = &peobj->sect[i];
-               if(sect->sh.Characteristics&IMAGE_SCN_MEM_DISCARDABLE)
-                       continue;
-
-               if((sect->sh.Characteristics&(IMAGE_SCN_CNT_CODE|IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_CNT_UNINITIALIZED_DATA)) == 0) {
-                       // This has been seen for .idata sections, which we
-                       // want to ignore.  See issues 5106 and 5273.
-                       continue;
-               }
-
-               if(pemap(peobj, sect) < 0)
-                       goto bad;
-               
-               name = smprint("%s(%s)", pkg, sect->name);
-               s = linklookup(ctxt, name, ctxt->version);
-               free(name);
-               switch(sect->sh.Characteristics&(IMAGE_SCN_CNT_UNINITIALIZED_DATA|IMAGE_SCN_CNT_INITIALIZED_DATA|
-                       IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE|IMAGE_SCN_CNT_CODE|IMAGE_SCN_MEM_EXECUTE)) {
-                       case IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ: //.rdata
-                               s->type = SRODATA;
-                               break;
-                       case IMAGE_SCN_CNT_UNINITIALIZED_DATA|IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE: //.bss
-                               s->type = SNOPTRBSS;
-                               break;
-                       case IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE: //.data
-                               s->type = SNOPTRDATA;
-                               break;
-                       case IMAGE_SCN_CNT_CODE|IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ: //.text
-                               s->type = STEXT;
-                               break;
-                       default:
-                               werrstr("unexpected flags %#08ux for PE section %s", sect->sh.Characteristics, sect->name);
-                               goto bad;
-               }
-               s->p = sect->base;
-               s->np = sect->size;
-               s->size = sect->size;
-               sect->sym = s;
-               if(strcmp(sect->name, ".rsrc") == 0)
-                       setpersrc(sect->sym);
-       }
-       
-       // load relocations
-       for(i=0; i<peobj->nsect; i++) {
-               rsect = &peobj->sect[i];
-               if(rsect->sym == 0 || rsect->sh.NumberOfRelocations == 0)
-                       continue;
-               if(rsect->sh.Characteristics&IMAGE_SCN_MEM_DISCARDABLE)
-                       continue;
-               if((sect->sh.Characteristics&(IMAGE_SCN_CNT_CODE|IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_CNT_UNINITIALIZED_DATA)) == 0) {
-                       // This has been seen for .idata sections, which we
-                       // want to ignore.  See issues 5106 and 5273.
-                       continue;
-               }
-               r = mal(rsect->sh.NumberOfRelocations*sizeof r[0]);
-               Bseek(f, peobj->base+rsect->sh.PointerToRelocations, 0);
-               for(j=0; j<rsect->sh.NumberOfRelocations; j++) {
-                       rp = &r[j];
-                       if(Bread(f, symbuf, 10) != 10)
-                               goto bad;
-                       
-                       uint32 rva, symindex;
-                       uint16 type;
-                       rva = le32(&symbuf[0]);
-                       symindex = le32(&symbuf[4]);
-                       type = le16(&symbuf[8]);
-                       if(readpesym(peobj, symindex, &sym) < 0)
-                               goto bad;
-                       if(sym->sym == nil) {
-                               werrstr("reloc of invalid sym %s idx=%d type=%d", sym->name, symindex, sym->type);
-                               goto bad;
-                       }
-                       rp->sym = sym->sym;
-                       rp->siz = 4;
-                       rp->off = rva;
-                       switch(type) {
-                               default:
-                                       diag("%s: unknown relocation type %d;", pn, type);
-                               case IMAGE_REL_I386_REL32:
-                               case IMAGE_REL_AMD64_REL32:
-                               case IMAGE_REL_AMD64_ADDR32: // R_X86_64_PC32
-                               case IMAGE_REL_AMD64_ADDR32NB:
-                                       rp->type = R_PCREL;
-                                       rp->add = (int32)le32(rsect->base+rp->off);
-                                       break;
-                               case IMAGE_REL_I386_DIR32NB:
-                               case IMAGE_REL_I386_DIR32:
-                                       rp->type = R_ADDR;
-                                       // load addend from image
-                                       rp->add = (int32)le32(rsect->base+rp->off);
-                                       break;
-                               case IMAGE_REL_AMD64_ADDR64: // R_X86_64_64
-                                       rp->siz = 8;
-                                       rp->type = R_ADDR;
-                                       // load addend from image
-                                       rp->add = le64(rsect->base+rp->off);
-                                       break;
-                       }
-                       // ld -r could generate multiple section symbols for the
-                       // same section but with different values, we have to take
-                       // that into account
-                       if(issect(&peobj->pesym[symindex]))
-                               rp->add += peobj->pesym[symindex].value;
-               }
-               qsort(r, rsect->sh.NumberOfRelocations, sizeof r[0], rbyoff);
-               
-               s = rsect->sym;
-               s->r = r;
-               s->nr = rsect->sh.NumberOfRelocations;
-       }
-
-       // enter sub-symbols into symbol table.
-       for(i=0; i<peobj->npesym; i++) {
-               if(peobj->pesym[i].name == 0)
-                       continue;
-               if(issect(&peobj->pesym[i]))
-                       continue;
-               if(peobj->pesym[i].sectnum > peobj->nsect)
-                       continue;
-               if(peobj->pesym[i].sectnum > 0) {
-                       sect = &peobj->sect[peobj->pesym[i].sectnum-1];
-                       if(sect->sym == 0)
-                               continue;
-               }
-               if(readpesym(peobj, i, &sym) < 0)
-                       goto bad;
-       
-               s = sym->sym;
-               if(sym->sectnum == 0) {// extern
-                       if(s->type == SDYNIMPORT)
-                               s->plt = -2; // flag for dynimport in PE object files.
-                       if (s->type == SXREF && sym->value > 0) {// global data
-                               s->type = SNOPTRDATA;
-                               s->size = sym->value;
-                       }
-                       continue;
-               } else if (sym->sectnum > 0 && sym->sectnum <= peobj->nsect) {
-                       sect = &peobj->sect[sym->sectnum-1];
-                       if(sect->sym == 0)
-                               diag("%s: %s sym == 0!", pn, s->name);
-               } else {
-                       diag("%s: %s sectnum < 0!", pn, s->name);
-               }
-
-               if(sect == nil) 
-                       return;
-
-               if(s->outer != nil) {
-                       if(s->dupok)
-                               continue;
-                       diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s->name, s->outer->name, sect->sym->name);
-                       errorexit();
-               }
-               s->sub = sect->sym->sub;
-               sect->sym->sub = s;
-               s->type = sect->sym->type | SSUB;
-               s->value = sym->value;
-               s->size = 4;
-               s->outer = sect->sym;
-               if(sect->sym->type == STEXT) {
-                       if(s->external && !s->dupok)
-                               diag("%s: duplicate definition of %s", pn, s->name);
-                       s->external = 1;
-               }
-       }
-
-       // Sort outer lists by address, adding to textp.
-       // This keeps textp in increasing address order.
-       for(i=0; i<peobj->nsect; i++) {
-               s = peobj->sect[i].sym;
-               if(s == nil)
-                       continue;
-               if(s->sub)
-                       s->sub = listsort(s->sub, valuecmp, listsubp);
-               if(s->type == STEXT) {
-                       if(s->onlist)
-                               sysfatal("symbol %s listed multiple times", s->name);
-                       s->onlist = 1;
-                       if(ctxt->etextp)
-                               ctxt->etextp->next = s;
-                       else
-                               ctxt->textp = s;
-                       ctxt->etextp = s;
-                       for(s = s->sub; s != nil; s = s->sub) {
-                               if(s->onlist)
-                                       sysfatal("symbol %s listed multiple times", s->name);
-                               s->onlist = 1;
-                               ctxt->etextp->next = s;
-                               ctxt->etextp = s;
-                       }
-               }
-       }
-
-       return;
-bad:
-       diag("%s: malformed pe file: %r", pn);
-}
-
-static int
-pemap(PeObj *peobj, PeSect *sect)
-{
-       if(sect->base != nil)
-               return 0;
-
-       sect->base = mal(sect->sh.SizeOfRawData);
-       if(sect->sh.PointerToRawData == 0) // .bss doesn't have data in object file
-               return 0;
-       werrstr("short read");
-       if(Bseek(peobj->f, peobj->base+sect->sh.PointerToRawData, 0) < 0 || 
-                       Bread(peobj->f, sect->base, sect->sh.SizeOfRawData) != sect->sh.SizeOfRawData)
-               return -1;
-       
-       return 0;
-}
-
-static int
-issect(PeSym *s)
-{
-       return s->sclass == IMAGE_SYM_CLASS_STATIC && s->type == 0 && s->name[0] == '.';
-}
-
-static int
-readpesym(PeObj *peobj, int i, PeSym **y)
-{
-       LSym *s;
-       PeSym *sym;
-       char *name, *p;
-
-       if(i >= peobj->npesym || i < 0) {
-               werrstr("invalid pe symbol index");
-               return -1;
-       }
-
-       sym = &peobj->pesym[i];
-       *y = sym;
-       
-       if(issect(sym))
-               name = peobj->sect[sym->sectnum-1].sym->name;
-       else {
-               name = sym->name;
-               if(strncmp(name, "__imp_", 6) == 0)
-                       name = &name[6]; // __imp_Name => Name
-               if(thearch.thechar == '8' && name[0] == '_')
-                       name = &name[1]; // _Name => Name
-       }
-       // remove last @XXX
-       p = strchr(name, '@');
-       if(p)
-               *p = 0;
-       
-       switch(sym->type) {
-       default:
-               werrstr("%s: invalid symbol type %d", sym->name, sym->type);
-               return -1;
-       case IMAGE_SYM_DTYPE_FUNCTION:
-       case IMAGE_SYM_DTYPE_NULL:
-               switch(sym->sclass) {
-               case IMAGE_SYM_CLASS_EXTERNAL: //global
-                       s = linklookup(ctxt, name, 0);
-                       break;
-               case IMAGE_SYM_CLASS_NULL:
-               case IMAGE_SYM_CLASS_STATIC:
-               case IMAGE_SYM_CLASS_LABEL:
-                       s = linklookup(ctxt, name, ctxt->version);
-                       s->dupok = 1;
-                       break;
-               default:
-                       werrstr("%s: invalid symbol binding %d", sym->name, sym->sclass);
-                       return -1;
-               }
-               break;
-       }
-
-       if(s != nil && s->type == 0 && !(sym->sclass == IMAGE_SYM_CLASS_STATIC && sym->value == 0))
-               s->type = SXREF;
-       if(strncmp(sym->name, "__imp_", 6) == 0)
-               s->got = -2; // flag for __imp_
-       sym->sym = s;
-
-       return 0;
-}
diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c
deleted file mode 100644 (file)
index 612c755..0000000
+++ /dev/null
@@ -1,1636 +0,0 @@
-// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/span.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-#include       "lib.h"
-#include       "elf.h"
-#include       "dwarf.h"
-#include       "../../runtime/stack.h"
-#include       "../../runtime/funcdata.h"
-
-#include       <ar.h>
-#if !(defined(_WIN32) || defined(PLAN9))
-#include       <sys/stat.h>
-#endif
-
-enum
-{
-       // Whether to assume that the external linker is "gold"
-       // (http://sourceware.org/ml/binutils/2008-03/msg00162.html).
-       AssumeGoldLinker = 0,
-};
-
-int iconv(Fmt*);
-
-char   symname[]       = "__.GOSYMDEF";
-char   pkgname[]       = "__.PKGDEF";
-static int     cout = -1;
-
-extern int     version;
-
-// Set if we see an object compiled by the host compiler that is not
-// from a package that is known to support internal linking mode.
-static int     externalobj = 0;
-
-static void    hostlinksetup(void);
-
-char*  goroot;
-char*  goarch;
-char*  goos;
-char*  theline;
-
-void
-Lflag(char *arg)
-{
-       char **p;
-
-       if(ctxt->nlibdir >= ctxt->maxlibdir) {
-               if (ctxt->maxlibdir == 0)
-                       ctxt->maxlibdir = 8;
-               else
-                       ctxt->maxlibdir *= 2;
-               p = erealloc(ctxt->libdir, ctxt->maxlibdir * sizeof(*p));
-               ctxt->libdir = p;
-       }
-       ctxt->libdir[ctxt->nlibdir++] = arg;
-}
-
-/*
- * Unix doesn't like it when we write to a running (or, sometimes,
- * recently run) binary, so remove the output file before writing it.
- * On Windows 7, remove() can force a subsequent create() to fail.
- * S_ISREG() does not exist on Plan 9.
- */
-static void
-mayberemoveoutfile(void) 
-{
-#if !(defined(_WIN32) || defined(PLAN9))
-       struct stat st;
-       if(lstat(outfile, &st) == 0 && !S_ISREG(st.st_mode))
-               return;
-#endif
-       remove(outfile);
-}
-
-void
-libinit(void)
-{
-       char *suffix, *suffixsep;
-
-       funcalign = thearch.funcalign;
-       fmtinstall('i', iconv);
-       fmtinstall('Y', Yconv);
-       fmtinstall('Z', Zconv);
-       mywhatsys();    // get goroot, goarch, goos
-
-       // add goroot to the end of the libdir list.
-       suffix = "";
-       suffixsep = "";
-       if(flag_installsuffix != nil) {
-               suffixsep = "_";
-               suffix = flag_installsuffix;
-       } else if(flag_race) {
-               suffixsep = "_";
-               suffix = "race";
-       }
-       Lflag(smprint("%s/pkg/%s_%s%s%s", goroot, goos, goarch, suffixsep, suffix));
-
-       mayberemoveoutfile();
-       cout = create(outfile, 1, 0775);
-       if(cout < 0) {
-               diag("cannot create %s: %r", outfile);
-               errorexit();
-       }
-       Binit(&coutbuf, cout, OWRITE);
-
-       if(INITENTRY == nil) {
-               INITENTRY = mal(strlen(goarch)+strlen(goos)+20);
-               if(!flag_shared) {
-                       sprint(INITENTRY, "_rt0_%s_%s", goarch, goos);
-               } else {
-                       sprint(INITENTRY, "_rt0_%s_%s_lib", goarch, goos);
-               }
-       }
-       linklookup(ctxt, INITENTRY, 0)->type = SXREF;
-}
-
-void
-errorexit(void)
-{
-       if(cout >= 0) {
-               // For rmtemp run at atexit time on Windows.
-               close(cout);
-       }
-       if(nerrors) {
-               if(cout >= 0)
-                       mayberemoveoutfile();
-               exits("error");
-       }
-       exits(0);
-}
-
-void
-loadinternal(char *name)
-{
-       char pname[1024];
-       int i, found;
-
-       found = 0;
-       for(i=0; i<ctxt->nlibdir; i++) {
-               snprint(pname, sizeof pname, "%s/%s.a", ctxt->libdir[i], name);
-               if(debug['v'])
-                       Bprint(&bso, "searching for %s.a in %s\n", name, pname);
-               if(access(pname, AEXIST) >= 0) {
-                       addlibpath(ctxt, "internal", "internal", pname, name);
-                       found = 1;
-                       break;
-               }
-       }
-       if(!found)
-               Bprint(&bso, "warning: unable to find %s.a\n", name);
-}
-
-void
-loadlib(void)
-{
-       int i, w, x;
-       LSym *s, *tlsg;
-       char* cgostrsym;
-
-       if(flag_shared) {
-               s = linklookup(ctxt, "runtime.islibrary", 0);
-               s->dupok = 1;
-               adduint8(ctxt, s, 1);
-       }
-
-       loadinternal("runtime");
-       if(thearch.thechar == '5')
-               loadinternal("math");
-       if(flag_race)
-               loadinternal("runtime/race");
-
-       for(i=0; i<ctxt->libraryp; i++) {
-               if(debug['v'] > 1)
-                       Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), ctxt->library[i].file, ctxt->library[i].objref);
-               iscgo |= strcmp(ctxt->library[i].pkg, "runtime/cgo") == 0;
-               objfile(ctxt->library[i].file, ctxt->library[i].pkg);
-       }
-
-       if(linkmode == LinkAuto) {
-               if(iscgo && externalobj)
-                       linkmode = LinkExternal;
-               else
-                       linkmode = LinkInternal;
-
-               // Force external linking for android.
-               if(strcmp(goos, "android") == 0)
-                       linkmode = LinkExternal;
-
-               // cgo on Darwin must use external linking
-               // we can always use external linking, but then there will be circular
-               // dependency problems when compiling natively (external linking requires
-               // runtime/cgo, runtime/cgo requires cmd/cgo, but cmd/cgo needs to be
-               // compiled using external linking.)
-               if(thearch.thechar == '5' && HEADTYPE == Hdarwin && iscgo)
-                       linkmode = LinkExternal;
-       }
-
-       if(linkmode == LinkExternal && !iscgo) {
-               // This indicates a user requested -linkmode=external.
-               // The startup code uses an import of runtime/cgo to decide
-               // whether to initialize the TLS.  So give it one.  This could
-               // be handled differently but it's an unusual case.
-               loadinternal("runtime/cgo");
-               if(i < ctxt->libraryp)
-                       objfile(ctxt->library[i].file, ctxt->library[i].pkg);
-
-               // Pretend that we really imported the package.
-               s = linklookup(ctxt, "go.importpath.runtime/cgo.", 0);
-               s->type = SDATA;
-               s->dupok = 1;
-               s->reachable = 1;
-
-               // Provided by the code that imports the package.
-               // Since we are simulating the import, we have to provide this string.
-               cgostrsym = "go.string.\"runtime/cgo\"";
-               if(linkrlookup(ctxt, cgostrsym, 0) == nil) {
-                       s = linklookup(ctxt, cgostrsym, 0);
-                       s->type = SRODATA;
-                       s->reachable = 1;
-                       addstrdata(cgostrsym, "runtime/cgo");
-               }
-       }
-
-       if(linkmode == LinkInternal) {
-               // Drop all the cgo_import_static declarations.
-               // Turns out we won't be needing them.
-               for(s = ctxt->allsym; s != nil; s = s->allsym)
-                       if(s->type == SHOSTOBJ) {
-                               // If a symbol was marked both
-                               // cgo_import_static and cgo_import_dynamic,
-                               // then we want to make it cgo_import_dynamic
-                               // now.
-                               if(s->extname != nil && s->dynimplib != nil && s->cgoexport == 0) {
-                                       s->type = SDYNIMPORT;
-                               } else
-                                       s->type = 0;
-                       }
-       }
-       
-       tlsg = linklookup(ctxt, "runtime.tlsg", 0);
-       // For most ports, runtime.tlsg is a placeholder symbol for TLS
-       // relocation. However, the Android and Darwin arm ports need it
-       // to be a real variable.
-       //
-       // TODO(crawshaw): android should require leaving the tlsg->type
-       // alone (as the runtime-provided SNOPTRBSS) just like darwin/arm.
-       // But some other part of the linker is expecting STLSBSS.
-       if (!(strcmp(goos, "darwin") == 0 && thearch.thechar == '5'))
-               tlsg->type = STLSBSS;
-       tlsg->size = thearch.ptrsize;
-       tlsg->hide = 1;
-       tlsg->reachable = 1;
-       ctxt->tlsg = tlsg;
-
-       // Now that we know the link mode, trim the dynexp list.
-       x = CgoExportDynamic;
-       if(linkmode == LinkExternal)
-               x = CgoExportStatic;
-       w = 0;
-       for(i=0; i<ndynexp; i++)
-               if(dynexp[i]->cgoexport & x)
-                       dynexp[w++] = dynexp[i];
-       ndynexp = w;
-       
-       // In internal link mode, read the host object files.
-       if(linkmode == LinkInternal)
-               hostobjs();
-       else
-               hostlinksetup();
-
-       // We've loaded all the code now.
-       // If there are no dynamic libraries needed, gcc disables dynamic linking.
-       // Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
-       // assumes that a dynamic binary always refers to at least one dynamic library.
-       // Rather than be a source of test cases for glibc, disable dynamic linking
-       // the same way that gcc would.
-       //
-       // Exception: on OS X, programs such as Shark only work with dynamic
-       // binaries, so leave it enabled on OS X (Mach-O) binaries.
-       // Also leave it enabled on Solaris which doesn't support
-       // statically linked binaries.
-       if(!flag_shared && !havedynamic && HEADTYPE != Hdarwin && HEADTYPE != Hsolaris)
-               debug['d'] = 1;
-       
-       importcycles();
-}
-
-/*
- * look for the next file in an archive.
- * adapted from libmach.
- */
-static vlong
-nextar(Biobuf *bp, vlong off, ArHdr *a)
-{
-       int r;
-       int32 arsize;
-       char *buf;
-
-       if (off&01)
-               off++;
-       Bseek(bp, off, 0);
-       buf = Brdline(bp, '\n');
-       r = Blinelen(bp);
-       if(buf == nil) {
-               if(r == 0)
-                       return 0;
-               return -1;
-       }
-       if(r != SAR_HDR)
-               return -1;
-       memmove(a, buf, SAR_HDR);
-       if(strncmp(a->fmag, ARFMAG, sizeof a->fmag))
-               return -1;
-       arsize = strtol(a->size, 0, 0);
-       if (arsize&1)
-               arsize++;
-       return arsize + r;
-}
-
-void
-objfile(char *file, char *pkg)
-{
-       vlong off, l;
-       Biobuf *f;
-       char magbuf[SARMAG];
-       char pname[150];
-       ArHdr arhdr;
-
-       pkg = smprint("%i", pkg);
-
-       if(debug['v'] > 1)
-               Bprint(&bso, "%5.2f ldobj: %s (%s)\n", cputime(), file, pkg);
-       Bflush(&bso);
-       f = Bopen(file, 0);
-       if(f == nil) {
-               diag("cannot open file: %s", file);
-               errorexit();
-       }
-       l = Bread(f, magbuf, SARMAG);
-       if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){
-               /* load it as a regular file */
-               l = Bseek(f, 0L, 2);
-               Bseek(f, 0L, 0);
-               ldobj(f, pkg, l, file, file, FileObj);
-               Bterm(f);
-               free(pkg);
-               return;
-       }
-       
-       /* skip over optional __.GOSYMDEF and process __.PKGDEF */
-       off = Boffset(f);
-       l = nextar(f, off, &arhdr);
-       if(l <= 0) {
-               diag("%s: short read on archive file symbol header", file);
-               goto out;
-       }
-       if(strncmp(arhdr.name, symname, strlen(symname)) == 0) {
-               off += l;
-               l = nextar(f, off, &arhdr);
-               if(l <= 0) {
-                       diag("%s: short read on archive file symbol header", file);
-                       goto out;
-               }
-       }
-
-       if(strncmp(arhdr.name, pkgname, strlen(pkgname))) {
-               diag("%s: cannot find package header", file);
-               goto out;
-       }
-       off += l;
-
-       if(debug['u'])
-               ldpkg(f, pkg, atolwhex(arhdr.size), file, Pkgdef);
-
-       /*
-        * load all the object files from the archive now.
-        * this gives us sequential file access and keeps us
-        * from needing to come back later to pick up more
-        * objects.  it breaks the usual C archive model, but
-        * this is Go, not C.  the common case in Go is that
-        * we need to load all the objects, and then we throw away
-        * the individual symbols that are unused.
-        *
-        * loading every object will also make it possible to
-        * load foreign objects not referenced by __.GOSYMDEF.
-        */
-       for(;;) {
-               l = nextar(f, off, &arhdr);
-               if(l == 0)
-                       break;
-               if(l < 0) {
-                       diag("%s: malformed archive", file);
-                       goto out;
-               }
-               off += l;
-
-               l = SARNAME;
-               while(l > 0 && arhdr.name[l-1] == ' ')
-                       l--;
-               snprint(pname, sizeof pname, "%s(%.*s)", file, utfnlen(arhdr.name, l), arhdr.name);
-               l = atolwhex(arhdr.size);
-               ldobj(f, pkg, l, pname, file, ArchiveObj);
-       }
-
-out:
-       Bterm(f);
-       free(pkg);
-}
-
-static void
-dowrite(int fd, char *p, int n)
-{
-       int m;
-       
-       while(n > 0) {
-               m = write(fd, p, n);
-               if(m <= 0) {
-                       ctxt->cursym = nil;
-                       diag("write error: %r");
-                       errorexit();
-               }
-               n -= m;
-               p += m;
-       }
-}
-
-typedef struct Hostobj Hostobj;
-
-struct Hostobj
-{
-       void (*ld)(Biobuf*, char*, int64, char*);
-       char *pkg;
-       char *pn;
-       char *file;
-       int64 off;
-       int64 length;
-};
-
-Hostobj *hostobj;
-int nhostobj;
-int mhostobj;
-
-// These packages can use internal linking mode.
-// Others trigger external mode.
-const char *internalpkg[] = {
-       "crypto/x509",
-       "net",
-       "os/user",
-       "runtime/cgo",
-       "runtime/race"
-};
-
-void
-ldhostobj(void (*ld)(Biobuf*, char*, int64, char*), Biobuf *f, char *pkg, int64 length, char *pn, char *file)
-{
-       int i, isinternal;
-       Hostobj *h;
-
-       isinternal = 0;
-       for(i=0; i<nelem(internalpkg); i++) {
-               if(strcmp(pkg, internalpkg[i]) == 0) {
-                       isinternal = 1;
-                       break;
-               }
-       }
-
-       // DragonFly declares errno with __thread, which results in a symbol
-       // type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not
-       // currently know how to handle TLS relocations, hence we have to
-       // force external linking for any libraries that link in code that
-       // uses errno. This can be removed if the Go linker ever supports
-       // these relocation types.
-       if(HEADTYPE == Hdragonfly)
-       if(strcmp(pkg, "net") == 0 || strcmp(pkg, "os/user") == 0)
-               isinternal = 0;
-
-       if(!isinternal)
-               externalobj = 1;
-
-       if(nhostobj >= mhostobj) {
-               if(mhostobj == 0)
-                       mhostobj = 16;
-               else
-                       mhostobj *= 2;
-               hostobj = erealloc(hostobj, mhostobj*sizeof hostobj[0]);
-       }
-       h = &hostobj[nhostobj++];
-       h->ld = ld;
-       h->pkg = estrdup(pkg);
-       h->pn = estrdup(pn);
-       h->file = estrdup(file);
-       h->off = Boffset(f);
-       h->length = length;
-}
-
-void
-hostobjs(void)
-{
-       int i;
-       Biobuf *f;
-       Hostobj *h;
-       
-       for(i=0; i<nhostobj; i++) {
-               h = &hostobj[i];
-               f = Bopen(h->file, OREAD);
-               if(f == nil) {
-                       ctxt->cursym = nil;
-                       diag("cannot reopen %s: %r", h->pn);
-                       errorexit();
-               }
-               Bseek(f, h->off, 0);
-               h->ld(f, h->pkg, h->length, h->pn);
-               Bterm(f);
-       }
-}
-
-// provided by lib9
-int runcmd(char**);
-char* mktempdir(void);
-void removeall(char*);
-
-static void
-rmtemp(void)
-{
-       removeall(tmpdir);
-}
-
-static void
-hostlinksetup(void)
-{
-       char *p;
-
-       if(linkmode != LinkExternal)
-               return;
-
-       // create temporary directory and arrange cleanup
-       if(tmpdir == nil) {
-               tmpdir = mktempdir();
-               atexit(rmtemp);
-       }
-
-       // change our output to temporary object file
-       close(cout);
-       p = smprint("%s/go.o", tmpdir);
-       cout = create(p, 1, 0775);
-       if(cout < 0) {
-               diag("cannot create %s: %r", p);
-               errorexit();
-       }
-       Binit(&coutbuf, cout, OWRITE);
-       free(p);
-}
-
-void
-hostlink(void)
-{
-       char *p, **argv;
-       int c, i, w, n, argc, length;
-       Hostobj *h;
-       Biobuf *f;
-       static char buf[64<<10];
-
-       if(linkmode != LinkExternal || nerrors > 0)
-               return;
-
-       c = 0;
-       p = extldflags;
-       while(p != nil) {
-               while(*p == ' ')
-                       p++;
-               if(*p == '\x00')
-                       break;
-               c++;
-               p = strchr(p + 1, ' ');
-       }
-
-       argv = malloc((14+nhostobj+nldflag+c)*sizeof argv[0]);
-       argc = 0;
-       if(extld == nil)
-               extld = "gcc";
-       argv[argc++] = extld;
-       switch(thearch.thechar){
-       case '8':
-               argv[argc++] = "-m32";
-               break;
-       case '6':
-       case '9':
-               argv[argc++] = "-m64";
-               break;
-       case '5':
-               argv[argc++] = "-marm";
-               break;
-       }
-       if(!debug['s'] && !debug_s) {
-               argv[argc++] = "-gdwarf-2"; 
-       } else {
-               argv[argc++] = "-s";
-       }
-       if(HEADTYPE == Hdarwin)
-               argv[argc++] = "-Wl,-no_pie,-pagezero_size,4000000";
-       if(HEADTYPE == Hopenbsd)
-               argv[argc++] = "-Wl,-nopie";
-       
-       if(iself && AssumeGoldLinker)
-               argv[argc++] = "-Wl,--rosegment";
-
-       if(flag_shared) {
-               argv[argc++] = "-Wl,-Bsymbolic";
-               argv[argc++] = "-shared";
-       }
-       argv[argc++] = "-o";
-       argv[argc++] = outfile;
-       
-       if(rpath)
-               argv[argc++] = smprint("-Wl,-rpath,%s", rpath);
-
-       // Force global symbols to be exported for dlopen, etc.
-       if(iself)
-               argv[argc++] = "-rdynamic";
-
-       if(strstr(argv[0], "clang") != nil)
-               argv[argc++] = "-Qunused-arguments";
-
-       // already wrote main object file
-       // copy host objects to temporary directory
-       for(i=0; i<nhostobj; i++) {
-               h = &hostobj[i];
-               f = Bopen(h->file, OREAD);
-               if(f == nil) {
-                       ctxt->cursym = nil;
-                       diag("cannot reopen %s: %r", h->pn);
-                       errorexit();
-               }
-               Bseek(f, h->off, 0);
-               p = smprint("%s/%06d.o", tmpdir, i);
-               argv[argc++] = p;
-               w = create(p, 1, 0775);
-               if(w < 0) {
-                       ctxt->cursym = nil;
-                       diag("cannot create %s: %r", p);
-                       errorexit();
-               }
-               length = h->length;
-               while(length > 0) {
-                       n = Bread(f, buf, sizeof buf);
-                       if(n <= 0)
-                               break;
-                       if(n > length)
-                               n = length;
-                       dowrite(w, buf, n);
-                       length -= n;
-               }
-               if(close(w) < 0) {
-                       ctxt->cursym = nil;
-                       diag("cannot write %s: %r", p);
-                       errorexit();
-               }
-               Bterm(f);
-       }
-       
-       argv[argc++] = smprint("%s/go.o", tmpdir);
-       for(i=0; i<nldflag; i++)
-               argv[argc++] = ldflag[i];
-
-       p = extldflags;
-       while(p != nil) {
-               while(*p == ' ')
-                       *p++ = '\x00';
-               if(*p == '\x00')
-                       break;
-               argv[argc++] = p;
-
-               // clang, unlike GCC, passes -rdynamic to the linker
-               // even when linking with -static, causing a linker
-               // error when using GNU ld.  So take out -rdynamic if
-               // we added it.  We do it in this order, rather than
-               // only adding -rdynamic later, so that -extldflags
-               // can override -rdynamic without using -static.
-               if(iself && strncmp(p, "-static", 7) == 0 && (p[7]==' ' || p[7]=='\x00')) {
-                       for(i=0; i<argc; i++) {
-                               if(strcmp(argv[i], "-rdynamic") == 0)
-                                       argv[i] = "-static";
-                       }
-               }
-
-               p = strchr(p + 1, ' ');
-       }
-
-       argv[argc] = nil;
-
-       quotefmtinstall();
-       if(debug['v']) {
-               Bprint(&bso, "host link:");
-               for(i=0; i<argc; i++)
-                       Bprint(&bso, " %q", argv[i]);
-               Bprint(&bso, "\n");
-               Bflush(&bso);
-       }
-
-       if(runcmd(argv) < 0) {
-               ctxt->cursym = nil;
-               diag("%s: running %s failed: %r", argv0, argv[0]);
-               errorexit();
-       }
-}
-
-void
-ldobj(Biobuf *f, char *pkg, int64 length, char *pn, char *file, int whence)
-{
-       char *line;
-       int n, c1, c2, c3, c4;
-       uint32 magic;
-       vlong import0, import1, eof, start;
-       char *t;
-
-       eof = Boffset(f) + length;
-
-       pn = estrdup(pn);
-
-       start = Boffset(f);
-       c1 = BGETC(f);
-       c2 = BGETC(f);
-       c3 = BGETC(f);
-       c4 = BGETC(f);
-       Bseek(f, start, 0);
-
-       magic = c1<<24 | c2<<16 | c3<<8 | c4;
-       if(magic == 0x7f454c46) {       // \x7F E L F
-               ldhostobj(ldelf, f, pkg, length, pn, file);
-               return;
-       }
-       if((magic&~1) == 0xfeedface || (magic&~0x01000000) == 0xcefaedfe) {
-               ldhostobj(ldmacho, f, pkg, length, pn, file);
-               return;
-       }
-       if(c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86) {
-               ldhostobj(ldpe, f, pkg, length, pn, file);
-               return;
-       }
-
-       /* check the header */
-       line = Brdline(f, '\n');
-       if(line == nil) {
-               if(Blinelen(f) > 0) {
-                       diag("%s: not an object file", pn);
-                       return;
-               }
-               goto eof;
-       }
-       n = Blinelen(f) - 1;
-       line[n] = '\x00';
-       if(strncmp(line, "go object ", 10) != 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", thearch.thechar, pn, thearch.thechar, thearch.thechar);
-                       errorexit();
-               }
-               if(strcmp(line, thestring) == 0) {
-                       // old header format: just $GOOS
-                       diag("%s: stale object file", pn);
-                       return;
-               }
-               diag("%s: not an object file", pn);
-               free(pn);
-               return;
-       }
-       
-       // First, check that the basic goos, goarch, and version match.
-       t = smprint("%s %s %s ", goos, getgoarch(), getgoversion());
-       line[n] = ' ';
-       if(strncmp(line+10, t, strlen(t)) != 0 && !debug['f']) {
-               line[n] = '\x00';
-               diag("%s: object is [%s] expected [%s]", pn, line+10, t);
-               free(t);
-               free(pn);
-               return;
-       }
-       
-       // Second, check that longer lines match each other exactly,
-       // so that the Go compiler and write additional information
-       // that must be the same from run to run.
-       line[n] = '\x00';
-       if(n-10 > strlen(t)) {
-               if(theline == nil)
-                       theline = estrdup(line+10);
-               else if(strcmp(theline, line+10) != 0) {
-                       line[n] = '\x00';
-                       diag("%s: object is [%s] expected [%s]", pn, line+10, theline);
-                       free(t);
-                       free(pn);
-                       return;
-               }
-       }
-       free(t);
-       line[n] = '\n';
-
-       /* skip over exports and other info -- ends with \n!\n */
-       import0 = Boffset(f);
-       c1 = '\n';      // the last line ended in \n
-       c2 = BGETC(f);
-       c3 = BGETC(f);
-       while(c1 != '\n' || c2 != '!' || c3 != '\n') {
-               c1 = c2;
-               c2 = c3;
-               c3 = BGETC(f);
-               if(c3 == Beof)
-                       goto eof;
-       }
-       import1 = Boffset(f);
-
-       Bseek(f, import0, 0);
-       ldpkg(f, pkg, import1 - import0 - 2, pn, whence);       // -2 for !\n
-       Bseek(f, import1, 0);
-
-       ldobjfile(ctxt, f, pkg, eof - Boffset(f), pn);
-       free(pn);
-       return;
-
-eof:
-       diag("truncated object file: %s", pn);
-       free(pn);
-}
-
-void
-zerosig(char *sp)
-{
-       LSym *s;
-
-       s = linklookup(ctxt, sp, 0);
-       s->sig = 0;
-}
-
-void
-mywhatsys(void)
-{
-       goroot = getgoroot();
-       goos = getgoos();
-       goarch = getgoarch();
-
-       if(strncmp(goarch, thestring, strlen(thestring)) != 0)
-               sysfatal("cannot use %cc with GOARCH=%s", thearch.thechar, goarch);
-}
-
-int
-pathchar(void)
-{
-       return '/';
-}
-
-static uchar*  hunk;
-static uint32  nhunk;
-enum {
-       NHUNK = 10<<20,
-};
-
-void*
-mal(uint32 n)
-{
-       void *v;
-
-       n = (n+7)&~7;
-       if(n > NHUNK) {
-               v = malloc(n);
-               if(v == nil) {
-                       diag("out of memory");
-                       errorexit();
-               }
-               memset(v, 0, n);
-               return v;
-       }
-       if(n > nhunk) {
-               hunk = malloc(NHUNK);
-               if(hunk == nil) {
-                       diag("out of memory");
-                       errorexit();
-               }
-               nhunk = NHUNK;
-       }
-
-       v = hunk;
-       nhunk -= n;
-       hunk += n;
-
-       memset(v, 0, n);
-       return v;
-}
-
-void
-unmal(void *v, uint32 n)
-{
-       n = (n+7)&~7;
-       if(hunk - n == v) {
-               hunk -= n;
-               nhunk += n;
-       }
-}
-
-// Copied from ../gc/subr.c:/^pathtoprefix; must stay in sync.
-/*
- * Convert raw string to the prefix that will be used in the symbol table.
- * Invalid bytes turn into %xx.         Right now the only bytes that need
- * escaping are %, ., and ", but we escape all control characters too.
- *
- * If you edit this, edit ../gc/subr.c:/^pathtoprefix too.
- * If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too.
- */
-static char*
-pathtoprefix(char *s)
-{
-       static char hex[] = "0123456789abcdef";
-       char *p, *r, *w, *l;
-       int n;
-
-       // find first character past the last slash, if any.
-       l = s;
-       for(r=s; *r; r++)
-               if(*r == '/')
-                       l = r+1;
-
-       // check for chars that need escaping
-       n = 0;
-       for(r=s; *r; r++)
-               if(*r <= ' ' || (*r == '.' && r >= l) || *r == '%' || *r == '"' || *r >= 0x7f)
-                       n++;
-
-       // quick exit
-       if(n == 0)
-               return s;
-
-       // escape
-       p = mal((r-s)+1+2*n);
-       for(r=s, w=p; *r; r++) {
-               if(*r <= ' ' || (*r == '.' && r >= l) || *r == '%' || *r == '"' || *r >= 0x7f) {
-                       *w++ = '%';
-                       *w++ = hex[(*r>>4)&0xF];
-                       *w++ = hex[*r&0xF];
-               } else
-                       *w++ = *r;
-       }
-       *w = '\x00';
-       return p;
-}
-
-int
-iconv(Fmt *fp)
-{
-       char *p;
-
-       p = va_arg(fp->args, char*);
-       if(p == nil) {
-               fmtstrcpy(fp, "<nil>");
-               return 0;
-       }
-       p = pathtoprefix(p);
-       fmtstrcpy(fp, p);
-       return 0;
-}
-
-Section*
-addsection(Segment *seg, char *name, int rwx)
-{
-       Section **l;
-       Section *sect;
-       
-       for(l=&seg->sect; *l; l=&(*l)->next)
-               ;
-       sect = mal(sizeof *sect);
-       sect->rwx = rwx;
-       sect->name = name;
-       sect->seg = seg;
-       sect->align = thearch.ptrsize; // everything is at least pointer-aligned
-       *l = sect;
-       return sect;
-}
-
-uint16
-le16(uchar *b)
-{
-       return b[0] | b[1]<<8;
-}
-
-uint32
-le32(uchar *b)
-{
-       return b[0] | b[1]<<8 | b[2]<<16 | (uint32)b[3]<<24;
-}
-
-uint64
-le64(uchar *b)
-{
-       return le32(b) | (uint64)le32(b+4)<<32;
-}
-
-uint16
-be16(uchar *b)
-{
-       return b[0]<<8 | b[1];
-}
-
-uint32
-be32(uchar *b)
-{
-       return (uint32)b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
-}
-
-uint64
-be64(uchar *b)
-{
-       return (uvlong)be32(b)<<32 | be32(b+4);
-}
-
-Endian be = { be16, be32, be64 };
-Endian le = { le16, le32, le64 };
-
-typedef struct Chain Chain;
-struct Chain
-{
-       LSym *sym;
-       Chain *up;
-       int limit;  // limit on entry to sym
-};
-
-static int stkcheck(Chain*, int);
-static void stkprint(Chain*, int);
-static void stkbroke(Chain*, int);
-static LSym *morestack;
-static LSym *newstack;
-
-// TODO: Record enough information in new object files to
-// allow stack checks here.
-
-static int
-haslinkregister(void)
-{
-       return thearch.thechar == '5' || thearch.thechar == '9';
-}
-
-static int
-callsize(void)
-{
-       if(haslinkregister())
-               return 0;
-       return thearch.regsize;
-}
-
-void
-dostkcheck(void)
-{
-       Chain ch;
-       LSym *s;
-
-       morestack = linklookup(ctxt, "runtime.morestack", 0);
-       newstack = linklookup(ctxt, "runtime.newstack", 0);
-
-       // Every splitting function ensures that there are at least StackLimit
-       // bytes available below SP when the splitting prologue finishes.
-       // If the splitting function calls F, then F begins execution with
-       // at least StackLimit - callsize() bytes available.
-       // Check that every function behaves correctly with this amount
-       // of stack, following direct calls in order to piece together chains
-       // of non-splitting functions.
-       ch.up = nil;
-       ch.limit = StackLimit - callsize();
-
-       // Check every function, but do the nosplit functions in a first pass,
-       // to make the printed failure chains as short as possible.
-       for(s = ctxt->textp; s != nil; s = s->next) {
-               // runtime.racesymbolizethunk is called from gcc-compiled C
-               // code running on the operating system thread stack.
-               // It uses more than the usual amount of stack but that's okay.
-               if(strcmp(s->name, "runtime.racesymbolizethunk") == 0)
-                       continue;
-
-               if(s->nosplit) {
-                       ctxt->cursym = s;
-                       ch.sym = s;
-                       stkcheck(&ch, 0);
-               }
-       }
-       for(s = ctxt->textp; s != nil; s = s->next) {
-               if(!s->nosplit) {
-                       ctxt->cursym = s;
-                       ch.sym = s;
-                       stkcheck(&ch, 0);
-               }
-       }
-}
-
-static int
-stkcheck(Chain *up, int depth)
-{
-       Chain ch, ch1;
-       LSym *s;
-       int limit;
-       Reloc *r;
-       int ri, endr;
-       Pciter pcsp;
-       
-       limit = up->limit;
-       s = up->sym;
-       
-       // Don't duplicate work: only need to consider each
-       // function at top of safe zone once.
-       if(limit == StackLimit-callsize()) {
-               if(s->stkcheck)
-                       return 0;
-               s->stkcheck = 1;
-       }
-       
-       if(depth > 100) {
-               diag("nosplit stack check too deep");
-               stkbroke(up, 0);
-               return -1;
-       }
-
-       if(s->external || s->pcln == nil) {
-               // external function.
-               // should never be called directly.
-               // only diagnose the direct caller.
-               if(depth == 1 && s->type != SXREF)
-                       diag("call to external function %s", s->name);
-               return -1;
-       }
-
-       if(limit < 0) {
-               stkbroke(up, limit);
-               return -1;
-       }
-
-       // morestack looks like it calls functions,
-       // but it switches the stack pointer first.
-       if(s == morestack)
-               return 0;
-
-       ch.up = up;
-       
-       // Walk through sp adjustments in function, consuming relocs.
-       ri = 0;
-       endr = s->nr;
-       for(pciterinit(ctxt, &pcsp, &s->pcln->pcsp); !pcsp.done; pciternext(&pcsp)) {
-               // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
-
-               // Check stack size in effect for this span.
-               if(limit - pcsp.value < 0) {
-                       stkbroke(up, limit - pcsp.value);
-                       return -1;
-               }
-
-               // Process calls in this span.
-               for(; ri < endr && s->r[ri].off < pcsp.nextpc; ri++) {
-                       r = &s->r[ri];
-                       switch(r->type) {
-                       case R_CALL:
-                       case R_CALLARM:
-                       case R_CALLPOWER:
-                               // Direct call.
-                               ch.limit = limit - pcsp.value - callsize();
-                               ch.sym = r->sym;
-                               if(stkcheck(&ch, depth+1) < 0)
-                                       return -1;
-
-                               // If this is a call to morestack, we've just raised our limit back
-                               // to StackLimit beyond the frame size.
-                               if(strncmp(r->sym->name, "runtime.morestack", 17) == 0) {
-                                       limit = StackLimit + s->locals;
-                                       if(haslinkregister())
-                                               limit += thearch.regsize;
-                               }
-                               break;
-
-                       case R_CALLIND:
-                               // Indirect call.  Assume it is a call to a splitting function,
-                               // so we have to make sure it can call morestack.
-                               // Arrange the data structures to report both calls, so that
-                               // if there is an error, stkprint shows all the steps involved.
-                               ch.limit = limit - pcsp.value - callsize();
-                               ch.sym = nil;
-                               ch1.limit = ch.limit - callsize(); // for morestack in called prologue
-                               ch1.up = &ch;
-                               ch1.sym = morestack;
-                               if(stkcheck(&ch1, depth+2) < 0)
-                                       return -1;
-                               break;
-                       }
-               }
-       }
-               
-       return 0;
-}
-
-static void
-stkbroke(Chain *ch, int limit)
-{
-       diag("nosplit stack overflow");
-       stkprint(ch, limit);
-}
-
-static void
-stkprint(Chain *ch, int limit)
-{
-       char *name;
-
-       if(ch->sym)
-               name = ch->sym->name;
-       else
-               name = "function pointer";
-
-       if(ch->up == nil) {
-               // top of chain.  ch->sym != nil.
-               if(ch->sym->nosplit)
-                       print("\t%d\tassumed on entry to %s\n", ch->limit, name);
-               else
-                       print("\t%d\tguaranteed after split check in %s\n", ch->limit, name);
-       } else {
-               stkprint(ch->up, ch->limit + callsize());
-               if(!haslinkregister())
-                       print("\t%d\ton entry to %s\n", ch->limit, name);
-       }
-       if(ch->limit != limit)
-               print("\t%d\tafter %s uses %d\n", limit, name, ch->limit - limit);
-}
-
-int
-Yconv(Fmt *fp)
-{
-       LSym *s;
-       Fmt fmt;
-       int i;
-       char *str;
-
-       s = va_arg(fp->args, LSym*);
-       if (s == nil) {
-               fmtprint(fp, "<nil>");
-       } else {
-               fmtstrinit(&fmt);
-               fmtprint(&fmt, "%s @0x%08llx [%lld]", s->name, (vlong)s->value, (vlong)s->size);
-               for (i = 0; i < s->size; i++) {
-                       if (!(i%8)) fmtprint(&fmt,  "\n\t0x%04x ", i);
-                       fmtprint(&fmt, "%02x ", s->p[i]);
-               }
-               fmtprint(&fmt, "\n");
-               for (i = 0; i < s->nr; i++) {
-                       fmtprint(&fmt, "\t0x%04x[%x] %d %s[%llx]\n",
-                             s->r[i].off,
-                             s->r[i].siz,
-                             s->r[i].type,
-                             s->r[i].sym->name,
-                             (vlong)s->r[i].add);
-               }
-               str = fmtstrflush(&fmt);
-               fmtstrcpy(fp, str);
-               free(str);
-       }
-
-       return 0;
-}
-
-void
-cflush(void)
-{
-       Bflush(&coutbuf);
-}
-
-vlong
-cpos(void)
-{
-       return Boffset(&coutbuf);
-}
-
-void
-cseek(vlong p)
-{
-       Bseek(&coutbuf, p, 0);
-}
-
-void
-cwrite(void *buf, int n)
-{
-       Bflush(&coutbuf); // TODO: Remove if safe.
-       Bwrite(&coutbuf, buf, n);
-}
-
-void
-cput(uint8 c)
-{
-       Bputc(&coutbuf, c);
-}
-
-void
-usage(void)
-{
-       fprint(2, "usage: %cl [options] main.%c\n", thearch.thechar, thearch.thechar);
-       flagprint(2);
-       exits("usage");
-}
-
-void
-setheadtype(char *s)
-{
-       int h;
-       
-       h = headtype(s);
-       if(h < 0) {
-               fprint(2, "unknown header type -H %s\n", s);
-               errorexit();
-       }
-       headstring = s;
-       HEADTYPE = headtype(s);
-}
-
-void
-setinterp(char *s)
-{
-       debug['I'] = 1; // denote cmdline interpreter override
-       interpreter = s;
-}
-
-void
-doversion(void)
-{
-       print("%cl version %s\n", thearch.thechar, getgoversion());
-       errorexit();
-}
-
-void
-genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*))
-{
-       Auto *a;
-       LSym *s;
-       int32 off;
-
-       // These symbols won't show up in the first loop below because we
-       // skip STEXT symbols. Normal STEXT symbols are emitted by walking textp.
-       s = linklookup(ctxt, "runtime.text", 0);
-       if(s->type == STEXT)
-               put(s, s->name, 'T', s->value, s->size, s->version, 0);
-       s = linklookup(ctxt, "runtime.etext", 0);
-       if(s->type == STEXT)
-               put(s, s->name, 'T', s->value, s->size, s->version, 0);
-
-       for(s=ctxt->allsym; s!=nil; s=s->allsym) {
-               if(s->hide || (s->name[0] == '.' && s->version == 0 && strcmp(s->name, ".rathole") != 0))
-                       continue;
-               switch(s->type&SMASK) {
-               case SCONST:
-               case SRODATA:
-               case SSYMTAB:
-               case SPCLNTAB:
-               case SDATA:
-               case SNOPTRDATA:
-               case SELFROSECT:
-               case SMACHOGOT:
-               case STYPE:
-               case SSTRING:
-               case SGOSTRING:
-               case SWINDOWS:
-                       if(!s->reachable)
-                               continue;
-                       put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype);
-                       continue;
-
-               case SBSS:
-               case SNOPTRBSS:
-                       if(!s->reachable)
-                               continue;
-                       if(s->np > 0)
-                               diag("%s should not be bss (size=%d type=%d special=%d)", s->name, (int)s->np, s->type, s->special);
-                       put(s, s->name, 'B', symaddr(s), s->size, s->version, s->gotype);
-                       continue;
-
-               case SFILE:
-                       put(nil, s->name, 'f', s->value, 0, s->version, 0);
-                       continue;
-               }
-       }
-
-       for(s = ctxt->textp; s != nil; s = s->next) {
-               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
-               put(nil, ".frame", 'm', s->locals+thearch.ptrsize, 0, 0, 0);
-
-               for(a=s->autom; a; a=a->link) {
-                       // Emit a or p according to actual offset, even if label is wrong.
-                       // This avoids negative offsets, which cannot be encoded.
-                       if(a->name != A_AUTO && a->name != A_PARAM)
-                               continue;
-                       
-                       // compute offset relative to FP
-                       if(a->name == A_PARAM)
-                               off = a->aoffset;
-                       else
-                               off = a->aoffset - thearch.ptrsize;
-                       
-                       // FP
-                       if(off >= 0) {
-                               put(nil, a->asym->name, 'p', off, 0, 0, a->gotype);
-                               continue;
-                       }
-                       
-                       // SP
-                       if(off <= -thearch.ptrsize) {
-                               put(nil, a->asym->name, 'a', -(off+thearch.ptrsize), 0, 0, a->gotype);
-                               continue;
-                       }
-                       
-                       // Otherwise, off is addressing the saved program counter.
-                       // Something underhanded is going on. Say nothing.
-               }
-       }
-       if(debug['v'] || debug['n'])
-               Bprint(&bso, "%5.2f symsize = %ud\n", cputime(), symsize);
-       Bflush(&bso);
-}
-
-vlong
-symaddr(LSym *s)
-{
-       if(!s->reachable)
-               diag("unreachable symbol in symaddr - %s", s->name);
-       return s->value;
-}
-
-void
-xdefine(char *p, int t, vlong v)
-{
-       LSym *s;
-
-       s = linklookup(ctxt, p, 0);
-       s->type = t;
-       s->value = v;
-       s->reachable = 1;
-       s->special = 1;
-}
-
-vlong
-datoff(vlong addr)
-{
-       if(addr >= segdata.vaddr)
-               return addr - segdata.vaddr + segdata.fileoff;
-       if(addr >= segtext.vaddr)
-               return addr - segtext.vaddr + segtext.fileoff;
-       diag("datoff %#llx", addr);
-       return 0;
-}
-
-vlong
-entryvalue(void)
-{
-       char *a;
-       LSym *s;
-
-       a = INITENTRY;
-       if(*a >= '0' && *a <= '9')
-               return atolwhex(a);
-       s = linklookup(ctxt, a, 0);
-       if(s->type == 0)
-               return INITTEXT;
-       if(s->type != STEXT)
-               diag("entry not text: %s", s->name);
-       return s->value;
-}
-
-static void
-undefsym(LSym *s)
-{
-       int i;
-       Reloc *r;
-
-       ctxt->cursym = s;
-       for(i=0; i<s->nr; i++) {
-               r = &s->r[i];
-               if(r->sym == nil) // happens for some external ARM relocs
-                       continue;
-               if(r->sym->type == Sxxx || r->sym->type == SXREF)
-                       diag("undefined: %s", r->sym->name);
-               if(!r->sym->reachable)
-                       diag("use of unreachable symbol: %s", r->sym->name);
-       }
-}
-
-void
-undef(void)
-{
-       LSym *s;
-       
-       for(s = ctxt->textp; s != nil; s = s->next)
-               undefsym(s);
-       for(s = datap; s != nil; s = s->next)
-               undefsym(s);
-       if(nerrors > 0)
-               errorexit();
-}
-
-void
-callgraph(void)
-{
-       LSym *s;
-       Reloc *r;
-       int i;
-
-       if(!debug['c'])
-               return;
-
-       for(s = ctxt->textp; s != nil; s = s->next) {
-               for(i=0; i<s->nr; i++) {
-                       r = &s->r[i];
-                       if(r->sym == nil)
-                               continue;
-                       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);
-               }
-       }
-}
-
-void
-diag(char *fmt, ...)
-{
-       char buf[1024], *tn, *sep;
-       va_list arg;
-
-       tn = "";
-       sep = "";
-       if(ctxt->cursym != nil) {
-               tn = ctxt->cursym->name;
-               sep = ": ";
-       }
-       va_start(arg, fmt);
-       vseprint(buf, buf+sizeof(buf), fmt, arg);
-       va_end(arg);
-       print("%s%s%s\n", tn, sep, buf);
-
-       nerrors++;
-       if(nerrors > 20) {
-               print("too many errors\n");
-               errorexit();
-       }
-}
-
-void
-checkgo(void)
-{
-       LSym *s;
-       Reloc *r;
-       int i;
-       int changed;
-       
-       if(!debug['C'])
-               return;
-       
-       // TODO(rsc,khr): Eventually we want to get to no Go-called C functions at all,
-       // which would simplify this logic quite a bit.
-
-       // Mark every Go-called C function with cfunc=2, recursively.
-       do {
-               changed = 0;
-               for(s = ctxt->textp; s != nil; s = s->next) {
-                       if(s->cfunc == 0 || (s->cfunc == 2 && s->nosplit)) {
-                               for(i=0; i<s->nr; i++) {
-                                       r = &s->r[i];
-                                       if(r->sym == nil)
-                                               continue;
-                                       if((r->type == R_CALL || r->type == R_CALLARM) && r->sym->type == STEXT) {
-                                               if(r->sym->cfunc == 1) {
-                                                       changed = 1;
-                                                       r->sym->cfunc = 2;
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }while(changed);
-
-       // Complain about Go-called C functions that can split the stack
-       // (that can be preempted for garbage collection or trigger a stack copy).
-       for(s = ctxt->textp; s != nil; s = s->next) {
-               if(s->cfunc == 0 || (s->cfunc == 2 && s->nosplit)) {
-                       for(i=0; i<s->nr; i++) {
-                               r = &s->r[i];
-                               if(r->sym == nil)
-                                       continue;
-                               if((r->type == R_CALL || r->type == R_CALLARM) && r->sym->type == STEXT) {
-                                       if(s->cfunc == 0 && r->sym->cfunc == 2 && !r->sym->nosplit)
-                                               print("Go %s calls C %s\n", s->name, r->sym->name);
-                                       else if(s->cfunc == 2 && s->nosplit && !r->sym->nosplit)
-                                               print("Go calls C %s calls %s\n", s->name, r->sym->name);
-                               }
-                       }
-               }
-       }
-}
-
-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;
-}
diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h
deleted file mode 100644 (file)
index fa4510d..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-// Derived from Inferno utils/6l/l.h
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/l.h
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// 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);
-       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.
-// A segment describes a block of file to load into memory.
-// A section further describes the pieces of that block for
-// use in debuggers and such.
-
-enum {
-       MAXIO           = 8192,
-       MINFUNC         = 16,   // minimum size for a function
-};
-
-typedef struct Segment Segment;
-typedef struct Section Section;
-
-struct Segment
-{
-       uchar   rwx;            // permission as usual unix bits (5 = r-x etc)
-       uvlong  vaddr;  // virtual address
-       uvlong  length;         // length in memory
-       uvlong  fileoff;        // file offset
-       uvlong  filelen;        // length on disk
-       Section*        sect;
-};
-
-struct Section
-{
-       uchar   rwx;
-       int16   extnum;
-       int32   align;
-       char    *name;
-       uvlong  vaddr;
-       uvlong  length;
-       Section *next;  // in segment list
-       Segment *seg;
-       void *elfsect;
-       uvlong  reloff;
-       uvlong  rellen;
-};
-
-extern char    symname[];
-
-EXTERN char*   INITENTRY;
-EXTERN char*   thestring;
-EXTERN LinkArch*       thelinkarch;
-EXTERN char*   outfile;
-EXTERN int     ndynexp;
-EXTERN LSym**  dynexp;
-EXTERN int     nldflag;
-EXTERN char**  ldflag;
-EXTERN int     havedynamic;
-EXTERN int     funcalign;
-EXTERN int     iscgo;
-EXTERN int     elfglobalsymndx;
-extern int     nelfsym;
-EXTERN char*   flag_installsuffix;
-EXTERN int     flag_race;
-EXTERN int flag_shared;
-EXTERN char*   tracksym;
-EXTERN char*   interpreter;
-EXTERN char*   tmpdir;
-EXTERN char*   extld;
-EXTERN char*   extldflags;
-EXTERN int     debug_s; // backup old value of debug['s']
-EXTERN Link*   ctxt;
-EXTERN int32   HEADR;
-EXTERN int32   HEADTYPE;
-EXTERN int32   INITRND;
-EXTERN int64   INITTEXT;
-EXTERN int64   INITDAT;
-EXTERN char*   INITENTRY;              /* entry point */
-EXTERN char*   noname;
-EXTERN char*   paramspace;
-EXTERN int     nerrors;
-
-EXTERN int     linkmode;
-EXTERN int64   liveness;
-
-// for dynexport field of LSym
-enum
-{
-       CgoExportDynamic = 1<<0,
-       CgoExportStatic = 1<<1,
-};
-
-EXTERN Segment segtext;
-EXTERN Segment segrodata;
-EXTERN Segment segdata;
-EXTERN Segment segdwarf;
-
-typedef struct Endian Endian;
-struct Endian
-{
-       uint16  (*e16)(uchar*);
-       uint32  (*e32)(uchar*);
-       uint64  (*e64)(uchar*);
-};
-
-extern Endian be, le;
-
-/* set by call to mywhatsys() */
-extern char*   goroot;
-extern char*   goarch;
-extern char*   goos;
-
-/* whence for ldpkg */
-enum {
-       FileObj = 0,
-       ArchiveObj,
-       Pkgdef
-};
-
-EXTERN char*   headstring;
-
-#pragma        varargck        type    "Y"     LSym*
-#pragma        varargck        type    "Z"     char*
-#pragma        varargck        type    "i"     char*
-
-// buffered output
-
-EXTERN Biobuf  bso;
-
-EXTERN Biobuf  coutbuf;
-void   cput(uint8);
-
-void   Lflag(char *arg);
-int    Yconv(Fmt *fp);
-int    Zconv(Fmt *fp);
-void   addexport(void);
-void   address(void);
-Section*addsection(Segment *seg, char *name, int rwx);
-void   addstrdata(char *name, char *value);
-vlong  addstring(LSym *s, char *str);
-void   asmelfsym(void);
-void   asmplan9sym(void);
-uint16 be16(uchar *b);
-uint32 be32(uchar *b);
-uint64 be64(uchar *b);
-void   callgraph(void);
-void   checkgo(void);
-void   cflush(void);
-void   codeblk(int64 addr, int64 size);
-vlong  cpos(void);
-void   cseek(vlong p);
-void   cwrite(void *buf, int n);
-void   datblk(int64 addr, int64 size);
-int    datcmp(LSym *s1, LSym *s2);
-vlong  datoff(vlong addr);
-void   deadcode(void);
-LSym*  decodetype_arrayelem(LSym *s);
-vlong  decodetype_arraylen(LSym *s);
-LSym*  decodetype_chanelem(LSym *s);
-int    decodetype_funcdotdotdot(LSym *s);
-int    decodetype_funcincount(LSym *s);
-LSym*  decodetype_funcintype(LSym *s, int i);
-int    decodetype_funcoutcount(LSym *s);
-LSym*  decodetype_funcouttype(LSym *s, int i);
-LSym*  decodetype_gcprog(LSym *s);
-uint8* decodetype_gcmask(LSym *s);
-vlong  decodetype_ifacemethodcount(LSym *s);
-uint8  decodetype_kind(LSym *s);
-uint8  decodetype_noptr(LSym *s);
-uint8  decodetype_usegcprog(LSym *s);
-LSym*  decodetype_mapkey(LSym *s);
-LSym*  decodetype_mapvalue(LSym *s);
-LSym*  decodetype_ptrelem(LSym *s);
-vlong  decodetype_size(LSym *s);
-int    decodetype_structfieldcount(LSym *s);
-char*  decodetype_structfieldname(LSym *s, int i);
-vlong  decodetype_structfieldoffs(LSym *s, int i);
-LSym*  decodetype_structfieldtype(LSym *s, int i);
-void   dodata(void);
-void   dostkcheck(void);
-void   dostkoff(void);
-void   dosymtype(void);
-void   doversion(void);
-void   doweak(void);
-void   dynreloc(void);
-void   dynrelocsym(LSym *s);
-vlong  entryvalue(void);
-void   errorexit(void);
-void   follow(void);
-void   genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*));
-void   gentext(void);
-void   growdatsize(vlong *datsizep, LSym *s);
-char*  headstr(int v);
-int    headtype(char *name);
-void   hostlink(void);
-void   hostobjs(void);
-int    iconv(Fmt *fp);
-void   importcycles(void);
-void   linkarchinit(void);
-void   ldelf(Biobuf *f, char *pkg, int64 length, char *pn);
-void   ldhostobj(void (*ld)(Biobuf*, char*, int64, char*), Biobuf *f, char *pkg, int64 length, char *pn, char *file);
-void   ldmacho(Biobuf *f, char *pkg, int64 length, char *pn);
-void   ldobj(Biobuf *f, char *pkg, int64 length, char *pn, char *file, int whence);
-void   ldpe(Biobuf *f, char *pkg, int64 length, char *pn);
-void   ldpkg(Biobuf *f, char *pkg, int64 length, char *filename, int whence);
-uint16 le16(uchar *b);
-uint32 le32(uchar *b);
-uint64 le64(uchar *b);
-void   libinit(void);
-LSym*  listsort(LSym *l, int (*cmp)(LSym*, LSym*), LSym** (*nextp)(LSym*));
-LSym** listnextp(LSym*);
-LSym** listsubp(LSym*);
-void   loadinternal(char *name);
-void   loadlib(void);
-void   lputb(uint32 l);
-void   lputl(uint32 l);
-void*  mal(uint32 n);
-void   mark(LSym *s);
-void   mywhatsys(void);
-void   objfile(char *file, char *pkg);
-void   patch(void);
-int    pathchar(void);
-void   pcln(void);
-void   pclntab(void);
-void   findfunctab(void);
-void   putelfsectionsym(LSym* s, int shndx);
-void   putelfsymshndx(vlong sympos, int shndx);
-void   putsymb(LSym *s, char *name, int t, vlong v, vlong size, int ver, LSym *typ);
-int    rbyoff(const void *va, const void *vb);
-void   reloc(void);
-void   relocsym(LSym *s);
-void   setheadtype(char *s);
-void   setinterp(char *s);
-void   setlinkmode(char *arg);
-void   span(void);
-void   strnput(char *s, int n);
-vlong  symaddr(LSym *s);
-void   symtab(void);
-void   textaddress(void);
-void   undef(void);
-void   unmal(void *v, uint32 n);
-void   usage(void);
-void   vputb(uint64 v);
-int    valuecmp(LSym *a, LSym *b);
-void   vputl(uint64 v);
-void   wputb(ushort w);
-void   wputl(ushort w);
-void   xdefine(char *p, int t, vlong v);
-void   zerosig(char *sp);
-void   archinit(void);
-void   diag(char *fmt, ...);
-
-void   ldmain(int, char**);
-
-#pragma        varargck        argpos  diag    1
-
diff --git a/src/cmd/ld/macho.c b/src/cmd/ld/macho.c
deleted file mode 100644 (file)
index 6ce5c0d..0000000
+++ /dev/null
@@ -1,785 +0,0 @@
-// 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.
-
-// Mach-O file writing
-// http://developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <link.h>
-#include "dwarf.h"
-#include "lib.h"
-#include "macho.h"
-
-static int     macho64;
-static MachoHdr        machohdr;
-static MachoLoad       *load;
-static MachoSeg        seg[16];
-static int     nload, mload, nseg, ndebug, nsect;
-
-enum
-{
-       SymKindLocal = 0,
-       SymKindExtdef,
-       SymKindUndef,
-       NumSymKind
-};
-
-static int nkind[NumSymKind];
-static LSym** sortsym;
-static int     nsortsym;
-
-// Amount of space left for adding load commands
-// that refer to dynamic libraries.  Because these have
-// to go in the Mach-O header, we can't just pick a
-// "big enough" header size.  The initial header is 
-// one page, the non-dynamic library stuff takes
-// up about 1300 bytes; we overestimate that as 2k.
-static int     load_budget = INITIAL_MACHO_HEADR - 2*1024;
-
-static void    machodysymtab(void);
-
-void
-machoinit(void)
-{
-       switch(thearch.thechar) {
-       // 64-bit architectures
-       case '6':
-       case '9':
-               macho64 = 1;
-               break;
-
-       // 32-bit architectures
-       default:
-               break;
-       }
-}
-
-MachoHdr*
-getMachoHdr(void)
-{
-       return &machohdr;
-}
-
-MachoLoad*
-newMachoLoad(uint32 type, uint32 ndata)
-{
-       MachoLoad *l;
-
-       if(nload >= mload) {
-               if(mload == 0)
-                       mload = 1;
-               else
-                       mload *= 2;
-               load = erealloc(load, mload*sizeof load[0]);
-       }
-
-       if(macho64 && (ndata & 1))
-               ndata++;
-       
-       l = &load[nload++];
-       l->type = type;
-       l->ndata = ndata;
-       l->data = mal(ndata*4);
-       return l;
-}
-
-MachoSeg*
-newMachoSeg(char *name, int msect)
-{
-       MachoSeg *s;
-
-       if(nseg >= nelem(seg)) {
-               diag("too many segs");
-               errorexit();
-       }
-       s = &seg[nseg++];
-       s->name = name;
-       s->msect = msect;
-       s->sect = mal(msect*sizeof s->sect[0]);
-       return s;
-}
-
-MachoSect*
-newMachoSect(MachoSeg *seg, char *name, char *segname)
-{
-       MachoSect *s;
-
-       if(seg->nsect >= seg->msect) {
-               diag("too many sects in segment %s", seg->name);
-               errorexit();
-       }
-       s = &seg->sect[seg->nsect++];
-       s->name = name;
-       s->segname = segname;
-       nsect++;
-       return s;
-}
-
-// Generic linking code.
-
-static char **dylib;
-static int ndylib;
-
-static vlong linkoff;
-
-int
-machowrite(void)
-{
-       vlong o1;
-       int loadsize;
-       int i, j;
-       MachoSeg *s;
-       MachoSect *t;
-       MachoLoad *l;
-
-       o1 = cpos();
-
-       loadsize = 4*4*ndebug;
-       for(i=0; i<nload; i++)
-               loadsize += 4*(load[i].ndata+2);
-       if(macho64) {
-               loadsize += 18*4*nseg;
-               loadsize += 20*4*nsect;
-       } else {
-               loadsize += 14*4*nseg;
-               loadsize += 17*4*nsect;
-       }
-
-       if(macho64)
-               thearch.lput(0xfeedfacf);
-       else
-               thearch.lput(0xfeedface);
-       thearch.lput(machohdr.cpu);
-       thearch.lput(machohdr.subcpu);
-       if(linkmode == LinkExternal)
-               thearch.lput(1);        /* file type - mach object */
-       else
-               thearch.lput(2);        /* file type - mach executable */
-       thearch.lput(nload+nseg+ndebug);
-       thearch.lput(loadsize);
-       thearch.lput(1);        /* flags - no undefines */
-       if(macho64)
-               thearch.lput(0);        /* reserved */
-
-       for(i=0; i<nseg; i++) {
-               s = &seg[i];
-               if(macho64) {
-                       thearch.lput(25);       /* segment 64 */
-                       thearch.lput(72+80*s->nsect);
-                       strnput(s->name, 16);
-                       thearch.vput(s->vaddr);
-                       thearch.vput(s->vsize);
-                       thearch.vput(s->fileoffset);
-                       thearch.vput(s->filesize);
-                       thearch.lput(s->prot1);
-                       thearch.lput(s->prot2);
-                       thearch.lput(s->nsect);
-                       thearch.lput(s->flag);
-               } else {
-                       thearch.lput(1);        /* segment 32 */
-                       thearch.lput(56+68*s->nsect);
-                       strnput(s->name, 16);
-                       thearch.lput(s->vaddr);
-                       thearch.lput(s->vsize);
-                       thearch.lput(s->fileoffset);
-                       thearch.lput(s->filesize);
-                       thearch.lput(s->prot1);
-                       thearch.lput(s->prot2);
-                       thearch.lput(s->nsect);
-                       thearch.lput(s->flag);
-               }
-               for(j=0; j<s->nsect; j++) {
-                       t = &s->sect[j];
-                       if(macho64) {
-                               strnput(t->name, 16);
-                               strnput(t->segname, 16);
-                               thearch.vput(t->addr);
-                               thearch.vput(t->size);
-                               thearch.lput(t->off);
-                               thearch.lput(t->align);
-                               thearch.lput(t->reloc);
-                               thearch.lput(t->nreloc);
-                               thearch.lput(t->flag);
-                               thearch.lput(t->res1);  /* reserved */
-                               thearch.lput(t->res2);  /* reserved */
-                               thearch.lput(0);        /* reserved */
-                       } else {
-                               strnput(t->name, 16);
-                               strnput(t->segname, 16);
-                               thearch.lput(t->addr);
-                               thearch.lput(t->size);
-                               thearch.lput(t->off);
-                               thearch.lput(t->align);
-                               thearch.lput(t->reloc);
-                               thearch.lput(t->nreloc);
-                               thearch.lput(t->flag);
-                               thearch.lput(t->res1);  /* reserved */
-                               thearch.lput(t->res2);  /* reserved */
-                       }
-               }
-       }
-
-       for(i=0; i<nload; i++) {
-               l = &load[i];
-               thearch.lput(l->type);
-               thearch.lput(4*(l->ndata+2));
-               for(j=0; j<l->ndata; j++)
-                       thearch.lput(l->data[j]);
-       }
-
-       return cpos() - o1;
-}
-
-void
-domacho(void)
-{
-       LSym *s;
-
-       if(debug['d'])
-               return;
-
-       // empirically, string table must begin with " \x00".
-       s = linklookup(ctxt, ".machosymstr", 0);
-       s->type = SMACHOSYMSTR;
-       s->reachable = 1;
-       adduint8(ctxt, s, ' ');
-       adduint8(ctxt, s, '\x00');
-       
-       s = linklookup(ctxt, ".machosymtab", 0);
-       s->type = SMACHOSYMTAB;
-       s->reachable = 1;
-       
-       if(linkmode != LinkExternal) {
-               s = linklookup(ctxt, ".plt", 0);        // will be __symbol_stub
-               s->type = SMACHOPLT;
-               s->reachable = 1;
-       
-               s = linklookup(ctxt, ".got", 0);        // will be __nl_symbol_ptr
-               s->type = SMACHOGOT;
-               s->reachable = 1;
-               s->align = 4;
-       
-               s = linklookup(ctxt, ".linkedit.plt", 0);       // indirect table for .plt
-               s->type = SMACHOINDIRECTPLT;
-               s->reachable = 1;
-       
-               s = linklookup(ctxt, ".linkedit.got", 0);       // indirect table for .got
-               s->type = SMACHOINDIRECTGOT;
-               s->reachable = 1;
-       }
-}
-
-void
-machoadddynlib(char *lib)
-{
-       // Will need to store the library name rounded up
-       // and 24 bytes of header metadata.  If not enough
-       // space, grab another page of initial space at the
-       // beginning of the output file.
-       load_budget -= (strlen(lib)+7)/8*8 + 24;
-       if(load_budget < 0) {
-               HEADR += 4096;
-               INITTEXT += 4096;
-               load_budget += 4096;
-       }
-
-       if(ndylib%32 == 0)
-               dylib = erealloc(dylib, (ndylib+32)*sizeof dylib[0]);
-       dylib[ndylib++] = lib;
-}
-
-static void
-machoshbits(MachoSeg *mseg, Section *sect, char *segname)
-{
-       MachoSect *msect;
-       char buf[40];
-       char *p;
-       
-       snprint(buf, sizeof buf, "__%s", sect->name+1);
-       for(p=buf; *p; p++)
-               if(*p == '.')
-                       *p = '_';
-
-       msect = newMachoSect(mseg, estrdup(buf), segname);
-       if(sect->rellen > 0) {
-               msect->reloc = sect->reloff;
-               msect->nreloc = sect->rellen / 8;
-       }
-
-       while(1<<msect->align < sect->align)
-               msect->align++;
-       msect->addr = sect->vaddr;
-       msect->size = sect->length;
-       
-       if(sect->vaddr < sect->seg->vaddr + sect->seg->filelen) {
-               // data in file
-               if(sect->length > sect->seg->vaddr + sect->seg->filelen - sect->vaddr)
-                       diag("macho cannot represent section %s crossing data and bss", sect->name);
-               msect->off = sect->seg->fileoff + sect->vaddr - sect->seg->vaddr;
-       } else {
-               // zero fill
-               msect->off = 0;
-               msect->flag |= 1;
-       }
-
-       if(sect->rwx & 1)
-               msect->flag |= 0x400; /* has instructions */
-       
-       if(strcmp(sect->name, ".plt") == 0) {
-               msect->name = "__symbol_stub1";
-               msect->flag = 0x80000408; /* only instructions, code, symbol stubs */
-               msect->res1 = 0;//nkind[SymKindLocal];
-               msect->res2 = 6;
-       }
-
-       if(strcmp(sect->name, ".got") == 0) {
-               msect->name = "__nl_symbol_ptr";
-               msect->flag = 6;        /* section with nonlazy symbol pointers */
-               msect->res1 = linklookup(ctxt, ".linkedit.plt", 0)->size / 4;   /* offset into indirect symbol table */
-       }
-}
-
-void
-asmbmacho(void)
-{
-       vlong v, w;
-       vlong va;
-       int a, i;
-       MachoHdr *mh;
-       MachoSeg *ms;
-       MachoLoad *ml;
-       Section *sect;
-
-       /* apple MACH */
-       va = INITTEXT - HEADR;
-       mh = getMachoHdr();
-       switch(thearch.thechar){
-       default:
-               diag("unknown mach architecture");
-               errorexit();
-       case '5':
-               mh->cpu = MACHO_CPU_ARM;
-               mh->subcpu = MACHO_SUBCPU_ARMV7;
-               break;
-       case '6':
-               mh->cpu = MACHO_CPU_AMD64;
-               mh->subcpu = MACHO_SUBCPU_X86;
-               break;
-       case '8':
-               mh->cpu = MACHO_CPU_386;
-               mh->subcpu = MACHO_SUBCPU_X86;
-               break;
-       }
-       
-       ms = nil;
-       if(linkmode == LinkExternal) {
-               /* segment for entire file */
-               ms = newMachoSeg("", 40);
-               ms->fileoffset = segtext.fileoff;
-               ms->filesize = segdata.fileoff + segdata.filelen - segtext.fileoff;
-       }
-
-       /* segment for zero page */
-       if(linkmode != LinkExternal) {
-               ms = newMachoSeg("__PAGEZERO", 0);
-               ms->vsize = va;
-       }
-
-       /* text */
-       v = rnd(HEADR+segtext.length, INITRND);
-       if(linkmode != LinkExternal) {
-               ms = newMachoSeg("__TEXT", 20);
-               ms->vaddr = va;
-               ms->vsize = v;
-               ms->fileoffset = 0;
-               ms->filesize = v;
-               ms->prot1 = 7;
-               ms->prot2 = 5;
-       }
-
-       for(sect=segtext.sect; sect!=nil; sect=sect->next)
-               machoshbits(ms, sect, "__TEXT");
-
-       /* data */
-       if(linkmode != LinkExternal) {
-               w = segdata.length;
-               ms = newMachoSeg("__DATA", 20);
-               ms->vaddr = va+v;
-               ms->vsize = w;
-               ms->fileoffset = v;
-               ms->filesize = segdata.filelen;
-               ms->prot1 = 3;
-               ms->prot2 = 3;
-       }
-
-       for(sect=segdata.sect; sect!=nil; sect=sect->next)
-               machoshbits(ms, sect, "__DATA");
-
-       if(linkmode != LinkExternal) {
-               switch(thearch.thechar) {
-               default:
-                       diag("unknown macho architecture");
-                       errorexit();
-               case '5':
-                       ml = newMachoLoad(5, 17+2);     /* unix thread */
-                       ml->data[0] = 1;        /* thread type */
-                       ml->data[1] = 17;       /* word count */
-                       ml->data[2+15] = entryvalue();  /* start pc */
-                       break;
-               case '6':
-                       ml = newMachoLoad(5, 42+2);     /* unix thread */
-                       ml->data[0] = 4;        /* thread type */
-                       ml->data[1] = 42;       /* word count */
-                       ml->data[2+32] = entryvalue();  /* start pc */
-                       ml->data[2+32+1] = entryvalue()>>16>>16;        // hide >>32 for 8l
-                       break;
-               case '8':
-                       ml = newMachoLoad(5, 16+2);     /* unix thread */
-                       ml->data[0] = 1;        /* thread type */
-                       ml->data[1] = 16;       /* word count */
-                       ml->data[2+10] = entryvalue();  /* start pc */
-                       break;
-               }
-       }
-       
-       if(!debug['d']) {
-               LSym *s1, *s2, *s3, *s4;
-
-               // must match domacholink below
-               s1 = linklookup(ctxt, ".machosymtab", 0);
-               s2 = linklookup(ctxt, ".linkedit.plt", 0);
-               s3 = linklookup(ctxt, ".linkedit.got", 0);
-               s4 = linklookup(ctxt, ".machosymstr", 0);
-
-               if(linkmode != LinkExternal) {
-                       ms = newMachoSeg("__LINKEDIT", 0);
-                       ms->vaddr = va+v+rnd(segdata.length, INITRND);
-                       ms->vsize = s1->size + s2->size + s3->size + s4->size;
-                       ms->fileoffset = linkoff;
-                       ms->filesize = ms->vsize;
-                       ms->prot1 = 7;
-                       ms->prot2 = 3;
-               }
-
-               ml = newMachoLoad(2, 4);        /* LC_SYMTAB */
-               ml->data[0] = linkoff;  /* symoff */
-               ml->data[1] = nsortsym; /* nsyms */
-               ml->data[2] = linkoff + s1->size + s2->size + s3->size; /* stroff */
-               ml->data[3] = s4->size; /* strsize */
-
-               machodysymtab();
-
-               if(linkmode != LinkExternal) {
-                       ml = newMachoLoad(14, 6);       /* LC_LOAD_DYLINKER */
-                       ml->data[0] = 12;       /* offset to string */
-                       strcpy((char*)&ml->data[1], "/usr/lib/dyld");
-       
-                       for(i=0; i<ndylib; i++) {
-                               ml = newMachoLoad(12, 4+(strlen(dylib[i])+1+7)/8*2);    /* LC_LOAD_DYLIB */
-                               ml->data[0] = 24;       /* offset of string from beginning of load */
-                               ml->data[1] = 0;        /* time stamp */
-                               ml->data[2] = 0;        /* version */
-                               ml->data[3] = 0;        /* compatibility version */
-                               strcpy((char*)&ml->data[4], dylib[i]);
-                       }
-               }
-       }
-
-       // TODO: dwarf headers go in ms too
-       if(!debug['s'] && linkmode != LinkExternal)
-               dwarfaddmachoheaders();
-
-       a = machowrite();
-       if(a > HEADR)
-               diag("HEADR too small: %d > %d", a, HEADR);
-}
-
-static int
-symkind(LSym *s)
-{
-       if(s->type == SDYNIMPORT)
-               return SymKindUndef;
-       if(s->cgoexport)
-               return SymKindExtdef;
-       return SymKindLocal;
-}
-
-static void
-addsym(LSym *s, char *name, int type, vlong addr, vlong size, int ver, LSym *gotype)
-{
-       USED(name);
-       USED(addr);
-       USED(size);
-       USED(ver);
-       USED(gotype);
-
-       if(s == nil)
-               return;
-
-       switch(type) {
-       default:
-               return;
-       case 'D':
-       case 'B':
-       case 'T':
-               break;
-       }
-       
-       if(sortsym) {
-               sortsym[nsortsym] = s;
-               nkind[symkind(s)]++;
-       }
-       nsortsym++;
-}
-       
-static int
-machoscmp(const void *p1, const void *p2)
-{
-       LSym *s1, *s2;
-       int k1, k2;
-
-       s1 = *(LSym**)p1;
-       s2 = *(LSym**)p2;
-       
-       k1 = symkind(s1);
-       k2 = symkind(s2);
-       if(k1 != k2)
-               return k1 - k2;
-
-       return strcmp(s1->extname, s2->extname);
-}
-
-static void
-machogenasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*))
-{
-       LSym *s;
-
-       genasmsym(put);
-       for(s=ctxt->allsym; s; s=s->allsym)
-               if(s->type == SDYNIMPORT || s->type == SHOSTOBJ)
-               if(s->reachable)
-                       put(s, nil, 'D', 0, 0, 0, nil);
-}
-                       
-void
-machosymorder(void)
-{
-       int i;
-
-       // On Mac OS X Mountain Lion, we must sort exported symbols
-       // So we sort them here and pre-allocate dynid for them
-       // See http://golang.org/issue/4029
-       for(i=0; i<ndynexp; i++)
-               dynexp[i]->reachable = 1;
-       machogenasmsym(addsym);
-       sortsym = mal(nsortsym * sizeof sortsym[0]);
-       nsortsym = 0;
-       machogenasmsym(addsym);
-       qsort(sortsym, nsortsym, sizeof sortsym[0], machoscmp);
-       for(i=0; i<nsortsym; i++)
-               sortsym[i]->dynid = i;
-}
-
-static void
-machosymtab(void)
-{
-       int i;
-       LSym *symtab, *symstr, *s, *o;
-       char *p;
-
-       symtab = linklookup(ctxt, ".machosymtab", 0);
-       symstr = linklookup(ctxt, ".machosymstr", 0);
-
-       for(i=0; i<nsortsym; i++) {
-               s = sortsym[i];
-               adduint32(ctxt, symtab, symstr->size);
-               
-               // Only add _ to C symbols. Go symbols have dot in the name.
-               if(strstr(s->extname, ".") == nil)
-                       adduint8(ctxt, symstr, '_');
-               // replace "·" as ".", because DTrace cannot handle it.
-               if(strstr(s->extname, "·") == nil) {
-                       addstring(symstr, s->extname);
-               } else {
-                       for(p = s->extname; *p; p++) {
-                               if((uchar)*p == 0xc2 && (uchar)*(p+1) == 0xb7) {
-                                       adduint8(ctxt, symstr, '.');
-                                       p++;
-                               } else {
-                                       adduint8(ctxt, symstr, *p);
-                               }
-                       }
-                       adduint8(ctxt, symstr, '\x00');
-               }
-               if(s->type == SDYNIMPORT || s->type == SHOSTOBJ) {
-                       adduint8(ctxt, symtab, 0x01); // type N_EXT, external symbol
-                       adduint8(ctxt, symtab, 0); // no section
-                       adduint16(ctxt, symtab, 0); // desc
-                       adduintxx(ctxt, symtab, 0, thearch.ptrsize); // no value
-               } else {
-                       if(s->cgoexport)
-                               adduint8(ctxt, symtab, 0x0f);
-                       else
-                               adduint8(ctxt, symtab, 0x0e);
-                       o = s;
-                       while(o->outer != nil)
-                               o = o->outer;
-                       if(o->sect == nil) {
-                               diag("missing section for %s", s->name);
-                               adduint8(ctxt, symtab, 0);
-                       } else
-                               adduint8(ctxt, symtab, ((Section*)o->sect)->extnum);
-                       adduint16(ctxt, symtab, 0); // desc
-                       adduintxx(ctxt, symtab, symaddr(s), thearch.ptrsize);
-               }
-       }
-}
-
-static void
-machodysymtab(void)
-{
-       int n;
-       MachoLoad *ml;
-       LSym *s1, *s2, *s3;
-
-       ml = newMachoLoad(11, 18);      /* LC_DYSYMTAB */
-
-       n = 0;
-       ml->data[0] = n;        /* ilocalsym */
-       ml->data[1] = nkind[SymKindLocal];      /* nlocalsym */
-       n += nkind[SymKindLocal];
-
-       ml->data[2] = n;        /* iextdefsym */
-       ml->data[3] = nkind[SymKindExtdef];     /* nextdefsym */
-       n += nkind[SymKindExtdef];
-
-       ml->data[4] = n;        /* iundefsym */
-       ml->data[5] = nkind[SymKindUndef];      /* nundefsym */
-
-       ml->data[6] = 0;        /* tocoffset */
-       ml->data[7] = 0;        /* ntoc */
-       ml->data[8] = 0;        /* modtaboff */
-       ml->data[9] = 0;        /* nmodtab */
-       ml->data[10] = 0;       /* extrefsymoff */
-       ml->data[11] = 0;       /* nextrefsyms */
-
-       // must match domacholink below
-       s1 = linklookup(ctxt, ".machosymtab", 0);
-       s2 = linklookup(ctxt, ".linkedit.plt", 0);
-       s3 = linklookup(ctxt, ".linkedit.got", 0);
-       ml->data[12] = linkoff + s1->size;      /* indirectsymoff */
-       ml->data[13] = (s2->size + s3->size) / 4;       /* nindirectsyms */
-
-       ml->data[14] = 0;       /* extreloff */
-       ml->data[15] = 0;       /* nextrel */
-       ml->data[16] = 0;       /* locreloff */
-       ml->data[17] = 0;       /* nlocrel */
-}
-
-vlong
-domacholink(void)
-{
-       int size;
-       LSym *s1, *s2, *s3, *s4;
-
-       machosymtab();
-
-       // write data that will be linkedit section
-       s1 = linklookup(ctxt, ".machosymtab", 0);
-       s2 = linklookup(ctxt, ".linkedit.plt", 0);
-       s3 = linklookup(ctxt, ".linkedit.got", 0);
-       s4 = linklookup(ctxt, ".machosymstr", 0);
-
-       // Force the linkedit section to end on a 16-byte
-       // boundary.  This allows pure (non-cgo) Go binaries
-       // to be code signed correctly.
-       //
-       // Apple's codesign_allocate (a helper utility for
-       // the codesign utility) can do this fine itself if
-       // it is run on a dynamic Mach-O binary.  However,
-       // when it is run on a pure (non-cgo) Go binary, where
-       // the linkedit section is mostly empty, it fails to
-       // account for the extra padding that it itself adds
-       // when adding the LC_CODE_SIGNATURE load command
-       // (which must be aligned on a 16-byte boundary).
-       //
-       // By forcing the linkedit section to end on a 16-byte
-       // boundary, codesign_allocate will not need to apply
-       // any alignment padding itself, working around the
-       // issue.
-       while(s4->size%16)
-               adduint8(ctxt, s4, 0);
-       
-       size = s1->size + s2->size + s3->size + s4->size;
-
-       if(size > 0) {
-               linkoff = rnd(HEADR+segtext.length, INITRND) + rnd(segdata.filelen, INITRND) + rnd(segdwarf.filelen, INITRND);
-               cseek(linkoff);
-
-               cwrite(s1->p, s1->size);
-               cwrite(s2->p, s2->size);
-               cwrite(s3->p, s3->size);
-               cwrite(s4->p, s4->size);
-       }
-
-       return rnd(size, INITRND);
-}
-
-
-void
-machorelocsect(Section *sect, LSym *first)
-{
-       LSym *sym;
-       int32 eaddr;
-       int ri;
-       Reloc *r;
-
-       // If main section has no bits, nothing to relocate.
-       if(sect->vaddr >= sect->seg->vaddr + sect->seg->filelen)
-               return;
-       
-       sect->reloff = cpos();
-       for(sym = first; sym != nil; sym = sym->next) {
-               if(!sym->reachable)
-                       continue;
-               if(sym->value >= sect->vaddr)
-                       break;
-       }
-       
-       eaddr = sect->vaddr + sect->length;
-       for(; sym != nil; sym = sym->next) {
-               if(!sym->reachable)
-                       continue;
-               if(sym->value >= eaddr)
-                       break;
-               ctxt->cursym = sym;
-               
-               for(ri=0; ri<sym->nr; ri++) {
-                       r = &sym->r[ri];
-                       if(r->done)
-                               continue;
-                       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);
-               }
-       }
-               
-       sect->rellen = cpos() - sect->reloff;
-}
-
-void
-machoemitreloc(void)
-{
-       Section *sect;
-
-       while(cpos()&7)
-               cput(0);
-
-       machorelocsect(segtext.sect, ctxt->textp);
-       for(sect=segtext.sect->next; sect!=nil; sect=sect->next)
-               machorelocsect(sect, datap);    
-       for(sect=segdata.sect; sect!=nil; sect=sect->next)
-               machorelocsect(sect, datap);    
-}
diff --git a/src/cmd/ld/macho.h b/src/cmd/ld/macho.h
deleted file mode 100644 (file)
index 32f905a..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-// 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.
-
-typedef struct MachoHdr MachoHdr;
-struct MachoHdr {
-       uint32  cpu;
-       uint32  subcpu;
-};
-
-typedef struct MachoSect MachoSect;
-struct MachoSect {
-       char*   name;
-       char*   segname;
-       uint64  addr;
-       uint64  size;
-       uint32  off;
-       uint32  align;
-       uint32  reloc;
-       uint32  nreloc;
-       uint32  flag;
-       uint32  res1;
-       uint32  res2;
-};
-
-typedef struct MachoSeg MachoSeg;
-struct MachoSeg {
-       char*   name;
-       uint64  vsize;
-       uint64  vaddr;
-       uint64  fileoffset;
-       uint64  filesize;
-       uint32  prot1;
-       uint32  prot2;
-       uint32  nsect;
-       uint32  msect;
-       MachoSect       *sect;
-       uint32  flag;
-};
-
-typedef struct MachoLoad MachoLoad;
-struct MachoLoad {
-       uint32  type;
-       uint32  ndata;
-       uint32  *data;
-};
-
-MachoHdr*      getMachoHdr(void);
-MachoSeg*      newMachoSeg(char*, int);
-MachoSect*     newMachoSect(MachoSeg*, char*, char*);
-MachoLoad*     newMachoLoad(uint32, uint32);
-int    machowrite(void);
-void   machoinit(void);
-void   machosymorder(void);
-void   machoemitreloc(void);
-
-/*
- * Total amount of space to reserve at the start of the file
- * for Header, PHeaders, and SHeaders.
- * May waste some.
- */
-enum {
-       INITIAL_MACHO_HEADR     = 4*1024,
-};
-
-enum {
-       MACHO_CPU_AMD64 = (1<<24)|7,
-       MACHO_CPU_386 = 7,
-       MACHO_SUBCPU_X86 = 3,
-       MACHO_CPU_ARM = 12,
-       MACHO_SUBCPU_ARM = 0,
-       MACHO_SUBCPU_ARMV7 = 9,
-
-       MACHO32SYMSIZE = 12,
-       MACHO64SYMSIZE = 16,
-       
-       MACHO_X86_64_RELOC_UNSIGNED = 0,
-       MACHO_X86_64_RELOC_SIGNED = 1,
-       MACHO_X86_64_RELOC_BRANCH = 2,
-       MACHO_X86_64_RELOC_GOT_LOAD = 3,
-       MACHO_X86_64_RELOC_GOT = 4,
-       MACHO_X86_64_RELOC_SUBTRACTOR = 5,
-       MACHO_X86_64_RELOC_SIGNED_1 = 6,
-       MACHO_X86_64_RELOC_SIGNED_2 = 7,
-       MACHO_X86_64_RELOC_SIGNED_4 = 8,
-       
-       MACHO_ARM_RELOC_VANILLA = 0,
-       MACHO_ARM_RELOC_BR24 = 5,
-       
-       MACHO_GENERIC_RELOC_VANILLA = 0,
-       
-       MACHO_FAKE_GOTPCREL = 100,
-};
-
-void   domacho(void);
-vlong  domacholink(void);
-void   asmbmacho(void);
-void   machoadddynlib(char*);
diff --git a/src/cmd/ld/pcln.c b/src/cmd/ld/pcln.c
deleted file mode 100644 (file)
index adb7661..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright 2013 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       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-#include       "lib.h"
-#include       "../../runtime/funcdata.h"
-
-static void
-addvarint(Pcdata *d, uint32 val)
-{
-       int32 n;
-       uint32 v;
-       uchar *p;
-
-       n = 0;
-       for(v = val; v >= 0x80; v >>= 7)
-               n++;
-       n++;
-
-       if(d->n + n > d->m) {
-               d->m = (d->n + n)*2;
-               d->p = erealloc(d->p, d->m);
-       }
-
-       p = d->p + d->n;
-       for(v = val; v >= 0x80; v >>= 7)
-               *p++ = v | 0x80;
-       *p = v;
-       d->n += n;
-}
-
-static int32
-addpctab(LSym *ftab, int32 off, Pcdata *d)
-{
-       int32 start;
-       
-       start = ftab->np;
-       symgrow(ctxt, ftab, start + d->n);
-       memmove(ftab->p + start, d->p, d->n);
-       
-       return setuint32(ctxt, ftab, off, start);
-}
-
-static int32
-ftabaddstring(LSym *ftab, char *s)
-{
-       int32 n, start;
-       
-       n = strlen(s)+1;
-       start = ftab->np;
-       symgrow(ctxt, ftab, start+n+1);
-       strcpy((char*)ftab->p + start, s);
-       return start;
-}
-
-static void
-renumberfiles(Link *ctxt, LSym **files, int nfiles, Pcdata *d)
-{
-       int i;
-       LSym *f;
-       Pcdata out;
-       Pciter it;
-       uint32 v;
-       int32 oldval, newval, val, dv;
-       
-       // Give files numbers.
-       for(i=0; i<nfiles; i++) {
-               f = files[i];
-               if(f->type != SFILEPATH) {
-                       f->value = ++ctxt->nhistfile;
-                       f->type = SFILEPATH;
-                       f->next = ctxt->filesyms;
-                       ctxt->filesyms = f;
-               }
-       }
-
-       newval = -1;
-       memset(&out, 0, sizeof out);
-
-       for(pciterinit(ctxt, &it, d); !it.done; pciternext(&it)) {
-               // value delta
-               oldval = it.value;
-               if(oldval == -1)
-                       val = -1;
-               else {  
-                       if(oldval < 0 || oldval >= nfiles)
-                               sysfatal("bad pcdata %d", oldval);
-                       val = files[oldval]->value;
-               }
-               dv = val - newval;
-               newval = val;
-               v = ((uint32)dv<<1) ^ (uint32)(int32)(dv>>31);
-               addvarint(&out, v);
-
-               // pc delta
-               addvarint(&out, (it.nextpc - it.pc) / it.pcscale);
-       }
-       
-       // terminating value delta
-       addvarint(&out, 0);
-
-       free(d->p);
-       *d = out;       
-}
-
-static int
-container(LSym *s)
-{
-       // We want to generate func table entries only for the "lowest level" symbols,
-       // not containers of subsymbols.
-       if(s != nil && s->sub != nil)
-               return 1;
-       return 0;
-}
-
-// pclntab initializes the pclntab symbol with
-// runtime function and file name information.
-void
-pclntab(void)
-{
-       int32 i, nfunc, start, funcstart;
-       LSym *ftab, *s, *last;
-       int32 off, end, frameptrsize;
-       int64 funcdata_bytes;
-       Pcln *pcln;
-       Pciter it;
-       static Pcln zpcln;
-       
-       funcdata_bytes = 0;
-       ftab = linklookup(ctxt, "runtime.pclntab", 0);
-       ftab->type = SPCLNTAB;
-       ftab->reachable = 1;
-
-       // See golang.org/s/go12symtab for the format. Briefly:
-       //      8-byte header
-       //      nfunc [thearch.ptrsize bytes]
-       //      function table, alternating PC and offset to func struct [each entry thearch.ptrsize bytes]
-       //      end PC [thearch.ptrsize bytes]
-       //      offset to file table [4 bytes]
-       nfunc = 0;
-       for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next) {
-               if(!container(ctxt->cursym))
-                       nfunc++;
-       }
-       symgrow(ctxt, ftab, 8+thearch.ptrsize+nfunc*2*thearch.ptrsize+thearch.ptrsize+4);
-       setuint32(ctxt, ftab, 0, 0xfffffffb);
-       setuint8(ctxt, ftab, 6, thearch.minlc);
-       setuint8(ctxt, ftab, 7, thearch.ptrsize);
-       setuintxx(ctxt, ftab, 8, nfunc, thearch.ptrsize);
-
-       nfunc = 0;
-       last = nil;
-       for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next) {
-               last = ctxt->cursym;
-               if(container(ctxt->cursym))
-                       continue;
-               pcln = ctxt->cursym->pcln;
-               if(pcln == nil)
-                       pcln = &zpcln;
-       
-               funcstart = ftab->np;
-               funcstart += -ftab->np & (thearch.ptrsize-1);
-
-               setaddr(ctxt, ftab, 8+thearch.ptrsize+nfunc*2*thearch.ptrsize, ctxt->cursym);
-               setuintxx(ctxt, ftab, 8+thearch.ptrsize+nfunc*2*thearch.ptrsize+thearch.ptrsize, funcstart, thearch.ptrsize);
-
-               // fixed size of struct, checked below
-               off = funcstart;
-               end = funcstart + thearch.ptrsize + 3*4 + 5*4 + pcln->npcdata*4 + pcln->nfuncdata*thearch.ptrsize;
-               if(pcln->nfuncdata > 0 && (end&(thearch.ptrsize-1)))
-                       end += 4;
-               symgrow(ctxt, ftab, end);
-
-               // entry uintptr
-               off = setaddr(ctxt, ftab, off, ctxt->cursym);
-
-               // name int32
-               off = setuint32(ctxt, ftab, off, ftabaddstring(ftab, ctxt->cursym->name));
-               
-               // args int32
-               // TODO: Move into funcinfo.
-               off = setuint32(ctxt, ftab, off, ctxt->cursym->args);
-       
-               // frame int32
-               // TODO: Remove entirely. The pcsp table is more precise.
-               // This is only used by a fallback case during stack walking
-               // when a called function doesn't have argument information.
-               // We need to make sure everything has argument information
-               // and then remove this.
-               frameptrsize = thearch.ptrsize;
-               if(ctxt->cursym->leaf)
-                       frameptrsize = 0;
-               off = setuint32(ctxt, ftab, off, ctxt->cursym->locals + frameptrsize);
-               
-               if(pcln != &zpcln) {
-                       renumberfiles(ctxt, pcln->file, pcln->nfile, &pcln->pcfile);
-                       if(0) {
-                               // Sanity check the new numbering
-                               for(pciterinit(ctxt, &it, &pcln->pcfile); !it.done; pciternext(&it)) {
-                                       if(it.value < 1 || it.value > ctxt->nhistfile) {
-                                               diag("bad file number in pcfile: %d not in range [1, %d]\n", it.value, ctxt->nhistfile);
-                                               errorexit();
-                                       }
-                               }
-                       }
-               }
-
-               // pcdata
-               off = addpctab(ftab, off, &pcln->pcsp);
-               off = addpctab(ftab, off, &pcln->pcfile);
-               off = addpctab(ftab, off, &pcln->pcline);
-               off = setuint32(ctxt, ftab, off, pcln->npcdata);
-               off = setuint32(ctxt, ftab, off, pcln->nfuncdata);
-               for(i=0; i<pcln->npcdata; i++)
-                       off = addpctab(ftab, off, &pcln->pcdata[i]);
-
-               // funcdata, must be pointer-aligned and we're only int32-aligned.
-               // Missing funcdata will be 0 (nil pointer).
-               if(pcln->nfuncdata > 0) {
-                       if(off&(thearch.ptrsize-1))
-                               off += 4;
-                       for(i=0; i<pcln->nfuncdata; i++) {
-                               if(pcln->funcdata[i] == nil)
-                                       setuintxx(ctxt, ftab, off+thearch.ptrsize*i, pcln->funcdataoff[i], thearch.ptrsize);
-                               else {
-                                       // TODO: Dedup.
-                                       funcdata_bytes += pcln->funcdata[i]->size;
-                                       setaddrplus(ctxt, ftab, off+thearch.ptrsize*i, pcln->funcdata[i], pcln->funcdataoff[i]);
-                               }
-                       }
-                       off += pcln->nfuncdata*thearch.ptrsize;
-               }
-
-               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, thearch.ptrsize);
-                       errorexit();
-               }
-       
-               nfunc++;
-       }
-       // Final entry of table is just end pc.
-       setaddrplus(ctxt, ftab, 8+thearch.ptrsize+nfunc*2*thearch.ptrsize, last, last->size);
-       
-       // Start file table.
-       start = ftab->np;
-       start += -ftab->np & (thearch.ptrsize-1);
-       setuint32(ctxt, ftab, 8+thearch.ptrsize+nfunc*2*thearch.ptrsize+thearch.ptrsize, start);
-
-       symgrow(ctxt, ftab, start+(ctxt->nhistfile+1)*4);
-       setuint32(ctxt, ftab, start, ctxt->nhistfile);
-       for(s = ctxt->filesyms; s != nil; s = s->next)
-               setuint32(ctxt, ftab, start + s->value*4, ftabaddstring(ftab, s->name));
-
-       ftab->size = ftab->np;
-       
-       if(debug['v'])
-               Bprint(&bso, "%5.2f pclntab=%lld bytes, funcdata total %lld bytes\n", cputime(), (vlong)ftab->size, (vlong)funcdata_bytes);
-}      
-
-enum {
-       BUCKETSIZE = 256*MINFUNC,
-       SUBBUCKETS = 16,
-       SUBBUCKETSIZE = BUCKETSIZE/SUBBUCKETS,
-       NOIDX = 0x7fffffff
-};
-
-// findfunctab generates a lookup table to quickly find the containing
-// function for a pc.  See src/runtime/symtab.go:findfunc for details.
-void
-findfunctab(void)
-{
-       LSym *t, *s, *e;
-       int32 idx, i, j, nbuckets, n, base;
-       vlong min, max, p, q;
-       int32 *indexes;
-
-       t = linklookup(ctxt, "runtime.findfunctab", 0);
-       t->type = SRODATA;
-       t->reachable = 1;
-
-       // find min and max address
-       min = ctxt->textp->value;
-       max = 0;
-       for(s = ctxt->textp; s != nil; s = s->next)
-               max = s->value + s->size;
-
-       // for each subbucket, compute the minimum of all symbol indexes
-       // that map to that subbucket.
-       n = (max-min+SUBBUCKETSIZE-1)/SUBBUCKETSIZE;
-       indexes = (int32*)malloc(n*4);
-       if(indexes == nil) {
-               diag("out of memory");
-               errorexit();
-       }
-       for(i = 0; i < n; i++)
-               indexes[i] = NOIDX;
-       idx = 0;
-       for(s = ctxt->textp; s != nil; s = s->next) {
-               if(container(s))
-                       continue;
-               p = s->value;
-               e = s->next;
-               while(container(e))
-                       e = e->next;
-               if(e != nil)
-                       q = e->value;
-               else
-                       q = max;
-
-               //print("%d: [%lld %lld] %s\n", idx, p, q, s->name);
-               for(; p < q; p += SUBBUCKETSIZE) {
-                       i = (p - min) / SUBBUCKETSIZE;
-                       if(indexes[i] > idx)
-                               indexes[i] = idx;
-               }
-               i = (q - 1 - min) / SUBBUCKETSIZE;
-               if(indexes[i] > idx)
-                       indexes[i] = idx;
-               idx++;
-       }
-
-       // allocate table
-       nbuckets = (max-min+BUCKETSIZE-1)/BUCKETSIZE;
-       symgrow(ctxt, t, 4*nbuckets + n);
-
-       // fill in table
-       for(i = 0; i < nbuckets; i++) {
-               base = indexes[i*SUBBUCKETS];
-               if(base == NOIDX)
-                       diag("hole in findfunctab");
-               setuint32(ctxt, t, i*(4+SUBBUCKETS), base);
-               for(j = 0; j < SUBBUCKETS && i*SUBBUCKETS+j < n; j++) {
-                       idx = indexes[i*SUBBUCKETS+j];
-                       if(idx == NOIDX)
-                               diag("hole in findfunctab");
-                       if(idx - base >= 256) {
-                               diag("too many functions in a findfunc bucket! %d/%d %d %d", i, nbuckets, j, idx-base);
-                       }
-                       setuint8(ctxt, t, i*(4+SUBBUCKETS)+4+j, idx-base);
-               }
-       }
-       free(indexes);
-}
diff --git a/src/cmd/ld/pe.c b/src/cmd/ld/pe.c
deleted file mode 100644 (file)
index 6c43581..0000000
+++ /dev/null
@@ -1,759 +0,0 @@
-// 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.
-
-// PE (Portable Executable) file writing
-// http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <link.h>
-#include "lib.h"
-#include "pe.h"
-#include "dwarf.h"
-
-// DOS stub that prints out
-// "This program cannot be run in DOS mode."
-static uchar dosstub[] =
-{
-       0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x04, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
-       0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
-       0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd,
-       0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68,
-       0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72,
-       0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f,
-       0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e,
-       0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20,
-       0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a,
-       0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static LSym *rsrcsym;
-
-static char* strtbl;
-static int strtblnextoff;
-static int strtblsize;
-
-int32 PESECTHEADR;
-int32 PEFILEHEADR;
-
-static int pe64;
-static int pensect;
-static int nextsectoff;
-static int nextfileoff;
-static int textsect;
-static int datasect;
-
-static IMAGE_FILE_HEADER fh;
-static IMAGE_OPTIONAL_HEADER oh;
-static PE64_IMAGE_OPTIONAL_HEADER oh64;
-static IMAGE_SECTION_HEADER sh[16];
-static IMAGE_DATA_DIRECTORY* dd;
-
-typedef struct Imp Imp;
-struct Imp {
-       LSym* s;
-       uvlong off;
-       Imp* next;
-};
-
-typedef struct Dll Dll;
-struct Dll {
-       char* name;
-       uvlong nameoff;
-       uvlong thunkoff;
-       Imp* ms;
-       Dll* next;
-};
-
-static Dll* dr;
-
-static LSym *dexport[1024];
-static int nexport;
-
-typedef struct COFFSym COFFSym;
-struct COFFSym
-{
-       LSym* sym;
-       int strtbloff;
-       int sect;
-       vlong value;
-};
-
-static COFFSym* coffsym;
-static int ncoffsym;
-
-static IMAGE_SECTION_HEADER*
-addpesection(char *name, int sectsize, int filesize)
-{
-       IMAGE_SECTION_HEADER *h;
-
-       if(pensect == 16) {
-               diag("too many sections");
-               errorexit();
-       }
-       h = &sh[pensect++];
-       strncpy((char*)h->Name, name, sizeof(h->Name));
-       h->VirtualSize = sectsize;
-       h->VirtualAddress = nextsectoff;
-       nextsectoff = rnd(nextsectoff+sectsize, PESECTALIGN);
-       h->PointerToRawData = nextfileoff;
-       if(filesize > 0) {
-               h->SizeOfRawData = rnd(filesize, PEFILEALIGN);
-               nextfileoff += h->SizeOfRawData;
-       }
-       return h;
-}
-
-static void
-chksectoff(IMAGE_SECTION_HEADER *h, vlong off)
-{
-       if(off != h->PointerToRawData) {
-               diag("%s.PointerToRawData = %#llux, want %#llux", (char *)h->Name, (vlong)h->PointerToRawData, off);
-               errorexit();
-       }
-}
-
-static void
-chksectseg(IMAGE_SECTION_HEADER *h, Segment *s)
-{
-       if(s->vaddr-PEBASE != h->VirtualAddress) {
-               diag("%s.VirtualAddress = %#llux, want %#llux", (char *)h->Name, (vlong)h->VirtualAddress, (vlong)(s->vaddr-PEBASE));
-               errorexit();
-       }
-       if(s->fileoff != h->PointerToRawData) {
-               diag("%s.PointerToRawData = %#llux, want %#llux", (char *)h->Name, (vlong)h->PointerToRawData, (vlong)(s->fileoff));
-               errorexit();
-       }
-}
-
-void
-peinit(void)
-{
-       int32 l;
-
-       switch(thearch.thechar) {
-       // 64-bit architectures
-       case '6':
-               pe64 = 1;
-               l = sizeof(oh64);
-               dd = oh64.DataDirectory;
-               break;
-       // 32-bit architectures
-       default:
-               l = sizeof(oh);
-               dd = oh.DataDirectory;
-               break;
-       }
-       
-       PEFILEHEADR = rnd(sizeof(dosstub)+sizeof(fh)+l+sizeof(sh), PEFILEALIGN);
-       PESECTHEADR = rnd(PEFILEHEADR, PESECTALIGN);
-       nextsectoff = PESECTHEADR;
-       nextfileoff = PEFILEHEADR;
-
-       // some mingw libs depend on this symbol, for example, FindPESectionByName
-       xdefine("__image_base__", SDATA, PEBASE);
-       xdefine("_image_base__", SDATA, PEBASE);
-}
-
-static void
-pewrite(void)
-{
-       cseek(0);
-       cwrite(dosstub, sizeof dosstub);
-       strnput("PE", 4);
-       // TODO: This code should not assume that the
-       // memory representation is little-endian or
-       // that the structs are packed identically to
-       // their file representation.
-       cwrite(&fh, sizeof fh);
-       if(pe64)
-               cwrite(&oh64, sizeof oh64);
-       else
-               cwrite(&oh, sizeof oh);
-       cwrite(sh, pensect * sizeof sh[0]);
-}
-
-static void
-strput(char *s)
-{
-       int n;
-
-       for(n=0; *s; n++)
-               cput(*s++);
-       cput('\x00');
-       n++;
-       // string must be padded to even size
-       if(n%2)
-               cput('\x00');
-}
-
-static Dll* 
-initdynimport(void)
-{
-       Imp *m;
-       Dll *d;
-       LSym *s, *dynamic;
-
-       dr = nil;
-       m = nil;
-       for(s = ctxt->allsym; s != nil; s = s->allsym) {
-               if(!s->reachable || s->type != SDYNIMPORT)
-                       continue;
-               for(d = dr; d != nil; d = d->next) {
-                       if(strcmp(d->name,s->dynimplib) == 0) {
-                               m = mal(sizeof *m);
-                               break;
-                       }
-               }
-               if(d == nil) {
-                       d = mal(sizeof *d);
-                       d->name = s->dynimplib;
-                       d->next = dr;
-                       dr = d;
-                       m = mal(sizeof *m);
-               }
-               m->s = s;
-               m->next = d->ms;
-               d->ms = m;
-       }
-       
-       dynamic = linklookup(ctxt, ".windynamic", 0);
-       dynamic->reachable = 1;
-       dynamic->type = SWINDOWS;
-       for(d = dr; d != nil; d = d->next) {
-               for(m = d->ms; m != nil; m = m->next) {
-                       m->s->type = SWINDOWS | SSUB;
-                       m->s->sub = dynamic->sub;
-                       dynamic->sub = m->s;
-                       m->s->value = dynamic->size;
-                       dynamic->size += thearch.ptrsize;
-               }
-               dynamic->size += thearch.ptrsize;
-       }
-               
-       return dr;
-}
-
-static void
-addimports(IMAGE_SECTION_HEADER *datsect)
-{
-       IMAGE_SECTION_HEADER *isect;
-       uvlong n, oftbase, ftbase;
-       vlong startoff, endoff;
-       Imp *m;
-       Dll *d;
-       LSym* dynamic;
-       
-       startoff = cpos();
-       dynamic = linklookup(ctxt, ".windynamic", 0);
-
-       // skip import descriptor table (will write it later)
-       n = 0;
-       for(d = dr; d != nil; d = d->next)
-               n++;
-       cseek(startoff + sizeof(IMAGE_IMPORT_DESCRIPTOR) * (n + 1));
-
-       // write dll names
-       for(d = dr; d != nil; d = d->next) {
-               d->nameoff = cpos() - startoff;
-               strput(d->name);
-       }
-
-       // write function names
-       for(d = dr; d != nil; d = d->next) {
-               for(m = d->ms; m != nil; m = m->next) {
-                       m->off = nextsectoff + cpos() - startoff;
-                       wputl(0); // hint
-                       strput(m->s->extname);
-               }
-       }
-       
-       // write OriginalFirstThunks
-       oftbase = cpos() - startoff;
-       n = cpos();
-       for(d = dr; d != nil; d = d->next) {
-               d->thunkoff = cpos() - n;
-               for(m = d->ms; m != nil; m = m->next) {
-                       if(pe64)
-                               vputl(m->off);
-                       else
-                               lputl(m->off);
-               }
-               if(pe64)
-                       vputl(0);
-               else
-                       lputl(0);
-       }
-
-       // add pe section and pad it at the end
-       n = cpos() - startoff;
-       isect = addpesection(".idata", n, n);
-       isect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
-               IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
-       chksectoff(isect, startoff);
-       strnput("", isect->SizeOfRawData - n);
-       endoff = cpos();
-
-       // write FirstThunks (allocated in .data section)
-       ftbase = dynamic->value - datsect->VirtualAddress - PEBASE;
-       cseek(datsect->PointerToRawData + ftbase);
-       for(d = dr; d != nil; d = d->next) {
-               for(m = d->ms; m != nil; m = m->next) {
-                       if(pe64)
-                               vputl(m->off);
-                       else
-                               lputl(m->off);
-               }
-               if(pe64)
-                       vputl(0);
-               else
-                       lputl(0);
-       }
-       
-       // finally write import descriptor table
-       cseek(startoff);
-       for(d = dr; d != nil; d = d->next) {
-               lputl(isect->VirtualAddress + oftbase + d->thunkoff);
-               lputl(0);
-               lputl(0);
-               lputl(isect->VirtualAddress + d->nameoff);
-               lputl(datsect->VirtualAddress + ftbase + d->thunkoff);
-       }
-       lputl(0); //end
-       lputl(0);
-       lputl(0);
-       lputl(0);
-       lputl(0);
-       
-       // update data directory
-       dd[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect->VirtualAddress;
-       dd[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect->VirtualSize;
-       dd[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = dynamic->value - PEBASE;
-       dd[IMAGE_DIRECTORY_ENTRY_IAT].Size = dynamic->size;
-
-       cseek(endoff);
-}
-
-static int
-pescmp(const void *p1, const void *p2)
-{
-       LSym *s1, *s2;
-
-       s1 = *(LSym**)p1;
-       s2 = *(LSym**)p2;
-       return strcmp(s1->extname, s2->extname);
-}
-
-static void
-initdynexport(void)
-{
-       LSym *s;
-       
-       nexport = 0;
-       for(s = ctxt->allsym; s != nil; s = s->allsym) {
-               if(!s->reachable || !(s->cgoexport & CgoExportDynamic))
-                       continue;
-               if(nexport+1 > nelem(dexport)) {
-                       diag("pe dynexport table is full");
-                       errorexit();
-               }
-               
-               dexport[nexport] = s;
-               nexport++;
-       }
-       
-       qsort(dexport, nexport, sizeof dexport[0], pescmp);
-}
-
-void
-addexports(void)
-{
-       IMAGE_SECTION_HEADER *sect;
-       IMAGE_EXPORT_DIRECTORY e;
-       int size, i, va, va_name, va_addr, va_na, v;
-
-       size = sizeof e + 10*nexport + strlen(outfile) + 1;
-       for(i=0; i<nexport; i++)
-               size += strlen(dexport[i]->extname) + 1;
-       
-       if (nexport == 0)
-               return;
-               
-       sect = addpesection(".edata", size, size);
-       sect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ;
-       chksectoff(sect, cpos());
-       va = sect->VirtualAddress;
-       dd[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = va;
-       dd[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect->VirtualSize;
-
-       va_name = va + sizeof e + nexport*4;
-       va_addr = va + sizeof e;
-       va_na = va + sizeof e + nexport*8;
-
-       e.Characteristics = 0;
-       e.MajorVersion = 0;
-       e.MinorVersion = 0;
-       e.NumberOfFunctions = nexport;
-       e.NumberOfNames = nexport;
-       e.Name = va + sizeof e + nexport*10; // Program names.
-       e.Base = 1;
-       e.AddressOfFunctions = va_addr;
-       e.AddressOfNames = va_name;
-       e.AddressOfNameOrdinals = va_na;
-       // put IMAGE_EXPORT_DIRECTORY
-       for (i=0; i<sizeof(e); i++)
-               cput(((char*)&e)[i]);
-       // put EXPORT Address Table
-       for(i=0; i<nexport; i++)
-               lputl(dexport[i]->value - PEBASE);              
-       // put EXPORT Name Pointer Table
-       v = e.Name + strlen(outfile)+1;
-       for(i=0; i<nexport; i++) {
-               lputl(v);
-               v += strlen(dexport[i]->extname)+1;
-       }
-       // put EXPORT Ordinal Table
-       for(i=0; i<nexport; i++)
-               wputl(i);
-       // put Names
-       strnput(outfile, strlen(outfile)+1);
-       for(i=0; i<nexport; i++)
-               strnput(dexport[i]->extname, strlen(dexport[i]->extname)+1);
-       strnput("", sect->SizeOfRawData - size);
-}
-
-void
-dope(void)
-{
-       LSym *rel;
-
-       /* relocation table */
-       rel = linklookup(ctxt, ".rel", 0);
-       rel->reachable = 1;
-       rel->type = SELFROSECT;
-
-       initdynimport();
-       initdynexport();
-}
-
-static int
-strtbladd(char *name)
-{
-       int newsize, thisoff;
-
-       newsize = strtblnextoff + strlen(name) + 1;
-       if(newsize > strtblsize) {
-               strtblsize = 2 * (newsize + (1<<18));
-               strtbl = realloc(strtbl, strtblsize);
-       }
-       thisoff = strtblnextoff+4; // first string starts at offset=4
-       strcpy(&strtbl[strtblnextoff], name);
-       strtblnextoff += strlen(name);
-       strtbl[strtblnextoff] = 0;
-       strtblnextoff++;
-       return thisoff;
-}
-
-/*
- * For more than 8 characters section names, name contains a slash (/) that is 
- * followed by an ASCII representation of a decimal number that is an offset into 
- * the string table. 
- * reference: pecoff_v8.docx Page 24.
- * <http://www.microsoft.com/whdc/system/platform/firmware/PECOFFdwn.mspx>
- */
-IMAGE_SECTION_HEADER*
-newPEDWARFSection(char *name, vlong size)
-{
-       IMAGE_SECTION_HEADER *h;
-       char s[8];
-       int off;
-
-       if(size == 0)
-               return nil;
-
-       off = strtbladd(name);
-       sprint(s, "/%d", off);
-       h = addpesection(s, size, size);
-       h->Characteristics = IMAGE_SCN_MEM_READ|
-               IMAGE_SCN_MEM_DISCARDABLE;
-
-       return h;
-}
-
-static void
-addpesym(LSym *s, char *name, int type, vlong addr, vlong size, int ver, LSym *gotype)
-{
-       COFFSym *cs;
-       USED(name);
-       USED(addr);
-       USED(size);
-       USED(ver);
-       USED(gotype);
-
-       if(s == nil)
-               return;
-
-       if(s->sect == nil)
-               return;
-
-       switch(type) {
-       default:
-               return;
-       case 'D':
-       case 'B':
-       case 'T':
-               break;
-       }
-
-       if(coffsym) {
-               cs = &coffsym[ncoffsym];
-               cs->sym = s;
-               if(strlen(s->name) > 8)
-                       cs->strtbloff = strtbladd(s->name);
-               if(s->value >= segdata.vaddr) {
-                       cs->value = s->value - segdata.vaddr;
-                       cs->sect = datasect;
-               } else if(s->value >= segtext.vaddr) {
-                       cs->value = s->value - segtext.vaddr;
-                       cs->sect = textsect;
-               } else {
-                       cs->value = 0;
-                       cs->sect = 0;
-                       diag("addpesym %#llx", addr);
-               }
-       }
-       ncoffsym++;
-}
-
-static void
-addpesymtable(void)
-{
-       IMAGE_SECTION_HEADER *h;
-       int i, size;
-       COFFSym *s;
-
-       if(!debug['s']) {
-               genasmsym(addpesym);
-               coffsym = mal(ncoffsym * sizeof coffsym[0]);
-               ncoffsym = 0;
-               genasmsym(addpesym);
-       }
-
-       size = strtblnextoff + 4 + 18*ncoffsym;
-       h = addpesection(".symtab", size, size);
-       h->Characteristics = IMAGE_SCN_MEM_READ|
-               IMAGE_SCN_MEM_DISCARDABLE;
-       chksectoff(h, cpos());
-       fh.PointerToSymbolTable = cpos();
-       fh.NumberOfSymbols = ncoffsym;
-       
-       // put COFF symbol table
-       for (i=0; i<ncoffsym; i++) {
-               s = &coffsym[i];
-               if(s->strtbloff == 0)
-                       strnput(s->sym->name, 8);
-               else {
-                       lputl(0);
-                       lputl(s->strtbloff);
-               }
-               lputl(s->value);
-               wputl(s->sect);
-               wputl(0x0308);  // "array of structs"
-               cput(2);        // storage class: external
-               cput(0);        // no aux entries
-       }
-
-       // put COFF string table
-       lputl(strtblnextoff + 4);
-       for (i=0; i<strtblnextoff; i++)
-               cput(strtbl[i]);
-       strnput("", h->SizeOfRawData - size);
-}
-
-void
-setpersrc(LSym *sym)
-{
-       if(rsrcsym != nil)
-               diag("too many .rsrc sections");
-       
-       rsrcsym = sym;
-}
-
-void
-addpersrc(void)
-{
-       IMAGE_SECTION_HEADER *h;
-       uchar *p;
-       uint32 val;
-       Reloc *r;
-       int ri;
-
-       if(rsrcsym == nil)
-               return;
-       
-       h = addpesection(".rsrc", rsrcsym->size, rsrcsym->size);
-       h->Characteristics = IMAGE_SCN_MEM_READ|
-               IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA;
-       chksectoff(h, cpos());
-       // relocation
-       for(ri=0; ri<rsrcsym->nr; ri++) {
-               r = &rsrcsym->r[ri];
-               p = rsrcsym->p + r->off;
-               val = h->VirtualAddress + r->add;
-               // 32-bit little-endian
-               p[0] = val;
-               p[1] = val>>8;
-               p[2] = val>>16;
-               p[3] = val>>24;
-       }
-       cwrite(rsrcsym->p, rsrcsym->size);
-       strnput("", h->SizeOfRawData - rsrcsym->size);
-
-       // update data directory
-       dd[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = h->VirtualAddress;
-       dd[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = h->VirtualSize;
-}
-
-void
-asmbpe(void)
-{
-       IMAGE_SECTION_HEADER *t, *d;
-
-       switch(thearch.thechar) {
-       default:
-               diag("unknown PE architecture");
-               errorexit();
-       case '6':
-               fh.Machine = IMAGE_FILE_MACHINE_AMD64;
-               break;
-       case '8':
-               fh.Machine = IMAGE_FILE_MACHINE_I386;
-               break;
-       }
-
-       t = addpesection(".text", segtext.length, segtext.length);
-       t->Characteristics = IMAGE_SCN_CNT_CODE|
-               IMAGE_SCN_CNT_INITIALIZED_DATA|
-               IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ;
-       chksectseg(t, &segtext);
-       textsect = pensect;
-
-       d = addpesection(".data", segdata.length, segdata.filelen);
-       d->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
-               IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
-       chksectseg(d, &segdata);
-       datasect = pensect;
-
-       if(!debug['s'])
-               dwarfaddpeheaders();
-
-       cseek(nextfileoff);
-       addimports(d);
-       addexports();
-       addpesymtable();
-       addpersrc();
-
-       fh.NumberOfSections = pensect;
-       // Being able to produce identical output for identical input is
-       // much more beneficial than having build timestamp in the header.
-       fh.TimeDateStamp = 0;
-       fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED|
-               IMAGE_FILE_EXECUTABLE_IMAGE|IMAGE_FILE_DEBUG_STRIPPED;
-       if (pe64) {
-               fh.SizeOfOptionalHeader = sizeof(oh64);
-               fh.Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
-               oh64.Magic = 0x20b;     // PE32+
-       } else {
-               fh.SizeOfOptionalHeader = sizeof(oh);
-               fh.Characteristics |= IMAGE_FILE_32BIT_MACHINE;
-               oh.Magic = 0x10b;       // PE32
-               oh.BaseOfData = d->VirtualAddress;
-       }
-       // Fill out both oh64 and oh. We only use one. Oh well.
-       oh64.MajorLinkerVersion = 3;
-       oh.MajorLinkerVersion = 3;
-       oh64.MinorLinkerVersion = 0;
-       oh.MinorLinkerVersion = 0;
-       oh64.SizeOfCode = t->SizeOfRawData;
-       oh.SizeOfCode = t->SizeOfRawData;
-       oh64.SizeOfInitializedData = d->SizeOfRawData;
-       oh.SizeOfInitializedData = d->SizeOfRawData;
-       oh64.SizeOfUninitializedData = 0;
-       oh.SizeOfUninitializedData = 0;
-       oh64.AddressOfEntryPoint = entryvalue()-PEBASE;
-       oh.AddressOfEntryPoint = entryvalue()-PEBASE;
-       oh64.BaseOfCode = t->VirtualAddress;
-       oh.BaseOfCode = t->VirtualAddress;
-       oh64.ImageBase = PEBASE;
-       oh.ImageBase = PEBASE;
-       oh64.SectionAlignment = PESECTALIGN;
-       oh.SectionAlignment = PESECTALIGN;
-       oh64.FileAlignment = PEFILEALIGN;
-       oh.FileAlignment = PEFILEALIGN;
-       oh64.MajorOperatingSystemVersion = 4;
-       oh.MajorOperatingSystemVersion = 4;
-       oh64.MinorOperatingSystemVersion = 0;
-       oh.MinorOperatingSystemVersion = 0;
-       oh64.MajorImageVersion = 1;
-       oh.MajorImageVersion = 1;
-       oh64.MinorImageVersion = 0;
-       oh.MinorImageVersion = 0;
-       oh64.MajorSubsystemVersion = 4;
-       oh.MajorSubsystemVersion = 4;
-       oh64.MinorSubsystemVersion = 0;
-       oh.MinorSubsystemVersion = 0;
-       oh64.SizeOfImage = nextsectoff;
-       oh.SizeOfImage = nextsectoff;
-       oh64.SizeOfHeaders = PEFILEHEADR;
-       oh.SizeOfHeaders = PEFILEHEADR;
-       if(strcmp(headstring, "windowsgui") == 0) {
-               oh64.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
-               oh.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
-       } else {
-               oh64.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
-               oh.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
-       }
-
-       // Disable stack growth as we don't want Windows to
-       // fiddle with the thread stack limits, which we set
-       // ourselves to circumvent the stack checks in the
-       // Windows exception dispatcher.
-       // Commit size must be strictly less than reserve
-       // size otherwise reserve will be rounded up to a
-       // larger size, as verified with VMMap.
-
-       // Go code would be OK with 64k stacks, but we need larger stacks for cgo.
-       // That default stack reserve size affects only the main thread,
-       // for other threads we specify stack size in runtime explicitly
-       // (runtime knows whether cgo is enabled or not).
-       // If you change stack reserve sizes here,
-       // change STACKSIZE in runtime/cgo/gcc_windows_{386,amd64}.c as well.
-       if(!iscgo) {
-               oh64.SizeOfStackReserve = 0x00010000;
-               oh.SizeOfStackReserve = 0x00010000;
-               oh64.SizeOfStackCommit = 0x0000ffff;
-               oh.SizeOfStackCommit = 0x0000ffff;
-       } else {
-               oh64.SizeOfStackReserve = 0x00200000;
-               oh.SizeOfStackReserve = 0x00100000;
-               // account for 2 guard pages
-               oh64.SizeOfStackCommit = 0x00200000 - 0x2000;
-               oh.SizeOfStackCommit = 0x00100000 - 0x2000;
-       }
-       oh64.SizeOfHeapReserve = 0x00100000;
-       oh.SizeOfHeapReserve = 0x00100000;
-       oh64.SizeOfHeapCommit = 0x00001000;
-       oh.SizeOfHeapCommit = 0x00001000;
-       oh64.NumberOfRvaAndSizes = 16;
-       oh.NumberOfRvaAndSizes = 16;
-
-       pewrite();
-}
diff --git a/src/cmd/ld/pe.h b/src/cmd/ld/pe.h
deleted file mode 100644 (file)
index 98632b0..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-// 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.
-
-typedef struct IMAGE_FILE_HEADER IMAGE_FILE_HEADER;
-struct IMAGE_FILE_HEADER {
-       uint16 Machine;
-       uint16 NumberOfSections;
-       uint32 TimeDateStamp;
-       uint32 PointerToSymbolTable;
-       uint32 NumberOfSymbols;
-       uint16 SizeOfOptionalHeader;
-       uint16 Characteristics;
-};
-
-typedef struct IMAGE_DATA_DIRECTORY IMAGE_DATA_DIRECTORY;
-struct IMAGE_DATA_DIRECTORY {
-       uint32 VirtualAddress;
-       uint32 Size;
-};
-
-typedef struct IMAGE_OPTIONAL_HEADER IMAGE_OPTIONAL_HEADER;
-struct IMAGE_OPTIONAL_HEADER {
-       uint16 Magic;
-       uint8  MajorLinkerVersion;
-       uint8  MinorLinkerVersion;
-       uint32 SizeOfCode;
-       uint32 SizeOfInitializedData;
-       uint32 SizeOfUninitializedData;
-       uint32 AddressOfEntryPoint;
-       uint32 BaseOfCode;
-       uint32 BaseOfData;
-       uint32 ImageBase;
-       uint32 SectionAlignment;
-       uint32 FileAlignment;
-       uint16 MajorOperatingSystemVersion;
-       uint16 MinorOperatingSystemVersion;
-       uint16 MajorImageVersion;
-       uint16 MinorImageVersion;
-       uint16 MajorSubsystemVersion;
-       uint16 MinorSubsystemVersion;
-       uint32 Win32VersionValue;
-       uint32 SizeOfImage;
-       uint32 SizeOfHeaders;
-       uint32 CheckSum;
-       uint16 Subsystem;
-       uint16 DllCharacteristics;
-       uint32 SizeOfStackReserve;
-       uint32 SizeOfStackCommit;
-       uint32 SizeOfHeapReserve;
-       uint32 SizeOfHeapCommit;
-       uint32 LoaderFlags;
-       uint32 NumberOfRvaAndSizes;
-       IMAGE_DATA_DIRECTORY DataDirectory[16];
-};
-
-typedef struct IMAGE_SECTION_HEADER IMAGE_SECTION_HEADER;
-struct IMAGE_SECTION_HEADER {
-       uint8  Name[8];
-       uint32 VirtualSize;
-       uint32 VirtualAddress;
-       uint32 SizeOfRawData;
-       uint32 PointerToRawData;
-       uint32 PointerToRelocations;
-       uint32 PointerToLineNumbers;
-       uint16 NumberOfRelocations;
-       uint16 NumberOfLineNumbers;
-       uint32 Characteristics;
-};
-
-typedef struct IMAGE_IMPORT_DESCRIPTOR IMAGE_IMPORT_DESCRIPTOR;
-struct IMAGE_IMPORT_DESCRIPTOR {
-       uint32 OriginalFirstThunk;
-       uint32 TimeDateStamp;
-       uint32 ForwarderChain;
-       uint32 Name;
-       uint32 FirstThunk;
-};
-
-typedef struct IMAGE_EXPORT_DIRECTORY IMAGE_EXPORT_DIRECTORY;
-struct IMAGE_EXPORT_DIRECTORY {
-       uint32 Characteristics;
-       uint32 TimeDateStamp;
-       uint16 MajorVersion;
-       uint16 MinorVersion;
-       uint32 Name;
-       uint32 Base;
-       uint32 NumberOfFunctions;
-       uint32 NumberOfNames;
-       uint32 AddressOfFunctions;
-       uint32 AddressOfNames;
-       uint32 AddressOfNameOrdinals;
-};
-
-enum {
-       PEBASE = 0x00400000,
-// SectionAlignment must be greater than or equal to FileAlignment.
-// The default is the page size for the architecture.
-       PESECTALIGN = 0x1000,
-// FileAlignment should be a power of 2 between 512 and 64 K, inclusive.
-// The default is 512. If the SectionAlignment is less than
-// the architecture's page size, then FileAlignment must match SectionAlignment.
-       PEFILEALIGN = (2<<8),
-};
-
-extern int32   PESECTHEADR;
-extern int32   PEFILEHEADR;
-
-enum {
-       IMAGE_FILE_MACHINE_I386 = 0x14c,
-       IMAGE_FILE_MACHINE_AMD64 = 0x8664,
-
-       IMAGE_FILE_RELOCS_STRIPPED = 0x0001,
-       IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002,
-       IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020,
-       IMAGE_FILE_32BIT_MACHINE = 0x0100,
-       IMAGE_FILE_DEBUG_STRIPPED = 0x0200,
-
-       IMAGE_SCN_CNT_CODE = 0x00000020,
-       IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040,
-       IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080,
-       IMAGE_SCN_MEM_EXECUTE = 0x20000000,
-       IMAGE_SCN_MEM_READ = 0x40000000,
-       IMAGE_SCN_MEM_WRITE = 0x80000000,
-       IMAGE_SCN_MEM_DISCARDABLE = 0x2000000,
-
-       IMAGE_DIRECTORY_ENTRY_EXPORT = 0,
-       IMAGE_DIRECTORY_ENTRY_IMPORT = 1,
-       IMAGE_DIRECTORY_ENTRY_RESOURCE = 2,
-       IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3,
-       IMAGE_DIRECTORY_ENTRY_SECURITY = 4,
-       IMAGE_DIRECTORY_ENTRY_BASERELOC = 5,
-       IMAGE_DIRECTORY_ENTRY_DEBUG = 6,
-       IMAGE_DIRECTORY_ENTRY_COPYRIGHT = 7,
-       IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = 7,
-       IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8,
-       IMAGE_DIRECTORY_ENTRY_TLS = 9,
-       IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10,
-       IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11,
-       IMAGE_DIRECTORY_ENTRY_IAT = 12,
-       IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 13,
-       IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14,
-
-       IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
-       IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
-};
-
-void peinit(void);
-void asmbpe(void);
-void dope(void);
-
-IMAGE_SECTION_HEADER* newPEDWARFSection(char *name, vlong size);
-
-// X64
-typedef struct PE64_IMAGE_OPTIONAL_HEADER PE64_IMAGE_OPTIONAL_HEADER;
-struct PE64_IMAGE_OPTIONAL_HEADER {
-       uint16 Magic;
-       uint8  MajorLinkerVersion;
-       uint8  MinorLinkerVersion;
-       uint32 SizeOfCode;
-       uint32 SizeOfInitializedData;
-       uint32 SizeOfUninitializedData;
-       uint32 AddressOfEntryPoint;
-       uint32 BaseOfCode;
-       uint64 ImageBase;
-       uint32 SectionAlignment;
-       uint32 FileAlignment;
-       uint16 MajorOperatingSystemVersion;
-       uint16 MinorOperatingSystemVersion;
-       uint16 MajorImageVersion;
-       uint16 MinorImageVersion;
-       uint16 MajorSubsystemVersion;
-       uint16 MinorSubsystemVersion;
-       uint32 Win32VersionValue;
-       uint32 SizeOfImage;
-       uint32 SizeOfHeaders;
-       uint32 CheckSum;
-       uint16 Subsystem;
-       uint16 DllCharacteristics;
-       uint64 SizeOfStackReserve;
-       uint64 SizeOfStackCommit;
-       uint64 SizeOfHeapReserve;
-       uint64 SizeOfHeapCommit;
-       uint32 LoaderFlags;
-       uint32 NumberOfRvaAndSizes;
-       IMAGE_DATA_DIRECTORY DataDirectory[16];
-};
-
-void setpersrc(LSym *sym);
diff --git a/src/cmd/ld/pobj.c b/src/cmd/ld/pobj.c
deleted file mode 100644 (file)
index f3bab30..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-// Inferno utils/6l/obj.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Reading object files.
-
-#define        EXTERN
-#include       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-#include       "lib.h"
-#include       "elf.h"
-#include       "macho.h"
-#include       "dwarf.h"
-#include       "pe.h"
-#include       <ar.h>
-
-char   *noname         = "<none>";
-char*  paramspace      = "FP";
-
-void
-ldmain(int argc, char **argv)
-{
-       int i;
-
-       ctxt = linknew(thelinkarch);
-       ctxt->thechar = thearch.thechar;
-       ctxt->thestring = thestring;
-       ctxt->diag = diag;
-       ctxt->bso = &bso;
-
-       Binit(&bso, 1, OWRITE);
-       memset(debug, 0, sizeof(debug));
-       nerrors = 0;
-       outfile = nil;
-       HEADTYPE = -1;
-       INITTEXT = -1;
-       INITDAT = -1;
-       INITRND = -1;
-       INITENTRY = 0;
-       linkmode = LinkAuto;
-       
-       // For testing behavior of go command when tools crash.
-       // Undocumented, not in standard flag parser to avoid
-       // exposing in usage message.
-       for(i=1; i<argc; i++)
-               if(strcmp(argv[i], "-crash_for_testing") == 0)
-                       *(volatile int*)0 = 0;
-       
-       if(thearch.thechar == '5' && ctxt->goarm == 5)
-               debug['F'] = 1;
-
-       flagcount("1", "use alternate profiling code", &debug['1']);
-       if(thearch.thechar == '6')
-               flagcount("8", "assume 64-bit addresses", &debug['8']);
-       flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo);
-       flagcount("C", "check Go calls to C code", &debug['C']);
-       flagint64("D", "addr: data address", &INITDAT);
-       flagstr("E", "sym: entry symbol", &INITENTRY);
-       if(thearch.thechar == '5')
-               flagcount("G", "debug pseudo-ops", &debug['G']);
-       flagfn1("I", "interp: set ELF interp", setinterp);
-       flagfn1("L", "dir: add dir to library path", Lflag);
-       flagfn1("H", "head: header type", setheadtype);
-       flagcount("K", "add stack underflow checks", &debug['K']);
-       if(thearch.thechar == '5')
-               flagcount("M", "disable software div/mod", &debug['M']);
-       flagcount("O", "print pc-line tables", &debug['O']);
-       flagcount("Q", "debug byte-register code gen", &debug['Q']);
-       if(thearch.thechar == '5')
-               flagcount("P", "debug code generation", &debug['P']);
-       flagint32("R", "rnd: address rounding", &INITRND);
-       flagcount("nil", "check type signatures", &debug['S']);
-       flagint64("T", "addr: text address", &INITTEXT);
-       flagfn0("V", "print version and exit", doversion);
-       flagcount("W", "disassemble input", &debug['W']);
-       flagfn2("X", "name value: define string data", addstrdata);
-       flagcount("Z", "clear stack frame on entry", &debug['Z']);
-       flagcount("a", "disassemble output", &debug['a']);
-       flagcount("c", "dump call graph", &debug['c']);
-       flagcount("d", "disable dynamic executable", &debug['d']);
-       flagstr("extld", "ld: linker to run in external mode", &extld);
-       flagstr("extldflags", "ldflags: flags for external linker", &extldflags);
-       flagcount("f", "ignore version mismatch", &debug['f']);
-       flagcount("g", "disable go package data checks", &debug['g']);
-       flagstr("installsuffix", "suffix: pkg directory suffix", &flag_installsuffix);
-       flagstr("k", "sym: set field tracking symbol", &tracksym);
-       flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode);
-       flagcount("n", "dump symbol table", &debug['n']);
-       flagstr("o", "outfile: set output file", &outfile);
-       flagstr("r", "dir1:dir2:...: set ELF dynamic linker search path", &rpath);
-       flagcount("race", "enable race detector", &flag_race);
-       flagcount("s", "disable symbol table", &debug['s']);
-       if(thearch.thechar == '5' || thearch.thechar == '6')
-               flagcount("shared", "generate shared object (implies -linkmode external)", &flag_shared);
-       flagstr("tmpdir", "dir: leave temporary files in this directory", &tmpdir);
-       flagcount("u", "reject unsafe packages", &debug['u']);
-       flagcount("v", "print link trace", &debug['v']);
-       flagcount("w", "disable DWARF generation", &debug['w']);
-       
-       flagparse(&argc, &argv, usage);
-       ctxt->bso = &bso;
-       ctxt->debugvlog = debug['v'];
-
-       if(argc != 1)
-               usage();
-
-       if(outfile == nil) {
-               if(HEADTYPE == Hwindows)
-                       outfile = smprint("%c.out.exe", thearch.thechar);
-               else
-                       outfile = smprint("%c.out", thearch.thechar);
-       }
-       libinit(); // creates outfile
-
-       if(HEADTYPE == -1)
-               HEADTYPE = headtype(goos);
-       ctxt->headtype = HEADTYPE;
-       if(headstring == nil)
-               headstring = headstr(HEADTYPE);
-
-       thearch.archinit();
-
-       if(debug['v'])
-               Bprint(&bso, "HEADER = -H%d -T0x%llux -D0x%llux -R0x%ux\n",
-                       HEADTYPE, INITTEXT, INITDAT, INITRND);
-       Bflush(&bso);
-
-       addlibpath(ctxt, "command line", "command line", argv[0], "main");
-       loadlib();
-       
-       if(thearch.thechar == '5') {
-               // mark some functions that are only referenced after linker code editing
-               if(debug['F'])
-                       mark(linkrlookup(ctxt, "_sfloat", 0));
-               mark(linklookup(ctxt, "runtime.read_tls_fallback", 0));
-       }
-
-       checkgo();
-       deadcode();
-       callgraph();
-       paramspace = "SP";      /* (FP) now (SP) on output */
-
-       doelf();
-       if(HEADTYPE == Hdarwin)
-               domacho();
-       dostkcheck();
-       if(HEADTYPE == Hwindows)
-               dope();
-       addexport();
-       thearch.gentext();              // trampolines, call stubs, etc.
-       textaddress();
-       pclntab();
-       findfunctab();
-       symtab();
-       dodata();
-       address();
-       doweak();
-       reloc();
-       thearch.asmb();
-       undef();
-       hostlink();
-       if(debug['v']) {
-               Bprint(&bso, "%5.2f cpu time\n", cputime());
-               Bprint(&bso, "%d symbols\n", ctxt->nsymbol);
-               Bprint(&bso, "%lld liveness data\n", liveness);
-       }
-       Bflush(&bso);
-
-       errorexit();
-}
diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c
deleted file mode 100644 (file)
index 34aa1cc..0000000
+++ /dev/null
@@ -1,449 +0,0 @@
-// Inferno utils/6l/span.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/span.c
-//
-//     Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//     Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-//     Portions Copyright © 1997-1999 Vita Nuova Limited
-//     Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//     Portions Copyright © 2004,2006 Bruce Ellis
-//     Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-//     Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//     Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Symbol table.
-
-#include       <u.h>
-#include       <libc.h>
-#include       <bio.h>
-#include       <link.h>
-#include       "lib.h"
-#include       "elf.h"
-#include       "dwarf.h"
-
-static int maxelfstr;
-
-static int
-putelfstr(char *s)
-{
-       int off, n;
-       char *p, *q;
-
-       if(elfstrsize == 0 && s[0] != 0) {
-               // first entry must be empty string
-               putelfstr("");
-       }
-
-       n = strlen(s)+1;
-       if(elfstrsize+n > maxelfstr) {
-               maxelfstr = 2*(elfstrsize+n+(1<<20));
-               elfstrdat = realloc(elfstrdat, maxelfstr);
-       }
-       off = elfstrsize;
-       elfstrsize += n;
-       memmove(elfstrdat+off, s, n);
-       // replace "·" as ".", because DTrace cannot handle it.
-       p = strstr(s, "·");
-       if(p != nil) {
-               p = q = elfstrdat+off;
-               while (*q != '\x00') {
-                       if((uchar)*q == 0xc2 && (uchar)*(q+1) == 0xb7) {
-                               q += 2;
-                               *p++ = '.';
-                               elfstrsize--;
-                       } else {
-                               *p++ = *q++;
-                       }
-               }
-               *p = '\x00';
-       }
-       return off;
-}
-
-static void
-putelfsyment(int off, vlong addr, vlong size, int info, int shndx, int other)
-{
-       switch(thearch.thechar) {
-       case '6':
-       case '9':
-               thearch.lput(off);
-               cput(info);
-               cput(other);
-               thearch.wput(shndx);
-               thearch.vput(addr);
-               thearch.vput(size);
-               symsize += ELF64SYMSIZE;
-               break;
-       default:
-               thearch.lput(off);
-               thearch.lput(addr);
-               thearch.lput(size);
-               cput(info);
-               cput(other);
-               thearch.wput(shndx);
-               symsize += ELF32SYMSIZE;
-               break;
-       }
-}
-
-static int numelfsym = 1; // 0 is reserved
-static int elfbind;
-
-static void
-putelfsym(LSym *x, char *s, int t, vlong addr, vlong size, int ver, LSym *go)
-{
-       int bind, type, off, other;
-       LSym *xo;
-
-       USED(go);
-       switch(t) {
-       default:
-               return;
-       case 'T':
-               type = STT_FUNC;
-               break;
-       case 'D':
-               type = STT_OBJECT;
-               break;
-       case 'B':
-               type = STT_OBJECT;
-               break;
-       }
-       xo = x;
-       while(xo->outer != nil)
-               xo = xo->outer;
-       if(xo->sect == nil) {
-               ctxt->cursym = x;
-               diag("missing section in putelfsym");
-               return;
-       }
-       if(((Section*)xo->sect)->elfsect == nil) {
-               ctxt->cursym = x;
-               diag("missing ELF section in putelfsym");
-               return;
-       }
-
-       // One pass for each binding: STB_LOCAL, STB_GLOBAL,
-       // maybe one day STB_WEAK.
-       bind = STB_GLOBAL;
-       if(ver || (x->type & SHIDDEN))
-               bind = STB_LOCAL;
-
-       // In external linking mode, we have to invoke gcc with -rdynamic
-       // to get the exported symbols put into the dynamic symbol table.
-       // To avoid filling the dynamic table with lots of unnecessary symbols,
-       // mark all Go symbols local (not global) in the final executable.
-       if(linkmode == LinkExternal && !(x->cgoexport&CgoExportStatic))
-               bind = STB_LOCAL;
-
-       if(bind != elfbind)
-               return;
-
-       off = putelfstr(s);
-       if(linkmode == LinkExternal)
-               addr -= ((Section*)xo->sect)->vaddr;
-       other = 2;
-       if(x->type&SHIDDEN)
-               other = 0;
-       putelfsyment(off, addr, size, (bind<<4)|(type&0xf), ((ElfShdr*)((Section*)xo->sect)->elfsect)->shnum, other);
-       x->elfsym = numelfsym++;
-}
-
-void
-putelfsectionsym(LSym* s, int shndx)
-{
-       putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_SECTION, shndx, 0);
-       s->elfsym = numelfsym++;
-}
-
-void
-putelfsymshndx(vlong sympos, int shndx)
-{
-       vlong here;
-
-       here = cpos();
-       switch(thearch.thechar) {
-       case '6':
-               cseek(sympos+6);
-               break;
-       default:
-               cseek(sympos+14);
-               break;
-       }
-       thearch.wput(shndx);
-       cseek(here);
-}
-
-void
-asmelfsym(void)
-{
-       LSym *s;
-       char *name;
-
-       // the first symbol entry is reserved
-       putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_NOTYPE, 0, 0);
-
-       dwarfaddelfsectionsyms();
-
-       elfbind = STB_LOCAL;
-       genasmsym(putelfsym);
-       
-       if(linkmode == LinkExternal && HEADTYPE != Hopenbsd) {
-               s = linklookup(ctxt, "runtime.tlsg", 0);
-               if(s->sect == nil) {
-                       ctxt->cursym = nil;
-                       diag("missing section for %s", s->name);
-                       errorexit();
-               }
-               if (strcmp(goos, "android") == 0) {
-                       // Android emulates runtime.tlsg as a regular variable.
-                       putelfsyment(putelfstr(s->name), 0, s->size, (STB_LOCAL<<4)|STT_OBJECT, ((ElfShdr*)((Section*)s->sect)->elfsect)->shnum, 0);
-               } else {
-                       putelfsyment(putelfstr(s->name), 0, s->size, (STB_LOCAL<<4)|STT_TLS, ((ElfShdr*)((Section*)s->sect)->elfsect)->shnum, 0);
-               }
-               s->elfsym = numelfsym++;
-       }
-
-       elfbind = STB_GLOBAL;
-       elfglobalsymndx = numelfsym;
-       genasmsym(putelfsym);
-       
-       for(s=ctxt->allsym; s!=nil; s=s->allsym) {
-               if(s->type != SHOSTOBJ && !(s->type == SDYNIMPORT && s->reachable))
-                       continue;
-               if(s->type == SDYNIMPORT)
-                       name = s->extname;
-               else
-                       name = s->name;
-               putelfsyment(putelfstr(name), 0, 0, (STB_GLOBAL<<4)|STT_NOTYPE, 0, 0);
-               s->elfsym = numelfsym++;
-       }
-}
-
-static void
-putplan9sym(LSym *x, char *s, int t, vlong addr, vlong size, int ver, LSym *go)
-{
-       int i, l;
-
-       USED(go);
-       USED(ver);
-       USED(size);
-       USED(x);
-       switch(t) {
-       case 'T':
-       case 'L':
-       case 'D':
-       case 'B':
-               if(ver)
-                       t += 'a' - 'A';
-       case 'a':
-       case 'p':
-       case 'f':
-       case 'z':
-       case 'Z':
-       case 'm':
-               l = 4;
-               if(HEADTYPE == Hplan9 && thearch.thechar == '6' && !debug['8']) {
-                       lputb(addr>>32);
-                       l = 8;
-               }
-               lputb(addr);
-               cput(t+0x80); /* 0x80 is variable length */
-
-               if(t == 'z' || t == 'Z') {
-                       cput(s[0]);
-                       for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
-                               cput(s[i]);
-                               cput(s[i+1]);
-                       }
-                       cput(0);
-                       cput(0);
-                       i++;
-               } else {
-                       /* skip the '<' in filenames */
-                       if(t == 'f')
-                               s++;
-                       for(i=0; s[i]; i++)
-                               cput(s[i]);
-                       cput(0);
-               }
-               symsize += l + 1 + i + 1;
-               break;
-       default:
-               return;
-       };
-}
-
-void
-asmplan9sym(void)
-{
-       genasmsym(putplan9sym);
-}
-
-static LSym *symt;
-
-void
-wputl(ushort w)
-{
-       cput(w);
-       cput(w>>8);
-}
-
-void
-wputb(ushort w)
-{
-       cput(w>>8);
-       cput(w);
-}
-
-void
-lputb(uint32 l)
-{
-       cput(l>>24);
-       cput(l>>16);
-       cput(l>>8);
-       cput(l);
-}
-
-void
-lputl(uint32 l)
-{
-       cput(l);
-       cput(l>>8);
-       cput(l>>16);
-       cput(l>>24);
-}
-
-void
-vputb(uint64 v)
-{
-       lputb(v>>32);
-       lputb(v);
-}
-
-void
-vputl(uint64 v)
-{
-       lputl(v);
-       lputl(v >> 32);
-}
-
-void
-symtab(void)
-{
-       LSym *s, *symtype, *symtypelink, *symgostring, *symgofunc;
-
-       dosymtype();
-
-       // Define these so that they'll get put into the symbol table.
-       // data.c:/^address will provide the actual values.
-       xdefine("runtime.text", STEXT, 0);
-       xdefine("runtime.etext", STEXT, 0);
-       xdefine("runtime.typelink", SRODATA, 0);
-       xdefine("runtime.etypelink", SRODATA, 0);
-       xdefine("runtime.rodata", SRODATA, 0);
-       xdefine("runtime.erodata", SRODATA, 0);
-       xdefine("runtime.noptrdata", SNOPTRDATA, 0);
-       xdefine("runtime.enoptrdata", SNOPTRDATA, 0);
-       xdefine("runtime.data", SDATA, 0);
-       xdefine("runtime.edata", SDATA, 0);
-       xdefine("runtime.bss", SBSS, 0);
-       xdefine("runtime.ebss", SBSS, 0);
-       xdefine("runtime.noptrbss", SNOPTRBSS, 0);
-       xdefine("runtime.enoptrbss", SNOPTRBSS, 0);
-       xdefine("runtime.end", SBSS, 0);
-       xdefine("runtime.epclntab", SRODATA, 0);
-       xdefine("runtime.esymtab", SRODATA, 0);
-
-       // garbage collection symbols
-       s = linklookup(ctxt, "runtime.gcdata", 0);
-       s->type = SRODATA;
-       s->size = 0;
-       s->reachable = 1;
-       xdefine("runtime.egcdata", SRODATA, 0);
-
-       s = linklookup(ctxt, "runtime.gcbss", 0);
-       s->type = SRODATA;
-       s->size = 0;
-       s->reachable = 1;
-       xdefine("runtime.egcbss", SRODATA, 0);
-
-       // pseudo-symbols to mark locations of type, string, and go string data.
-       s = linklookup(ctxt, "type.*", 0);
-       s->type = STYPE;
-       s->size = 0;
-       s->reachable = 1;
-       symtype = s;
-
-       s = linklookup(ctxt, "go.string.*", 0);
-       s->type = SGOSTRING;
-       s->size = 0;
-       s->reachable = 1;
-       symgostring = s;
-       
-       s = linklookup(ctxt, "go.func.*", 0);
-       s->type = SGOFUNC;
-       s->size = 0;
-       s->reachable = 1;
-       symgofunc = s;
-       
-       symtypelink = linklookup(ctxt, "runtime.typelink", 0);
-
-       symt = linklookup(ctxt, "runtime.symtab", 0);
-       symt->type = SSYMTAB;
-       symt->size = 0;
-       symt->reachable = 1;
-
-       // assign specific types so that they sort together.
-       // within a type they sort by size, so the .* symbols
-       // just defined above will be first.
-       // hide the specific symbols.
-       for(s = ctxt->allsym; s != nil; s = s->allsym) {
-               if(!s->reachable || s->special || s->type != SRODATA)
-                       continue;
-               if(strncmp(s->name, "type.", 5) == 0) {
-                       s->type = STYPE;
-                       s->hide = 1;
-                       s->outer = symtype;
-               }
-               if(strncmp(s->name, "go.typelink.", 12) == 0) {
-                       s->type = STYPELINK;
-                       s->hide = 1;
-                       s->outer = symtypelink;
-               }
-               if(strncmp(s->name, "go.string.", 10) == 0) {
-                       s->type = SGOSTRING;
-                       s->hide = 1;
-                       s->outer = symgostring;
-               }
-               if(strncmp(s->name, "go.func.", 8) == 0) {
-                       s->type = SGOFUNC;
-                       s->hide = 1;
-                       s->outer = symgofunc;
-               }
-               if(strncmp(s->name, "gcargs.", 7) == 0 || strncmp(s->name, "gclocals.", 9) == 0 || strncmp(s->name, "gclocals·", 10) == 0) {
-                       s->type = SGOFUNC;
-                       s->hide = 1;
-                       s->outer = symgofunc;
-                       s->align = 4;
-                       liveness += (s->size+s->align-1)&~(s->align-1);
-               }
-       }
-}
similarity index 87%
rename from src/cmd/ld/textflag.h
rename to src/runtime/textflag.h
index 0ee8b5f1cef7bd701c5d2fd9c0f6a14d4a2eebba..2a76e76c29655ceb9dc93b9254ee72508bde6753 100644 (file)
 #define WRAPPER 32
 // This function uses its incoming context register.
 #define NEEDCTXT 64
-
-/*c2go
-enum
-{
-       NOPROF = 1,
-       DUPOK = 2,
-       NOSPLIT = 4,
-       RODATA = 8,
-       NOPTR = 16,
-       WRAPPER = 32,
-       NEEDCTXT = 64,
-};
-*/