📄 mangle.cpp
字号:
out_ref_ptr(t);
out(cc);
out_classname(pc);
if (! m_dont_lookup_class) mClassList.push_back(pc);
}
}
};
OpNames gcc2_fns[] = {
{"=", "as"},
{"==","eq"},
{"!=","ne"}, // *fix 1.2.4 added
{"[]","vc"},
{"<<","ls"},
{">>","rs"},
{"+","pl"},
{"-","mi"},
{"+=","apl"},
{"-=","ami"},
{"*","ml"},
{"++","pp"},
{"--","mm"},
{"<","lt"},
{">","gt"},
{"&&","aa"},
{"||","oo"},
{"&","ad"},
{"|","or"},
{NULL,NULL}
};
class GCC2Mangler: public Mangler {
public:
GCC2Mangler()
{
m_begin_name = "";
m_rpt_type = "T";
m_void_args = "v";
m_end_stdarg = "e";
m_end_args = "";
m_plain_function = "F";
m_function_ptr = "PF";
m_method_ptr = ""; // ?que
m_end_function_ptr = "_v";
m_method_ptr_type = ""; // *add 1.2.3
m_use_return_type = false;
m_plain_obj = "G";
m_const_attrib = "C";
m_plain_attrib = "";
m_ref_chr = 'R';
m_array_char = 'P';
m_ptr_char = 'P';
m_method_type_first = true;
m_convention_first = false;
m_collect_repeats = "N";
m_end_class = "";
m_template_name = "t";
m_template_args = "1Z";
m_namespace = NULL;
m_discard_sig_types = true;
m_enum = "";
}
bool simple_type(Type t) // GCC2Mangler
{
// return ! t.is_class() && ! t.is_signature();
return t.is_number() && !t.is_ref_or_ptr();
}
void out_simple_classname(const string& name) // GCC2Mangler
{
outi(name.length());
outs(name.c_str());
}
void do_void_args() // GCC2Mangler
{
// a curious exception - class member functions don't get a special void args
// *fix 1.2.4 class_context() is non-null if a function is a member (static!)
if (! m_fn->class_context()) Mangler::do_void_args();
}
char type_encode(Type t) // GCC2Mangler
{
char ch;
if (t.is_void()) ch = 'v'; else
if (t.is_bool()) ch = 'b';
else
if (t.is_int()) {
if(t.is_unsigned()) out('U');
if (t.is_char()) ch = 'c'; else
if (t.is_short()) ch = 's'; else
if (t.is_long()) ch = 'l';
else ch = 'i'; // plain 'int'
} else
if (t.is_float()) {
if (t.is_double()) ch = 'd';
else ch = 'f';
} else
return 0;
return ch;
}
void out_fun_name(string fun_name) // GCC2Mangler
{
const char *name = fun_name.c_str();
if (m_fn->is_constructor()) outs("__"); else
if (m_fn->is_destructor()) outs(GCC_DTOR);
else {
char *mn = lookup_opname(gcc2_fns,name);
if (mn != NULL) { outs("__"); outs(mn); }
else {
outs(name);
}
outs("__");
}
}
void do_calling_convention() // GCC2Mangler
{
// if (m_fn->is_stdcall()) outs("@0");
}
void out_method_type(int access) // GCC2Mangler
{
if (!m_fn->is_static() && m_fn->is_const()) out('C');
}
};
//////// GCC 3 mangler ////////////////////////
struct ArgTypeEntry {
Type m_t;
int m_arg_idx;
};
typedef std::list<ArgTypeEntry> ArgTypeList;
ArgTypeList mArgTypeList;
struct TypeObjEntry {
void* m_pt;
Type m_t;
int m_type_idx;
};
typedef std::list<TypeObjEntry> TypeObjList;
TypeObjList mTypeObjList;
const int NOT_FOUND = -2;
int match_exact_arg(Type t);
int match_type_arg(Type& t);
OpNames gcc3_fns[] = {
{"__C__","C1"},
{"__D__","C2"},
{"=", "aS"},
{"==","eq"},
{"!=","ne"},
{"[]","ix"},
{"<<","ls"},
{">>","rs"},
{"+","pl"},
{"-","mi"},
{"+=","pL"},
{"-=","mI"},
{"*","ml"},
{"++","pp"},
{"--","mm"},
{"<","lt"},
{">","gt"},
{"&&","aa"},
{"||","oo"},
{"&","an"},
{"|","or"},
{NULL,NULL}
};
class GCC3Mangler: public Mangler {
int m_no_attrib;
int m_type_idx;
Type m_t;
bool m_no_namespace;
public:
char type_encode(Type t)
{
char ch;
if (t.is_void()) ch = 'v'; else
if (t.is_bool()) ch = 'b';
else
if (t.is_int()) {
if (! t.is_unsigned()) {
if (t.is_char()) ch = 'c'; else
if (t.is_short()) ch = 's'; else
if (t.is_long()) ch = 'l';
else ch = 'i'; // plain 'int'
} else {
if (t.is_char()) ch = 'h'; else
if (t.is_short()) ch = 't'; else
if (t.is_long()) ch = 'm';
else ch = 'j';
}
} else
if (t.is_float()) {
if (t.is_double()) ch = 'd';
else ch = 'f';
} else
return 0;
return ch;
}
bool simple_type(Type t) // GCC3Mangler
{
return t.is_number() && !t.is_ref_or_ptr();
}
void out_attrib_char(char ch)
{
++m_no_attrib;
out(ch);
}
void out_ref_ptr(Type t)
{
// put out ref/ptr attributes
if (t.is_ref_or_ptr()) {
if(t.is_reference()) out_attrib_char('R');
if(t.is_pointer()) {
for(int i = 0; i < t.pointer_depth(); i++) out_attrib_char('P');
}
//..the UnderC type system can't currently represent _multiple const attributes_
if (t.is_const()) out_attrib_char('K');
}
}
void out_name(const string& name)
{
outi(name.length());
outs(name.c_str());
}
bool out_namespace(Table* pc)
{
if (! pc || m_no_namespace) return false;
Namespace* ns = pc->type()==IS_NAMESPACE ? (Namespace*)pc : 0;
//dynamic_cast<Namespace*>(pc);
if (ns) {
out('N');
out_name(ns->name());
add_type(ns);
return true;
}
else return false;
}
void add_type(void* pt)
{
TypeObjEntry toe;
toe.m_pt = pt;
toe.m_type_idx = m_type_idx;
toe.m_t = m_t;
mTypeObjList.push_back(toe);
++m_type_idx;
}
void out_classname(Class *pc)
{
string name;
bool wuz_inside_ns = out_namespace (pc->inside_namespace());
add_type(pc);
if (pc->get_template()) {
out_name(pc->get_template()->name());
out('I');
TypeList& tl = pc->get_template()->type_parms();
TypeList::iterator tli;
for (tli = tl.begin(); tli != tl.end(); ++tli)
out_type(*tli);
out('E');
} else {
out_name(pc->name());
}
if (wuz_inside_ns) out('E');
}
void out_type(Type t)
{
// encoding function ptrs
if (t.is_signature()) {
Signature* sig = t.as_signature();
//bool wuz_inside_ns = out_namespace(sig->context());
if (sig->class_ptr() == NULL) { // NOT a method
outs("PF");
} else {
out('M');
out_classname(sig->class_ptr());
out('F');
}
out_type(sig->return_type());
do_signature(sig);
out('E');
//if (wuz_inside_ns) out('E');
}
// classes and enums are output simularly
else if (t.is_class()) out_classname(t.as_class());
else if (t.is_enum()) {
Enum* e = t.as_enum();
bool wuz_inside_ns = out_namespace(e->context());
out_name(e->name());
add_type(e);
if (wuz_inside_ns) out('E');
}
else out(type_encode(t));
}
void out_ref(int idx)
{
// references to previous types are of the form Sx_,
// where x is either empty or a hexadecimal digit.
out('S');
if (idx > -1) outx(idx);
out('_');
}
void do_signature(Signature *sig)
{
if (sig->begin() == sig->end()) out('v');
else {
int arg_idx, type_idx,start_type_idx,start_arg_idx = 0;
Signature::iterator sigi;
for (sigi = sig->begin(); sigi != sig->end(); ++sigi) {
m_t = *sigi;
// simple types encode simply according to the above rules
if (simple_type(m_t)) out(type_encode(m_t));
else
// has this (non-simple) type already appeared in the arglist?
if ((arg_idx = match_exact_arg(m_t)) != NOT_FOUND) out_ref(arg_idx);
else {
// how many attributes (const, pointer, etc) in this type?
m_no_attrib = 0;
// has the type already appeared in the arglist?
if ((type_idx = match_type_arg(m_t)) != NOT_FOUND) {
out_ref_ptr(m_t);
out_ref(type_idx);
} else {
out_ref_ptr(m_t);
out_type(m_t);
}
start_arg_idx = m_type_idx + m_no_attrib - 1;
ArgTypeEntry ate;
ate.m_t = m_t;
ate.m_arg_idx = start_arg_idx;
mArgTypeList.push_back(ate);
m_type_idx = start_arg_idx + 1;
}
}
}
}
void out_fun_name(string fun_name) // GCC3Mangler
{
const char *name = fun_name.c_str();
bool wuz_inside_ns = false, wuz_inside_class = false;
outs("_Z");
PClass pc = m_fn->class_context();
if (pc != NULL) { // is a class member function
out('N');
if (m_fn->is_const()) out('K');
out_classname(pc);
wuz_inside_class = true;
} else { // may well be inside a namespace...
Table* cntxt = m_fn->context();
if (cntxt)
wuz_inside_ns = out_namespace(cntxt->parent_context());
}
// the actual name
char *mn = lookup_opname(gcc3_fns,name);
if (mn != NULL) outs(mn);
else
out_name(name);
if (wuz_inside_class || wuz_inside_ns) out('E');
}
char *mangle(Function *pfn) // GCC3Mangler
{
reset();
m_no_namespace = true;
m_t = t_void;
m_fn = pfn;
m_type_idx = -1;
mArgTypeList.clear();
mTypeObjList.clear();
out_fun_name(pfn->name());
// any arguments
do_signature(m_fn->signature());
// end output string
end();
return ptr();
}
};
int match_exact_arg(Type t)
{
ArgTypeList::iterator ali;
for(ali = mArgTypeList.begin(); ali != mArgTypeList.end(); ++ali)
if (t == ali->m_t) return ali->m_arg_idx;
return NOT_FOUND;
}
int match_type_arg(Type& t)
{
void *pt;
if (t.is_class()) pt = t.as_class(); else
if (t.is_enum()) pt = t.as_enum();
else return NOT_FOUND;
TypeObjList::iterator ali;
for (ali = mTypeObjList.begin(); ali != mTypeObjList.end(); ++ali)
if (ali->m_pt == pt) { // a class or enum has been repeated!
int idx = ali->m_type_idx;
Type at = ali->m_t;
// we must allow for _partial_ matches, where this argument already has
// some of the necessary qualifiers.
if (t.is_const()) {
if (at.is_const()) {
t.strip_const();
idx++;
} else return idx; // t has more qualifiers
}
int ad = at.is_pointer() ? at.pointer_depth() : 0;
int d = t.is_pointer() ? t.pointer_depth() : 0;
if (ad > 0 && d > 0 && ad > d) {
for(int i = 0, n = ad - d; i < n; i++) {
t.decr_pointer();
idx++;
}
}
if (at.is_reference() && t.is_reference()) {
t.strip_reference();
idx++;
}
return idx;
}
return NOT_FOUND;
}
static MSMangler ms_mangler;
static GCC2Mangler gcc2_mangler;
static GCC3Mangler gcc3_mangler;
char *Mangle::microsoft(Function *pf)
{
return ms_mangler.mangle(pf);
}
char *Mangle::GCC2(Function *pf)
{
return gcc2_mangler.mangle(pf);
}
char *Mangle::GCC3(Function *pf)
{
return gcc3_mangler.mangle(pf);
}
char *i2a(int i)
{
static char buff[15];
sprintf(buff,"%d",i);
return buff;
}
char *i2ax(int i)
{
static char buff[15];
sprintf(buff,"%X",i);
return buff;
}
char *lookup_opname(OpNames *popn, const char *n)
{
for(; popn->cname != NULL; popn++)
if (strcmp(popn->cname,n)==0) return popn->mname;
return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -