URI: 
       tmore mangler - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 7dc9c4c62cb6a0c803e76ef06eb5d145c5375692
   DIR parent 72dd4491a89b97cff9941f692b81c682b3f2a506
  HTML Author: rsc <devnull@localhost>
       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(-)
       ---
   DIR 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;
                        }
                }
   DIR 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<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 */
   DIR 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; 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;
        }
        
       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;