aboutsummaryrefslogtreecommitdiff
path: root/src/libmach/dwarfpubnames.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmach/dwarfpubnames.c')
-rw-r--r--src/libmach/dwarfpubnames.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/libmach/dwarfpubnames.c b/src/libmach/dwarfpubnames.c
new file mode 100644
index 00000000..b09d2866
--- /dev/null
+++ b/src/libmach/dwarfpubnames.c
@@ -0,0 +1,76 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include "elf.h"
+#include "dwarf.h"
+
+static int
+_dwarfnametounit(Dwarf *d, char *name, DwarfBlock *bl, DwarfSym *s)
+{
+ int vers;
+ ulong len, unit, off;
+ uchar *next;
+ char *str;
+ DwarfBuf b;
+
+ b.d = d;
+ b.p = bl->data;
+ b.ep = b.p + bl->len;
+
+ while(b.p < b.ep){
+ len = dwarfget4(&b);
+ if(len > b.ep-b.p){
+ werrstr("bad length in dwarf name header");
+ return -1;
+ }
+ next = b.p + len;
+ vers = dwarfget2(&b);
+ if(vers != 1 && vers != 2){
+ werrstr("bad version %d in dwarf name header", vers);
+ return -1;
+ }
+ unit = dwarfget4(&b);
+ dwarfget4(&b); /* unit length */
+ while(b.p < next){
+ off = dwarfget4(&b);
+ if(off == 0)
+ break;
+ str = dwarfgetstring(&b);
+ if(strcmp(str, name) == 0){
+ if(dwarfenumunit(d, unit, s) < 0)
+ return -1;
+ if(unit + off >= s->b.ep - d->info.data){
+ werrstr("bad offset in name entry");
+ return -1;
+ }
+ s->b.p = d->info.data + unit + off;
+ if(dwarfnextsym(d, s, 1) < 0)
+ return -1;
+ if(s->attrs.name==nil || strcmp(s->attrs.name, name)!=0){
+ werrstr("unexpected name %#q in lookup for %#q", s->attrs.name, name);
+ return -1;
+ }
+ return 0;
+ }
+ }
+ b.p = next;
+ }
+ werrstr("unknown name '%s'", name);
+ return -1;
+}
+
+int
+dwarflookupname(Dwarf *d, char *name, DwarfSym *sym)
+{
+ return _dwarfnametounit(d, name, &d->pubnames, sym);
+}
+
+/*
+
+int
+dwarflookuptype(Dwarf *d, char *name, DwarfSym *sym)
+{
+ return _dwarfnametounit(d, name, &d->pubtypes, sym);
+}
+
+ */