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
7 * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
10 * Parts of this file based on work Copyright (c) 1990, 1993
11 * The Regents of the University of California. All rights reserved.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
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.
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
44 RosSymGetAddressInformation
45 (PROSSYM_INFO RosSymInfo
,
46 ULONG_PTR RelativeAddress
,
47 PROSSYM_LINEINFO RosSymLineInfo
)
49 ROSSYM_REGISTERS registers
;
50 DwarfParam params
[sizeof(RosSymLineInfo
->Parameters
)/sizeof(RosSymLineInfo
->Parameters
[0])];
53 int res
= dwarfpctoline
56 RelativeAddress
+ RosSymInfo
->pe
->imagebase
,
57 &RosSymLineInfo
->FileName
,
58 &RosSymLineInfo
->FunctionName
,
59 &RosSymLineInfo
->LineNumber
);
61 werrstr("Could not get basic function info");
65 if (!(RosSymLineInfo
->Flags
& ROSSYM_LINEINFO_HAS_REGISTERS
))
68 registers
= RosSymLineInfo
->Registers
;
74 RelativeAddress
+ RosSymInfo
->pe
->imagebase
,
75 proc
.attrs
.framebase
.c
,
78 werrstr("Can't get cfa location for %s", RosSymLineInfo
->FunctionName
);
85 RelativeAddress
+ RosSymInfo
->pe
->imagebase
,
86 sizeof(params
)/sizeof(params
[0]),
90 werrstr("%s: could not get params at all", RosSymLineInfo
->FunctionName
);
91 RosSymLineInfo
->NumParams
= 0;
95 werrstr("%s: res %d", RosSymLineInfo
->FunctionName
, res
);
96 RosSymLineInfo
->NumParams
= res
;
98 res
= dwarfcomputecfa(RosSymInfo
, &cfa
, ®isters
, &cfaLocation
);
100 werrstr("%s: could not get our own cfa", RosSymLineInfo
->FunctionName
);
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
);
110 RelativeAddress
+ RosSymInfo
->pe
->imagebase
,
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
;
126 RosSymFreeAggregate(PROSSYM_AGGREGATE Aggregate
)
129 for (i
= 0; i
< Aggregate
->NumElements
; i
++) {
130 free(Aggregate
->Elements
[i
].Name
);
131 free(Aggregate
->Elements
[i
].Type
);
133 free(Aggregate
->Elements
);
137 RosSymAggregate(PROSSYM_INFO RosSymInfo
, PCHAR Type
, PROSSYM_AGGREGATE Aggregate
)
140 ulong unit
, typeoff
= 0;
142 // Get the first unit
143 if (dwarfaddrtounit(RosSymInfo
, RosSymInfo
->pe
->codestart
+ RosSymInfo
->pe
->imagebase
, &unit
) == -1)
146 if (Type
[0] == '#') {
147 for (tchar
= Type
+ 1; *tchar
; tchar
++) {
149 typeoff
+= *tchar
- '0';
151 if (dwarfseeksym(RosSymInfo
, unit
, typeoff
, &type
) == -1)
153 } else if (dwarflookupnameinunit(RosSymInfo
, unit
, Type
, &type
) != 0 ||
154 (type
.attrs
.tag
!= TagStructType
&& type
.attrs
.tag
!= TagUnionType
))
157 DwarfSym element
= { }, inner
= { };
160 werrstr("type %s (want %s) type %x\n", type
.attrs
.name
, Type
, type
.attrs
.type
);
162 if (type
.attrs
.have
.type
) {
163 if (dwarfseeksym(RosSymInfo
, unit
, type
.attrs
.type
, &inner
) == -1)
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
++;
175 werrstr("%d members\n", count
);
177 if (!count
) return FALSE
;
178 memset(&element
, 0, sizeof(element
));
179 Aggregate
->NumElements
= count
;
180 Aggregate
->Elements
= malloc(sizeof(ROSSYM_AGGREGATE_MEMBER
) * count
);
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
);
190 Aggregate
->Elements
[count
].TypeId
= element
.attrs
.type
;
191 // Seek our range in loc
193 DwarfBuf instream
= { };
195 locbuf
.d
= RosSymInfo
;
196 locbuf
.addrsize
= RosSymInfo
->addrsize
;
198 if (element
.attrs
.have
.datamemberloc
) {
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
);
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
);
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)
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
);
234 char strbuf
[128] = {'#'}, *bufptr
= strbuf
+ 1;
235 ulong idcopy
= Aggregate
->Elements
[count
].TypeId
;
237 while (mult
* 10 < idcopy
) mult
*= 10;
239 *bufptr
++ = '0' + ((idcopy
/ mult
) % 10);
242 Aggregate
->Elements
[count
].Type
= malloc(strlen(strbuf
) + 1);
243 strcpy(Aggregate
->Elements
[count
].Type
, strbuf
);
245 if (type
.attrs
.tag
== TagPointerType
)
246 Aggregate
->Elements
[count
].Size
= RosSymInfo
->addrsize
;
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
;