File indexing completed on 2024-05-05 05:44:03
0001 /* 0002 Copyright (C) 2013-2014 Volker Krause <vkrause@kde.org> 0003 0004 This program is free software; you can redistribute it and/or modify it 0005 under the terms of the GNU Library General Public License as published by 0006 the Free Software Foundation; either version 2 of the License, or (at your 0007 option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, but WITHOUT 0010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 0012 License for more details. 0013 0014 You should have received a copy of the GNU General Public License 0015 along with this program. If not, see <https://www.gnu.org/licenses/>. 0016 */ 0017 0018 #include <config-elf-dissector.h> 0019 0020 // workarounds for conflicting declaration in libiberty.h 0021 #define HAVE_DECL_BASENAME 1 0022 #define HAVE_DECL_ASPRINTF 1 0023 #define HAVE_DECL_VASPRINTF 1 0024 0025 #include <demangle.h> 0026 0027 #include <QByteArray> 0028 0029 #include <iostream> 0030 0031 using namespace std; 0032 0033 // not in a public binutils header, but needed anyway 0034 struct demangle_operator_info 0035 { 0036 const char *type; 0037 const char *name; 0038 int len; 0039 int args; 0040 }; 0041 0042 struct demangle_builtin_type_info { 0043 const char *name; 0044 int len; 0045 const char *java_name; 0046 int java_len; 0047 /*enum d_builtin_type_print*/ int print; 0048 }; 0049 0050 static int nodeCount = 0; 0051 0052 static void writeNode(const char* name) 0053 { 0054 cout << " node" << nodeCount << "[label = \"" << name << "\"];" << endl; 0055 } 0056 0057 static void writeLink(int source, int target) 0058 { 0059 if (source == 0 || target == 0) 0060 return; 0061 cout << " node" << source << " -> node" << target << ";" << endl; 0062 } 0063 0064 static int handleNameComponent(demangle_component* component) 0065 { 0066 if (!component) 0067 return 0; 0068 0069 ++nodeCount; 0070 const int sourceNode = nodeCount; 0071 switch (component->type) { 0072 case DEMANGLE_COMPONENT_NAME: 0073 writeNode(QByteArray(component->u.s_name.s, component->u.s_name.len)); 0074 break; 0075 case DEMANGLE_COMPONENT_QUAL_NAME: 0076 writeNode("QUAL_NAME"); 0077 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0078 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0079 break; 0080 case DEMANGLE_COMPONENT_LOCAL_NAME: 0081 writeNode("LOCAL_NAME"); 0082 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0083 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0084 break; 0085 case DEMANGLE_COMPONENT_TYPED_NAME: 0086 writeNode("TYPED_NAME"); 0087 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0088 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0089 break; 0090 case DEMANGLE_COMPONENT_TEMPLATE: 0091 writeNode("TEMPLATE"); 0092 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0093 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0094 break; 0095 case DEMANGLE_COMPONENT_TEMPLATE_PARAM: 0096 writeNode(QByteArray("TEMPLATE_PARAM: ") + QByteArray::number((int)component->u.s_number.number)); 0097 // ??? 0098 break; 0099 case DEMANGLE_COMPONENT_FUNCTION_PARAM: 0100 writeNode(QByteArray("FUNCTION_PARAM: ") + QByteArray::number((int)component->u.s_number.number)); 0101 // ??? "This holds a number, which is the parameter index." 0102 break; 0103 case DEMANGLE_COMPONENT_CTOR: 0104 writeNode("CTOR"); 0105 // TODO: do we need to consider u.s_ctor.kind? 0106 writeLink(sourceNode, handleNameComponent(component->u.s_ctor.name)); 0107 break; 0108 case DEMANGLE_COMPONENT_DTOR: 0109 writeNode("DTOR"); 0110 // TODO: do we need to consider u.s_dtor.kind? 0111 writeLink(sourceNode, handleNameComponent(component->u.s_dtor.name)); 0112 break; 0113 case DEMANGLE_COMPONENT_VTABLE: 0114 writeNode("VTABLE"); 0115 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0116 break; 0117 case DEMANGLE_COMPONENT_VTT: 0118 writeNode("VTT"); 0119 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0120 break; 0121 case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE: 0122 writeNode("CONSTRUCTION_VTABLE"); 0123 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0124 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0125 break; 0126 case DEMANGLE_COMPONENT_TYPEINFO: 0127 writeNode("TYPEINFO"); 0128 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0129 break; 0130 case DEMANGLE_COMPONENT_TYPEINFO_NAME: 0131 writeNode("TYPEINFO_NAME"); 0132 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0133 break; 0134 case DEMANGLE_COMPONENT_TYPEINFO_FN: 0135 writeNode("TYPEINFO_FN"); 0136 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0137 break; 0138 case DEMANGLE_COMPONENT_THUNK: 0139 writeNode("THUNK"); 0140 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0141 break; 0142 case DEMANGLE_COMPONENT_VIRTUAL_THUNK: 0143 writeNode("VIRTUAL_THUNK"); 0144 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0145 break; 0146 case DEMANGLE_COMPONENT_COVARIANT_THUNK: 0147 writeNode("COVARIANT_THUNK"); 0148 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0149 break; 0150 case DEMANGLE_COMPONENT_JAVA_CLASS: 0151 writeNode("JAVA_CLASS"); 0152 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0153 break; 0154 case DEMANGLE_COMPONENT_GUARD: 0155 writeNode("GUARD"); 0156 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0157 break; 0158 #if BINUTILS_VERSION >= BINUTILS_VERSION_CHECK(2, 24) 0159 case DEMANGLE_COMPONENT_TLS_INIT: 0160 writeNode("TLS_INIT"); 0161 // content? 0162 break; 0163 case DEMANGLE_COMPONENT_TLS_WRAPPER: 0164 writeNode("TLS_WRAPPER"); 0165 // content ?? 0166 break; 0167 #endif 0168 case DEMANGLE_COMPONENT_REFTEMP: 0169 writeNode("REFTEMP"); 0170 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0171 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0172 break; 0173 case DEMANGLE_COMPONENT_HIDDEN_ALIAS: 0174 writeNode("HIDDEN_ALIAS"); 0175 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0176 break; 0177 case DEMANGLE_COMPONENT_SUB_STD: 0178 writeNode(QByteArray("SUB_STD: ") + QByteArray(component->u.s_name.s, component->u.s_name.len)); 0179 break; 0180 case DEMANGLE_COMPONENT_RESTRICT: 0181 writeNode("RESTRICT"); 0182 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0183 break; 0184 case DEMANGLE_COMPONENT_VOLATILE: 0185 writeNode("VOLATILE"); 0186 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0187 break; 0188 case DEMANGLE_COMPONENT_CONST: 0189 writeNode("CONST"); 0190 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0191 break; 0192 case DEMANGLE_COMPONENT_RESTRICT_THIS: 0193 writeNode("RESTRICT_THIS"); 0194 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0195 break; 0196 case DEMANGLE_COMPONENT_VOLATILE_THIS: 0197 writeNode("VOLATILE_THIS"); 0198 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0199 break; 0200 case DEMANGLE_COMPONENT_CONST_THIS: 0201 writeNode("CONST_THIS"); 0202 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0203 break; 0204 #if BINUTILS_VERSION >= BINUTILS_VERSION_CHECK(2, 24) 0205 case DEMANGLE_COMPONENT_REFERENCE_THIS: 0206 writeNode("REFERENCE_THIS"); 0207 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0208 break; 0209 case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: 0210 writeNode("RVALUE_REFERENCE_THIS"); 0211 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0212 break; 0213 #endif 0214 case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: 0215 writeNode("VENDOR_TYPE_QUAL"); 0216 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0217 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0218 break; 0219 case DEMANGLE_COMPONENT_POINTER: 0220 writeNode("POINTER"); 0221 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0222 break; 0223 case DEMANGLE_COMPONENT_REFERENCE: 0224 writeNode("REFERENCE"); 0225 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0226 break; 0227 case DEMANGLE_COMPONENT_RVALUE_REFERENCE: 0228 writeNode("RVALUE_REFERENCE"); 0229 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0230 break; 0231 case DEMANGLE_COMPONENT_COMPLEX: 0232 writeNode("COMPLEX"); 0233 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0234 break; 0235 case DEMANGLE_COMPONENT_IMAGINARY: 0236 writeNode("IMAGINARY"); 0237 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0238 break; 0239 case DEMANGLE_COMPONENT_BUILTIN_TYPE: 0240 writeNode(QByteArray("BUILTIN_TYPE: ") + QByteArray(component->u.s_builtin.type->name, component->u.s_builtin.type->len)); 0241 break; 0242 case DEMANGLE_COMPONENT_VENDOR_TYPE: 0243 writeNode("VENDOR_TYPE"); 0244 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0245 break; 0246 case DEMANGLE_COMPONENT_FUNCTION_TYPE: 0247 writeNode("FUNCTION_TYPE"); 0248 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0249 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0250 break; 0251 case DEMANGLE_COMPONENT_ARRAY_TYPE: 0252 writeNode("ARRAY_TYPE"); 0253 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0254 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0255 break; 0256 case DEMANGLE_COMPONENT_PTRMEM_TYPE: 0257 writeNode("PTRMEM_TYPE"); 0258 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0259 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0260 break; 0261 case DEMANGLE_COMPONENT_FIXED_TYPE: 0262 writeNode("FIXED_TYPE"); 0263 // TODO ??? 0264 break; 0265 case DEMANGLE_COMPONENT_VECTOR_TYPE: 0266 writeNode("VECTOR_TYPE"); 0267 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0268 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0269 break; 0270 case DEMANGLE_COMPONENT_ARGLIST: 0271 writeNode("ARGLIST"); 0272 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0273 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0274 break; 0275 case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST: 0276 writeNode("TEMPLATE_ARGLIST"); 0277 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0278 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0279 break; 0280 #if BINUTILS_VERSION >= BINUTILS_VERSION_CHECK(2, 32) 0281 case DEMANGLE_COMPONENT_TPARM_OBJ: 0282 writeNode("TPARM_OBJ"); 0283 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0284 break; 0285 #endif 0286 #if BINUTILS_VERSION >= BINUTILS_VERSION_CHECK(2, 23) 0287 case DEMANGLE_COMPONENT_INITIALIZER_LIST: 0288 writeNode("INITIALIZER_LIST"); 0289 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0290 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0291 break; 0292 #endif 0293 case DEMANGLE_COMPONENT_OPERATOR: 0294 writeNode(QByteArray("OPERATOR ") + QByteArray(component->u.s_operator.op->name, component->u.s_operator.op->len)); 0295 break; 0296 case DEMANGLE_COMPONENT_EXTENDED_OPERATOR: 0297 writeNode("EXTENDED_OPERATOR"); 0298 // TODO 0299 /* An extended operator. This holds the number of arguments, and 0300 the name of the extended operator. */ 0301 break; 0302 case DEMANGLE_COMPONENT_CAST: 0303 writeNode("CAST"); 0304 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0305 break; 0306 #if BINUTILS_VERSION >= BINUTILS_VERSION_CHECK(2, 26) 0307 case DEMANGLE_COMPONENT_CONVERSION: 0308 writeNode("CONVERSION"); 0309 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0310 break; 0311 #endif 0312 #if BINUTILS_VERSION >= BINUTILS_VERSION_CHECK(2, 23) 0313 case DEMANGLE_COMPONENT_NULLARY: 0314 writeNode("NULLARY"); 0315 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0316 break; 0317 #endif 0318 case DEMANGLE_COMPONENT_UNARY: 0319 writeNode("UNARY"); 0320 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0321 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0322 break; 0323 case DEMANGLE_COMPONENT_BINARY: 0324 writeNode("BINARY"); 0325 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0326 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0327 break; 0328 case DEMANGLE_COMPONENT_BINARY_ARGS: 0329 writeNode("BINARY_ARGS"); 0330 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0331 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0332 break; 0333 case DEMANGLE_COMPONENT_TRINARY: 0334 writeNode("TRINARY"); 0335 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0336 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0337 break; 0338 case DEMANGLE_COMPONENT_TRINARY_ARG1: 0339 writeNode("TRINARY_ARG1"); 0340 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0341 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0342 break; 0343 case DEMANGLE_COMPONENT_TRINARY_ARG2: 0344 writeNode("TRINARY_ARG2"); 0345 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0346 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0347 break; 0348 case DEMANGLE_COMPONENT_LITERAL: 0349 writeNode("LITERAL"); 0350 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0351 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0352 break; 0353 case DEMANGLE_COMPONENT_LITERAL_NEG: 0354 writeNode("LITERAL_NEG"); 0355 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0356 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0357 break; 0358 case DEMANGLE_COMPONENT_JAVA_RESOURCE: 0359 writeNode("JAVA_RESOURCE"); 0360 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0361 break; 0362 case DEMANGLE_COMPONENT_COMPOUND_NAME: 0363 writeNode("COMPOUND_NAME"); 0364 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0365 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0366 break; 0367 case DEMANGLE_COMPONENT_CHARACTER: 0368 writeNode("CHARACTER"); 0369 // TODO: content? 0370 break; 0371 case DEMANGLE_COMPONENT_NUMBER: 0372 writeNode(QByteArray("NUMBER: ") + QByteArray::number((int)component->u.s_number.number)); 0373 break; 0374 case DEMANGLE_COMPONENT_DECLTYPE: 0375 writeNode("DECLTYPE"); 0376 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0377 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0378 // TODO: content? 0379 break; 0380 case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS: 0381 writeNode("GLOBAL_CONSTRUCTORS"); 0382 // TODO: content? 0383 break; 0384 case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS: 0385 writeNode("GLOBAL_DESTRUCTORS"); 0386 // TODO: content? 0387 break; 0388 case DEMANGLE_COMPONENT_LAMBDA: 0389 writeNode(QByteArray("LAMBDA: ") + QByteArray::number(component->u.s_unary_num.num)); 0390 writeLink(sourceNode, handleNameComponent(component->u.s_unary_num.sub)); 0391 break; 0392 case DEMANGLE_COMPONENT_DEFAULT_ARG: 0393 writeNode(QByteArray("DEFAULT_ARG: ") + QByteArray::number((int)component->u.s_unary_num.num)); 0394 writeLink(sourceNode, handleNameComponent(component->u.s_unary_num.sub)); 0395 break; 0396 case DEMANGLE_COMPONENT_UNNAMED_TYPE: 0397 writeNode(QByteArray("UNNAMED_TYPE: ") + QByteArray::number((int)component->u.s_number.number)); 0398 break; 0399 #if BINUTILS_VERSION >= BINUTILS_VERSION_CHECK(2, 23) 0400 case DEMANGLE_COMPONENT_TRANSACTION_CLONE: 0401 writeNode("TRANSACTION_CLONE"); 0402 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0403 break; 0404 case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE: 0405 writeNode("NONTRANSACTION_CLONE"); 0406 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0407 break; 0408 #endif 0409 case DEMANGLE_COMPONENT_PACK_EXPANSION: 0410 writeNode("PACK_EXPANSION"); 0411 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0412 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0413 break; 0414 #if BINUTILS_VERSION >= BINUTILS_VERSION_CHECK(2, 24) 0415 case DEMANGLE_COMPONENT_TAGGED_NAME: 0416 writeNode("TAGGED_NAME"); 0417 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0418 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0419 break; 0420 #endif 0421 #if BINUTILS_VERSION >= BINUTILS_VERSION_CHECK(2, 27) 0422 case DEMANGLE_COMPONENT_TRANSACTION_SAFE: 0423 writeNode("TRANSACTION_SAFE"); 0424 // ?? 0425 break; 0426 #endif 0427 #if BINUTILS_VERSION >= BINUTILS_VERSION_CHECK(2, 23) 0428 case DEMANGLE_COMPONENT_CLONE: 0429 writeNode("COMPONENT_CLONE"); 0430 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0431 writeLink(sourceNode, handleNameComponent(component->u.s_binary.right)); 0432 break; 0433 #endif 0434 #if BINUTILS_VERSION >= BINUTILS_VERSION_CHECK(2, 28) 0435 case DEMANGLE_COMPONENT_NOEXCEPT: 0436 writeNode("NOEXCEPT"); 0437 writeLink(sourceNode, handleNameComponent(component->u.s_binary.left)); 0438 break; 0439 case DEMANGLE_COMPONENT_THROW_SPEC: 0440 writeNode("THROW_SPEC"); 0441 // ?? 0442 break; 0443 #endif 0444 } 0445 return sourceNode; 0446 } 0447 0448 int main(int argc, char** argv) 0449 { 0450 if (argc < 2) 0451 return 1; 0452 0453 void *memory = nullptr; 0454 demangle_component *component = cplus_demangle_v3_components(argv[1], DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES | DMGL_VERBOSE, &memory); 0455 0456 cout << "digraph ast {" << endl; 0457 0458 handleNameComponent(component); 0459 0460 cout << "}" << endl; 0461 0462 size_t size; 0463 char * fullName = cplus_demangle_print(DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES | DMGL_VERBOSE, component, strlen(argv[1]), &size); 0464 cerr << fullName << endl; 0465 free(fullName); 0466 0467 free(memory); 0468 return 0; 0469 }