2 * Copyright (c) 2008 Hyogeol Lee <hyogeollee@gmail.com>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer
10 * in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/types.h>
38 #include "_libelftc.h"
40 ELFTC_VCSID("$Id: libelftc_dem_arm.c 3447 2016-05-03 13:32:23Z emaste $");
43 * @file cpp_demangle_arm.c
44 * @brief Decode function name encoding in ARM.
46 * Function name encoding in "The Annotated C++ Reference Manual".
48 * Ref : "The Annotated C++ Reference Manual", Margaet A.Ellis,
49 * Bjarne Stroustrup, AT&T Bell Laboratories 1990, pp 122-126.
53 ENCODE_FUNC, ENCODE_OP, ENCODE_OP_CT, ENCODE_OP_DT, ENCODE_OP_USER
61 struct demangle_data {
62 bool ptr, ref, cnst, array;
63 struct cstring array_str;
65 enum encode_type type;
66 struct vector_str vec;
67 struct vector_str arg;
70 #define SIMPLE_HASH(x,y) (64 * x + y)
71 #define CPP_DEMANGLE_ARM_TRY 128
73 static void dest_cstring(struct cstring *);
74 static void dest_demangle_data(struct demangle_data *);
75 static bool init_cstring(struct cstring *, size_t);
76 static bool init_demangle_data(struct demangle_data *);
77 static bool push_CTDT(const char *, size_t, struct vector_str *);
78 static bool read_array(struct demangle_data *);
79 static bool read_class(struct demangle_data *);
80 static bool read_func(struct demangle_data *);
81 static bool read_func_name(struct demangle_data *);
82 static bool read_func_ptr(struct demangle_data *);
83 static bool read_memptr(struct demangle_data *);
84 static bool read_op(struct demangle_data *);
85 static bool read_op_user(struct demangle_data *);
86 static bool read_qual_name(struct demangle_data *);
87 static int read_subst(struct demangle_data *);
88 static int read_subst_iter(struct demangle_data *);
89 static bool read_type(struct demangle_data *);
92 * @brief Decode the input string by the ARM style.
94 * @return New allocated demangled string or NULL if failed.
97 cpp_demangle_ARM(const char *org)
99 struct demangle_data d;
100 size_t arg_begin, arg_len;
107 if (init_demangle_data(&d) == false)
114 if (read_func_name(&d) == false)
117 if (d.type == ENCODE_OP_CT) {
118 if (push_CTDT("::", 2, &d.vec) == false)
124 if (d.type == ENCODE_OP_DT) {
125 if (push_CTDT("::~", 3, &d.vec) == false)
131 if (d.type == ENCODE_OP_USER)
139 /* start argument types */
140 if (vector_str_push(&d.vec, "(", 1) == false)
145 const int rtn_subst = read_subst(&d);
149 else if (rtn_subst == 1)
156 const int rtn_subst_iter = read_subst_iter(&d);
158 if (rtn_subst_iter == -1)
160 else if(rtn_subst_iter == 1)
166 arg_begin = d.vec.size;
168 if (read_type(&d) == false)
172 if (vector_str_push(&d.vec, "*", 1) == false)
179 if (vector_str_push(&d.vec, "&", 1) == false)
185 if (d.cnst == true) {
186 if (vector_str_push(&d.vec, " const", 6) == false)
192 if (d.array == true) {
193 if (vector_str_push(&d.vec, d.array_str.buf,
194 d.array_str.size) == false)
197 dest_cstring(&d.array_str);
204 if ((arg = vector_str_substr(&d.vec, arg_begin, d.vec.size - 1,
208 if (vector_str_push(&d.arg, arg, arg_len) == false)
213 if (vector_str_push(&d.vec, ", ", 2) == false)
216 if (++try > CPP_DEMANGLE_ARM_TRY)
220 /* end argument types */
221 if (vector_str_push(&d.vec, ")", 1) == false)
225 rtn = vector_str_get_flat(&d.vec, NULL);
227 dest_demangle_data(&d);
233 * @brief Test input string is encoded by the ARM style.
235 * @return True if input string is encoded by the ARM style.
238 is_cpp_mangled_ARM(const char *org)
244 return (strstr(org, "__") != NULL);
248 dest_cstring(struct cstring *s)
260 dest_demangle_data(struct demangle_data *d)
264 vector_str_dest(&d->arg);
265 vector_str_dest(&d->vec);
267 dest_cstring(&d->array_str);
272 init_cstring(struct cstring *s, size_t len)
275 if (s == NULL || len <= 1)
278 if ((s->buf = malloc(sizeof(char) * len)) == NULL)
287 init_demangle_data(struct demangle_data *d)
298 d->array_str.buf = NULL;
299 d->array_str.size = 0;
301 d->type = ENCODE_FUNC;
303 if (vector_str_init(&d->vec) == false)
306 if (vector_str_init(&d->arg) == false) {
307 vector_str_dest(&d->vec);
316 push_CTDT(const char *s, size_t l, struct vector_str *v)
319 if (s == NULL || l == 0 || v == NULL)
322 if (vector_str_push(v, s, l) == false)
326 if (vector_str_push(v, v->container[v->size - 2],
327 strlen(v->container[v->size - 2])) == false)
330 if (vector_str_push(v, "()", 2) == false)
337 read_array(struct demangle_data *d)
342 if (d == NULL || d->p == NULL)
352 if (ELFTC_ISDIGIT(*end) == 0)
364 dest_cstring(&d->array_str);
365 if (init_cstring(&d->array_str, len + 3) == false)
368 strncpy(d->array_str.buf + 1, d->p, len);
369 *d->array_str.buf = '[';
370 *(d->array_str.buf + len + 1) = ']';
379 read_class(struct demangle_data *d)
387 len = strtol(d->p, &str, 10);
388 if (len == 0 && (errno == EINVAL || errno == ERANGE))
394 if (vector_str_push(&d->vec, str, len) == false)
403 read_func(struct demangle_data *d)
412 assert(d->p != NULL && "d->p (org str) is NULL");
413 if ((delim = strstr(d->p, "__")) == NULL)
423 if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) {
426 if (read_qual_name(d) == false)
428 } else if (ELFTC_ISDIGIT(*d->p)) {
429 if (read_class(d) == false)
432 if (vector_str_push(&d->vec, "::", 2) == false)
436 if (vector_str_push(&d->vec, name, len) == false)
443 read_func_name(struct demangle_data *d)
455 assert(d->p != NULL && "d->p (org str) is NULL");
457 if (*d->p == '_' && *(d->p + 1) == '_') {
461 if (read_op(d) == false)
464 if (d->type == ENCODE_OP_CT || d->type == ENCODE_OP_DT ||
465 d->type == ENCODE_OP_USER)
471 /* assume delimiter is removed */
472 if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) {
475 assert(d->vec.size > 0);
477 len = strlen(d->vec.container[d->vec.size - 1]);
478 if ((op_name = malloc(sizeof(char) * (len + 1)))
482 snprintf(op_name, len + 1, "%s",
483 d->vec.container[d->vec.size - 1]);
484 vector_str_pop(&d->vec);
486 if (read_qual_name(d) == false)
489 if (vector_str_push(&d->vec, "::", 2) == false)
492 if (vector_str_push(&d->vec, op_name, len) == false)
496 } else if (ELFTC_ISDIGIT(*d->p)) {
497 assert(d->vec.size > 0);
499 len = strlen(d->vec.container[d->vec.size - 1]);
500 if ((op_name = malloc(sizeof(char) * (len + 1)))
504 snprintf(op_name, len + 1, "%s",
505 d->vec.container[d->vec.size - 1]);
506 vector_str_pop(&d->vec);
508 if (read_class(d) == false)
511 if (vector_str_push(&d->vec, "::", 2) == false)
514 if (vector_str_push(&d->vec, op_name, len) == false)
520 return (read_func(d));
528 /* Read function ptr type */
530 read_func_ptr(struct demangle_data *d)
532 struct demangle_data fptr;
533 size_t arg_len, rtn_len;
534 char *arg_type, *rtn_type;
540 if (init_demangle_data(&fptr) == false)
549 if (read_type(&fptr) == false) {
550 dest_demangle_data(&fptr);
555 if (fptr.ptr == true) {
556 if (vector_str_push(&fptr.vec, "*", 1) == false) {
557 dest_demangle_data(&fptr);
565 if (fptr.ref == true) {
566 if (vector_str_push(&fptr.vec, "&", 1) == false) {
567 dest_demangle_data(&fptr);
575 if (fptr.cnst == true) {
576 if (vector_str_push(&fptr.vec, " const", 6) == false) {
577 dest_demangle_data(&fptr);
588 if (vector_str_push(&fptr.vec, ", ", 2) == false) {
589 dest_demangle_data(&fptr);
594 if (++lim > CPP_DEMANGLE_ARM_TRY) {
596 dest_demangle_data(&fptr);
602 arg_type = vector_str_get_flat(&fptr.vec, &arg_len);
606 dest_demangle_data(&fptr);
608 if (init_demangle_data(&fptr) == false) {
617 if (read_type(&fptr) == false) {
619 dest_demangle_data(&fptr);
624 rtn_type = vector_str_get_flat(&fptr.vec, &rtn_len);
628 dest_demangle_data(&fptr);
630 if (vector_str_push(&d->vec, rtn_type, rtn_len) == false) {
639 if (vector_str_push(&d->vec, " (*)(", 5) == false) {
645 if (vector_str_push(&d->vec, arg_type, arg_len) == false) {
653 return (vector_str_push(&d->vec, ")", 1));
657 read_memptr(struct demangle_data *d)
659 struct demangle_data mptr;
664 if (d == NULL || d->p == NULL)
667 if (init_demangle_data(&mptr) == false)
674 if (*mptr.p == 'Q') {
677 if (read_qual_name(&mptr) == false)
680 if (read_class(&mptr) == false)
686 if ((mptr_str = vector_str_get_flat(&mptr.vec, &len)) == NULL)
689 if (vector_str_push(&d->vec, mptr_str, len) == false)
692 if (vector_str_push(&d->vec, "::*", 3) == false)
698 dest_demangle_data(&mptr);
704 read_op(struct demangle_data *d)
710 assert(d->p != NULL && "d->p (org str) is NULL");
712 switch (SIMPLE_HASH(*(d->p), *(d->p+1))) {
713 case SIMPLE_HASH('m', 'l') :
715 return (vector_str_push(&d->vec, "operator*", 9));
716 case SIMPLE_HASH('d', 'v') :
718 return (vector_str_push(&d->vec, "operator/", 9));
719 case SIMPLE_HASH('m', 'd') :
721 return (vector_str_push(&d->vec, "operator%", 9));
722 case SIMPLE_HASH('p', 'l') :
724 return (vector_str_push(&d->vec, "operator+", 9));
725 case SIMPLE_HASH('m', 'i') :
727 return (vector_str_push(&d->vec, "operator-", 9));
728 case SIMPLE_HASH('l', 's') :
730 return (vector_str_push(&d->vec, "operator<<", 10));
731 case SIMPLE_HASH('r', 's') :
733 return (vector_str_push(&d->vec, "operator>>", 10));
734 case SIMPLE_HASH('e', 'q') :
736 return (vector_str_push(&d->vec, "operator==", 10));
737 case SIMPLE_HASH('n', 'e') :
739 return (vector_str_push(&d->vec, "operator!=", 10));
740 case SIMPLE_HASH('l', 't') :
742 return (vector_str_push(&d->vec, "operator<", 9));
743 case SIMPLE_HASH('g', 't') :
745 return (vector_str_push(&d->vec, "operator>", 9));
746 case SIMPLE_HASH('l', 'e') :
748 return (vector_str_push(&d->vec, "operator<=", 10));
749 case SIMPLE_HASH('g', 'e') :
751 return (vector_str_push(&d->vec, "operator>=", 10));
752 case SIMPLE_HASH('a', 'd') :
756 return (vector_str_push(&d->vec, "operator/=",
759 return (vector_str_push(&d->vec, "operator&", 9));
760 case SIMPLE_HASH('o', 'r') :
762 return (vector_str_push(&d->vec, "operator|", 9));
763 case SIMPLE_HASH('e', 'r') :
765 return (vector_str_push(&d->vec, "operator^", 9));
766 case SIMPLE_HASH('a', 'a') :
770 return (vector_str_push(&d->vec, "operator&=",
773 return (vector_str_push(&d->vec, "operator&&",
775 case SIMPLE_HASH('o', 'o') :
777 return (vector_str_push(&d->vec, "operator||", 10));
778 case SIMPLE_HASH('n', 't') :
780 return (vector_str_push(&d->vec, "operator!", 9));
781 case SIMPLE_HASH('c', 'o') :
783 return (vector_str_push(&d->vec, "operator~", 9));
784 case SIMPLE_HASH('p', 'p') :
786 return (vector_str_push(&d->vec, "operator++", 10));
787 case SIMPLE_HASH('m', 'm') :
789 return (vector_str_push(&d->vec, "operator--", 10));
790 case SIMPLE_HASH('a', 's') :
792 return (vector_str_push(&d->vec, "operator=", 9));
793 case SIMPLE_HASH('r', 'f') :
795 return (vector_str_push(&d->vec, "operator->", 10));
796 case SIMPLE_HASH('a', 'p') :
798 if (*(d->p + 2) != 'l')
802 return (vector_str_push(&d->vec, "operator+=", 10));
803 case SIMPLE_HASH('a', 'm') :
807 return (vector_str_push(&d->vec, "operator-=",
809 } else if (*d->p == 'u') {
811 return (vector_str_push(&d->vec, "operator*=",
813 } else if (*d->p == 'd') {
815 return (vector_str_push(&d->vec, "operator%=",
820 case SIMPLE_HASH('a', 'l') :
822 if (*(d->p + 2) != 's')
826 return (vector_str_push(&d->vec, "operator<<=", 11));
827 case SIMPLE_HASH('a', 'r') :
829 if (*(d->p + 2) != 's')
833 return (vector_str_push(&d->vec, "operator>>=", 11));
834 case SIMPLE_HASH('a', 'o') :
836 if (*(d->p + 2) != 'r')
840 return (vector_str_push(&d->vec, "operator|=", 10));
841 case SIMPLE_HASH('a', 'e') :
843 if (*(d->p + 2) != 'r')
847 return (vector_str_push(&d->vec, "operator^=", 10));
848 case SIMPLE_HASH('c', 'm') :
850 return (vector_str_push(&d->vec, "operator,", 9));
851 case SIMPLE_HASH('r', 'm') :
853 return (vector_str_push(&d->vec, "operator->*", 11));
854 case SIMPLE_HASH('c', 'l') :
856 return (vector_str_push(&d->vec, "()", 2));
857 case SIMPLE_HASH('v', 'c') :
859 return (vector_str_push(&d->vec, "[]", 2));
860 case SIMPLE_HASH('c', 't') :
862 d->type = ENCODE_OP_CT;
864 if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) {
867 return (read_qual_name(d));
868 } else if (ELFTC_ISDIGIT(*d->p))
869 return (read_class(d));
872 case SIMPLE_HASH('d', 't') :
874 d->type = ENCODE_OP_DT;
876 if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) {
879 return (read_qual_name(d));
880 } else if (ELFTC_ISDIGIT(*d->p))
881 return (read_class(d));
884 case SIMPLE_HASH('n', 'w') :
886 return (vector_str_push(&d->vec, "operator new()", 14));
887 case SIMPLE_HASH('d', 'l') :
889 return (vector_str_push(&d->vec, "operator delete()",
891 case SIMPLE_HASH('o', 'p') :
892 /* __op<TO_TYPE>__<FROM_TYPE> */
895 d->type = ENCODE_OP_USER;
897 return (read_op_user(d));
904 read_op_user(struct demangle_data *d)
906 struct demangle_data from, to;
907 size_t from_len, to_len;
909 char *from_str, *to_str;
914 if (init_demangle_data(&from) == false)
920 if (init_demangle_data(&to) == false)
927 if (read_qual_name(&to) == false)
931 if (vector_str_pop(&to.vec) == false)
934 if (read_class(&to) == false)
941 if ((to_str = vector_str_get_flat(&to.vec, &to_len)) == NULL)
945 if (*from.p == 'Q') {
948 if (read_qual_name(&from) == false)
952 if (vector_str_pop(&from.vec) == false)
955 if (read_class(&from) == false)
959 if ((from_str = vector_str_get_flat(&from.vec, &from_len)) == NULL)
962 if (vector_str_push(&d->vec, from_str, from_len) == false)
965 if (vector_str_push(&d->vec, "::operator ", 11) == false)
968 if (vector_str_push(&d->vec, to_str, to_len) == false)
971 rtn = vector_str_push(&d->vec, "()", 2);
975 dest_demangle_data(&to);
976 dest_demangle_data(&from);
981 /* single digit + class names */
983 read_qual_name(struct demangle_data *d)
991 assert(d->p != NULL && "d->p (org str) is NULL");
992 assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range");
999 for (i = 0; i < num ; ++i) {
1000 if (read_class(d) == false)
1003 if (vector_str_push(&d->vec, "::", 2) == false)
1013 /* Return -1 at fail, 0 at success, and 1 at end */
1015 read_subst(struct demangle_data *d)
1023 idx = strtol(d->p + 1, &str, 10);
1024 if (idx == 0 && (errno == EINVAL || errno == ERANGE))
1028 assert(str != NULL);
1032 if (vector_str_push(&d->vec, d->arg.container[idx - 1],
1033 strlen(d->arg.container[idx - 1])) == false)
1036 if (vector_str_push(&d->arg, d->arg.container[idx - 1],
1037 strlen(d->arg.container[idx - 1])) == false)
1047 read_subst_iter(struct demangle_data *d)
1058 assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range");
1060 repeat = *d->p - 48;
1066 idx = strtol(d->p, &str, 10);
1067 if (idx == 0 && (errno == EINVAL || errno == ERANGE))
1071 assert(str != NULL);
1075 for (i = 0; i < repeat ; ++i) {
1076 if (vector_str_push(&d->vec, d->arg.container[idx - 1],
1077 strlen(d->arg.container[idx - 1])) == false)
1080 if (vector_str_push(&d->arg, d->arg.container[idx - 1],
1081 strlen(d->arg.container[idx - 1])) == false)
1084 if (i != repeat - 1 &&
1085 vector_str_push(&d->vec, ", ", 2) == false)
1096 read_type(struct demangle_data *d)
1102 assert(d->p != NULL && "d->p (org str) is NULL");
1104 while (*d->p == 'U' || *d->p == 'C' || *d->p == 'V' || *d->p == 'S' ||
1105 *d->p == 'P' || *d->p == 'R' || *d->p == 'A' || *d->p == 'F' ||
1111 if (vector_str_push(&d->vec, "unsigned ", 9) == false)
1121 if (vector_str_push(&d->vec, "const ", 6) ==
1130 if (vector_str_push(&d->vec, "volatile ", 9) == false)
1137 if (vector_str_push(&d->vec, "signed ", 7) == false)
1145 return (read_func_ptr(d));
1161 if (read_array(d) == false)
1168 if (read_memptr(d) == false)
1177 if (ELFTC_ISDIGIT(*d->p))
1178 return (read_class(d));
1184 return (read_qual_name(d));
1188 return (vector_str_push(&d->vec, "void", 4));
1192 return (vector_str_push(&d->vec, "char", 4));
1196 return (vector_str_push(&d->vec, "short", 5));
1200 return (vector_str_push(&d->vec, "int", 3));
1204 return (vector_str_push(&d->vec, "long", 4));
1208 return (vector_str_push(&d->vec, "float", 5));
1212 return (vector_str_push(&d->vec, "double", 6));
1216 return (vector_str_push(&d->vec, "long double", 11));
1220 return (vector_str_push(&d->vec, "...", 3));