summaryrefslogtreecommitdiff
path: root/src/cmd/ld
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-08-03 16:54:30 +0200
committerOndřej Surý <ondrej@sury.org>2011-08-03 16:54:30 +0200
commit28592ee1ea1f5cdffcf85472f9de0285d928cf12 (patch)
tree32944e18b23f7fe4a0818a694aa2a6dfb1835463 /src/cmd/ld
parente836bee4716dc0d4d913537ad3ad1925a7ac32d0 (diff)
downloadgolang-upstream/59.tar.gz
Imported Upstream version 59upstream/59
Diffstat (limited to 'src/cmd/ld')
-rw-r--r--src/cmd/ld/data.c67
-rw-r--r--src/cmd/ld/dwarf.c2
-rw-r--r--src/cmd/ld/elf.h74
-rw-r--r--src/cmd/ld/ldelf.c7
-rw-r--r--src/cmd/ld/ldmacho.c1
-rw-r--r--src/cmd/ld/ldpe.c12
-rw-r--r--src/cmd/ld/lib.c2
-rw-r--r--src/cmd/ld/lib.h4
-rw-r--r--src/cmd/ld/pe.c6
-rw-r--r--src/cmd/ld/symtab.c15
10 files changed, 113 insertions, 77 deletions
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index 3f3faade0..f1132fc8b 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -249,7 +249,7 @@ dynrelocsym(Sym *s)
return;
for(r=s->r; r<s->r+s->nr; r++) {
targ = r->sym;
- if(r->sym->plt == -2) { // make dynimport JMP table for PE object files.
+ 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;
@@ -278,6 +278,10 @@ dynreloc(void)
{
Sym *s;
+ // -d supresses 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);
@@ -482,13 +486,13 @@ codeblk(int32 addr, int32 size)
q = sym->p;
while(n >= 16) {
- Bprint(&bso, "%.6ux\t%-20.16I\n", addr, q);
+ 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, n, q);
+ Bprint(&bso, "%.6ux\t%-20.*I\n", addr, (int)n, q);
addr += n;
continue;
}
@@ -502,7 +506,7 @@ codeblk(int32 addr, int32 size)
Bprint(&bso, "%.6ux\t", p->pc);
q = sym->p + p->pc - sym->value;
n = epc - p->pc;
- Bprint(&bso, "%-20.*I | %P\n", n, q, p);
+ Bprint(&bso, "%-20.*I | %P\n", (int)n, q, p);
addr += n;
}
}
@@ -543,7 +547,7 @@ datblk(int32 addr, int32 size)
Bprint(&bso, "%-20s %.8ux| 00 ...\n", "(pre-pad)", addr);
addr = sym->value;
}
- Bprint(&bso, "%-20s %.8ux|", sym->name, addr);
+ Bprint(&bso, "%-20s %.8ux|", sym->name, (uint)addr);
p = sym->p;
ep = p + sym->np;
while(p < ep)
@@ -555,8 +559,8 @@ datblk(int32 addr, int32 size)
}
if(addr < eaddr)
- Bprint(&bso, "%-20s %.8ux| 00 ...\n", "(post-pad)", addr);
- Bprint(&bso, "%-20s %.8ux|\n", "", eaddr);
+ Bprint(&bso, "%-20s %.8ux| 00 ...\n", "(post-pad)", (uint)addr);
+ Bprint(&bso, "%-20s %.8ux|\n", "", (uint)eaddr);
}
void
@@ -781,18 +785,38 @@ dodata(void)
*/
/* read-only data */
- sect = addsection(&segtext, ".rodata", 06);
+ sect = addsection(&segtext, ".rodata", 04);
sect->vaddr = 0;
datsize = 0;
s = datap;
- for(; s != nil && s->type < SDATA; s = s->next) {
+ for(; s != nil && s->type < SSYMTAB; s = s->next) {
s->type = SRODATA;
t = rnd(s->size, PtrSize);
s->value = datsize;
datsize += t;
}
sect->len = datsize - sect->vaddr;
-
+
+ /* gosymtab */
+ sect = addsection(&segtext, ".gosymtab", 04);
+ sect->vaddr = datsize;
+ for(; s != nil && s->type < SPCLNTAB; s = s->next) {
+ s->type = SRODATA;
+ s->value = datsize;
+ datsize += s->size;
+ }
+ sect->len = datsize - sect->vaddr;
+
+ /* gopclntab */
+ sect = addsection(&segtext, ".gopclntab", 04);
+ sect->vaddr = datsize;
+ for(; s != nil && s->type < SDATA; s = s->next) {
+ s->type = SRODATA;
+ s->value = datsize;
+ datsize += s->size;
+ }
+ sect->len = datsize - sect->vaddr;
+
/* data */
datsize = 0;
sect = addsection(&segdata, ".data", 06);
@@ -808,9 +832,9 @@ dodata(void)
t = rnd(t, PtrSize);
else if(t > 2)
t = rnd(t, 4);
- if(t & 1)
+ if(t & 1) {
;
- else if(t & 2)
+ } else if(t & 2)
datsize = rnd(datsize, 2);
else if(t & 4)
datsize = rnd(datsize, 4);
@@ -834,9 +858,9 @@ dodata(void)
t = rnd(t, PtrSize);
else if(t > 2)
t = rnd(t, 4);
- if(t & 1)
+ if(t & 1) {
;
- else if(t & 2)
+ } else if(t & 2)
datsize = rnd(datsize, 2);
else if(t & 4)
datsize = rnd(datsize, 4);
@@ -886,7 +910,7 @@ textaddress(void)
void
address(void)
{
- Section *s, *text, *data, *rodata;
+ Section *s, *text, *data, *rodata, *symtab, *pclntab;
Sym *sym, *sub;
uvlong va;
@@ -917,7 +941,9 @@ address(void)
segdata.filelen = segdata.sect->len; // assume .data is first
text = segtext.sect;
- rodata = segtext.sect->next;
+ rodata = text->next;
+ symtab = rodata->next;
+ pclntab = symtab->next;
data = segdata.sect;
for(sym = datap; sym != nil; sym = sym->next) {
@@ -934,12 +960,11 @@ address(void)
xdefine("etext", STEXT, text->vaddr + text->len);
xdefine("rodata", SRODATA, rodata->vaddr);
xdefine("erodata", SRODATA, rodata->vaddr + rodata->len);
+ xdefine("symtab", SRODATA, symtab->vaddr);
+ xdefine("esymtab", SRODATA, symtab->vaddr + symtab->len);
+ xdefine("pclntab", SRODATA, pclntab->vaddr);
+ xdefine("epclntab", SRODATA, pclntab->vaddr + pclntab->len);
xdefine("data", SBSS, data->vaddr);
xdefine("edata", SBSS, data->vaddr + data->len);
xdefine("end", SBSS, segdata.vaddr + segdata.len);
-
- sym = lookup("pclntab", 0);
- xdefine("epclntab", SRODATA, sym->value + sym->size);
- sym = lookup("symtab", 0);
- xdefine("esymtab", SRODATA, sym->value + sym->size);
}
diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c
index 50b42183e..1c10dc796 100644
--- a/src/cmd/ld/dwarf.c
+++ b/src/cmd/ld/dwarf.c
@@ -1822,7 +1822,7 @@ flushunit(DWDie *dwinfo, vlong pc, vlong unitstart, int32 header_length)
seek(cout, unitstart, 0);
LPUT(here - unitstart - sizeof(int32)); // unit_length
WPUT(3); // dwarf version
- LPUT(header_length); // header lenght starting here
+ LPUT(header_length); // header length starting here
cflush();
seek(cout, here, 0);
}
diff --git a/src/cmd/ld/elf.h b/src/cmd/ld/elf.h
index d1370d28b..c63df2241 100644
--- a/src/cmd/ld/elf.h
+++ b/src/cmd/ld/elf.h
@@ -110,7 +110,6 @@ typedef struct {
#define ELFOSABI_OPENVMS 13 /* Open VMS */
#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */
#define ELFOSABI_ARM 97 /* ARM */
-#define ELFOSABI_NACL 123 /* Native Client */
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */
@@ -262,8 +261,8 @@ typedef struct {
/* Values for d_tag. */
#define DT_NULL 0 /* Terminating entry. */
-#define DT_NEEDED 1 /* String table offset of a needed shared
- library. */
+/* String table offset of a needed shared library. */
+#define DT_NEEDED 1
#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */
#define DT_PLTGOT 3 /* Processor-dependent address. */
#define DT_HASH 4 /* Address of symbol hash table. */
@@ -276,8 +275,8 @@ typedef struct {
#define DT_SYMENT 11 /* Size of each symbol table entry. */
#define DT_INIT 12 /* Address of initialization function. */
#define DT_FINI 13 /* Address of finalization function. */
-#define DT_SONAME 14 /* String table offset of shared object
- name. */
+/* String table offset of shared object name. */
+#define DT_SONAME 14
#define DT_RPATH 15 /* String table offset of library path. [sup] */
#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */
#define DT_REL 17 /* Address of ElfNN_Rel relocations. */
@@ -285,30 +284,29 @@ typedef struct {
#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */
#define DT_PLTREL 20 /* Type of relocation used for PLT. */
#define DT_DEBUG 21 /* Reserved (not used). */
-#define DT_TEXTREL 22 /* Indicates there may be relocations in
- non-writable segments. [sup] */
+/* Indicates there may be relocations in non-writable segments. [sup] */
+#define DT_TEXTREL 22
#define DT_JMPREL 23 /* Address of PLT relocations. */
#define DT_BIND_NOW 24 /* [sup] */
-#define DT_INIT_ARRAY 25 /* Address of the array of pointers to
- initialization functions */
-#define DT_FINI_ARRAY 26 /* Address of the array of pointers to
- termination functions */
-#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of
- initialization functions. */
-#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of
- terminationfunctions. */
-#define DT_RUNPATH 29 /* String table offset of a null-terminated
- library search path string. */
+/* Address of the array of pointers to initialization functions */
+#define DT_INIT_ARRAY 25
+/* Address of the array of pointers to termination functions */
+#define DT_FINI_ARRAY 26
+/* Size in bytes of the array of initialization functions. */
+#define DT_INIT_ARRAYSZ 27
+/* Size in bytes of the array of terminationfunctions. */
+#define DT_FINI_ARRAYSZ 28
+/* String table offset of a null-terminated library search path string. */
+#define DT_RUNPATH 29
#define DT_FLAGS 30 /* Object specific flag values. */
-#define DT_ENCODING 32 /* 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 */
-#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to
- pre-initialization functions. */
-#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of
- pre-initialization functions. */
+/* 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 */
+#define DT_ENCODING 32
+/* Address of the array of pointers to pre-initialization functions. */
+#define DT_PREINIT_ARRAY 32
+/* Size in bytes of the array of pre-initialization functions. */
+#define DT_PREINIT_ARRAYSZ 33
#define DT_LOOS 0x6000000d /* First OS-specific */
#define DT_HIOS 0x6ffff000 /* Last OS-specific */
#define DT_LOPROC 0x70000000 /* First processor-specific type. */
@@ -319,19 +317,19 @@ typedef struct {
#define DT_VERSYM 0x6ffffff0
/* Values for DT_FLAGS */
-#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may
- make reference to the $ORIGIN substitution
- string */
+/* Indicates that the object being loaded may make reference to
+ the $ORIGIN substitution string */
+#define DF_ORIGIN 0x0001
#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */
-#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in
- non-writable segments. */
-#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should
- process all relocations for the object
- containing this entry before transferring
- control to the program. */
-#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or
- executable contains code using a static
- thread-local storage scheme. */
+/* Indicates there may be relocations in non-writable segments. */
+#define DF_TEXTREL 0x0004
+/* Indicates that the dynamic linker should process all
+ relocations for the object containing this entry before
+ transferring control to the program. */
+#define DF_BIND_NOW 0x0008
+/* Indicates that the shared object or executable contains code
+ using a static thread-local storage scheme. */
+#define DF_STATIC_TLS 0x0010
/* Values for n_type. Used in core files. */
#define NT_PRSTATUS 1 /* Process status. */
diff --git a/src/cmd/ld/ldelf.c b/src/cmd/ld/ldelf.c
index d61020e49..8334e988e 100644
--- a/src/cmd/ld/ldelf.c
+++ b/src/cmd/ld/ldelf.c
@@ -328,15 +328,16 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
Reloc *r, *rp;
Sym *s;
+ USED(pkg);
if(debug['v'])
Bprint(&bso, "%5.2f ldelf %s\n", cputime(), pn);
version++;
base = Boffset(f);
- if(Bread(f, &hdrbuf, sizeof hdrbuf) != sizeof hdrbuf)
+ if(Bread(f, hdrbuf, sizeof hdrbuf) != sizeof hdrbuf)
goto bad;
- hdr = (ElfHdrBytes*)&hdrbuf;
+ hdr = (ElfHdrBytes*)hdrbuf;
if(memcmp(hdr->ident, ElfMagic, 4) != 0)
goto bad;
switch(hdr->ident[5]) {
@@ -518,7 +519,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
name = smprint("%s(%s)", pn, sect->name);
s = lookup(name, version);
free(name);
- switch(sect->flags&(ElfSectFlagAlloc|ElfSectFlagWrite|ElfSectFlagExec)) {
+ switch((int)sect->flags&(ElfSectFlagAlloc|ElfSectFlagWrite|ElfSectFlagExec)) {
default:
werrstr("unexpected flags for ELF section %s", sect->name);
goto bad;
diff --git a/src/cmd/ld/ldmacho.c b/src/cmd/ld/ldmacho.c
index bbb21d51a..abbc3b3cd 100644
--- a/src/cmd/ld/ldmacho.c
+++ b/src/cmd/ld/ldmacho.c
@@ -440,6 +440,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
Reloc *r, *rp;
char *name;
+ USED(pkg);
version++;
base = Boffset(f);
if(Bread(f, hdr, sizeof hdr) != sizeof hdr)
diff --git a/src/cmd/ld/ldpe.c b/src/cmd/ld/ldpe.c
index d6aa267c4..98c866fee 100644
--- a/src/cmd/ld/ldpe.c
+++ b/src/cmd/ld/ldpe.c
@@ -125,10 +125,13 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
Sym *s;
Reloc *r, *rp;
PeSym *sym;
-
+
+ USED(len);
+ USED(pkg);
if(debug['v'])
Bprint(&bso, "%5.2f ldpe %s\n", cputime(), pn);
+ sect = nil;
version++;
base = Boffset(f);
@@ -304,6 +307,8 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
diag("%s: %s sectnum <0!", pn, s->name, sym->sectnum);
}
+ if(sect == nil)
+ return;
s->sub = sect->sym->sub;
sect->sym->sub = s;
s->type = sect->sym->type | SSUB;
@@ -366,12 +371,11 @@ readsym(PeObj *obj, int i, PeSym **y)
sym = &obj->pesym[i];
*y = sym;
- s = nil;
name = sym->name;
if(sym->sclass == IMAGE_SYM_CLASS_STATIC && sym->value == 0) // section
name = obj->sect[sym->sectnum-1].sym->name;
- if(strncmp(sym->name, "__imp__", 6) == 0)
+ if(strncmp(sym->name, "__imp__", 7) == 0)
name = &sym->name[7]; // __imp__Name => Name
else if(sym->name[0] == '_')
name = &sym->name[1]; // _Name => Name
@@ -403,6 +407,8 @@ readsym(PeObj *obj, int i, PeSym **y)
if(s != nil && s->type == 0 && !(sym->sclass == IMAGE_SYM_CLASS_STATIC && sym->value == 0))
s->type = SXREF;
+ if(strncmp(sym->name, "__imp__", 7) == 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
index 04ee790a4..77a62f5de 100644
--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -956,7 +956,7 @@ pclntab(void)
uchar *bp;
sym = lookup("pclntab", 0);
- sym->type = SRODATA;
+ sym->type = SPCLNTAB;
sym->reachable = 1;
if(debug['s'])
return;
diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h
index dfd18fbff..347987195 100644
--- a/src/cmd/ld/lib.h
+++ b/src/cmd/ld/lib.h
@@ -40,6 +40,8 @@ enum
SSTRING,
SGOSTRING,
SRODATA,
+ SSYMTAB,
+ SPCLNTAB,
SDATA,
SMACHO, /* Mach-O __nl_symbol_ptr */
SMACHOGOT,
@@ -260,10 +262,8 @@ enum {
Hipaq, // ipaq
Hdarwin, // Apple Mach-O
Hlinux, // Linux ELF
- Hnacl, // Google Native Client
Hfreebsd, // FreeBSD ELF
Hwindows, // MS Windows PE
- Htiny // tiny (os image)
};
typedef struct Header Header;
diff --git a/src/cmd/ld/pe.c b/src/cmd/ld/pe.c
index 91e15d343..9ac0a50d8 100644
--- a/src/cmd/ld/pe.c
+++ b/src/cmd/ld/pe.c
@@ -5,8 +5,6 @@
// PE (Portable Executable) file writing
// http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
-#include <time.h>
-
#include "l.h"
#include "../ld/lib.h"
#include "../ld/pe.h"
@@ -150,7 +148,7 @@ pewrite(void)
ewrite(cout, &oh64, sizeof oh64);
else
ewrite(cout, &oh, sizeof oh);
- ewrite(cout, &sh, nsect * sizeof sh[0]);
+ ewrite(cout, sh, nsect * sizeof sh[0]);
}
static void
@@ -175,7 +173,7 @@ initdynimport(void)
Sym *s, *dynamic;
dr = nil;
-
+ m = nil;
for(s = allsym; s != S; s = s->allsym) {
if(!s->reachable || !s->dynimpname || s->dynexport)
continue;
diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c
index e3093b2aa..60e146b35 100644
--- a/src/cmd/ld/symtab.c
+++ b/src/cmd/ld/symtab.c
@@ -90,6 +90,7 @@ putelfsym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
{
int bind, type, shndx, off;
+ USED(go);
switch(t) {
default:
return;
@@ -127,6 +128,10 @@ putplan9sym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
{
int i;
+ USED(go);
+ USED(ver);
+ USED(size);
+ USED(x);
switch(t) {
case 'T':
case 'L':
@@ -252,6 +257,7 @@ putsymb(Sym *s, char *name, int t, vlong v, vlong size, int ver, Sym *typ)
int i, f, l;
Reloc *rel;
+ USED(size);
if(t == 'f')
name++;
l = 4;
@@ -280,7 +286,6 @@ putsymb(Sym *s, char *name, int t, vlong v, vlong size, int ver, Sym *typ)
}
scput(0);
scput(0);
- i++;
}
else {
for(i=0; name[i]; i++)
@@ -311,9 +316,9 @@ putsymb(Sym *s, char *name, int t, vlong v, vlong size, int ver, Sym *typ)
return;
}
if(ver)
- Bprint(&bso, "%c %.8llux %s<%d> %s\n", t, v, s, ver, typ ? typ->name : "");
+ Bprint(&bso, "%c %.8llux %s<%d> %s\n", t, v, s->name, ver, typ ? typ->name : "");
else
- Bprint(&bso, "%c %.8llux %s %s\n", t, v, s, typ ? typ->name : "");
+ Bprint(&bso, "%c %.8llux %s %s\n", t, v, s->name, typ ? typ->name : "");
}
}
@@ -346,7 +351,7 @@ symtab(void)
s->reachable = 1;
symt = lookup("symtab", 0);
- symt->type = SRODATA;
+ symt->type = SSYMTAB;
symt->size = 0;
symt->reachable = 1;
@@ -367,5 +372,7 @@ symtab(void)
}
}
+ if(debug['s'])
+ return;
genasmsym(putsymb);
}