summaryrefslogtreecommitdiff
path: root/src/cmd/ld/lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/ld/lib.c')
-rw-r--r--src/cmd/ld/lib.c70
1 files changed, 61 insertions, 9 deletions
diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c
index e645502b3..8cd570463 100644
--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -61,6 +61,7 @@ void
libinit(void)
{
fmtinstall('i', iconv);
+ fmtinstall('Y', Yconv);
mywhatsys(); // get goroot, goarch, goos
if(strcmp(goarch, thestring) != 0)
print("goarch is not known: %s\n", goarch);
@@ -470,8 +471,8 @@ eof:
diag("truncated object file: %s", pn);
}
-Sym*
-lookup(char *symb, int v)
+static Sym*
+_lookup(char *symb, int v, int creat)
{
Sym *s;
char *p;
@@ -485,10 +486,12 @@ lookup(char *symb, int v)
// not if(h < 0) h = ~h, because gcc 4.3 -O2 miscompiles it.
h &= 0xffffff;
h %= NHASH;
+ c = symb[0];
for(s = hash[h]; s != S; s = s->hash)
- if(s->version == v)
if(memcmp(s->name, symb, l) == 0)
return s;
+ if(!creat)
+ return nil;
s = mal(sizeof(*s));
if(debug['v'] > 1)
@@ -508,9 +511,25 @@ lookup(char *symb, int v)
s->size = 0;
hash[h] = s;
nsymbol++;
+
+ s->allsym = allsym;
+ allsym = s;
return s;
}
+Sym*
+lookup(char *name, int v)
+{
+ return _lookup(name, v, 1);
+}
+
+// read-only lookup
+Sym*
+rlookup(char *name, int v)
+{
+ return _lookup(name, v, 0);
+}
+
void
copyhistfrog(char *buf, int nbuf)
{
@@ -829,7 +848,7 @@ unmal(void *v, uint32 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
+ * Invalid bytes turn into %xx. Right now the only bytes that need
* escaping are %, ., and ", but we escape all control characters too.
*/
static char*
@@ -1104,7 +1123,7 @@ static Sym *newstack;
enum
{
HasLinkRegister = (thechar == '5'),
- CallSize = (!HasLinkRegister)*PtrSize, // bytes of stack required for a call
+ CallSize = (!HasLinkRegister)*PtrSize, // bytes of stack required for a call
};
void
@@ -1130,7 +1149,7 @@ dostkcheck(void)
// Check calling contexts.
// Some nosplits get called a little further down,
- // like newproc and deferproc. We could hard-code
+ // like newproc and deferproc. We could hard-code
// that knowledge but it's more robust to look at
// the actual call sites.
for(s = textp; s != nil; s = s->next) {
@@ -1283,11 +1302,44 @@ headtype(char *name)
void
undef(void)
{
- int i;
Sym *s;
- for(i=0; i<NHASH; i++)
- for(s = hash[i]; s != S; s = s->hash)
+ for(s = allsym; s != S; s = s->allsym)
if(s->type == SXREF)
diag("%s(%d): not defined", s->name, s->version);
}
+
+int
+Yconv(Fmt *fp)
+{
+ Sym *s;
+ Fmt fmt;
+ int i;
+ char *str;
+
+ s = va_arg(fp->args, Sym*);
+ if (s == S) {
+ fmtprint(fp, "<nil>");
+ } else {
+ fmtstrinit(&fmt);
+ fmtprint(&fmt, "%s @0x%08x [%d]", s->name, s->value, 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;
+}