ReactOS  0.4.14-dev-376-gaedba84
find.c
Go to the documentation of this file.
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
45 (PROSSYM_INFO RosSymInfo,
46  ULONG_PTR RelativeAddress,
47  PROSSYM_LINEINFO RosSymLineInfo)
48 {
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  &registers) == -1) {
78  werrstr("Can't get cfa location for %s", RosSymLineInfo->FunctionName);
79  return TRUE;
80  }
81 
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, &registers, &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);
108  (RosSymInfo,
109  &proc,
110  RelativeAddress + RosSymInfo->pe->imagebase,
111  cfaLocation,
112  &registers,
113  &params[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
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
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 */
uint addrsize
Definition: dwarf.h:212
signed char * PCHAR
Definition: retypes.h:7
int dwarfaddrtounit(Dwarf *, ulong, ulong *)
Definition: dwarfaranges.c:17
#define werrstr(str,...)
Definition: compat.h:34
BOOLEAN RosSymAggregate(PROSSYM_INFO RosSymInfo, PCHAR Type, PROSSYM_AGGREGATE Aggregate)
Definition: find.c:137
#define TRUE
Definition: types.h:120
Type
Definition: Type.h:6
static unsigned int bufptr
Definition: tncon.cpp:77
char * FileName
Definition: rossym.h:86
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLuint GLuint GLsizei count
Definition: gl.h:1545
int dwarfcomputecfa(Dwarf *d, DwarfExpr *cfa, PROSSYM_REGISTERS registers, ulong *cfaLocation)
Definition: dwarfcfa.c:404
Dwarf * d
Definition: dwarf.h:209
#define free
Definition: debug_ros.c:5
ULONG NumParams
Definition: rossym.h:89
ULONG NumElements
Definition: rossym.h:101
int dwarfnextsymat(Dwarf *, DwarfSym *, int)
Definition: dwarfinfo.c:293
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
static HANDLE proc()
Definition: pdb.c:32
int dwarfpctoline(Dwarf *, ulong, char **, char **, char **, char **, ulong *, ulong *, ulong *)
Definition: dwarfpc.c:49
uint32_t ULONG_PTR
Definition: typedefs.h:63
int dwarfseeksym(Dwarf *, ulong, ulong, DwarfSym *)
Definition: dwarfinfo.c:171
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
GLenum const GLfloat * params
Definition: glext.h:5645
int dwarfargvalue(Dwarf *d, DwarfSym *proc, ulong pc, ulong cfa, PROSSYM_REGISTERS registers, DwarfParam *parameters)
Definition: dwarfinfo.c:909
ROSSYM_PARAMETER Parameters[16]
Definition: rossym.h:90
png_const_structrp png_const_inforp int * unit
Definition: png.h:2161
char * ValueName
Definition: rossym.h:67
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static IStream instream
Definition: saxreader.c:2106
PROSSYM_AGGREGATE_MEMBER Elements
Definition: rossym.h:102
int registers[NUMREGS]
ULONGLONG Value
Definition: rossym.h:66
unsigned int len
Definition: writer.c:86
char * FunctionName
Definition: rossym.h:87
int dwarfgetarg(Dwarf *d, const char *name, DwarfBuf *locbuf, ulong cfa, PROSSYM_REGISTERS registers, ulong *value)
Definition: dwarfinfo.c:658
int dwarfgetparams(Dwarf *d, DwarfSym *s, ulong pc, int pnum, DwarfParam *paramblocks)
Definition: dwarfinfo.c:987
unsigned long ulong
Definition: linux.h:275
VOID RosSymFreeAggregate(PROSSYM_AGGREGATE Aggregate)
Definition: find.c:126
BOOLEAN RosSymGetAddressInformation(PROSSYM_INFO RosSymInfo, ULONG_PTR RelativeAddress, ULONG *LineNumber, char *FileName, char *FunctionName)
Definition: find.c:94
#define tchar
Definition: safestr.h:13
int dwarflookupnameinunit(Dwarf *, ulong, char *, DwarfSym *)
Definition: dwarfinfo.c:126
ROSSYM_LINEINFO_FLAGS Flags
Definition: rossym.h:84
ROSSYM_REGISTERS Registers
Definition: rossym.h:88
ULONG LineNumber
Definition: rossym.h:85
Definition: name.c:36
GLuint res
Definition: glext.h:9613
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define malloc
Definition: debug_ros.c:4
int dwarfregunwind(Dwarf *d, ulong pc, ulong fde, DwarfExpr *cfa, PROSSYM_REGISTERS registers)
Definition: dwarfcfa.c:419
#define memset(x, y, z)
Definition: compat.h:39