name mangling, process control
This commit is contained in:
parent
689be54125
commit
7d6f5677c1
6 changed files with 780 additions and 10 deletions
|
|
@ -47,13 +47,6 @@ ptraceattach(int pid)
|
|||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
if(nattached==1 && attachedpids[0] == pid)
|
||||
goto already;
|
||||
if(nattached)
|
||||
detachproc(attachedpids[0]);
|
||||
*/
|
||||
|
||||
for(i=0; i<nattached; i++)
|
||||
if(attachedpids[i]==pid)
|
||||
return 0;
|
||||
|
|
@ -243,7 +236,7 @@ ptraceregrw(Regs *regs, char *name, ulong *val, int isr)
|
|||
*val = u;
|
||||
}else{
|
||||
u = *val;
|
||||
if(ptrace(PTRACE_POKEUSER, pid, addr, &u) < 0)
|
||||
if(ptrace(PTRACE_POKEUSER, pid, addr, (void*)u) < 0)
|
||||
goto ptraceerr;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -321,7 +314,6 @@ isstopped(int pid)
|
|||
36. processor
|
||||
*/
|
||||
|
||||
|
||||
int
|
||||
procnotes(int pid, char ***pnotes)
|
||||
{
|
||||
|
|
@ -386,7 +378,19 @@ procnotes(int pid, char ***pnotes)
|
|||
int
|
||||
ctlproc(int pid, char *msg)
|
||||
{
|
||||
int p, status;
|
||||
int i, p, status;
|
||||
|
||||
if(strcmp(msg, "attached") == 0){
|
||||
for(i=0; i<nattached; i++)
|
||||
if(attachedpids[i]==pid)
|
||||
return 0;
|
||||
if(nattached == nelem(attachedpids)){
|
||||
werrstr("attached to too many processes");
|
||||
return -1;
|
||||
}
|
||||
attachedpids[nattached++] = pid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(strcmp(msg, "hang") == 0){
|
||||
if(pid == getpid())
|
||||
|
|
@ -411,6 +415,11 @@ ctlproc(int pid, char *msg)
|
|||
return -1;
|
||||
goto waitstop;
|
||||
}
|
||||
if(strcmp(msg, "step") == 0){
|
||||
if(ptrace(PTRACE_SINGLESTEP, pid, 0, 0) < 0)
|
||||
return -1;
|
||||
goto waitstop;
|
||||
}
|
||||
if(strcmp(msg, "waitstop") == 0){
|
||||
waitstop:
|
||||
if(isstopped(pid))
|
||||
|
|
@ -424,6 +433,7 @@ ctlproc(int pid, char *msg)
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
//fprint(2, "got pid %d status %x\n", pid, status);
|
||||
if(WIFEXITED(status) || WIFSTOPPED(status))
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
73
src/libmach/mangle.c
Normal file
73
src/libmach/mangle.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <mach.h>
|
||||
|
||||
static char *(*demanglers[])(char*, char*) =
|
||||
{
|
||||
demanglegcc2,
|
||||
demanglegcc3,
|
||||
};
|
||||
|
||||
char*
|
||||
demangle(char *s, char *buf, int strip)
|
||||
{
|
||||
char *t;
|
||||
char *r, *w;
|
||||
int i, nangle, nparen;
|
||||
|
||||
for(i=0; i<nelem(demanglers); i++){
|
||||
t = demanglers[i](s, buf);
|
||||
if(t != s)
|
||||
break;
|
||||
}
|
||||
if(t == s || !strip)
|
||||
return t;
|
||||
|
||||
/* copy name without <> and () - not right, but convenient */
|
||||
/* convert :: to $ - not right, but convenient (should fix acid) */
|
||||
nangle = 0;
|
||||
nparen = 0;
|
||||
for(r=w=buf; *r; r++){
|
||||
switch(*r){
|
||||
case '<':
|
||||
nangle++;
|
||||
break;
|
||||
case '>':
|
||||
nangle--;
|
||||
break;
|
||||
case '(':
|
||||
nparen++;
|
||||
break;
|
||||
case ')':
|
||||
nparen--;
|
||||
break;
|
||||
default:
|
||||
if(nparen == 0 && nangle == 0){
|
||||
if(*r == ':' && *(r+1) == ':'){
|
||||
*w++ = '$';
|
||||
r++;
|
||||
}
|
||||
else
|
||||
*w++ = *r;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
*w = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
void
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=1; i<argc; i++){
|
||||
print("%s\n", demangle(argv[i], 0));
|
||||
print("\t%s\n", demangle(argv[i], 1));
|
||||
}
|
||||
exits(nil);
|
||||
}
|
||||
#endif
|
||||
337
src/libmach/manglegcc2.c
Normal file
337
src/libmach/manglegcc2.c
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
* gcc2 name demangler.
|
||||
*/
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <mach.h>
|
||||
|
||||
#define debug 0
|
||||
|
||||
typedef struct Chartab Chartab;
|
||||
struct Chartab
|
||||
{
|
||||
char c;
|
||||
char *s;
|
||||
};
|
||||
|
||||
static char*
|
||||
chartabsearch(Chartab *ct, int c)
|
||||
{
|
||||
for(; ct->c; ct++)
|
||||
if(ct->c == c)
|
||||
return ct->s;
|
||||
return nil;
|
||||
}
|
||||
|
||||
typedef struct Gccstate Gccstate;
|
||||
struct Gccstate
|
||||
{
|
||||
char *name[128];
|
||||
int nname;
|
||||
};
|
||||
static int gccname(char**, char**, Gccstate*);
|
||||
char*
|
||||
demanglegcc2(char *s, char *buf)
|
||||
{
|
||||
char *p, *os, *name, *t;
|
||||
int namelen;
|
||||
Gccstate state;
|
||||
|
||||
state.nname = 0;
|
||||
os = s;
|
||||
p = buf;
|
||||
|
||||
if(memcmp(os, "_._", 3) == 0){
|
||||
name = "destructor";
|
||||
namelen = strlen(name);
|
||||
s = os+3;
|
||||
}else{
|
||||
/* the mangled part begins with the final __ */
|
||||
if((s = strstr(os, "__")) == nil)
|
||||
return os;
|
||||
do{
|
||||
t = s;
|
||||
if(strchr("123456789FHQt", s[2]))
|
||||
break;
|
||||
}while((s = strstr(t+1, "__")) != nil);
|
||||
|
||||
s = t;
|
||||
name = os;
|
||||
namelen = t - os;
|
||||
if(namelen == 0){
|
||||
name = "constructor";
|
||||
namelen = strlen(name);
|
||||
}
|
||||
s += 2;
|
||||
}
|
||||
|
||||
switch(*s){
|
||||
default:
|
||||
return os;
|
||||
|
||||
case 'F': /* plain function */
|
||||
s++;
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
case 'H':
|
||||
case 't':
|
||||
case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
if(!gccname(&s, &p, &state)){
|
||||
if(debug) fprint(2, "bad name: %s\n", os);
|
||||
return os;
|
||||
}
|
||||
strcpy(p, "::");
|
||||
p += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
memmove(p, name, namelen);
|
||||
p += namelen;
|
||||
|
||||
if(*s && *s != '_'){
|
||||
/* the rest of the name is the argument types */
|
||||
*p++ = '(';
|
||||
while(*s != 0 && *s != '_' && gccname(&s, &p, &state))
|
||||
*p++ = ',';
|
||||
if(*(p-1) == ',')
|
||||
p--;
|
||||
*p++ = ')';
|
||||
}
|
||||
|
||||
if(*s == '_'){
|
||||
/* the remainder is the type of the return value */
|
||||
}
|
||||
|
||||
*p = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static Chartab typetab[] =
|
||||
{
|
||||
'b', "bool",
|
||||
'c', "char",
|
||||
'd', "double",
|
||||
'i', "int",
|
||||
'l', "long",
|
||||
'v', "void",
|
||||
0, 0
|
||||
};
|
||||
|
||||
static int
|
||||
gccnumber(char **ps, int *pn)
|
||||
{
|
||||
char *s;
|
||||
int n;
|
||||
|
||||
s = *ps;
|
||||
if(!isdigit((uchar)*s))
|
||||
return 0;
|
||||
n = strtol(s, &s, 10);
|
||||
if(*s == '_')
|
||||
s++;
|
||||
*ps = s;
|
||||
*pn = n;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pick apart the next mangled name section.
|
||||
* Names and types are treated as the same.
|
||||
* Let's see how far we can go before that becomes a problem.
|
||||
*/
|
||||
static int
|
||||
gccname(char **ps, char **pp, Gccstate *state)
|
||||
{
|
||||
int i, n, m, val;
|
||||
char c, *os, *s, *t, *p;
|
||||
|
||||
s = *ps;
|
||||
os = s;
|
||||
p = *pp;
|
||||
|
||||
/* print("\tgccname: %s\n", s); */
|
||||
|
||||
#if 0
|
||||
/* overloaded operators */
|
||||
for(i=0; operators[i].shrt; i++){
|
||||
if(memcmp(operators[i].shrt, s, 2) == 0){
|
||||
strcpy(p, "operator$");
|
||||
strcat(p, operators[i].lng);
|
||||
p += strlen(p);
|
||||
s += 2;
|
||||
goto suffix;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* basic types */
|
||||
if((t = chartabsearch(typetab, *s)) != nil){
|
||||
s++;
|
||||
strcpy(p, t);
|
||||
p += strlen(t);
|
||||
goto suffix;
|
||||
}
|
||||
|
||||
switch(*s){
|
||||
default:
|
||||
bad:
|
||||
if(debug) fprint(2, "gccname: %s (%s)\n", os, s);
|
||||
return 0;
|
||||
|
||||
case '1': case '2': case '3': case '4': /* name length */
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
n = strtol(s, &s, 10);
|
||||
memmove(p, s, n);
|
||||
p += n;
|
||||
s += n;
|
||||
break;
|
||||
|
||||
case 'C': /* const */
|
||||
s++;
|
||||
strcpy(p, "const ");
|
||||
p += strlen(p);
|
||||
if(!gccname(&s, &p, state))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case 'U': /* unsigned */
|
||||
s++;
|
||||
strcpy(p, "unsigned ");
|
||||
p += strlen(p);
|
||||
if(!gccname(&s, &p, state))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case 'L': /* default value */
|
||||
t = s;
|
||||
s++;
|
||||
if(!gccname(&s, &p, state))
|
||||
return 0;
|
||||
if(!isdigit((uchar)*s)){
|
||||
fprint(2, "bad value: %s\n", t);
|
||||
return 0;
|
||||
}
|
||||
n = strtol(s, &s, 10);
|
||||
if(*s != 'E'){
|
||||
fprint(2, "bad value2: %s\n", t);
|
||||
return 0;
|
||||
}
|
||||
sprint(p, "=%d", n);
|
||||
p += strlen(p);
|
||||
s++;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'N': /* repeated name/type */
|
||||
case 'X':
|
||||
c = *s++;
|
||||
if(!isdigit((uchar)*s) || !isdigit((uchar)*(s+1)))
|
||||
goto bad;
|
||||
n = *s++ - '0';
|
||||
m = *s++ - '0';
|
||||
sprint(p, "%c%d/%d", c, n, m);
|
||||
p += strlen(p);
|
||||
break;
|
||||
|
||||
case 'Q': /* hierarchical name */
|
||||
s++;
|
||||
if(!isdigit((uchar)*s))
|
||||
goto bad;
|
||||
n = *s++ - '0';
|
||||
for(i=0; i<n; i++){
|
||||
if(!gccname(&s, &p, state)){
|
||||
if(debug) fprint(2, "bad name in hierarchy: %s in %s\n", s, os);
|
||||
return 0;
|
||||
}
|
||||
if(i+1 < n){
|
||||
strcpy(p, "::");
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'P': /* pointer to */
|
||||
s++;
|
||||
if(!gccname(&s, &p, state))
|
||||
return 0;
|
||||
*p++ = '*';
|
||||
break;
|
||||
|
||||
case 'R': /* reference to */
|
||||
s++;
|
||||
if(!gccname(&s, &p, state))
|
||||
return 0;
|
||||
*p++ = '&';
|
||||
break;
|
||||
|
||||
case 'S': /* standard or previously-seen name */
|
||||
s++;
|
||||
if('0' <= *s && *s <= '9'){
|
||||
/* previously seen */
|
||||
t = s-1;
|
||||
n = strtol(s, &s, 10);
|
||||
if(*s != '_'){
|
||||
fprint(2, "bad S: %s\n", t);
|
||||
return 0;
|
||||
}
|
||||
s++;
|
||||
sprint(p, "S%d_", n);
|
||||
p += strlen(p);
|
||||
break;
|
||||
}
|
||||
goto bad;
|
||||
|
||||
case 't': /* named template */
|
||||
c = *s++;
|
||||
if(!gccname(&s, &p, state))
|
||||
return 0;
|
||||
goto template;
|
||||
case 'H': /* nameless template */
|
||||
c = *s++;
|
||||
template:
|
||||
if(!gccnumber(&s, &n))
|
||||
goto bad;
|
||||
*p++ = '<';
|
||||
for(i=0; i<n; i++){
|
||||
val = 1;
|
||||
if(*s == 'Z'){
|
||||
val = 0;
|
||||
s++;
|
||||
}
|
||||
if(!gccname(&s, &p, state))
|
||||
goto bad;
|
||||
if(val){
|
||||
if(!gccnumber(&s, &m))
|
||||
goto bad;
|
||||
sprint(p, "=%d", m);
|
||||
p += strlen(p);
|
||||
}
|
||||
if(i+1 < n)
|
||||
*p++ = ',';
|
||||
}
|
||||
*p++ = '>';
|
||||
if(c == 'H'){
|
||||
if(*s != '_')
|
||||
goto bad;
|
||||
s++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'T': /* previously-seen type??? e.g., T2 */
|
||||
t = s;
|
||||
for(s++; isdigit((uchar)*s); s++)
|
||||
;
|
||||
memmove(p, t, s-t);
|
||||
p += s-t;
|
||||
break;
|
||||
}
|
||||
|
||||
suffix:
|
||||
*ps = s;
|
||||
*pp = p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
339
src/libmach/manglegcc3.c
Normal file
339
src/libmach/manglegcc3.c
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
/*
|
||||
* gcc3 name demangler.
|
||||
*/
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <mach.h>
|
||||
|
||||
typedef struct Chartab Chartab;
|
||||
struct Chartab
|
||||
{
|
||||
char c;
|
||||
char *s;
|
||||
};
|
||||
|
||||
static char*
|
||||
chartabsearch(Chartab *ct, int c)
|
||||
{
|
||||
for(; ct->c; ct++)
|
||||
if(ct->c == c)
|
||||
return ct->s;
|
||||
return nil;
|
||||
}
|
||||
|
||||
typedef struct Gccstate Gccstate;
|
||||
struct Gccstate
|
||||
{
|
||||
char *name[128];
|
||||
int nname;
|
||||
};
|
||||
static int gccname(char**, char**, Gccstate*);
|
||||
char*
|
||||
demanglegcc3(char *s, char *buf)
|
||||
{
|
||||
char *p, *os;
|
||||
Gccstate state;
|
||||
|
||||
state.nname = 0;
|
||||
os = s;
|
||||
/* mangled names always start with _Z */
|
||||
if(s[0] != '_' || s[1] != 'Z')
|
||||
return s;
|
||||
s += 2;
|
||||
|
||||
p = buf;
|
||||
if(!gccname(&s, &p, &state)){
|
||||
if(strchr(os, '@') == nil)
|
||||
fprint(2, "demangle: %s\n");
|
||||
return os;
|
||||
}
|
||||
if(*s){
|
||||
/* the rest of the name is the argument types */
|
||||
*p++ = '(';
|
||||
while(*s != 0 && gccname(&s, &p, &state))
|
||||
*p++ = ',';
|
||||
if(*(p-1) == ',')
|
||||
p--;
|
||||
*p++ = ')';
|
||||
}
|
||||
*p = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static Chartab stdnames[] =
|
||||
{
|
||||
'a', "std::allocator",
|
||||
'b', "std::basic_string",
|
||||
'd', "std::iostream",
|
||||
'i', "std::istream",
|
||||
'o', "std::ostream",
|
||||
's', "std::string",
|
||||
0, 0
|
||||
};
|
||||
|
||||
static Chartab typetab[] =
|
||||
{
|
||||
'b', "bool",
|
||||
'c', "char",
|
||||
'd', "double",
|
||||
'i', "int",
|
||||
'j', "uint",
|
||||
'v', "void",
|
||||
0, 0
|
||||
};
|
||||
|
||||
static struct {
|
||||
char *shrt;
|
||||
char *actual;
|
||||
char *lng;
|
||||
} operators[] =
|
||||
{
|
||||
"aN", "&=", "andeq",
|
||||
"aS", "=", "assign",
|
||||
"aa", "&&", "andand",
|
||||
"ad", "&", "and",
|
||||
"an", "&", "and",
|
||||
"cl", "()", "construct",
|
||||
"cm", ",", "comma",
|
||||
"co", "~", "twiddle",
|
||||
"dV", "/=", "diveq",
|
||||
"da", "delete[]", "deletearray",
|
||||
"de", "*", "star",
|
||||
"dl", "delete", "delete",
|
||||
"dv", "/", "div",
|
||||
"eO", "^=", "xoreq",
|
||||
"eo", "^", "xor",
|
||||
"eq", "==", "eq",
|
||||
"ge", ">=", "geq",
|
||||
"gt", ">", "gt",
|
||||
"ix", "[]", "index",
|
||||
"IS", "<<=", "lsheq",
|
||||
"le", "<=", "leq",
|
||||
"ls", "<<", "lsh",
|
||||
"lt", "<", "lt",
|
||||
"ml", "-=", "subeq",
|
||||
"mL", "*=", "muleq",
|
||||
"mi", "-", "sub",
|
||||
"mI", "*", "mul",
|
||||
"mm", "--", "dec",
|
||||
"na", "new[]", "newarray",
|
||||
"ne", "!=", "neq",
|
||||
"ng", "-", "neg",
|
||||
"nt", "!", "not",
|
||||
"nw", "new", "new",
|
||||
"oR", "|=", "oreq",
|
||||
"oo", "||", "oror",
|
||||
"or", "|", "or",
|
||||
"pL", "+=", "addeq",
|
||||
"pl", "+", "add",
|
||||
"pm", "->*", "pointstoderef",
|
||||
"pp", "++", "inc",
|
||||
"ps", "+", "pos",
|
||||
"pt", "->", "pointsto",
|
||||
"qu", "?", "question",
|
||||
"rM", "%=", "modeq",
|
||||
"rS", ">>=", "rsheq",
|
||||
"rm", "%", "mod",
|
||||
"rs", ">>", "rsh",
|
||||
"st", "sizeof", "sizeoftype",
|
||||
"sz", "sizeof", "sizeofexpr",
|
||||
|
||||
0,0,0
|
||||
};
|
||||
|
||||
/*
|
||||
* Pick apart the next mangled name section.
|
||||
* Names and types are treated as the same.
|
||||
* Let's see how far we can go before that becomes a problem.
|
||||
*/
|
||||
static int
|
||||
gccname(char **ps, char **pp, Gccstate *state)
|
||||
{
|
||||
int i, n;
|
||||
char *os, *s, *t, *p;
|
||||
Gccstate nstate;
|
||||
|
||||
s = *ps;
|
||||
os = s;
|
||||
p = *pp;
|
||||
|
||||
/* print("\tgccname: %s\n", s); */
|
||||
|
||||
/* overloaded operators */
|
||||
for(i=0; operators[i].shrt; i++){
|
||||
if(memcmp(operators[i].shrt, s, 2) == 0){
|
||||
strcpy(p, "operator$");
|
||||
strcat(p, operators[i].lng);
|
||||
p += strlen(p);
|
||||
s += 2;
|
||||
goto suffix;
|
||||
}
|
||||
}
|
||||
|
||||
/* basic types */
|
||||
if((t = chartabsearch(typetab, *s)) != nil){
|
||||
s++;
|
||||
strcpy(p, t);
|
||||
p += strlen(t);
|
||||
goto suffix;
|
||||
}
|
||||
|
||||
switch(*s){
|
||||
default:
|
||||
bad:
|
||||
fprint(2, "bad name: %s\n", s);
|
||||
return 0;
|
||||
|
||||
case '1': case '2': case '3': case '4': /* name length */
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
n = strtol(s, &s, 10);
|
||||
memmove(p, s, n);
|
||||
p += n;
|
||||
s += n;
|
||||
break;
|
||||
|
||||
case 'C': /* C1: constructor? */
|
||||
strtol(s+1, &s, 10);
|
||||
strcpy(p, "constructor");
|
||||
p += strlen(p);
|
||||
break;
|
||||
|
||||
case 'D': /* D1: destructor? */
|
||||
strtol(s+1, &s, 10);
|
||||
strcpy(p, "destructor");
|
||||
p += strlen(p);
|
||||
break;
|
||||
|
||||
case 'K': /* const */
|
||||
s++;
|
||||
strcpy(p, "const ");
|
||||
p += strlen(p);
|
||||
if(!gccname(&s, &p, state))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case 'L': /* default value */
|
||||
t = s;
|
||||
s++;
|
||||
if(!gccname(&s, &p, state))
|
||||
return 0;
|
||||
if(!isdigit((uchar)*s)){
|
||||
fprint(2, "bad value: %s\n", t);
|
||||
return 0;
|
||||
}
|
||||
n = strtol(s, &s, 10);
|
||||
if(*s != 'E'){
|
||||
fprint(2, "bad value2: %s\n", t);
|
||||
return 0;
|
||||
}
|
||||
sprint(p, "=%d", n);
|
||||
p += strlen(p);
|
||||
s++;
|
||||
break;
|
||||
|
||||
case 'N': /* hierarchical name */
|
||||
s++;
|
||||
while(*s != 'E'){
|
||||
if(!gccname(&s, &p, state)){
|
||||
fprint(2, "bad name in hierarchy: %s in %s\n", s, os);
|
||||
return 0;
|
||||
}
|
||||
strcpy(p, "::");
|
||||
p += 2;
|
||||
}
|
||||
p -= 2;
|
||||
s++;
|
||||
break;
|
||||
|
||||
case 'P': /* pointer to */
|
||||
s++;
|
||||
if(!gccname(&s, &p, state))
|
||||
return 0;
|
||||
*p++ = '*';
|
||||
break;
|
||||
|
||||
case 'R': /* reference to */
|
||||
s++;
|
||||
if(!gccname(&s, &p, state))
|
||||
return 0;
|
||||
*p++ = '&';
|
||||
break;
|
||||
|
||||
case 'S': /* standard or previously-seen name */
|
||||
s++;
|
||||
if('0' <= *s && *s <= '9'){
|
||||
/* previously seen */
|
||||
t = s-1;
|
||||
n = strtol(s, &s, 10);
|
||||
if(*s != '_'){
|
||||
fprint(2, "bad S: %s\n", t);
|
||||
return 0;
|
||||
}
|
||||
s++;
|
||||
sprint(p, "S%d_", n);
|
||||
p += strlen(p);
|
||||
break;
|
||||
}
|
||||
/* SA_ ??? */
|
||||
if(*s == 'A' && *(s+1) == '_'){
|
||||
strcpy(p, "SA_");
|
||||
p += 3;
|
||||
s += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
/* standard name */
|
||||
if(*s == 't'){
|
||||
strcpy(p, "std::");
|
||||
p += 5;
|
||||
s++;
|
||||
if(!gccname(&s, &p, state))
|
||||
return 0;
|
||||
}else if((t = chartabsearch(stdnames, *s)) != nil){
|
||||
strcpy(p, t);
|
||||
p += strlen(p);
|
||||
s++;
|
||||
}else{
|
||||
strcpy(p, "std::");
|
||||
p += 5;
|
||||
*p++ = *s++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'T': /* previously-seen type??? T0_ also T_*/
|
||||
t = s;
|
||||
for(; *s != '_'; s++){
|
||||
if(*s == 0){
|
||||
s = t;
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
s++;
|
||||
memmove(p, t, s-t);
|
||||
p += s-t;
|
||||
break;
|
||||
}
|
||||
|
||||
suffix:
|
||||
if(*s == 'I'){
|
||||
/* template suffix */
|
||||
nstate.nname = 0;
|
||||
*p++ = '<';
|
||||
s++;
|
||||
while(*s != 'E'){
|
||||
if(!gccname(&s, &p, &nstate)){
|
||||
fprint(2, "bad name in template: %s\n", s);
|
||||
return 0;
|
||||
}
|
||||
*p++ = ',';
|
||||
}
|
||||
*(p-1) = '>';
|
||||
s++;
|
||||
}
|
||||
|
||||
*ps = s;
|
||||
*pp = p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -32,6 +32,9 @@ OFILES=\
|
|||
macho.$O\
|
||||
machocorepower.$O\
|
||||
machpower.$O\
|
||||
mangle.$O\
|
||||
manglegcc2.$O\
|
||||
manglegcc3.$O\
|
||||
map.$O\
|
||||
regs.$O\
|
||||
stabs.$O\
|
||||
|
|
|
|||
|
|
@ -491,6 +491,8 @@ symclose(Fhdr *hdr)
|
|||
Symbol*
|
||||
_addsym(Fhdr *fp, Symbol *sym)
|
||||
{
|
||||
char *t;
|
||||
static char buf[65536];
|
||||
Symbol *s;
|
||||
|
||||
if(fp->nsym%128 == 0){
|
||||
|
|
@ -502,6 +504,12 @@ _addsym(Fhdr *fp, Symbol *sym)
|
|||
if(machdebug)
|
||||
fprint(2, "sym %s %c %L\n", sym->name, sym->type, sym->loc);
|
||||
sym->fhdr = fp;
|
||||
t = demangle(sym->name, buf, 1);
|
||||
if(t != sym->name){
|
||||
sym->name = strdup(t);
|
||||
if(sym->name == nil)
|
||||
return nil;
|
||||
}
|
||||
s = &fp->sym[fp->nsym++];
|
||||
*s = *sym;
|
||||
return s;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue