1 /* 2 * Copyright 2008, François Revol, revol@free.fr 3 * Distributed under the terms of the MIT License. 4 */ 5 #include <ctype.h> 6 #include <cxxabi.h> 7 #include <debug.h> 8 #include <malloc.h> 9 #include <string.h> 10 11 #define DEMANGLE_BUFFER_SIZE (16*1024) 12 static char sDemangleBuffer[DEMANGLE_BUFFER_SIZE]; 13 14 extern "C" void set_debug_demangle_hook(const char *(*demangle_hook)(const char *)); 15 16 /* gcc's __cxa_demangle calls malloc and friends... 17 * we don't want to let it call the real one from inside the kernel debugger... 18 * instead we just return it a static buffer. 19 */ 20 21 void *malloc(size_t len) 22 { 23 if (len < DEMANGLE_BUFFER_SIZE) 24 return sDemangleBuffer; 25 return NULL; 26 } 27 28 29 void free(void *ptr) 30 { 31 } 32 33 34 void *realloc(void * old_ptr, size_t new_size) 35 { 36 return NULL; 37 } 38 39 40 /* doesn't work, va_list sux... */ 41 #if 0 42 class DemangleDebugOutputFilter : public DebugOutputFilter { 43 public: 44 DemangleDebugOutputFilter(); 45 virtual ~DemangleDebugOutputFilter(); 46 void SetChain(DebugOutputFilter *chain); 47 virtual void PrintString(const char* string); 48 virtual void Print(const char* format, va_list args); 49 private: 50 DebugOutputFilter *fChained; 51 }; 52 53 54 DemangleDebugOutputFilter::DemangleDebugOutputFilter() 55 { 56 } 57 58 59 DemangleDebugOutputFilter::~DemangleDebugOutputFilter() 60 { 61 } 62 63 64 void 65 DemangleDebugOutputFilter::SetChain(DebugOutputFilter *chain) 66 { 67 fChained = chain; 68 } 69 70 71 void 72 DemangleDebugOutputFilter::PrintString(const char* string) 73 { 74 fChained->PrintString(string); 75 } 76 77 78 void 79 DemangleDebugOutputFilter::Print(const char* format, va_list args) 80 { 81 int i; 82 const char *p = format; 83 while ((p = strchr(p, '%'))) { 84 if (p[1] == '%') { 85 p+=2; 86 continue; 87 } 88 p++; 89 while (*p && !isalpha(*p)) 90 p++; 91 switch (*p) { 92 case 's': 93 { 94 const char **ptr = &va_arg(args, char *); 95 //char *symbol = va_arg(args, char *); 96 char *symbol = *ptr; 97 char *demangled; 98 size_t length = DEMANGLE_BUFFER_SIZE; 99 int status; 100 101 demangled = abi::__cxa_demangle(symbol, sDemangleBuffer, &length, &status); 102 if (status > 0) { 103 } 104 break; 105 } 106 case 'd': 107 case 'i': 108 { 109 int d; 110 d = va_arg(args, int); 111 break; 112 } 113 case 'L': 114 { 115 long long d; 116 d = va_arg(args, long long); 117 break; 118 } 119 case 'f': 120 { 121 float f; 122 f = va_arg(args, float); 123 break; 124 } 125 case '\0': 126 break; 127 default: 128 panic("unknown printf format\n"); 129 break; 130 } 131 i++; 132 } 133 fChained->Print(format, args); 134 } 135 #endif 136 137 static const char *kdebug_demangle(const char *sym) 138 { 139 char *demangled; 140 size_t length = DEMANGLE_BUFFER_SIZE; 141 int status; 142 143 demangled = abi::__cxa_demangle(sym, sDemangleBuffer, &length, &status); 144 if (status == 0) 145 return demangled; 146 // something bad happened 147 return sym; 148 } 149 150 static void 151 exit_debugger() 152 { 153 } 154 155 156 static status_t 157 std_ops(int32 op, ...) 158 { 159 if (op == B_MODULE_INIT) { 160 #if 0 161 DebugOutputFilter *old; 162 DemangleDebugOutputFilter *filter = new(std::nothrow) DemangleDebugOutputFilter; 163 old = set_debug_output_filter(filter); 164 filter->SetChain(old); 165 #endif 166 debug_set_demangle_hook(kdebug_demangle); 167 168 return B_OK; 169 } else if (op == B_MODULE_UNINIT) { 170 return B_OK; 171 } 172 173 return B_BAD_VALUE; 174 } 175 176 177 static struct debugger_module_info sModuleInfo = { 178 { 179 "debugger/demangle/v1", 180 B_KEEP_LOADED, 181 &std_ops 182 }, 183 184 NULL, 185 exit_debugger, 186 NULL, 187 NULL 188 }; 189 190 module_info *modules[] = { 191 (module_info *)&sModuleInfo, 192 NULL 193 }; 194 195