From 46cf7042cf511215001bb28c072821998a83d011 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 15 Mar 2020 20:28:02 +0100 Subject: Added support for packed template arguments in Itanium demangling. --- plugins/itanium/abi.c | 57 +++++++++++++++++++++++++++++++++++++++++++-- plugins/itanium/component.c | 52 ++++++++++++++++++++++++++++++++++++++++- plugins/itanium/component.h | 9 +++++++ tests/mangling/itanium.py | 3 +++ 4 files changed, 118 insertions(+), 3 deletions(-) diff --git a/plugins/itanium/abi.c b/plugins/itanium/abi.c index 300bf59..0304938 100644 --- a/plugins/itanium/abi.c +++ b/plugins/itanium/abi.c @@ -1818,6 +1818,7 @@ static itanium_component *itd_type(GItaniumDemangling *context) * ::= C # complex pair (C 2000) * ::= G # imaginary (C 2000) * ::= U # vendor extended type qualifier + * ::= Dp # pack expansion (C++0x) * */ @@ -1946,6 +1947,17 @@ static itanium_component *itd_type(GItaniumDemangling *context) handled = true; break; + case 'D': + if (peek_input_buffer_next_char(ibuf) == 'p') + { + advance_input_buffer(ibuf, 2); + + result = itd_type(context); + handled = true; + + } + break; + case 'T': /** @@ -2832,7 +2844,7 @@ static itanium_component *itd_template_args(GItaniumDemangling *context) arg = itd_template_arg(context); if (arg == NULL) return NULL; - result = itd_append_right_to_binary(ICT_TYPES_LIST, NULL, arg); + result = itd_merge_list_right_to_binary(ICT_TYPES_LIST, NULL, arg); while (1) { @@ -2845,7 +2857,7 @@ static itanium_component *itd_template_args(GItaniumDemangling *context) break; } - result = itd_append_right_to_binary(ICT_TYPES_LIST, result, arg); + result = itd_merge_list_right_to_binary(ICT_TYPES_LIST, result, arg); } @@ -2881,6 +2893,7 @@ static itanium_component *itd_template_arg(GItaniumDemangling *context) itanium_component *result; /* Construction à retourner */ input_buffer *ibuf; /* Tampon de texte manipulé */ char peek; /* Prochain caractère lu */ + itanium_component *packed; /* Argument compressé */ /** * La règle traitée ici est la suivante : @@ -2888,6 +2901,7 @@ static itanium_component *itd_template_arg(GItaniumDemangling *context) * ::= # type or template * ::= X E # expression * ::= # simple expressions + * ::= J * E # argument pack * */ @@ -2912,9 +2926,48 @@ static itanium_component *itd_template_arg(GItaniumDemangling *context) else if (peek == 'L') result = itd_expr_primary(context); + else if (peek == 'J') + { + advance_input_buffer(ibuf, 1); + + result = NULL; + + while (peek_input_buffer_char(ibuf) != 'E') + { + packed = itd_template_arg(context); + + if (packed == NULL) + { + if (result != NULL) + { + itd_unref_comp(result); + result = NULL; + } + + goto packed_failed; + + } + + result = itd_merge_list_right_to_binary(ICT_TYPES_LIST, result, packed); + + } + + if (result == NULL) + result = itd_make_with_type(ICT_PACKED_EMPTY); + + if (!check_input_buffer_char(ibuf, 'E')) + { + itd_unref_comp(result); + result = NULL; + } + + } + else result = itd_type(context); + packed_failed: + return result; } diff --git a/plugins/itanium/component.c b/plugins/itanium/component.c index f5aad1d..f035e36 100644 --- a/plugins/itanium/component.c +++ b/plugins/itanium/component.c @@ -254,6 +254,9 @@ static void visit_comp(itanium_component *comp, visit_comp_fc visitor) break; + case ICT_PACKED_EMPTY: + break; + case ICT_EXPR_LIST: visit_comp(comp->binary.left, visitor); @@ -810,6 +813,46 @@ itanium_component *itd_append_right_to_binary(ItaniumComponentType type, itanium /****************************************************************************** * * * Paramètres : type = type du composant à mettre en place. * +* left = second composant à associer. * +* * +* Description : Construit un composant dans un contexte Itanium. * +* * +* Retour : Composant extrait ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +itanium_component *itd_merge_list_right_to_binary(ItaniumComponentType type, itanium_component *parent, itanium_component *left) +{ + itanium_component *result; /* Composant à renvoyer */ + itanium_component *iter; /* Boucle de parcours */ + + if (left->type != ICT_TYPES_LIST) + result = itd_append_right_to_binary(type, parent, left); + + else + { + if (parent == NULL) + result = left; + + else + { + for (iter = parent; iter->binary.right != NULL; iter = iter->binary.right) + ; + iter->binary.right = left; + } + + } + + return (parent != NULL ? parent : result); + +} + + +/****************************************************************************** +* * +* Paramètres : type = type du composant à mettre en place. * * c0 = premier composant à associer. * * c1 = second composant à associer. * * c2 = troisième composant à associer. * @@ -1146,6 +1189,9 @@ char *itd_translate_component(const itanium_component *comp, char *base) break; + case ICT_PACKED_EMPTY: + break; + case ICT_EXPR_LIST: /** @@ -1751,12 +1797,15 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp, Routin case ICT_TEMPLATE_ARGS: - assert(comp->unary->type == ICT_TYPES_LIST); + assert(comp->unary->type == ICT_TYPES_LIST || comp->unary->type == ICT_PACKED_EMPTY); result = g_template_type_new(); for (iter = comp->unary; iter != NULL && result != NULL; iter = iter->binary.right) { + if (iter->type == ICT_PACKED_EMPTY) + continue; + assert(iter->type == ICT_TYPES_LIST); param = itd_translate_component_to_type(iter->binary.left, rtype); @@ -1774,6 +1823,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp, Routin break; case ICT_TYPES_LIST: + case ICT_PACKED_EMPTY: /** * Les listes doient être rassemblées par l'appelant ! diff --git a/plugins/itanium/component.h b/plugins/itanium/component.h index 36852d9..c4b5eb3 100644 --- a/plugins/itanium/component.h +++ b/plugins/itanium/component.h @@ -178,6 +178,12 @@ typedef enum _ItaniumComponentType ICT_TYPES_LIST, /** + * Paramètres compressés de patron non définis. + * (cf. règle ::= J * E ) + */ + ICT_PACKED_EMPTY, + + /** * Liste d'expressions, sous forme binaire comme pour ICT_TYPES_LIST : * -> left = élément de la liste de types. * -> right = reste de la liste de types. @@ -283,6 +289,9 @@ itanium_component *itd_make_binary(ItaniumComponentType, itanium_component *, it itanium_component *itd_append_right_to_binary(ItaniumComponentType, itanium_component *, itanium_component *); /* Construit un composant dans un contexte Itanium. */ +itanium_component *itd_merge_list_right_to_binary(ItaniumComponentType, itanium_component *, itanium_component *); + +/* Construit un composant dans un contexte Itanium. */ itanium_component *itd_make_ternary(ItaniumComponentType, itanium_component *, itanium_component *, itanium_component *); /* Modifie légèrement le type d'un composant donné. */ diff --git a/tests/mangling/itanium.py b/tests/mangling/itanium.py index a1cc517..1b24c3d 100644 --- a/tests/mangling/itanium.py +++ b/tests/mangling/itanium.py @@ -214,3 +214,6 @@ class TestItaniumMangling(ChrysalideTestCase): demangled = demangler.decode_routine('_ZNSt3__111__tree_nextIPNS_16__tree_node_baseIPvEEEET_S5_') self.check_demangling(demangled, 'std::__1::__tree_node_base *std::__1::__tree_next *>(std::__1::__tree_node_base *)') + + demangled = demangler.decode_routine('_ZNSt3__110shared_ptrIN7android14CameraMetadataEE11make_sharedIJRKS2_EEES3_DpOT_') + self.check_demangling(demangled, 'std::__1::shared_ptr std::__1::shared_ptr::make_shared(const android::CameraMetadata &&&)') -- cgit v0.11.2-87-g4458