aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-11-29 19:02:19 +0000
committerrsc <devnull@localhost>2005-11-29 19:02:19 +0000
commit7dc9c4c62cb6a0c803e76ef06eb5d145c5375692 (patch)
tree8c46294587a1f5a48e0bcb040b938b9e8c88a0fe
parent72dd4491a89b97cff9941f692b81c682b3f2a506 (diff)
downloadplan9port-7dc9c4c62cb6a0c803e76ef06eb5d145c5375692.tar.gz
plan9port-7dc9c4c62cb6a0c803e76ef06eb5d145c5375692.tar.bz2
plan9port-7dc9c4c62cb6a0c803e76ef06eb5d145c5375692.zip
more mangler
-rw-r--r--src/libmach/mangle.c10
-rw-r--r--src/libmach/manglegcc2.c55
-rw-r--r--src/libmach/sym.c75
3 files changed, 119 insertions, 21 deletions
diff --git a/src/libmach/mangle.c b/src/libmach/mangle.c
index e9030252..e2d827ce 100644
--- a/src/libmach/mangle.c
+++ b/src/libmach/mangle.c
@@ -43,14 +43,8 @@ demangle(char *s, char *buf, int strip)
nparen--;
break;
default:
- if(nparen == 0 && nangle == 0){
- if(*r == ':' && *(r+1) == ':'){
- *w++ = '$';
- r++;
- }
- else
- *w++ = *r;
- }
+ if(nparen == 0 && nangle == 0)
+ *w++ = *r;
break;
}
}
diff --git a/src/libmach/manglegcc2.c b/src/libmach/manglegcc2.c
index 59f4d46e..1fae4ebe 100644
--- a/src/libmach/manglegcc2.c
+++ b/src/libmach/manglegcc2.c
@@ -7,6 +7,7 @@
*
* Not implemented:
* unicode mangling
+ * rename operator functions
*/
/*
RULES TO ADD:
@@ -178,7 +179,9 @@ demanglegcc2(char *s, char *buf)
if(name == constructor || name == destructor){
*p = 0;
t = strrchr(buf, ':');
- if(t == nil)
+ if(t)
+ t++;
+ else
t = buf;
}
strcpy(p, "::");
@@ -190,6 +193,8 @@ demanglegcc2(char *s, char *buf)
name = t;
}
}
+ if(p >= buf+2 && memcmp(p-2, "::", 2) == 0 && *(p-3) == ')')
+ p -= 2;
memmove(p, name, namelen);
p += namelen;
@@ -444,6 +449,8 @@ gccname(char **ps, char **pp)
break;
case 'H': /* template specialization */
+ if(memcmp(s-2, "__", 2) != 0)
+ fprint(2, "wow: %s\n", s-2);
t = s;
s++;
if(!gccnumber(&s, &n, 0))
@@ -474,14 +481,44 @@ gccname(char **ps, char **pp)
return 0;
}
s++;
- p1 = p;
- /* name */
- if(!gccname(&s, &p))
- return 0;
- /* XXX
-__adjust_heap__H3ZPt4pair2Zt12basic_string3ZcZt11char_traits1ZcZt9allocator1ZcZt12basic_string3ZcZt11char_traits1ZcZt9allocator1ZcZiZt4pair2Zt12basic_string3ZcZt11char_traits1ZcZt9allocator1ZcZt12basic_string3ZcZt11char_traits1ZcZt9allocator1Zc_X01X11X11X21_v
- */
- /* XXX swap p0, p1, p - maybe defer to main */
+
+ /*
+ * Can't seem to tell difference between a qualifying name
+ * and arguments. Not sure which is which. It appears that if
+ * you get a name, use it, otherwise look for types.
+ * The G type qualifier appears to have no effect other than
+ * turning an ambiguous name into a definite type.
+ *
+ * SetFlag__H1Zb_P15FlagSettingMode_v
+ * => void SetFlag<bool>(FlagSettingMode *)
+ * SetFlag__H1Zb_15FlagSettingMode_v
+ * => void FlagSettingMode::SetFlag<bool>()
+ * SetFlag__H1Zb_G15FlagSettingMode_v
+ * => void SetFlag<bool>(FlagSettingMode)
+ */
+ if(strchr("ACFGPRSUVX", *s)){
+ /* args */
+ t = s;
+ p1 = p;
+ *p++ = '(';
+ while(*s != '_'){
+ if(*s == 0 || !gccname(&s, &p)){
+ werrstr("bad H args: %s", t);
+ return 0;
+ }
+ }
+ *p++ = ')';
+ s++;
+ }else{
+ p1 = p;
+ /* name */
+ if(!gccname(&s, &p))
+ return 0;
+ }
+ /*
+ * Need to do some rearrangement of <> () and names here.
+ * Doesn't matter since we strip out the <> and () anyway.
+ */
break;
case 'M': /* M1S: pointer to member */
diff --git a/src/libmach/sym.c b/src/libmach/sym.c
index c3d05191..a5b057de 100644
--- a/src/libmach/sym.c
+++ b/src/libmach/sym.c
@@ -187,6 +187,40 @@ flookupsym(Fhdr *fhdr, char *name)
return nil;
}
+Symbol*
+flookupsymx(Fhdr *fhdr, char *name)
+{
+ Symbol **a, *t;
+ uint n, m;
+ int i;
+
+ a = fhdr->byxname;
+ n = fhdr->nsym;
+ if(a == nil)
+ return nil;
+
+ while(n > 0){
+ m = n/2;
+ t = a[m];
+ i = strcmp(name, t->xname);
+ if(i < 0)
+ n = m;
+ else if(i > 0){
+ n -= m+1;
+ a += m+1;
+ }else{
+ /* found! */
+ m += a - fhdr->byxname;
+ a = fhdr->byxname;
+ assert(strcmp(name, a[m]->xname) == 0);
+ while(m > 0 && strcmp(name, a[m-1]->xname) == 0)
+ m--;
+ return a[m];
+ }
+ }
+ return nil;
+}
+
int
lookupsym(char *fn, char *var, Symbol *s)
{
@@ -199,10 +233,12 @@ lookupsym(char *fn, char *var, Symbol *s)
return -1;
t = nil;
for(p=fhdrlist; p; p=p->next)
- if((t=flookupsym(p, nam)) != nil){
+ if((t=flookupsym(p, nam)) != nil
+ || (t=flookupsymx(p, nam)) != nil){
relocsym(&s1, t, p->base);
break;
}
+
if(t == nil)
goto err;
if(fn && var)
@@ -423,6 +459,27 @@ byloccmp(const void *va, const void *vb)
/* name, location, class */
static int
+byxnamecmp(const void *va, const void *vb)
+{
+ int i;
+ Symbol *a, *b;
+
+ a = *(Symbol**)va;
+ b = *(Symbol**)vb;
+ i = strcmp(a->xname, b->xname);
+ if(i != 0)
+ return i;
+ i = strcmp(a->name, b->name);
+ if(i != 0)
+ return i;
+ i = loccmp(&a->loc, &b->loc);
+ if(i != 0)
+ return i;
+ return a->class - b->class;
+}
+
+/* name, location, class */
+static int
bynamecmp(const void *va, const void *vb)
{
int i;
@@ -466,12 +523,21 @@ symopen(Fhdr *hdr)
hdr->byname = malloc(hdr->nsym*sizeof(hdr->byname[0]));
if(hdr->byname == nil){
- fprint(2, "could not allocate table to sort by location\n");
+ fprint(2, "could not allocate table to sort by name\n");
}else{
for(i=0; i<hdr->nsym; i++)
hdr->byname[i] = &hdr->sym[i];
qsort(hdr->byname, hdr->nsym, sizeof(hdr->byname[0]), bynamecmp);
}
+
+ hdr->byxname = malloc(hdr->nsym*sizeof(hdr->byxname[0]));
+ if(hdr->byxname == nil){
+ fprint(2, "could not allocate table to sort by xname\n");
+ }else{
+ for(i=0; i<hdr->nsym; i++)
+ hdr->byxname[i] = &hdr->sym[i];
+ qsort(hdr->byxname, hdr->nsym, sizeof(hdr->byxname[0]), byxnamecmp);
+ }
return 0;
}
@@ -506,10 +572,11 @@ _addsym(Fhdr *fp, Symbol *sym)
sym->fhdr = fp;
t = demangle(sym->name, buf, 1);
if(t != sym->name){
- sym->name = strdup(t);
- if(sym->name == nil)
+ t = strdup(t);
+ if(t == nil)
return nil;
}
+ sym->xname = t;
s = &fp->sym[fp->nsym++];
*s = *sym;
return s;