1 | diff --git a/src/apps/debugger/dwarf/DwarfFile.cpp b/src/apps/debugger/dwarf/DwarfFile.cpp
|
---|
2 | index f95d18e..2224f62 100644
|
---|
3 | --- a/src/apps/debugger/dwarf/DwarfFile.cpp
|
---|
4 | +++ b/src/apps/debugger/dwarf/DwarfFile.cpp
|
---|
5 | @@ -11,6 +11,9 @@
|
---|
6 | #include <new>
|
---|
7 |
|
---|
8 | #include <AutoDeleter.h>
|
---|
9 | +#include <Entry.h>
|
---|
10 | +#include <FindDirectory.h>
|
---|
11 | +#include <Path.h>
|
---|
12 |
|
---|
13 | #include "AttributeClasses.h"
|
---|
14 | #include "AttributeValue.h"
|
---|
15 | @@ -27,6 +30,30 @@
|
---|
16 | #include "Variant.h"
|
---|
17 |
|
---|
18 |
|
---|
19 | +// #pragma mark - AutoSectionPutter
|
---|
20 | +
|
---|
21 | +
|
---|
22 | +class AutoSectionPutter {
|
---|
23 | +public:
|
---|
24 | + AutoSectionPutter(ElfFile* elfFile, ElfSection* elfSection)
|
---|
25 | + :
|
---|
26 | + fElfFile(elfFile),
|
---|
27 | + fElfSection(elfSection)
|
---|
28 | + {
|
---|
29 | + }
|
---|
30 | +
|
---|
31 | + ~AutoSectionPutter()
|
---|
32 | + {
|
---|
33 | + if (fElfSection != NULL)
|
---|
34 | + fElfFile->PutSection(fElfSection);
|
---|
35 | + }
|
---|
36 | +
|
---|
37 | +private:
|
---|
38 | + ElfFile* fElfFile;
|
---|
39 | + ElfSection* fElfSection;
|
---|
40 | +};
|
---|
41 | +
|
---|
42 | +
|
---|
43 | // #pragma mark - ExpressionEvaluationContext
|
---|
44 |
|
---|
45 |
|
---|
46 | @@ -281,7 +308,9 @@ private:
|
---|
47 | DwarfFile::DwarfFile()
|
---|
48 | :
|
---|
49 | fName(NULL),
|
---|
50 | + fAlternateName(NULL),
|
---|
51 | fElfFile(NULL),
|
---|
52 | + fAlternateElfFile(NULL),
|
---|
53 | fDebugInfoSection(NULL),
|
---|
54 | fDebugAbbrevSection(NULL),
|
---|
55 | fDebugStringSection(NULL),
|
---|
56 | @@ -305,19 +334,24 @@ DwarfFile::~DwarfFile()
|
---|
57 | delete table;
|
---|
58 |
|
---|
59 | if (fElfFile != NULL) {
|
---|
60 | - fElfFile->PutSection(fDebugInfoSection);
|
---|
61 | - fElfFile->PutSection(fDebugAbbrevSection);
|
---|
62 | - fElfFile->PutSection(fDebugStringSection);
|
---|
63 | - fElfFile->PutSection(fDebugRangesSection);
|
---|
64 | - fElfFile->PutSection(fDebugLineSection);
|
---|
65 | - fElfFile->PutSection(fDebugFrameSection);
|
---|
66 | + ElfFile* debugInfoFile = fAlternateElfFile != NULL
|
---|
67 | + ? fAlternateElfFile : fElfFile;
|
---|
68 | +
|
---|
69 | + debugInfoFile->PutSection(fDebugInfoSection);
|
---|
70 | + debugInfoFile->PutSection(fDebugAbbrevSection);
|
---|
71 | + debugInfoFile->PutSection(fDebugStringSection);
|
---|
72 | + debugInfoFile->PutSection(fDebugRangesSection);
|
---|
73 | + debugInfoFile->PutSection(fDebugLineSection);
|
---|
74 | + debugInfoFile->PutSection(fDebugFrameSection);
|
---|
75 | fElfFile->PutSection(fEHFrameSection);
|
---|
76 | - fElfFile->PutSection(fDebugLocationSection);
|
---|
77 | - fElfFile->PutSection(fDebugPublicTypesSection);
|
---|
78 | + debugInfoFile->PutSection(fDebugLocationSection);
|
---|
79 | + debugInfoFile->PutSection(fDebugPublicTypesSection);
|
---|
80 | delete fElfFile;
|
---|
81 | + delete fAlternateElfFile;
|
---|
82 | }
|
---|
83 |
|
---|
84 | free(fName);
|
---|
85 | + free(fAlternateName);
|
---|
86 | }
|
---|
87 |
|
---|
88 |
|
---|
89 | @@ -337,23 +371,24 @@ DwarfFile::Load(const char* fileName)
|
---|
90 | if (error != B_OK)
|
---|
91 | return error;
|
---|
92 |
|
---|
93 | - // get the interesting sections
|
---|
94 | - fDebugInfoSection = fElfFile->GetSection(".debug_info");
|
---|
95 | - fDebugAbbrevSection = fElfFile->GetSection(".debug_abbrev");
|
---|
96 | - if (fDebugInfoSection == NULL || fDebugAbbrevSection == NULL) {
|
---|
97 | - WARNING("DwarfManager::File::Load(\"%s\"): no "
|
---|
98 | - ".debug_info or .debug_abbrev.\n", fileName);
|
---|
99 | - return B_ERROR;
|
---|
100 | - }
|
---|
101 | + error = _LocateDebugInfo();
|
---|
102 | + if (error != B_OK)
|
---|
103 | + return error;
|
---|
104 | +
|
---|
105 | + ElfFile* debugInfoFile = fAlternateElfFile != NULL
|
---|
106 | + ? fAlternateElfFile : fElfFile;
|
---|
107 |
|
---|
108 | // non mandatory sections
|
---|
109 | - fDebugStringSection = fElfFile->GetSection(".debug_str");
|
---|
110 | - fDebugRangesSection = fElfFile->GetSection(".debug_ranges");
|
---|
111 | - fDebugLineSection = fElfFile->GetSection(".debug_line");
|
---|
112 | - fDebugFrameSection = fElfFile->GetSection(".debug_frame");
|
---|
113 | + fDebugStringSection = debugInfoFile->GetSection(".debug_str");
|
---|
114 | + fDebugRangesSection = debugInfoFile->GetSection(".debug_ranges");
|
---|
115 | + fDebugLineSection = debugInfoFile->GetSection(".debug_line");
|
---|
116 | + fDebugFrameSection = debugInfoFile->GetSection(".debug_frame");
|
---|
117 | + // .eh_frame doesn't appear to get copied into separate debug
|
---|
118 | + // info files properly, therefore always use it off the main
|
---|
119 | + // executable image
|
---|
120 | fEHFrameSection = fElfFile->GetSection(".eh_frame");
|
---|
121 | - fDebugLocationSection = fElfFile->GetSection(".debug_loc");
|
---|
122 | - fDebugPublicTypesSection = fElfFile->GetSection(".debug_pubtypes");
|
---|
123 | + fDebugLocationSection = debugInfoFile->GetSection(".debug_loc");
|
---|
124 | + fDebugPublicTypesSection = debugInfoFile->GetSection(".debug_pubtypes");
|
---|
125 |
|
---|
126 | // iterate through the debug info section
|
---|
127 | DataReader dataReader(fDebugInfoSection->Data(),
|
---|
128 | @@ -2224,3 +2259,106 @@ DwarfFile::_FindLocationExpression(CompilationUnit* unit, uint64 offset,
|
---|
129 | }
|
---|
130 | }
|
---|
131 | }
|
---|
132 | +
|
---|
133 | +
|
---|
134 | +status_t
|
---|
135 | +DwarfFile::_LocateDebugInfo()
|
---|
136 | +{
|
---|
137 | + ElfFile* debugInfoFile = fElfFile;
|
---|
138 | + ElfSection* debugLinkSection = fElfFile->GetSection(".gnu_debuglink");
|
---|
139 | + if (debugLinkSection != NULL) {
|
---|
140 | + AutoSectionPutter putter(fElfFile, debugLinkSection);
|
---|
141 | +
|
---|
142 | + // the file specifies a debug link, look at its target instead
|
---|
143 | + // for debug information.
|
---|
144 | + // Format: null-terminated filename, as many 0 padding bytes as
|
---|
145 | + // needed to reach the next 32-bit address boundary, followed
|
---|
146 | + // by a 32-bit CRC
|
---|
147 | +
|
---|
148 | + BString debugPath;
|
---|
149 | + status_t result = _GetDebugInfoPath(debugPath,
|
---|
150 | + (const char*)debugLinkSection->Data());
|
---|
151 | + if (result != B_OK)
|
---|
152 | + return result;
|
---|
153 | +
|
---|
154 | + fAlternateName = strdup(debugPath.String());
|
---|
155 | +
|
---|
156 | + if (fAlternateName == NULL)
|
---|
157 | + return B_NO_MEMORY;
|
---|
158 | +
|
---|
159 | +/*
|
---|
160 | + // TODO: validate CRC
|
---|
161 | + int32 debugCRC = *(int32*)((char*)debugLinkSection->Data()
|
---|
162 | + + debugLinkSection->Size() - sizeof(int32));
|
---|
163 | +*/
|
---|
164 | + fAlternateElfFile = new(std::nothrow) ElfFile;
|
---|
165 | + if (fAlternateElfFile == NULL)
|
---|
166 | + return B_NO_MEMORY;
|
---|
167 | +
|
---|
168 | + result = fAlternateElfFile->Init(fAlternateName);
|
---|
169 | + if (result != B_OK)
|
---|
170 | + return result;
|
---|
171 | +
|
---|
172 | + debugInfoFile = fAlternateElfFile;
|
---|
173 | + }
|
---|
174 | +
|
---|
175 | + // get the interesting sections
|
---|
176 | + fDebugInfoSection = debugInfoFile->GetSection(".debug_info");
|
---|
177 | + fDebugAbbrevSection = debugInfoFile->GetSection(".debug_abbrev");
|
---|
178 | + if (fDebugInfoSection == NULL || fDebugAbbrevSection == NULL) {
|
---|
179 | + WARNING("DwarfManager::File::Load(\"%s\"): no "
|
---|
180 | + ".debug_info or .debug_abbrev.\n", fName);
|
---|
181 | + return B_ERROR;
|
---|
182 | + }
|
---|
183 | +
|
---|
184 | + return B_OK;
|
---|
185 | +}
|
---|
186 | +
|
---|
187 | +
|
---|
188 | +status_t
|
---|
189 | +DwarfFile::_GetDebugInfoPath(BString& _infoPath, const char* debugFileName)
|
---|
190 | +{
|
---|
191 | + int16 dirLocations[] = { B_SYSTEM_DIRECTORY, B_COMMON_DIRECTORY,
|
---|
192 | + B_USER_CONFIG_DIRECTORY, -1 };
|
---|
193 | +
|
---|
194 | + // first, see if we have a relative match to our local directory
|
---|
195 | + BPath basePath;
|
---|
196 | + status_t result = basePath.SetTo(fName);
|
---|
197 | + if (result != B_OK)
|
---|
198 | + return result;
|
---|
199 | + basePath.GetParent(&basePath);
|
---|
200 | + if (strcmp(basePath.Leaf(), "lib") == 0 || strcmp(basePath.Leaf(),
|
---|
201 | + "add-ons") == 0) {
|
---|
202 | + _infoPath.SetToFormat("%s/../debug/%s", basePath.Path(),
|
---|
203 | + debugFileName);
|
---|
204 | + } else
|
---|
205 | + _infoPath.SetToFormat("%s/debug/%s", basePath.Path(), debugFileName);
|
---|
206 | +
|
---|
207 | + BEntry entry(_infoPath.String());
|
---|
208 | + result = entry.InitCheck();
|
---|
209 | + if (result != B_OK && result != B_ENTRY_NOT_FOUND)
|
---|
210 | + return result;
|
---|
211 | + if (entry.Exists())
|
---|
212 | + return B_OK;
|
---|
213 | +
|
---|
214 | + // See if our image is in any of the system locations.
|
---|
215 | + // if so, look for its debug info in the corresponding location.
|
---|
216 | + for (int16 i = 0; dirLocations[i] >= 0; i++) {
|
---|
217 | + result = find_directory((directory_which)dirLocations[i], &basePath);
|
---|
218 | + if (result != B_OK)
|
---|
219 | + return result;
|
---|
220 | +
|
---|
221 | + if (strncmp(fName, basePath.Path(), strlen(basePath.Path())) == 0) {
|
---|
222 | + _infoPath.SetToFormat("%s/develop/debug/%s", basePath.Path(),
|
---|
223 | + debugFileName);
|
---|
224 | + entry.SetTo(_infoPath.String());
|
---|
225 | + result = entry.InitCheck();
|
---|
226 | + if (result != B_OK && result != B_ENTRY_NOT_FOUND)
|
---|
227 | + return result;
|
---|
228 | + return entry.Exists() ? B_OK : B_ENTRY_NOT_FOUND;
|
---|
229 | + }
|
---|
230 | + }
|
---|
231 | +
|
---|
232 | + return B_ENTRY_NOT_FOUND;
|
---|
233 | +}
|
---|
234 | +
|
---|
235 | diff --git a/src/apps/debugger/dwarf/DwarfFile.h b/src/apps/debugger/dwarf/DwarfFile.h
|
---|
236 | index b7d53b8..e060469 100644
|
---|
237 | --- a/src/apps/debugger/dwarf/DwarfFile.h
|
---|
238 | +++ b/src/apps/debugger/dwarf/DwarfFile.h
|
---|
239 | @@ -150,12 +150,18 @@ private:
|
---|
240 | const void*& _expression,
|
---|
241 | off_t& _length) const;
|
---|
242 |
|
---|
243 | + status_t _LocateDebugInfo();
|
---|
244 | + status_t _GetDebugInfoPath(BString& _infoPath,
|
---|
245 | + const char* fileName);
|
---|
246 | +
|
---|
247 | private:
|
---|
248 | friend class DwarfFile::ExpressionEvaluationContext;
|
---|
249 |
|
---|
250 | private:
|
---|
251 | char* fName;
|
---|
252 | + char* fAlternateName;
|
---|
253 | ElfFile* fElfFile;
|
---|
254 | + ElfFile* fAlternateElfFile;
|
---|
255 | ElfSection* fDebugInfoSection;
|
---|
256 | ElfSection* fDebugAbbrevSection;
|
---|
257 | ElfSection* fDebugStringSection;
|
---|