1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * FILE: lib/rossym/find.c 5 * PURPOSE: Find symbol info for an address 6 * 7 * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com) 8 */ 9 /* 10 * Parts of this file based on work Copyright (c) 1990, 1993 11 * The Regents of the University of California. All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38 #include <precomp.h> 39 40 #define NDEBUG 41 #include <debug.h> 42 43 BOOLEAN 44 RosSymGetAddressInformation 45 (PROSSYM_INFO RosSymInfo, 46 ULONG_PTR RelativeAddress, 47 PROSSYM_LINEINFO RosSymLineInfo) 48 { 49 ROSSYM_REGISTERS registers; 50 DwarfParam params[sizeof(RosSymLineInfo->Parameters)/sizeof(RosSymLineInfo->Parameters[0])]; 51 DwarfSym proc = { }; 52 int i; 53 int res = dwarfpctoline 54 (RosSymInfo, 55 &proc, 56 RelativeAddress + RosSymInfo->pe->imagebase, 57 &RosSymLineInfo->FileName, 58 &RosSymLineInfo->FunctionName, 59 &RosSymLineInfo->LineNumber); 60 if (res == -1) { 61 werrstr("Could not get basic function info"); 62 return FALSE; 63 } 64 65 if (!(RosSymLineInfo->Flags & ROSSYM_LINEINFO_HAS_REGISTERS)) 66 return TRUE; 67 68 registers = RosSymLineInfo->Registers; 69 70 DwarfExpr cfa = { }; 71 ulong cfaLocation; 72 if (dwarfregunwind 73 (RosSymInfo, 74 RelativeAddress + RosSymInfo->pe->imagebase, 75 proc.attrs.framebase.c, 76 &cfa, 77 ®isters) == -1) { 78 werrstr("Can't get cfa location for %s", RosSymLineInfo->FunctionName); 79 return TRUE; 80 } 81 82 res = dwarfgetparams 83 (RosSymInfo, 84 &proc, 85 RelativeAddress + RosSymInfo->pe->imagebase, 86 sizeof(params)/sizeof(params[0]), 87 params); 88 89 if (res == -1) { 90 werrstr("%s: could not get params at all", RosSymLineInfo->FunctionName); 91 RosSymLineInfo->NumParams = 0; 92 return TRUE; 93 } 94 95 werrstr("%s: res %d", RosSymLineInfo->FunctionName, res); 96 RosSymLineInfo->NumParams = res; 97 98 res = dwarfcomputecfa(RosSymInfo, &cfa, ®isters, &cfaLocation); 99 if (res == -1) { 100 werrstr("%s: could not get our own cfa", RosSymLineInfo->FunctionName); 101 return TRUE; 102 } 103 104 for (i = 0; i < RosSymLineInfo->NumParams; i++) { 105 werrstr("Getting arg %s, unit %x, type %x", 106 params[i].name, params[i].unit, params[i].type); 107 res = dwarfargvalue 108 (RosSymInfo, 109 &proc, 110 RelativeAddress + RosSymInfo->pe->imagebase, 111 cfaLocation, 112 ®isters, 113 ¶ms[i]); 114 if (res == -1) { RosSymLineInfo->NumParams = i; return TRUE; } 115 werrstr("%s: %x", params[i].name, params[i].value); 116 RosSymLineInfo->Parameters[i].ValueName = malloc(strlen(params[i].name)+1); 117 strcpy(RosSymLineInfo->Parameters[i].ValueName, params[i].name); 118 free(params[i].name); 119 RosSymLineInfo->Parameters[i].Value = params[i].value; 120 } 121 122 return TRUE; 123 } 124 125 VOID 126 RosSymFreeAggregate(PROSSYM_AGGREGATE Aggregate) 127 { 128 int i; 129 for (i = 0; i < Aggregate->NumElements; i++) { 130 free(Aggregate->Elements[i].Name); 131 free(Aggregate->Elements[i].Type); 132 } 133 free(Aggregate->Elements); 134 } 135 136 BOOLEAN 137 RosSymAggregate(PROSSYM_INFO RosSymInfo, PCHAR Type, PROSSYM_AGGREGATE Aggregate) 138 { 139 char *tchar; 140 ulong unit, typeoff = 0; 141 DwarfSym type = { }; 142 // Get the first unit 143 if (dwarfaddrtounit(RosSymInfo, RosSymInfo->pe->codestart + RosSymInfo->pe->imagebase, &unit) == -1) 144 return FALSE; 145 146 if (Type[0] == '#') { 147 for (tchar = Type + 1; *tchar; tchar++) { 148 typeoff *= 10; 149 typeoff += *tchar - '0'; 150 } 151 if (dwarfseeksym(RosSymInfo, unit, typeoff, &type) == -1) 152 return FALSE; 153 } else if (dwarflookupnameinunit(RosSymInfo, unit, Type, &type) != 0 || 154 (type.attrs.tag != TagStructType && type.attrs.tag != TagUnionType)) 155 return FALSE; 156 157 DwarfSym element = { }, inner = { }; 158 int count = 0; 159 160 werrstr("type %s (want %s) type %x\n", type.attrs.name, Type, type.attrs.type); 161 162 if (type.attrs.have.type) { 163 if (dwarfseeksym(RosSymInfo, unit, type.attrs.type, &inner) == -1) 164 return FALSE; 165 type = inner; 166 } 167 168 werrstr("finding members %d\n", type.attrs.haskids); 169 while (dwarfnextsymat(RosSymInfo, &type, &element) != -1) { 170 if (element.attrs.have.name) 171 werrstr("%x %s\n", element.attrs.tag, element.attrs.name); 172 if (element.attrs.tag == TagMember) count++; 173 } 174 175 werrstr("%d members\n", count); 176 177 if (!count) return FALSE; 178 memset(&element, 0, sizeof(element)); 179 Aggregate->NumElements = count; 180 Aggregate->Elements = malloc(sizeof(ROSSYM_AGGREGATE_MEMBER) * count); 181 count = 0; 182 werrstr("Enumerating %s\n", Type); 183 while (dwarfnextsymat(RosSymInfo, &type, &element) != -1) { 184 memset(&Aggregate->Elements[count], 0, sizeof(*Aggregate->Elements)); 185 if (element.attrs.tag == TagMember) { 186 if (element.attrs.have.name) { 187 Aggregate->Elements[count].Name = malloc(strlen(element.attrs.name) + 1); 188 strcpy(Aggregate->Elements[count].Name, element.attrs.name); 189 } 190 Aggregate->Elements[count].TypeId = element.attrs.type; 191 // Seek our range in loc 192 DwarfBuf locbuf; 193 DwarfBuf instream = { }; 194 195 locbuf.d = RosSymInfo; 196 locbuf.addrsize = RosSymInfo->addrsize; 197 198 if (element.attrs.have.datamemberloc) { 199 instream = locbuf; 200 instream.p = element.attrs.datamemberloc.b.data; 201 instream.ep = element.attrs.datamemberloc.b.data + element.attrs.datamemberloc.b.len; 202 werrstr("datamemberloc type %x %p:%x\n", 203 element.attrs.have.datamemberloc, 204 element.attrs.datamemberloc.b.data, element.attrs.datamemberloc.b.len); 205 } 206 207 if (dwarfgetarg(RosSymInfo, element.attrs.name, &instream, 0, NULL, &Aggregate->Elements[count].BaseOffset) == -1) 208 Aggregate->Elements[count].BaseOffset = -1; 209 werrstr("tag %x name %s base %x type %x\n", 210 element.attrs.tag, element.attrs.name, 211 Aggregate->Elements[count].BaseOffset, 212 Aggregate->Elements[count].TypeId); 213 count++; 214 } 215 } 216 for (count = 0; count < Aggregate->NumElements; count++) { 217 memset(&type, 0, sizeof(type)); 218 memset(&inner, 0, sizeof(inner)); 219 werrstr("seeking type %x (%s) from %s\n", 220 Aggregate->Elements[count].TypeId, 221 Aggregate->Elements[count].Type, 222 Aggregate->Elements[count].Name); 223 dwarfseeksym(RosSymInfo, unit, Aggregate->Elements[count].TypeId, &type); 224 while (type.attrs.have.type && type.attrs.tag != TagPointerType) { 225 if (dwarfseeksym(RosSymInfo, unit, type.attrs.type, &inner) == -1) 226 return FALSE; 227 type = inner; 228 } 229 //dwarfdumpsym(RosSymInfo, &type); 230 if (type.attrs.have.name) { 231 Aggregate->Elements[count].Type = malloc(strlen(type.attrs.name) + 1); 232 strcpy(Aggregate->Elements[count].Type, type.attrs.name); 233 } else { 234 char strbuf[128] = {'#'}, *bufptr = strbuf + 1; 235 ulong idcopy = Aggregate->Elements[count].TypeId; 236 ulong mult = 1; 237 while (mult * 10 < idcopy) mult *= 10; 238 while (mult > 0) { 239 *bufptr++ = '0' + ((idcopy / mult) % 10); 240 mult /= 10; 241 } 242 Aggregate->Elements[count].Type = malloc(strlen(strbuf) + 1); 243 strcpy(Aggregate->Elements[count].Type, strbuf); 244 } 245 if (type.attrs.tag == TagPointerType) 246 Aggregate->Elements[count].Size = RosSymInfo->addrsize; 247 else 248 Aggregate->Elements[count].Size = type.attrs.bytesize; 249 if (type.attrs.have.bitsize) 250 Aggregate->Elements[count].Bits = type.attrs.bitsize; 251 if (type.attrs.have.bitoffset) 252 Aggregate->Elements[count].FirstBit = type.attrs.bitoffset; 253 } 254 return TRUE; 255 } 256 257 /* EOF */ 258