diff options
Diffstat (limited to 'src/cmd/ld/lib.c')
-rw-r--r-- | src/cmd/ld/lib.c | 70 |
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; +} |