commit 7dc9c4c62cb6a0c803e76ef06eb5d145c5375692 from: rsc date: Tue Nov 29 19:02:19 2005 UTC more mangler commit - 72dd4491a89b97cff9941f692b81c682b3f2a506 commit + 7dc9c4c62cb6a0c803e76ef06eb5d145c5375692 blob - e9030252edcd69b7e9ea693b917146343452c4a4 blob + e2d827ceb127ecd1313d1409108f9f6ade9f244f --- src/libmach/mangle.c +++ 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; } } blob - 59f4d46e549c840a69e05e465a3b7ca54e01e6bf blob + 1fae4ebe250b4106c1e2f26f49678631e375332f --- src/libmach/manglegcc2.c +++ 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(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 */ blob - c3d05191311a6bf1897a87bd3da31c9a984ac0dd blob + a5b057de075dbe78a59f09156c8009c700a84cff --- src/libmach/sym.c +++ 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; 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; } @@ -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;