vfs: check userland buffers before reading them.
[haiku.git] / src / kits / debugger / debug_info / DwarfStackFrameDebugInfo.cpp
blobb2fe7b30ec1be7918b3104be15ba49e8a23a5d41
1 /*
2 * Copyright 2012, Rene Gollent, rene@gollent.com.
3 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Distributed under the terms of the MIT License.
5 */
8 #include "DwarfStackFrameDebugInfo.h"
10 #include <new>
12 #include "Architecture.h"
13 #include "CompilationUnit.h"
14 #include "CpuState.h"
15 #include "DebugInfoEntries.h"
16 #include "Dwarf.h"
17 #include "DwarfFile.h"
18 #include "DwarfTargetInterface.h"
19 #include "DwarfTypeFactory.h"
20 #include "DwarfUtils.h"
21 #include "DwarfTypes.h"
22 #include "FunctionID.h"
23 #include "FunctionParameterID.h"
24 #include "GlobalTypeLookup.h"
25 #include "LocalVariableID.h"
26 #include "Register.h"
27 #include "RegisterMap.h"
28 #include "ReturnValueID.h"
29 #include "StringUtils.h"
30 #include "Tracing.h"
31 #include "ValueLocation.h"
32 #include "Variable.h"
35 // #pragma mark - DwarfFunctionParameterID
38 struct DwarfStackFrameDebugInfo::DwarfFunctionParameterID
39 : public FunctionParameterID {
41 DwarfFunctionParameterID(FunctionID* functionID, const BString& name)
43 fFunctionID(functionID),
44 fName(name)
46 fFunctionID->AcquireReference();
49 virtual ~DwarfFunctionParameterID()
51 fFunctionID->ReleaseReference();
54 virtual bool operator==(const ObjectID& other) const
56 const DwarfFunctionParameterID* parameterID
57 = dynamic_cast<const DwarfFunctionParameterID*>(&other);
58 return parameterID != NULL && *fFunctionID == *parameterID->fFunctionID
59 && fName == parameterID->fName;
62 protected:
63 virtual uint32 ComputeHashValue() const
65 uint32 hash = fFunctionID->HashValue();
66 return hash * 19 + StringUtils::HashValue(fName);
69 private:
70 FunctionID* fFunctionID;
71 const BString fName;
75 // #pragma mark - DwarfLocalVariableID
78 struct DwarfStackFrameDebugInfo::DwarfLocalVariableID : public LocalVariableID {
80 DwarfLocalVariableID(FunctionID* functionID, const BString& name,
81 int32 line, int32 column)
83 fFunctionID(functionID),
84 fName(name),
85 fLine(line),
86 fColumn(column)
88 fFunctionID->AcquireReference();
91 virtual ~DwarfLocalVariableID()
93 fFunctionID->ReleaseReference();
96 virtual bool operator==(const ObjectID& other) const
98 const DwarfLocalVariableID* otherID
99 = dynamic_cast<const DwarfLocalVariableID*>(&other);
100 return otherID != NULL && *fFunctionID == *otherID->fFunctionID
101 && fName == otherID->fName && fLine == otherID->fLine
102 && fColumn == otherID->fColumn;
105 protected:
106 virtual uint32 ComputeHashValue() const
108 uint32 hash = fFunctionID->HashValue();
109 hash = hash * 19 + StringUtils::HashValue(fName);
110 hash = hash * 19 + fLine;
111 hash = hash * 19 + fColumn;
112 return hash;
115 private:
116 FunctionID* fFunctionID;
117 const BString fName;
118 int32 fLine;
119 int32 fColumn;
123 // #pragma mark - DwarfReturnValueID
126 struct DwarfStackFrameDebugInfo::DwarfReturnValueID
127 : public ReturnValueID {
129 DwarfReturnValueID(FunctionID* functionID)
131 fFunctionID(functionID),
132 fName("(returned)")
134 fFunctionID->AcquireReference();
137 virtual ~DwarfReturnValueID()
139 fFunctionID->ReleaseReference();
142 virtual bool operator==(const ObjectID& other) const
144 const DwarfReturnValueID* returnValueID
145 = dynamic_cast<const DwarfReturnValueID*>(&other);
146 return returnValueID != NULL
147 && *fFunctionID == *returnValueID->fFunctionID
148 && fName == returnValueID->fName;
151 protected:
152 virtual uint32 ComputeHashValue() const
154 uint32 hash = fFunctionID->HashValue();
155 return hash * 25 + StringUtils::HashValue(fName);
158 private:
159 FunctionID* fFunctionID;
160 const BString fName;
164 // #pragma mark - DwarfStackFrameDebugInfo
167 DwarfStackFrameDebugInfo::DwarfStackFrameDebugInfo(Architecture* architecture,
168 image_id imageID, DwarfFile* file, CompilationUnit* compilationUnit,
169 DIESubprogram* subprogramEntry, GlobalTypeLookup* typeLookup,
170 GlobalTypeCache* typeCache, target_addr_t instructionPointer,
171 target_addr_t framePointer, target_addr_t relocationDelta,
172 DwarfTargetInterface* targetInterface, RegisterMap* fromDwarfRegisterMap)
174 StackFrameDebugInfo(),
175 fTypeContext(new(std::nothrow) DwarfTypeContext(architecture, imageID, file,
176 compilationUnit, subprogramEntry, instructionPointer, framePointer,
177 relocationDelta, targetInterface, fromDwarfRegisterMap)),
178 fTypeLookup(typeLookup),
179 fTypeCache(typeCache)
181 fTypeCache->AcquireReference();
185 DwarfStackFrameDebugInfo::~DwarfStackFrameDebugInfo()
187 fTypeCache->ReleaseReference();
189 if (fTypeContext != NULL)
190 fTypeContext->ReleaseReference();
192 delete fTypeFactory;
196 status_t
197 DwarfStackFrameDebugInfo::Init()
199 if (fTypeContext == NULL)
200 return B_NO_MEMORY;
202 // create a type context without dependency to the stack frame
203 DwarfTypeContext* typeContext = new(std::nothrow) DwarfTypeContext(
204 fTypeContext->GetArchitecture(), fTypeContext->ImageID(),
205 fTypeContext->File(), fTypeContext->GetCompilationUnit(), NULL, 0, 0,
206 fTypeContext->RelocationDelta(), fTypeContext->TargetInterface(),
207 fTypeContext->FromDwarfRegisterMap());
208 if (typeContext == NULL)
209 return B_NO_MEMORY;
210 BReference<DwarfTypeContext> typeContextReference(typeContext, true);
212 // create the type factory
213 fTypeFactory = new(std::nothrow) DwarfTypeFactory(typeContext, fTypeLookup,
214 fTypeCache);
215 if (fTypeFactory == NULL)
216 return B_NO_MEMORY;
218 return B_OK;
222 status_t
223 DwarfStackFrameDebugInfo::CreateParameter(FunctionID* functionID,
224 DIEFormalParameter* parameterEntry, Variable*& _parameter)
226 // get the name
227 BString name;
228 DwarfUtils::GetDIEName(parameterEntry, name);
230 TRACE_LOCALS("DwarfStackFrameDebugInfo::CreateParameter(DIE: %p): name: "
231 "\"%s\"\n", parameterEntry, name.String());
233 // create the ID
234 DwarfFunctionParameterID* id = new(std::nothrow) DwarfFunctionParameterID(
235 functionID, name);
236 if (id == NULL)
237 return B_NO_MEMORY;
238 BReference<DwarfFunctionParameterID> idReference(id, true);
240 // create the variable
241 return _CreateVariable(id, name, _GetDIEType(parameterEntry),
242 parameterEntry->GetLocationDescription(), _parameter);
246 status_t
247 DwarfStackFrameDebugInfo::CreateLocalVariable(FunctionID* functionID,
248 DIEVariable* variableEntry, Variable*& _variable)
250 // get the name
251 BString name;
252 DwarfUtils::GetDIEName(variableEntry, name);
254 TRACE_LOCALS("DwarfStackFrameDebugInfo::CreateLocalVariable(DIE: %p): "
255 "name: \"%s\"\n", variableEntry, name.String());
257 // get the declaration location
258 int32 line = -1;
259 int32 column = -1;
260 const char* file;
261 const char* directory;
262 DwarfUtils::GetDeclarationLocation(fTypeContext->File(), variableEntry,
263 directory, file, line, column);
264 // TODO: If the declaration location is unavailable, we should probably
265 // add a component to the ID to make it unique nonetheless (the name
266 // might not suffice).
268 // create the ID
269 DwarfLocalVariableID* id = new(std::nothrow) DwarfLocalVariableID(
270 functionID, name, line, column);
271 if (id == NULL)
272 return B_NO_MEMORY;
273 BReference<DwarfLocalVariableID> idReference(id, true);
275 // create the variable
276 return _CreateVariable(id, name, _GetDIEType(variableEntry),
277 variableEntry->GetLocationDescription(), _variable);
281 status_t
282 DwarfStackFrameDebugInfo::CreateReturnValue(FunctionID* functionID,
283 DIEType* returnType, ValueLocation* location, CpuState* state,
284 Variable*& _variable)
286 if (returnType == NULL)
287 return B_BAD_VALUE;
289 // create the type
290 DwarfType* type;
291 status_t error = fTypeFactory->CreateType(returnType, type);
292 if (error != B_OK)
293 return error;
294 BReference<DwarfType> typeReference(type, true);
296 DwarfReturnValueID* id = new(std::nothrow) DwarfReturnValueID(
297 functionID);
298 if (id == NULL)
299 return B_NO_MEMORY;
301 BString name;
302 name.SetToFormat("%s returned", functionID->FunctionName().String());
304 Variable* variable = new(std::nothrow) Variable(id, name,
305 type, location, state);
306 if (variable == NULL)
307 return B_NO_MEMORY;
309 _variable = variable;
311 return B_OK;
315 status_t
316 DwarfStackFrameDebugInfo::_CreateVariable(ObjectID* id, const BString& name,
317 DIEType* typeEntry, LocationDescription* locationDescription,
318 Variable*& _variable)
320 if (typeEntry == NULL)
321 return B_BAD_VALUE;
323 // create the type
324 DwarfType* type;
325 status_t error = fTypeFactory->CreateType(typeEntry, type);
326 if (error != B_OK)
327 return error;
328 BReference<DwarfType> typeReference(type, true);
330 // get the location, if possible
331 ValueLocation* location = new(std::nothrow) ValueLocation(
332 fTypeContext->GetArchitecture()->IsBigEndian());
333 if (location == NULL)
334 return B_NO_MEMORY;
335 BReference<ValueLocation> locationReference(location, true);
337 if (locationDescription->IsValid()) {
338 status_t error = type->ResolveLocation(fTypeContext,
339 locationDescription, 0, false, *location);
340 if (error != B_OK)
341 return error;
343 TRACE_LOCALS_ONLY(location->Dump());
346 // create the variable
347 Variable* variable = new(std::nothrow) Variable(id, name, type, location);
348 if (variable == NULL)
349 return B_NO_MEMORY;
351 _variable = variable;
352 return B_OK;
356 template<typename EntryType>
357 /*static*/ DIEType*
358 DwarfStackFrameDebugInfo::_GetDIEType(EntryType* entry)
360 if (DIEType* typeEntry = entry->GetType())
361 return typeEntry;
363 if (EntryType* abstractOrigin = dynamic_cast<EntryType*>(
364 entry->AbstractOrigin())) {
365 entry = abstractOrigin;
366 if (DIEType* typeEntry = entry->GetType())
367 return typeEntry;
370 if (EntryType* specification = dynamic_cast<EntryType*>(
371 entry->Specification())) {
372 entry = specification;
373 if (DIEType* typeEntry = entry->GetType())
374 return typeEntry;
377 return NULL;