tmore mangler - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
commit 7dc9c4c62cb6a0c803e76ef06eb5d145c5375692
parent 72dd4491a89b97cff9941f692b81c682b3f2a506
Author: rsc 
Date:   Tue, 29 Nov 2005 19:02:19 +0000

more mangler

Diffstat:
  M src/libmach/mangle.c                |      10 ++--------
  M src/libmach/manglegcc2.c            |      55 ++++++++++++++++++++++++++-----
  M src/libmach/sym.c                   |      75 +++++++++++++++++++++++++++++--

3 files changed, 119 insertions(+), 21 deletions(-)
---
diff --git a/src/libmach/mangle.c b/src/libmach/mangle.c
t@@ -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
t@@ -7,6 +7,7 @@
  *
  * Not implemented:
  *        unicode mangling
+ *        rename operator functions
  */
 /*
 RULES TO ADD:
t@@ -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, "::");
t@@ -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;
         
t@@ -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))
t@@ -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(FlagSettingMode *)
+                 *        SetFlag__H1Zb_15FlagSettingMode_v
+                 *        =>        void FlagSettingMode::SetFlag()
+                 *        SetFlag__H1Zb_G15FlagSettingMode_v
+                 *        =>        void SetFlag(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
t@@ -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)
 {
t@@ -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)
t@@ -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;
t@@ -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; insym; 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; insym; i++)
+                        hdr->byxname[i] = &hdr->sym[i];
+                qsort(hdr->byxname, hdr->nsym, sizeof(hdr->byxname[0]), byxnamecmp);
+        }
         return 0;
 }
 
t@@ -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;