ReactOS 0.4.16-dev-753-g705a985
undname.c File Reference
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "msvcrt.h"
#include "wine/debug.h"
Include dependency graph for undname.c:

Go to the source code of this file.

Classes

struct  array
 
struct  parsed_symbol
 
struct  datatype_t
 

Macros

#define BLOCK_SIZE   1024
 
#define AVAIL_SIZE   (1024 - sizeof(void*))
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (msvcrt)
 
static BOOL symbol_demangle (struct parsed_symbol *sym)
 
static voidund_alloc (struct parsed_symbol *sym, unsigned int len)
 
static void und_free_all (struct parsed_symbol *sym)
 
static void str_array_init (struct array *a)
 
static BOOL str_array_push (struct parsed_symbol *sym, const char *ptr, int len, struct array *a)
 
static charstr_array_get_ref (struct array *cref, unsigned idx)
 
static char *WINAPIV str_printf (struct parsed_symbol *sym, const char *format,...)
 
static BOOL demangle_datatype (struct parsed_symbol *sym, struct datatype_t *ct, struct array *pmt, BOOL in_args)
 
static const charget_number (struct parsed_symbol *sym)
 
static charget_args (struct parsed_symbol *sym, struct array *pmt_ref, BOOL z_term, char open_char, char close_char)
 
static BOOL get_modifier (struct parsed_symbol *sym, const char **ret, const char **ptr_modif)
 
static BOOL get_modified_type (struct datatype_t *ct, struct parsed_symbol *sym, struct array *pmt_ref, char modif, BOOL in_args)
 
static charget_literal_string (struct parsed_symbol *sym)
 
static charget_template_name (struct parsed_symbol *sym)
 
static BOOL get_class (struct parsed_symbol *sym)
 
static charget_class_string (struct parsed_symbol *sym, int start)
 
static charget_class_name (struct parsed_symbol *sym)
 
static BOOL get_calling_convention (char ch, const char **call_conv, const char **exported, unsigned flags)
 
static const charget_simple_type (char c)
 
static const charget_extended_type (char c)
 
static BOOL handle_data (struct parsed_symbol *sym)
 
static BOOL handle_method (struct parsed_symbol *sym, BOOL cast_op)
 
char *CDECL __unDNameEx (char *buffer, const char *mangled, int buflen, malloc_func_t memget, free_func_t memfree, void *unknown, unsigned short int flags)
 
char *CDECL __unDName (char *buffer, const char *mangled, int buflen, malloc_func_t memget, free_func_t memfree, unsigned short int flags)
 

Macro Definition Documentation

◆ AVAIL_SIZE

#define AVAIL_SIZE   (1024 - sizeof(void*))

◆ BLOCK_SIZE

#define BLOCK_SIZE   1024

Function Documentation

◆ __unDName()

char *CDECL __unDName ( char buffer,
const char mangled,
int  buflen,
malloc_func_t  memget,
free_func_t  memfree,
unsigned short int  flags 
)

Definition at line 1650 of file undname.c.

1653{
1654 return __unDNameEx(buffer, mangled, buflen, memget, memfree, NULL, flags);
1655}
#define NULL
Definition: types.h:112
GLuint buffer
Definition: glext.h:5915
GLbitfield flags
Definition: glext.h:7161
char *CDECL __unDNameEx(char *buffer, const char *mangled, int buflen, malloc_func_t memget, free_func_t memfree, void *unknown, unsigned short int flags)
Definition: undname.c:1603

Referenced by type_info_name().

◆ __unDNameEx()

char *CDECL __unDNameEx ( char buffer,
const char mangled,
int  buflen,
malloc_func_t  memget,
free_func_t  memfree,
void unknown,
unsigned short int  flags 
)

Definition at line 1603 of file undname.c.

1606{
1607 struct parsed_symbol sym;
1608 const char* result;
1609
1610 TRACE("(%p,%s,%d,%p,%p,%p,%x)\n",
1611 buffer, debugstr_a(mangled), buflen, memget, memfree, unknown, flags);
1612
1613 /* The flags details is not documented by MS. However, it looks exactly
1614 * like the UNDNAME_ manifest constants from imagehlp.h and dbghelp.h
1615 * So, we copied those (on top of the file)
1616 */
1617 memset(&sym, 0, sizeof(struct parsed_symbol));
1622
1623 sym.flags = flags;
1624 sym.mem_alloc_ptr = memget;
1625 sym.mem_free_ptr = memfree;
1626 sym.current = mangled;
1627 str_array_init( &sym.names );
1628 str_array_init( &sym.stack );
1629
1630 result = symbol_demangle(&sym) ? sym.result : mangled;
1631 if (buffer && buflen)
1632 {
1633 lstrcpynA( buffer, result, buflen);
1634 }
1635 else
1636 {
1637 buffer = memget(strlen(result) + 1);
1638 if (buffer) strcpy(buffer, result);
1639 }
1640
1641 und_free_all(&sym);
1642
1643 return buffer;
1644}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define UNDNAME_NO_ALLOCATION_LANGUAGE
Definition: dbghelp.h:1256
#define UNDNAME_NO_FUNCTION_RETURNS
Definition: dbghelp.h:1254
#define UNDNAME_NO_ACCESS_SPECIFIERS
Definition: dbghelp.h:1260
#define UNDNAME_NO_MEMBER_TYPE
Definition: dbghelp.h:1262
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1605
#define lstrcpynA
Definition: compat.h:751
#define UNDNAME_NAME_ONLY
Definition: compat.h:1017
GLuint64EXT * result
Definition: glext.h:11304
#define debugstr_a
Definition: kernel32.h:31
strcpy
Definition: string.h:131
#define UNDNAME_NO_COMPLEX_TYPE
Definition: msvcrt.h:140
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
static void und_free_all(struct parsed_symbol *sym)
Definition: undname.c:144
static BOOL symbol_demangle(struct parsed_symbol *sym)
Definition: undname.c:1344
static void str_array_init(struct array *a)
Definition: undname.c:161

Referenced by __unDName().

◆ demangle_datatype()

static BOOL demangle_datatype ( struct parsed_symbol sym,
struct datatype_t ct,
struct array pmt,
BOOL  in_args 
)
static

Definition at line 794 of file undname.c.

796{
797 char dt;
798 BOOL add_pmt = TRUE;
799
800 assert(ct);
801 ct->left = ct->right = NULL;
802
803 switch (dt = *sym->current++)
804 {
805 case '_':
806 /* MS type: __int8,__int16 etc */
807 ct->left = get_extended_type(*sym->current++);
808 break;
809 case 'C': case 'D': case 'E': case 'F': case 'G':
810 case 'H': case 'I': case 'J': case 'K': case 'M':
811 case 'N': case 'O': case 'X': case 'Z':
812 /* Simple data types */
813 ct->left = get_simple_type(dt);
814 add_pmt = FALSE;
815 break;
816 case 'T': /* union */
817 case 'U': /* struct */
818 case 'V': /* class */
819 case 'Y': /* cointerface */
820 /* Class/struct/union/cointerface */
821 {
822 const char* struct_name = NULL;
823 const char* type_name = NULL;
824
825 if (!(struct_name = get_class_name(sym)))
826 goto done;
827 if (!(sym->flags & UNDNAME_NO_COMPLEX_TYPE))
828 {
829 switch (dt)
830 {
831 case 'T': type_name = "union "; break;
832 case 'U': type_name = "struct "; break;
833 case 'V': type_name = "class "; break;
834 case 'Y': type_name = "cointerface "; break;
835 }
836 }
837 ct->left = str_printf(sym, "%s%s", type_name, struct_name);
838 }
839 break;
840 case '?':
841 /* not all the time is seems */
842 if (in_args)
843 {
844 const char* ptr;
845 if (!(ptr = get_number(sym))) goto done;
846 ct->left = str_printf(sym, "`template-parameter-%s'", ptr);
847 }
848 else
849 {
850 if (!get_modified_type(ct, sym, pmt_ref, '?', in_args)) goto done;
851 }
852 break;
853 case 'A': /* reference */
854 case 'B': /* volatile reference */
855 if (!get_modified_type(ct, sym, pmt_ref, dt, in_args)) goto done;
856 break;
857 case 'Q': /* const pointer */
858 case 'R': /* volatile pointer */
859 case 'S': /* const volatile pointer */
860 if (!get_modified_type(ct, sym, pmt_ref, in_args ? dt : 'P', in_args)) goto done;
861 break;
862 case 'P': /* Pointer */
863 if (isdigit(*sym->current))
864 {
865 /* FIXME:
866 * P6 = Function pointer
867 * P8 = Member function pointer
868 * others who knows.. */
869 if (*sym->current == '8')
870 {
871 char* args = NULL;
872 const char* call_conv;
873 const char* exported;
874 struct datatype_t sub_ct;
875 unsigned mark = sym->stack.num;
876 const char* class;
877 const char* modifier;
878 const char* ptr_modif;
879
880 sym->current++;
881
882 if (!(class = get_class_name(sym)))
883 goto done;
884 if (!get_modifier(sym, &modifier, &ptr_modif))
885 goto done;
886 if (modifier)
887 modifier = str_printf(sym, "%s %s", modifier, ptr_modif);
888 else if(ptr_modif)
889 modifier = str_printf(sym, " %s", ptr_modif);
890 if (!get_calling_convention(*sym->current++,
891 &call_conv, &exported,
893 goto done;
894 if (!demangle_datatype(sym, &sub_ct, pmt_ref, FALSE))
895 goto done;
896
897 args = get_args(sym, pmt_ref, TRUE, '(', ')');
898 if (!args) goto done;
899 sym->stack.num = mark;
900
901 ct->left = str_printf(sym, "%s%s (%s %s::*",
902 sub_ct.left, sub_ct.right, call_conv, class);
903 ct->right = str_printf(sym, ")%s%s", args, modifier);
904 }
905 else if (*sym->current == '6')
906 {
907 char* args = NULL;
908 const char* call_conv;
909 const char* exported;
910 struct datatype_t sub_ct;
911 unsigned mark = sym->stack.num;
912
913 sym->current++;
914
915 if (!get_calling_convention(*sym->current++,
916 &call_conv, &exported,
918 !demangle_datatype(sym, &sub_ct, pmt_ref, FALSE))
919 goto done;
920
921 args = get_args(sym, pmt_ref, TRUE, '(', ')');
922 if (!args) goto done;
923 sym->stack.num = mark;
924
925 ct->left = str_printf(sym, "%s%s (%s*",
926 sub_ct.left, sub_ct.right, call_conv);
927 ct->right = str_printf(sym, ")%s", args);
928 }
929 else goto done;
930 }
931 else if (!get_modified_type(ct, sym, pmt_ref, 'P', in_args)) goto done;
932 break;
933 case 'W':
934 if (*sym->current == '4')
935 {
936 char* enum_name;
937 sym->current++;
938 if (!(enum_name = get_class_name(sym)))
939 goto done;
941 ct->left = enum_name;
942 else
943 ct->left = str_printf(sym, "enum %s", enum_name);
944 }
945 else goto done;
946 break;
947 case '0': case '1': case '2': case '3': case '4':
948 case '5': case '6': case '7': case '8': case '9':
949 /* Referring back to previously parsed type */
950 /* left and right are pushed as two separate strings */
951 if (!pmt_ref) goto done;
952 ct->left = str_array_get_ref(pmt_ref, (dt - '0') * 2);
953 ct->right = str_array_get_ref(pmt_ref, (dt - '0') * 2 + 1);
954 if (!ct->left) goto done;
955 add_pmt = FALSE;
956 break;
957 case '$':
958 switch (*sym->current++)
959 {
960 case '0':
961 if (!(ct->left = get_number(sym))) goto done;
962 break;
963 case 'D':
964 {
965 const char* ptr;
966 if (!(ptr = get_number(sym))) goto done;
967 ct->left = str_printf(sym, "`template-parameter%s'", ptr);
968 }
969 break;
970 case 'F':
971 {
972 const char* p1;
973 const char* p2;
974 if (!(p1 = get_number(sym))) goto done;
975 if (!(p2 = get_number(sym))) goto done;
976 ct->left = str_printf(sym, "{%s,%s}", p1, p2);
977 }
978 break;
979 case 'G':
980 {
981 const char* p1;
982 const char* p2;
983 const char* p3;
984 if (!(p1 = get_number(sym))) goto done;
985 if (!(p2 = get_number(sym))) goto done;
986 if (!(p3 = get_number(sym))) goto done;
987 ct->left = str_printf(sym, "{%s,%s,%s}", p1, p2, p3);
988 }
989 break;
990 case 'Q':
991 {
992 const char* ptr;
993 if (!(ptr = get_number(sym))) goto done;
994 ct->left = str_printf(sym, "`non-type-template-parameter%s'", ptr);
995 }
996 break;
997 case '$':
998 if (*sym->current == 'B')
999 {
1000 unsigned mark = sym->stack.num;
1001 struct datatype_t sub_ct;
1002 const char* arr = NULL;
1003 sym->current++;
1004
1005 /* multidimensional arrays */
1006 if (*sym->current == 'Y')
1007 {
1008 const char* n1;
1009 int num;
1010
1011 sym->current++;
1012 if (!(n1 = get_number(sym))) goto done;
1013 num = atoi(n1);
1014
1015 while (num--)
1016 arr = str_printf(sym, "%s[%s]", arr, get_number(sym));
1017 }
1018
1019 if (!demangle_datatype(sym, &sub_ct, pmt_ref, FALSE)) goto done;
1020
1021 if (arr)
1022 ct->left = str_printf(sym, "%s %s", sub_ct.left, arr);
1023 else
1024 ct->left = sub_ct.left;
1025 ct->right = sub_ct.right;
1026 sym->stack.num = mark;
1027 }
1028 else if (*sym->current == 'C')
1029 {
1030 const char *ptr, *ptr_modif;
1031
1032 sym->current++;
1033 if (!get_modifier(sym, &ptr, &ptr_modif)) goto done;
1034 if (!demangle_datatype(sym, ct, pmt_ref, in_args)) goto done;
1035 ct->left = str_printf(sym, "%s %s", ct->left, ptr);
1036 }
1037 break;
1038 }
1039 break;
1040 default :
1041 ERR("Unknown type %c\n", dt);
1042 break;
1043 }
1044 if (add_pmt && pmt_ref && in_args)
1045 {
1046 /* left and right are pushed as two separate strings */
1047 if (!str_array_push(sym, ct->left ? ct->left : "", -1, pmt_ref) ||
1048 !str_array_push(sym, ct->right ? ct->right : "", -1, pmt_ref))
1049 return FALSE;
1050 }
1051done:
1052
1053 return ct->left != NULL;
1054}
#define isdigit(c)
Definition: acclib.h:68
#define ERR(fmt,...)
Definition: precomp.h:57
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define assert(x)
Definition: debug.h:53
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint num
Definition: glext.h:9618
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
static PVOID ptr
Definition: dispmode.c:27
int n1
Definition: dwarfget.c:147
Definition: match.c:390
const char * right
Definition: undname.c:90
const char * left
Definition: undname.c:89
unsigned flags
Definition: undname.c:72
struct array stack
Definition: undname.c:80
const char * current
Definition: undname.c:76
static BOOL demangle_datatype(struct parsed_symbol *sym, struct datatype_t *ct, struct array *pmt, BOOL in_args)
Definition: undname.c:794
static BOOL get_modified_type(struct datatype_t *ct, struct parsed_symbol *sym, struct array *pmt_ref, char modif, BOOL in_args)
Definition: undname.c:431
static const char * get_number(struct parsed_symbol *sym)
Definition: undname.c:298
static BOOL get_modifier(struct parsed_symbol *sym, const char **ret, const char **ptr_modif)
Definition: undname.c:407
static char * get_args(struct parsed_symbol *sym, struct array *pmt_ref, BOOL z_term, char open_char, char close_char)
Definition: undname.c:349
static BOOL get_calling_convention(char ch, const char **call_conv, const char **exported, unsigned flags)
Definition: undname.c:690
static char *WINAPIV str_printf(struct parsed_symbol *sym, const char *format,...)
Definition: undname.c:239
static BOOL str_array_push(struct parsed_symbol *sym, const char *ptr, int len, struct array *a)
Definition: undname.c:171
static const char * get_extended_type(char c)
Definition: undname.c:764
static char * str_array_get_ref(struct array *cref, unsigned idx)
Definition: undname.c:220
static const char * get_simple_type(char c)
Definition: undname.c:735
static char * get_class_name(struct parsed_symbol *sym)
Definition: undname.c:674

Referenced by demangle_datatype(), get_args(), get_modified_type(), handle_data(), handle_method(), and symbol_demangle().

◆ get_args()

static char * get_args ( struct parsed_symbol sym,
struct array pmt_ref,
BOOL  z_term,
char  open_char,
char  close_char 
)
static

Definition at line 349 of file undname.c.

352{
353 struct datatype_t ct;
354 struct array arg_collect;
355 char* args_str = NULL;
356 char* last;
357 unsigned int i;
358
359 str_array_init(&arg_collect);
360
361 /* Now come the function arguments */
362 while (*sym->current)
363 {
364 /* Decode each data type and append it to the argument list */
365 if (*sym->current == '@')
366 {
367 sym->current++;
368 break;
369 }
370 if (!demangle_datatype(sym, &ct, pmt_ref, TRUE))
371 return NULL;
372 /* 'void' terminates an argument list in a function */
373 if (z_term && !strcmp(ct.left, "void")) break;
374 if (!str_array_push(sym, str_printf(sym, "%s%s", ct.left, ct.right), -1,
375 &arg_collect))
376 return NULL;
377 if (!strcmp(ct.left, "...")) break;
378 }
379 /* Functions are always terminated by 'Z'. If we made it this far and
380 * don't find it, we have incorrectly identified a data type.
381 */
382 if (z_term && *sym->current++ != 'Z') return NULL;
383
384 if (arg_collect.num == 0 ||
385 (arg_collect.num == 1 && !strcmp(arg_collect.elts[0], "void")))
386 return str_printf(sym, "%cvoid%c", open_char, close_char);
387 for (i = 1; i < arg_collect.num; i++)
388 {
389 args_str = str_printf(sym, "%s,%s", args_str, arg_collect.elts[i]);
390 }
391
392 last = args_str ? args_str : arg_collect.elts[0];
393 if (close_char == '>' && last[strlen(last) - 1] == '>')
394 args_str = str_printf(sym, "%c%s%s %c",
395 open_char, arg_collect.elts[0], args_str, close_char);
396 else
397 args_str = str_printf(sym, "%c%s%s%c",
398 open_char, arg_collect.elts[0], args_str, close_char);
399
400 return args_str;
401}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static char close_char
Definition: i386-dis.c:2054
static char open_char
Definition: i386-dis.c:2053
static UINT UINT last
Definition: font.c:45

Referenced by demangle_datatype(), get_template_name(), handle_method(), and symbol_demangle().

◆ get_calling_convention()

static BOOL get_calling_convention ( char  ch,
const char **  call_conv,
const char **  exported,
unsigned  flags 
)
static

Definition at line 690 of file undname.c.

692{
693 *call_conv = *exported = NULL;
694
696 {
698 {
699 if (((ch - 'A') % 2) == 1) *exported = "dll_export ";
700 switch (ch)
701 {
702 case 'A': case 'B': *call_conv = "cdecl"; break;
703 case 'C': case 'D': *call_conv = "pascal"; break;
704 case 'E': case 'F': *call_conv = "thiscall"; break;
705 case 'G': case 'H': *call_conv = "stdcall"; break;
706 case 'I': case 'J': *call_conv = "fastcall"; break;
707 case 'K': case 'L': break;
708 case 'M': *call_conv = "clrcall"; break;
709 default: ERR("Unknown calling convention %c\n", ch); return FALSE;
710 }
711 }
712 else
713 {
714 if (((ch - 'A') % 2) == 1) *exported = "__dll_export ";
715 switch (ch)
716 {
717 case 'A': case 'B': *call_conv = "__cdecl"; break;
718 case 'C': case 'D': *call_conv = "__pascal"; break;
719 case 'E': case 'F': *call_conv = "__thiscall"; break;
720 case 'G': case 'H': *call_conv = "__stdcall"; break;
721 case 'I': case 'J': *call_conv = "__fastcall"; break;
722 case 'K': case 'L': break;
723 case 'M': *call_conv = "__clrcall"; break;
724 default: ERR("Unknown calling convention %c\n", ch); return FALSE;
725 }
726 }
727 }
728 return TRUE;
729}
#define UNDNAME_NO_MS_KEYWORDS
Definition: dbghelp.h:1253
#define UNDNAME_NO_LEADING_UNDERSCORES
Definition: dbghelp.h:1252

Referenced by demangle_datatype(), and handle_method().

◆ get_class()

static BOOL get_class ( struct parsed_symbol sym)
static

Definition at line 583 of file undname.c.

584{
585 const char* name = NULL;
586
587 while (*sym->current != '@')
588 {
589 switch (*sym->current)
590 {
591 case '\0': return FALSE;
592
593 case '0': case '1': case '2': case '3':
594 case '4': case '5': case '6': case '7':
595 case '8': case '9':
596 name = str_array_get_ref(&sym->names, *sym->current++ - '0');
597 break;
598 case '?':
599 switch (*++sym->current)
600 {
601 case '$':
602 sym->current++;
603 if ((name = get_template_name(sym)) &&
604 !str_array_push(sym, name, -1, &sym->names))
605 return FALSE;
606 break;
607 case '?':
608 {
609 struct array stack = sym->stack;
610 unsigned int start = sym->names.start;
611 unsigned int num = sym->names.num;
612
613 str_array_init( &sym->stack );
614 if (symbol_demangle( sym )) name = str_printf( sym, "`%s'", sym->result );
615 sym->names.start = start;
616 sym->names.num = num;
617 sym->stack = stack;
618 }
619 break;
620 default:
621 if (!(name = get_number( sym ))) return FALSE;
622 name = str_printf( sym, "`%s'", name );
623 break;
624 }
625 break;
626 default:
628 break;
629 }
630 if (!name || !str_array_push(sym, name, -1, &sym->stack))
631 return FALSE;
632 }
633 sym->current++;
634 return TRUE;
635}
GLuint start
Definition: gl.h:1545
Definition: name.c:39
char * result
Definition: undname.c:77
struct array names
Definition: undname.c:79
Definition: format.c:80
static char * get_literal_string(struct parsed_symbol *sym)
Definition: undname.c:517
static char * get_template_name(struct parsed_symbol *sym)
Definition: undname.c:547

Referenced by get_class_name(), and symbol_demangle().

◆ get_class_name()

static char * get_class_name ( struct parsed_symbol sym)
static

Definition at line 674 of file undname.c.

675{
676 unsigned mark = sym->stack.num;
677 char* s = NULL;
678
679 if (get_class(sym))
680 s = get_class_string(sym, mark);
681 sym->stack.num = mark;
682 return s;
683}
GLdouble s
Definition: gl.h:2039
static BOOL get_class(struct parsed_symbol *sym)
Definition: undname.c:583
static char * get_class_string(struct parsed_symbol *sym, int start)
Definition: undname.c:642

Referenced by demangle_datatype(), and handle_data().

◆ get_class_string()

static char * get_class_string ( struct parsed_symbol sym,
int  start 
)
static

Definition at line 642 of file undname.c.

643{
644 int i;
645 unsigned int len, sz;
646 char* ret;
647 struct array *a = &sym->stack;
648
649 for (len = 0, i = start; i < a->num; i++)
650 {
651 assert(a->elts[i]);
652 len += 2 + strlen(a->elts[i]);
653 }
654 if (!(ret = und_alloc(sym, len - 1))) return NULL;
655 for (len = 0, i = a->num - 1; i >= start; i--)
656 {
657 sz = strlen(a->elts[i]);
658 memcpy(ret + len, a->elts[i], sz);
659 len += sz;
660 if (i > start)
661 {
662 ret[len++] = ':';
663 ret[len++] = ':';
664 }
665 }
666 ret[len] = '\0';
667 return ret;
668}
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static void * und_alloc(struct parsed_symbol *sym, unsigned int len)
Definition: undname.c:102
int ret

Referenced by get_class_name(), handle_data(), and handle_method().

◆ get_extended_type()

static const char * get_extended_type ( char  c)
static

Definition at line 764 of file undname.c.

765{
766 const char* type_string;
767
768 switch (c)
769 {
770 case 'D': type_string = "__int8"; break;
771 case 'E': type_string = "unsigned __int8"; break;
772 case 'F': type_string = "__int16"; break;
773 case 'G': type_string = "unsigned __int16"; break;
774 case 'H': type_string = "__int32"; break;
775 case 'I': type_string = "unsigned __int32"; break;
776 case 'J': type_string = "__int64"; break;
777 case 'K': type_string = "unsigned __int64"; break;
778 case 'L': type_string = "__int128"; break;
779 case 'M': type_string = "unsigned __int128"; break;
780 case 'N': type_string = "bool"; break;
781 case 'W': type_string = "wchar_t"; break;
782 default: type_string = NULL; break;
783 }
784 return type_string;
785}
const GLubyte * c
Definition: glext.h:8905

Referenced by demangle_datatype().

◆ get_literal_string()

static char * get_literal_string ( struct parsed_symbol sym)
static

Definition at line 517 of file undname.c.

518{
519 const char *ptr = sym->current;
520
521 do {
522 if (!((*sym->current >= 'A' && *sym->current <= 'Z') ||
523 (*sym->current >= 'a' && *sym->current <= 'z') ||
524 (*sym->current >= '0' && *sym->current <= '9') ||
525 *sym->current == '_' || *sym->current == '$')) {
526 TRACE("Failed at '%c' in %s\n", *sym->current, debugstr_a(ptr));
527 return NULL;
528 }
529 } while (*++sym->current != '@');
530 sym->current++;
531 if (!str_array_push(sym, ptr, sym->current - 1 - ptr, &sym->names))
532 return NULL;
533
534 return str_array_get_ref(&sym->names, sym->names.num - sym->names.start - 1);
535}

Referenced by get_class(), and get_template_name().

◆ get_modified_type()

static BOOL get_modified_type ( struct datatype_t ct,
struct parsed_symbol sym,
struct array pmt_ref,
char  modif,
BOOL  in_args 
)
static

Definition at line 431 of file undname.c.

433{
434 const char* modifier;
435 const char* str_modif;
436 const char *ptr_modif = "";
437
438 if (*sym->current == 'E')
439 {
440 if (!(sym->flags & UNDNAME_NO_MS_KEYWORDS))
441 {
443 ptr_modif = " ptr64";
444 else
445 ptr_modif = " __ptr64";
446 }
447 sym->current++;
448 }
449
450 switch (modif)
451 {
452 case 'A': str_modif = str_printf(sym, " &%s", ptr_modif); break;
453 case 'B': str_modif = str_printf(sym, " &%s volatile", ptr_modif); break;
454 case 'P': str_modif = str_printf(sym, " *%s", ptr_modif); break;
455 case 'Q': str_modif = str_printf(sym, " *%s const", ptr_modif); break;
456 case 'R': str_modif = str_printf(sym, " *%s volatile", ptr_modif); break;
457 case 'S': str_modif = str_printf(sym, " *%s const volatile", ptr_modif); break;
458 case '?': str_modif = ""; break;
459 default: return FALSE;
460 }
461
462 if (get_modifier(sym, &modifier, &ptr_modif))
463 {
464 unsigned mark = sym->stack.num;
465 struct datatype_t sub_ct;
466
467 /* multidimensional arrays */
468 if (*sym->current == 'Y')
469 {
470 const char* n1;
471 int num;
472
473 sym->current++;
474 if (!(n1 = get_number(sym))) return FALSE;
475 num = atoi(n1);
476
477 if (str_modif[0] == ' ' && !modifier)
478 str_modif++;
479
480 if (modifier)
481 {
482 str_modif = str_printf(sym, " (%s%s)", modifier, str_modif);
483 modifier = NULL;
484 }
485 else
486 str_modif = str_printf(sym, " (%s)", str_modif);
487
488 while (num--)
489 str_modif = str_printf(sym, "%s[%s]", str_modif, get_number(sym));
490 }
491
492 /* Recurse to get the referred-to type */
493 if (!demangle_datatype(sym, &sub_ct, pmt_ref, FALSE))
494 return FALSE;
495 if (modifier)
496 ct->left = str_printf(sym, "%s %s%s", sub_ct.left, modifier, str_modif );
497 else
498 {
499 /* don't insert a space between duplicate '*' */
500 if (!in_args && str_modif[0] && str_modif[1] == '*' && sub_ct.left[strlen(sub_ct.left)-1] == '*')
501 str_modif++;
502 ct->left = str_printf(sym, "%s%s", sub_ct.left, str_modif );
503 }
504 ct->right = sub_ct.right;
505 sym->stack.num = mark;
506 }
507 return TRUE;
508}

Referenced by demangle_datatype().

◆ get_modifier()

static BOOL get_modifier ( struct parsed_symbol sym,
const char **  ret,
const char **  ptr_modif 
)
static

Definition at line 407 of file undname.c.

408{
409 *ptr_modif = NULL;
410 if (*sym->current == 'E')
411 {
412 if (!(sym->flags & UNDNAME_NO_MS_KEYWORDS))
413 {
414 *ptr_modif = "__ptr64";
416 *ptr_modif = *ptr_modif + 2;
417 }
418 sym->current++;
419 }
420 switch (*sym->current++)
421 {
422 case 'A': *ret = NULL; break;
423 case 'B': *ret = "const"; break;
424 case 'C': *ret = "volatile"; break;
425 case 'D': *ret = "const volatile"; break;
426 default: return FALSE;
427 }
428 return TRUE;
429}

Referenced by demangle_datatype(), get_modified_type(), handle_data(), and handle_method().

◆ get_number()

static const char * get_number ( struct parsed_symbol sym)
static

Definition at line 298 of file undname.c.

299{
300 char* ptr;
301 BOOL sgn = FALSE;
302
303 if (*sym->current == '?')
304 {
305 sgn = TRUE;
306 sym->current++;
307 }
308 if (*sym->current >= '0' && *sym->current <= '8')
309 {
310 ptr = und_alloc(sym, 3);
311 if (sgn) ptr[0] = '-';
312 ptr[sgn ? 1 : 0] = *sym->current + 1;
313 ptr[sgn ? 2 : 1] = '\0';
314 sym->current++;
315 }
316 else if (*sym->current == '9')
317 {
318 ptr = und_alloc(sym, 4);
319 if (sgn) ptr[0] = '-';
320 ptr[sgn ? 1 : 0] = '1';
321 ptr[sgn ? 2 : 1] = '0';
322 ptr[sgn ? 3 : 2] = '\0';
323 sym->current++;
324 }
325 else if (*sym->current >= 'A' && *sym->current <= 'P')
326 {
327 int ret = 0;
328
329 while (*sym->current >= 'A' && *sym->current <= 'P')
330 {
331 ret *= 16;
332 ret += *sym->current++ - 'A';
333 }
334 if (*sym->current != '@') return NULL;
335
336 ptr = und_alloc(sym, 17);
337 sprintf(ptr, "%s%u", sgn ? "-" : "", ret);
338 sym->current++;
339 }
340 else return NULL;
341 return ptr;
342}
#define sprintf(buf, format,...)
Definition: sprintf.c:55
long sgn(REAL x)
Definition: varray.cc:48

Referenced by demangle_datatype(), get_class(), get_modified_type(), handle_method(), and symbol_demangle().

◆ get_simple_type()

static const char * get_simple_type ( char  c)
static

Definition at line 735 of file undname.c.

736{
737 const char* type_string;
738
739 switch (c)
740 {
741 case 'C': type_string = "signed char"; break;
742 case 'D': type_string = "char"; break;
743 case 'E': type_string = "unsigned char"; break;
744 case 'F': type_string = "short"; break;
745 case 'G': type_string = "unsigned short"; break;
746 case 'H': type_string = "int"; break;
747 case 'I': type_string = "unsigned int"; break;
748 case 'J': type_string = "long"; break;
749 case 'K': type_string = "unsigned long"; break;
750 case 'M': type_string = "float"; break;
751 case 'N': type_string = "double"; break;
752 case 'O': type_string = "long double"; break;
753 case 'X': type_string = "void"; break;
754 case 'Z': type_string = "..."; break;
755 default: type_string = NULL; break;
756 }
757 return type_string;
758}

Referenced by demangle_datatype().

◆ get_template_name()

static char * get_template_name ( struct parsed_symbol sym)
static

Definition at line 547 of file undname.c.

548{
549 char *name, *args;
550 unsigned num_mark = sym->names.num;
551 unsigned start_mark = sym->names.start;
552 unsigned stack_mark = sym->stack.num;
553 struct array array_pmt;
554
555 sym->names.start = sym->names.num;
556 if (!(name = get_literal_string(sym))) {
557 sym->names.start = start_mark;
558 return FALSE;
559 }
560 str_array_init(&array_pmt);
561 args = get_args(sym, &array_pmt, FALSE, '<', '>');
562 if (args != NULL)
563 name = str_printf(sym, "%s%s", name, args);
564 sym->names.num = num_mark;
565 sym->names.start = start_mark;
566 sym->stack.num = stack_mark;
567 return name;
568}
#define args
Definition: format.c:66

Referenced by get_class(), and symbol_demangle().

◆ handle_data()

static BOOL handle_data ( struct parsed_symbol sym)
static

Definition at line 1061 of file undname.c.

1062{
1063 const char* access = NULL;
1064 const char* member_type = NULL;
1065 const char* modifier = NULL;
1066 const char* ptr_modif;
1067 struct datatype_t ct;
1068 char* name = NULL;
1069 BOOL ret = FALSE;
1070
1071 /* 0 private static
1072 * 1 protected static
1073 * 2 public static
1074 * 3 private non-static
1075 * 4 protected non-static
1076 * 5 public non-static
1077 * 6 ?? static
1078 * 7 ?? static
1079 */
1080
1081 if (!(sym->flags & UNDNAME_NO_ACCESS_SPECIFIERS))
1082 {
1083 /* we only print the access for static members */
1084 switch (*sym->current)
1085 {
1086 case '0': access = "private: "; break;
1087 case '1': access = "protected: "; break;
1088 case '2': access = "public: "; break;
1089 }
1090 }
1091
1092 if (!(sym->flags & UNDNAME_NO_MEMBER_TYPE))
1093 {
1094 if (*sym->current >= '0' && *sym->current <= '2')
1095 member_type = "static ";
1096 }
1097
1098 name = get_class_string(sym, 0);
1099
1100 switch (*sym->current++)
1101 {
1102 case '0': case '1': case '2':
1103 case '3': case '4': case '5':
1104 {
1105 unsigned mark = sym->stack.num;
1106 struct array pmt;
1107
1108 str_array_init(&pmt);
1109
1110 if (!demangle_datatype(sym, &ct, &pmt, FALSE)) goto done;
1111 if (!get_modifier(sym, &modifier, &ptr_modif)) goto done;
1112 if (modifier && ptr_modif) modifier = str_printf(sym, "%s %s", modifier, ptr_modif);
1113 else if (!modifier) modifier = ptr_modif;
1114 sym->stack.num = mark;
1115 }
1116 break;
1117 case '6' : /* compiler generated static */
1118 case '7' : /* compiler generated static */
1119 ct.left = ct.right = NULL;
1120 if (!get_modifier(sym, &modifier, &ptr_modif)) goto done;
1121 if (*sym->current != '@')
1122 {
1123 char* cls = NULL;
1124
1125 if (!(cls = get_class_name(sym)))
1126 goto done;
1127 ct.right = str_printf(sym, "{for `%s'}", cls);
1128 }
1129 break;
1130 case '8':
1131 case '9':
1132 modifier = ct.left = ct.right = NULL;
1133 break;
1134 default: goto done;
1135 }
1136 if (sym->flags & UNDNAME_NAME_ONLY) ct.left = ct.right = modifier = NULL;
1137
1138 sym->result = str_printf(sym, "%s%s%s%s%s%s%s%s", access,
1139 member_type, ct.left,
1140 modifier && ct.left ? " " : NULL, modifier,
1141 modifier || ct.left ? " " : NULL, name, ct.right);
1142 ret = TRUE;
1143done:
1144 return ret;
1145}
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866

Referenced by accumulate_inheritable_handles(), execute_command(), and symbol_demangle().

◆ handle_method()

static BOOL handle_method ( struct parsed_symbol sym,
BOOL  cast_op 
)
static

Definition at line 1152 of file undname.c.

1153{
1154 char accmem;
1155 const char* access = NULL;
1156 int access_id = -1;
1157 const char* member_type = NULL;
1158 struct datatype_t ct_ret;
1159 const char* call_conv;
1160 const char* modifier = NULL;
1161 const char* exported;
1162 const char* args_str = NULL;
1163 const char* name = NULL;
1164 BOOL ret = FALSE, has_args = TRUE, has_ret = TRUE;
1165 unsigned mark;
1166 struct array array_pmt;
1167
1168 /* FIXME: why 2 possible letters for each option?
1169 * 'A' private:
1170 * 'B' private:
1171 * 'C' private: static
1172 * 'D' private: static
1173 * 'E' private: virtual
1174 * 'F' private: virtual
1175 * 'G' private: thunk
1176 * 'H' private: thunk
1177 * 'I' protected:
1178 * 'J' protected:
1179 * 'K' protected: static
1180 * 'L' protected: static
1181 * 'M' protected: virtual
1182 * 'N' protected: virtual
1183 * 'O' protected: thunk
1184 * 'P' protected: thunk
1185 * 'Q' public:
1186 * 'R' public:
1187 * 'S' public: static
1188 * 'T' public: static
1189 * 'U' public: virtual
1190 * 'V' public: virtual
1191 * 'W' public: thunk
1192 * 'X' public: thunk
1193 * 'Y'
1194 * 'Z'
1195 * "$0" private: thunk vtordisp
1196 * "$1" private: thunk vtordisp
1197 * "$2" protected: thunk vtordisp
1198 * "$3" protected: thunk vtordisp
1199 * "$4" public: thunk vtordisp
1200 * "$5" public: thunk vtordisp
1201 * "$B" vcall thunk
1202 * "$R" thunk vtordispex
1203 */
1204 accmem = *sym->current++;
1205 if (accmem == '$')
1206 {
1207 if (*sym->current >= '0' && *sym->current <= '5')
1208 access_id = (*sym->current - '0') / 2;
1209 else if (*sym->current == 'R')
1210 access_id = (sym->current[1] - '0') / 2;
1211 else if (*sym->current != 'B')
1212 goto done;
1213 }
1214 else if (accmem >= 'A' && accmem <= 'Z')
1215 access_id = (accmem - 'A') / 8;
1216 else
1217 goto done;
1218
1219 switch (access_id)
1220 {
1221 case 0: access = "private: "; break;
1222 case 1: access = "protected: "; break;
1223 case 2: access = "public: "; break;
1224 }
1225 if (accmem == '$' || (accmem - 'A') % 8 == 6 || (accmem - 'A') % 8 == 7)
1226 access = str_printf(sym, "[thunk]:%s", access ? access : " ");
1227
1228 if (accmem == '$' && *sym->current != 'B')
1229 member_type = "virtual ";
1230 else if (accmem <= 'X')
1231 {
1232 switch ((accmem - 'A') % 8)
1233 {
1234 case 2: case 3: member_type = "static "; break;
1235 case 4: case 5: case 6: case 7: member_type = "virtual "; break;
1236 }
1237 }
1238
1240 access = NULL;
1241 if (sym->flags & UNDNAME_NO_MEMBER_TYPE)
1242 member_type = NULL;
1243
1244 name = get_class_string(sym, 0);
1245
1246 if (accmem == '$' && *sym->current == 'B') /* vcall thunk */
1247 {
1248 const char *n;
1249
1250 sym->current++;
1251 n = get_number(sym);
1252
1253 if(!n || *sym->current++ != 'A') goto done;
1254 name = str_printf(sym, "%s{%s,{flat}}' }'", name, n);
1255 has_args = FALSE;
1256 has_ret = FALSE;
1257 }
1258 else if (accmem == '$' && *sym->current == 'R') /* vtordispex thunk */
1259 {
1260 const char *n1, *n2, *n3, *n4;
1261
1262 sym->current += 2;
1263 n1 = get_number(sym);
1264 n2 = get_number(sym);
1265 n3 = get_number(sym);
1266 n4 = get_number(sym);
1267
1268 if(!n1 || !n2 || !n3 || !n4) goto done;
1269 name = str_printf(sym, "%s`vtordispex{%s,%s,%s,%s}' ", name, n1, n2, n3, n4);
1270 }
1271 else if (accmem == '$') /* vtordisp thunk */
1272 {
1273 const char *n1, *n2;
1274
1275 sym->current++;
1276 n1 = get_number(sym);
1277 n2 = get_number(sym);
1278
1279 if (!n1 || !n2) goto done;
1280 name = str_printf(sym, "%s`vtordisp{%s,%s}' ", name, n1, n2);
1281 }
1282 else if ((accmem - 'A') % 8 == 6 || (accmem - 'A') % 8 == 7) /* a thunk */
1283 name = str_printf(sym, "%s`adjustor{%s}' ", name, get_number(sym));
1284
1285 if (has_args && (accmem == '$' ||
1286 (accmem <= 'X' && (accmem - 'A') % 8 != 2 && (accmem - 'A') % 8 != 3)))
1287 {
1288 const char *ptr_modif;
1289 /* Implicit 'this' pointer */
1290 /* If there is an implicit this pointer, const modifier follows */
1291 if (!get_modifier(sym, &modifier, &ptr_modif)) goto done;
1292 if (modifier || ptr_modif) modifier = str_printf(sym, "%s %s", modifier, ptr_modif);
1293 }
1294
1295 if (!get_calling_convention(*sym->current++, &call_conv, &exported,
1296 sym->flags))
1297 goto done;
1298
1299 str_array_init(&array_pmt);
1300
1301 /* Return type, or @ if 'void' */
1302 if (has_ret && *sym->current == '@')
1303 {
1304 ct_ret.left = "void";
1305 ct_ret.right = NULL;
1306 sym->current++;
1307 }
1308 else if (has_ret)
1309 {
1310 if (!demangle_datatype(sym, &ct_ret, &array_pmt, FALSE))
1311 goto done;
1312 }
1313 if (!has_ret || sym->flags & UNDNAME_NO_FUNCTION_RETURNS)
1314 ct_ret.left = ct_ret.right = NULL;
1315 if (cast_op)
1316 {
1317 name = str_printf(sym, "%s%s%s", name, ct_ret.left, ct_ret.right);
1318 ct_ret.left = ct_ret.right = NULL;
1319 }
1320
1321 mark = sym->stack.num;
1322 if (has_args && !(args_str = get_args(sym, &array_pmt, TRUE, '(', ')'))) goto done;
1323 if (sym->flags & UNDNAME_NAME_ONLY) args_str = modifier = NULL;
1324 if (sym->flags & UNDNAME_NO_THISTYPE) modifier = NULL;
1325 sym->stack.num = mark;
1326
1327 /* Note: '()' after 'Z' means 'throws', but we don't care here
1328 * Yet!!! FIXME
1329 */
1330 sym->result = str_printf(sym, "%s%s%s%s%s%s%s%s%s%s%s",
1331 access, member_type, ct_ret.left,
1332 (ct_ret.left && !ct_ret.right) ? " " : NULL,
1333 call_conv, call_conv ? " " : NULL, exported,
1334 name, args_str, modifier, ct_ret.right);
1335 ret = TRUE;
1336done:
1337 return ret;
1338}
#define UNDNAME_NO_THISTYPE
Definition: dbghelp.h:1259
GLdouble n
Definition: glext.h:7729
int n4
Definition: dwarfget.c:147
int n2
Definition: dwarfget.c:147
int n3
Definition: dwarfget.c:147

Referenced by symbol_demangle().

◆ str_array_get_ref()

static char * str_array_get_ref ( struct array cref,
unsigned  idx 
)
static

Definition at line 220 of file undname.c.

221{
222 assert(cref);
223 if (cref->start + idx >= cref->max)
224 {
225 WARN("Out of bounds: %p %d + %d >= %d\n",
226 cref, cref->start, idx, cref->max);
227 return NULL;
228 }
229 TRACE("Returning %p[%d] => %s\n",
230 cref, idx, debugstr_a(cref->elts[cref->start + idx]));
231 return cref->elts[cref->start + idx];
232}
#define WARN(fmt,...)
Definition: precomp.h:61
unsigned int idx
Definition: utils.c:41
char ** elts
Definition: undname.c:66
unsigned start
Definition: undname.c:62
unsigned max
Definition: undname.c:64

Referenced by demangle_datatype(), get_class(), and get_literal_string().

◆ str_array_init()

static void str_array_init ( struct array a)
static

Definition at line 161 of file undname.c.

162{
163 a->start = a->num = a->max = a->alloc = 0;
164 a->elts = NULL;
165}

Referenced by __unDNameEx(), get_args(), get_class(), get_template_name(), handle_data(), handle_method(), and symbol_demangle().

◆ str_array_push()

static BOOL str_array_push ( struct parsed_symbol sym,
const char ptr,
int  len,
struct array a 
)
static

Definition at line 171 of file undname.c.

173{
174 char** new;
175
176 assert(ptr);
177 assert(a);
178
179 if (!a->alloc)
180 {
181 new = und_alloc(sym, (a->alloc = 32) * sizeof(a->elts[0]));
182 if (!new) return FALSE;
183 a->elts = new;
184 }
185 else if (a->max >= a->alloc)
186 {
187 new = und_alloc(sym, (a->alloc * 2) * sizeof(a->elts[0]));
188 if (!new) return FALSE;
189 memcpy(new, a->elts, a->alloc * sizeof(a->elts[0]));
190 a->alloc *= 2;
191 a->elts = new;
192 }
193 if (len == -1) len = strlen(ptr);
194 a->elts[a->num] = und_alloc(sym, len + 1);
195 assert(a->elts[a->num]);
196 memcpy(a->elts[a->num], ptr, len);
197 a->elts[a->num][len] = '\0';
198 if (++a->num >= a->max) a->max = a->num;
199 {
200 int i;
201 char c;
202
203 for (i = a->max - 1; i >= 0; i--)
204 {
205 c = '>';
206 if (i < a->start) c = '-';
207 else if (i >= a->num) c = '}';
208 TRACE("%p\t%d%c %s\n", a, i, c, debugstr_a(a->elts[i]));
209 }
210 }
211
212 return TRUE;
213}
#define c
Definition: ke_i.h:80

Referenced by demangle_datatype(), get_args(), get_class(), get_literal_string(), and symbol_demangle().

◆ str_printf()

static char *WINAPIV str_printf ( struct parsed_symbol sym,
const char format,
  ... 
)
static

Definition at line 239 of file undname.c.

240{
242 unsigned int len = 1, i, sz;
243 char* tmp;
244 char* p;
245 char* t;
246
248 for (i = 0; format[i]; i++)
249 {
250 if (format[i] == '%')
251 {
252 switch (format[++i])
253 {
254 case 's': t = va_arg(args, char*); if (t) len += strlen(t); break;
255 case 'c': (void)va_arg(args, int); len++; break;
256 default: i--; /* fall through */
257 case '%': len++; break;
258 }
259 }
260 else len++;
261 }
262 va_end(args);
263 if (!(tmp = und_alloc(sym, len))) return NULL;
265 for (p = tmp, i = 0; format[i]; i++)
266 {
267 if (format[i] == '%')
268 {
269 switch (format[++i])
270 {
271 case 's':
272 t = va_arg(args, char*);
273 if (t)
274 {
275 sz = strlen(t);
276 memcpy(p, t, sz);
277 p += sz;
278 }
279 break;
280 case 'c':
281 *p++ = (char)va_arg(args, int);
282 break;
283 default: i--; /* fall through */
284 case '%': *p++ = '%'; break;
285 }
286 }
287 else *p++ = format[i];
288 }
289 va_end(args);
290 *p = '\0';
291 return tmp;
292}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define va_arg(ap, T)
Definition: acmsvcex.h:89
unsigned char
Definition: typeof.h:29
GLdouble GLdouble t
Definition: gl.h:2047
GLfloat GLfloat p
Definition: glext.h:8902
Definition: format.c:58

Referenced by demangle_datatype(), get_args(), get_class(), get_modified_type(), get_template_name(), handle_data(), handle_method(), and symbol_demangle().

◆ symbol_demangle()

static BOOL symbol_demangle ( struct parsed_symbol sym)
static

Definition at line 1344 of file undname.c.

1345{
1346 BOOL ret = FALSE;
1347 unsigned do_after = 0;
1348 static CHAR dashed_null[] = "--null--";
1349
1350 /* FIXME seems wrong as name, as it demangles a simple data type */
1351 if (sym->flags & UNDNAME_NO_ARGUMENTS)
1352 {
1353 struct datatype_t ct;
1354
1355 if (demangle_datatype(sym, &ct, NULL, FALSE))
1356 {
1357 sym->result = str_printf(sym, "%s%s", ct.left, ct.right);
1358 ret = TRUE;
1359 }
1360 goto done;
1361 }
1362
1363 /* MS mangled names always begin with '?' */
1364 if (*sym->current != '?') return FALSE;
1365 sym->current++;
1366
1367 /* Then function name or operator code */
1368 if (*sym->current == '?' && (sym->current[1] != '$' || sym->current[2] == '?'))
1369 {
1370 const char* function_name = NULL;
1371
1372 if (sym->current[1] == '$')
1373 {
1374 do_after = 6;
1375 sym->current += 2;
1376 }
1377
1378 /* C++ operator code (one character, or two if the first is '_') */
1379 switch (*++sym->current)
1380 {
1381 case '0': do_after = 1; break;
1382 case '1': do_after = 2; break;
1383 case '2': function_name = "operator new"; break;
1384 case '3': function_name = "operator delete"; break;
1385 case '4': function_name = "operator="; break;
1386 case '5': function_name = "operator>>"; break;
1387 case '6': function_name = "operator<<"; break;
1388 case '7': function_name = "operator!"; break;
1389 case '8': function_name = "operator=="; break;
1390 case '9': function_name = "operator!="; break;
1391 case 'A': function_name = "operator[]"; break;
1392 case 'B': function_name = "operator "; do_after = 3; break;
1393 case 'C': function_name = "operator->"; break;
1394 case 'D': function_name = "operator*"; break;
1395 case 'E': function_name = "operator++"; break;
1396 case 'F': function_name = "operator--"; break;
1397 case 'G': function_name = "operator-"; break;
1398 case 'H': function_name = "operator+"; break;
1399 case 'I': function_name = "operator&"; break;
1400 case 'J': function_name = "operator->*"; break;
1401 case 'K': function_name = "operator/"; break;
1402 case 'L': function_name = "operator%"; break;
1403 case 'M': function_name = "operator<"; break;
1404 case 'N': function_name = "operator<="; break;
1405 case 'O': function_name = "operator>"; break;
1406 case 'P': function_name = "operator>="; break;
1407 case 'Q': function_name = "operator,"; break;
1408 case 'R': function_name = "operator()"; break;
1409 case 'S': function_name = "operator~"; break;
1410 case 'T': function_name = "operator^"; break;
1411 case 'U': function_name = "operator|"; break;
1412 case 'V': function_name = "operator&&"; break;
1413 case 'W': function_name = "operator||"; break;
1414 case 'X': function_name = "operator*="; break;
1415 case 'Y': function_name = "operator+="; break;
1416 case 'Z': function_name = "operator-="; break;
1417 case '_':
1418 switch (*++sym->current)
1419 {
1420 case '0': function_name = "operator/="; break;
1421 case '1': function_name = "operator%="; break;
1422 case '2': function_name = "operator>>="; break;
1423 case '3': function_name = "operator<<="; break;
1424 case '4': function_name = "operator&="; break;
1425 case '5': function_name = "operator|="; break;
1426 case '6': function_name = "operator^="; break;
1427 case '7': function_name = "`vftable'"; break;
1428 case '8': function_name = "`vbtable'"; break;
1429 case '9': function_name = "`vcall'"; break;
1430 case 'A': function_name = "`typeof'"; break;
1431 case 'B': function_name = "`local static guard'"; break;
1432 case 'C': function_name = "`string'"; do_after = 4; break;
1433 case 'D': function_name = "`vbase destructor'"; break;
1434 case 'E': function_name = "`vector deleting destructor'"; break;
1435 case 'F': function_name = "`default constructor closure'"; break;
1436 case 'G': function_name = "`scalar deleting destructor'"; break;
1437 case 'H': function_name = "`vector constructor iterator'"; break;
1438 case 'I': function_name = "`vector destructor iterator'"; break;
1439 case 'J': function_name = "`vector vbase constructor iterator'"; break;
1440 case 'K': function_name = "`virtual displacement map'"; break;
1441 case 'L': function_name = "`eh vector constructor iterator'"; break;
1442 case 'M': function_name = "`eh vector destructor iterator'"; break;
1443 case 'N': function_name = "`eh vector vbase constructor iterator'"; break;
1444 case 'O': function_name = "`copy constructor closure'"; break;
1445 case 'R':
1447 switch (*++sym->current)
1448 {
1449 case '0':
1450 {
1451 struct datatype_t ct;
1452 struct array pmt;
1453
1454 sym->current++;
1455 str_array_init(&pmt);
1456 demangle_datatype(sym, &ct, &pmt, FALSE);
1457 if (!demangle_datatype(sym, &ct, NULL, FALSE))
1458 goto done;
1459 function_name = str_printf(sym, "%s%s `RTTI Type Descriptor'",
1460 ct.left, ct.right);
1461 sym->current--;
1462 }
1463 break;
1464 case '1':
1465 {
1466 const char* n1, *n2, *n3, *n4;
1467 sym->current++;
1468 n1 = get_number(sym);
1469 n2 = get_number(sym);
1470 n3 = get_number(sym);
1471 n4 = get_number(sym);
1472 sym->current--;
1473 function_name = str_printf(sym, "`RTTI Base Class Descriptor at (%s,%s,%s,%s)'",
1474 n1, n2, n3, n4);
1475 }
1476 break;
1477 case '2': function_name = "`RTTI Base Class Array'"; break;
1478 case '3': function_name = "`RTTI Class Hierarchy Descriptor'"; break;
1479 case '4': function_name = "`RTTI Complete Object Locator'"; break;
1480 default:
1481 ERR("Unknown RTTI operator: _R%c\n", *sym->current);
1482 break;
1483 }
1484 break;
1485 case 'S': function_name = "`local vftable'"; break;
1486 case 'T': function_name = "`local vftable constructor closure'"; break;
1487 case 'U': function_name = "operator new[]"; break;
1488 case 'V': function_name = "operator delete[]"; break;
1489 case 'X': function_name = "`placement delete closure'"; break;
1490 case 'Y': function_name = "`placement delete[] closure'"; break;
1491 default:
1492 ERR("Unknown operator: _%c\n", *sym->current);
1493 return FALSE;
1494 }
1495 break;
1496 default:
1497 /* FIXME: Other operators */
1498 ERR("Unknown operator: %c\n", *sym->current);
1499 return FALSE;
1500 }
1501 sym->current++;
1502 switch (do_after)
1503 {
1504 case 1: case 2:
1505 if (!str_array_push(sym, dashed_null, -1, &sym->stack))
1506 return FALSE;
1507 break;
1508 case 4:
1509 sym->result = (char*)function_name;
1510 ret = TRUE;
1511 goto done;
1512 case 6:
1513 {
1514 char *args;
1515 struct array array_pmt;
1516
1517 str_array_init(&array_pmt);
1518 args = get_args(sym, &array_pmt, FALSE, '<', '>');
1519 if (args != NULL) function_name = str_printf(sym, "%s%s", function_name, args);
1520 sym->names.num = 0;
1521 }
1522 /* fall through */
1523 default:
1524 if (!str_array_push(sym, function_name, -1, &sym->stack))
1525 return FALSE;
1526 break;
1527 }
1528 }
1529 else if (*sym->current == '$')
1530 {
1531 /* Strange construct, it's a name with a template argument list
1532 and that's all. */
1533 sym->current++;
1534 ret = (sym->result = get_template_name(sym)) != NULL;
1535 goto done;
1536 }
1537 else if (*sym->current == '?' && sym->current[1] == '$')
1538 do_after = 5;
1539
1540 /* Either a class name, or '@' if the symbol is not a class member */
1541 switch (*sym->current)
1542 {
1543 case '@': sym->current++; break;
1544 case '$': break;
1545 default:
1546 /* Class the function is associated with, terminated by '@@' */
1547 if (!get_class(sym)) goto done;
1548 break;
1549 }
1550
1551 switch (do_after)
1552 {
1553 case 0: default: break;
1554 case 1: case 2:
1555 /* it's time to set the member name for ctor & dtor */
1556 if (sym->stack.num <= 1) goto done;
1557 if (do_after == 1)
1558 sym->stack.elts[0] = sym->stack.elts[1];
1559 else
1560 sym->stack.elts[0] = str_printf(sym, "~%s", sym->stack.elts[1]);
1561 /* ctors and dtors don't have return type */
1563 break;
1564 case 3:
1565 sym->flags &= ~UNDNAME_NO_FUNCTION_RETURNS;
1566 break;
1567 case 5:
1568 sym->names.start++;
1569 break;
1570 }
1571
1572 /* Function/Data type and access level */
1573 if (*sym->current >= '0' && *sym->current <= '9')
1574 ret = handle_data(sym);
1575 else if ((*sym->current >= 'A' && *sym->current <= 'Z') || *sym->current == '$')
1576 ret = handle_method(sym, do_after == 3);
1577 else ret = FALSE;
1578done:
1579 if (ret) assert(sym->result);
1580 else WARN("Failed at %s\n", debugstr_a(sym->current));
1581
1582 return ret;
1583}
#define UNDNAME_NO_ARGUMENTS
Definition: dbghelp.h:1266
wchar_t const *const function_name
static BOOL handle_method(struct parsed_symbol *sym, BOOL cast_op)
Definition: undname.c:1152
static BOOL handle_data(struct parsed_symbol *sym)
Definition: undname.c:1061
char CHAR
Definition: xmlstorage.h:175

Referenced by __unDNameEx(), and get_class().

◆ und_alloc()

static void * und_alloc ( struct parsed_symbol sym,
unsigned int  len 
)
static

Definition at line 102 of file undname.c.

103{
104 void* ptr;
105
106#define BLOCK_SIZE 1024
107#define AVAIL_SIZE (1024 - sizeof(void*))
108
109 if (len > AVAIL_SIZE)
110 {
111 /* allocate a specific block */
112 ptr = sym->mem_alloc_ptr(sizeof(void*) + len);
113 if (!ptr) return NULL;
114 *(void**)ptr = sym->alloc_list;
115 sym->alloc_list = ptr;
116 sym->avail_in_first = 0;
117 ptr = (char*)sym->alloc_list + sizeof(void*);
118 }
119 else
120 {
121 if (len > sym->avail_in_first)
122 {
123 /* add a new block */
125 if (!ptr) return NULL;
126 *(void**)ptr = sym->alloc_list;
127 sym->alloc_list = ptr;
129 }
130 /* grab memory from head block */
131 ptr = (char*)sym->alloc_list + BLOCK_SIZE - sym->avail_in_first;
132 sym->avail_in_first -= len;
133 }
134 return ptr;
135#undef BLOCK_SIZE
136#undef AVAIL_SIZE
137}
void * alloc_list
Definition: undname.c:82
malloc_func_t mem_alloc_ptr
Definition: undname.c:73
unsigned avail_in_first
Definition: undname.c:83
#define AVAIL_SIZE
#define BLOCK_SIZE

Referenced by get_class_string(), get_number(), str_array_push(), and str_printf().

◆ und_free_all()

static void und_free_all ( struct parsed_symbol sym)
static

Definition at line 144 of file undname.c.

145{
146 void* next;
147
148 while (sym->alloc_list)
149 {
150 next = *(void**)sym->alloc_list;
151 if(sym->mem_free_ptr) sym->mem_free_ptr(sym->alloc_list);
152 sym->alloc_list = next;
153 }
154 sym->avail_in_first = 0;
155}
static unsigned __int64 next
Definition: rand_nt.c:6
free_func_t mem_free_ptr
Definition: undname.c:74

Referenced by __unDNameEx().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msvcrt  )