Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(429)

Side by Side Diff: experimental/visual_studio_plugin/src/NaClVsx.Package/DebugSupport/DWARF/DwarfReaderImpl.cs

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #region
6
7 using System;
8 using System.Collections.Generic;
9 using System.Diagnostics;
10 using NaClVsx;
11
12 #endregion
13
14 namespace Google.NaClVsx.DebugSupport.DWARF {
15 /// <summary>
16 /// The interface implemented by this class lives in
17 /// NaClVsx.DebugHelpers/DwarfParser.h
18 /// </summary>
19 class DwarfReaderImpl : IDwarfReader {
20 public DwarfReaderImpl(SymbolDatabase db) {
21 db_ = db;
22 }
23
24 #region Implementation of IDwarfReader
25
26 public void StartCompilationUnit() {
27 // File and directory ids are unique only within a compilation unit.
28 dirs_.Clear();
29 compilationUnitIndex_++;
30 }
31
32 public void EndCompilationUnit() {}
33
34 public void StartDIE(ulong parent, ulong offset, DwarfTag tag) {
35 var entry =
36 new DebugInfoEntry {
37 Key = offset,
38 OuterScope = scopeStack_.PeekOrDefault(),
39 ParentKey = parent,
40 Tag = tag
41 };
42
43 db_.Entries[offset] = entry;
44 }
45
46 public void EndDIE(ulong offset) {
47 var entry = db_.Entries[offset];
48
49 // If this DIE is a scope, it should at this point be at the top of the
50 // scope stack.
51 if (scopeStack_.PeekOrDefault() == entry) {
52 scopeStack_.Pop();
53
54 // Add a transition back to the parent scope. This may get overwritten
55 // if a sibling scope starts where this one ends, but that's cool.
56 //
57 // Note: we can only do this if the scope has a high pc value. Labels
58 // don't.
59 object highpc;
60 if (entry.Attributes.TryGetValue(
61 DwarfAttribute.DW_AT_high_pc, out highpc)) {
62 if (db_.ScopeTransitions.ContainsKey((ulong) highpc)) {
63 // This can happen if a parent and child scope end on the same pc
64 // value. The parent wins, so overwrite the previous entry.
65 db_.ScopeTransitions[(ulong) highpc].Entry = entry.OuterScope;
66 } else {
67 db_.ScopeTransitions.Add(
68 (ulong) highpc,
69 new SymbolDatabase.ScopeTransition {
70 Address = (ulong) highpc,
71 Entry = entry.OuterScope
72 });
73 }
74 }
75 }
76 }
77
78 public void ProcessAttribute(ulong offset,
79 ulong parent,
80 DwarfAttribute attr,
81 object data) {
82 var entry = db_.Entries[offset];
83
84 var key = attributeIndex_++;
85 db_.Attributes.Add(
86 key,
87 new SymbolDatabase.DebugInfoAttribute {
88 Key = key,
89 ParentKey = parent,
90 Tag = attr,
91 Value = data
92 });
93 entry.Attributes.Add(attr, data);
94
95
96 // If we have a PC range, it's time to make a new scope
97 if (attr == DwarfAttribute.DW_AT_low_pc) {
98 var addr = (ulong) data;
99
100 // Add a scope transition for this entry.
101 // Replace any existing scope transition at the point where
102 // this entry starts. Existing transitions are expected--it
103 // just means that this entry starts where its sibling ends.
104 if (db_.ScopeTransitions.ContainsKey(addr)) {
105 db_.ScopeTransitions[addr].Entry = entry;
106 } else {
107 db_.ScopeTransitions.Add(
108 addr,
109 new SymbolDatabase.ScopeTransition {
110 Address = addr,
111 Entry = entry
112 });
113 }
114 // This entry may already be on the scope track if it has low_pc and
115 // ranges.
116 if (scopeStack_.PeekOrDefault() != entry) {
117 scopeStack_.Push(db_.Entries[parent]);
118 }
119 } else if (attr == DwarfAttribute.DW_AT_ranges) {
120 // We can't make the scope transition because ranges are parsed on a
121 // different code path, so we'll handle it during a post-processing
122 // step.
123 // This entry may already be on the scope track if it has low_pc as
124 // well as ranges.
125 if (scopeStack_.PeekOrDefault() != entry) {
126 scopeStack_.Push(db_.Entries[parent]);
127 }
128 }
129 }
130
131 public void DefineDir(string name, uint dirNum) {
132 try {
133 dirs_[dirNum] = name;
134 }
135 catch (Exception e) {
136 Debug.WriteLine(e.Message);
137 }
138 }
139
140 public void DefineFile(string name,
141 int fileNum,
142 uint dirNum) {
143 var key = MakeFileKey((uint) fileNum);
144 string relpath;
145 if (!dirs_.TryGetValue(dirNum, out relpath)) {
146 relpath = "";
147 }
148 db_.Files.Add(
149 key,
150 new SymbolDatabase.SourceFile {
151 Key = key,
152 Filename = name,
153 RelativePath = relpath,
154 CurrentAbsolutePath = name
155 });
156 }
157
158 public void AddLine(ulong address,
159 ulong length,
160 uint fileNum,
161 uint lineNum,
162 uint columnNum) {
163 //
164 // There are several cases in the C++ standard library where a line entry
165 // has zero length. This appears to happen when a line of code is
166 // elided for whatever reason. The problem is that the address might be
167 // perfectly valid for a different line of code, which would lead to
168 // duplicate entries in our location table. So if length is zero, bail.
169 //
170 if (length == 0) {
171 return;
172 }
173
174 //
175 // Add the address and location to our locations table.
176 //
177 try {
178 var
179 sourceLocation = new SymbolDatabase.SourceLocation {
180 StartAddress = address,
181 Length = length,
182 SourceFileKey = MakeFileKey(fileNum),
183 Line = lineNum,
184 Column = columnNum,
185 };
186
187 db_.Locations.Add(address, sourceLocation);
188 }
189 catch (Exception e) {
190 Debug.WriteLine(e.Message);
191 }
192 }
193
194 public void AddLocListEntry(ulong offset,
195 bool isFirstEntry,
196 ulong lowPc,
197 ulong highPc,
198 byte[] data) {
199 if (isFirstEntry) {
200 currentLocList_ = offset;
201 db_.LocLists.Add(offset, new List<SymbolDatabase.LocListEntry>());
202 }
203 var list = db_.LocLists[currentLocList_];
204 list.Add(
205 new SymbolDatabase.LocListEntry {
206 StartAddress = lowPc,
207 EndAddress = highPc,
208 Data = data
209 });
210 }
211
212 public bool BeginCfiEntry(ulong address) {
213 currentFrame_ = new SymbolDatabase.CallFrame {Address = address};
214 return true;
215 }
216
217 public bool AddCfiRule(ulong address,
218 int reg,
219 IDwarfReader.CfiRuleType ruleType,
220 int baseRegister,
221 int offset,
222 byte[] expression) {
223 currentFrame_.Rules.Add(
224 new SymbolDatabase.CallFrame.Rule {
225 Address = address,
226 BaseRegister = baseRegister,
227 Expression = expression,
228 Offset = offset,
229 RegisterId = reg,
230 RuleType = ruleType
231 });
232 return true;
233 }
234
235 public bool EndCfiEntry() {
236 if (currentFrame_ == null) {
237 throw new DwarfParseException("Mismatched begin/end CFI entries");
238 }
239 db_.CallFrames.Add(currentFrame_.Address, currentFrame_);
240
241 currentFrame_ = null;
242 return true;
243 }
244
245 public void AddRangeListEntry(ulong offset,
246 ulong baseAddress,
247 ulong lowPC,
248 ulong highPC) {
249 if (lowPC != highPC) {
250 if (!db_.RangeLists.ContainsKey(offset)) {
251 db_.RangeLists.Add(offset, new Dictionary<ulong, RangeListEntry>());
252 }
253 if (!db_.RangeLists[offset].ContainsKey(lowPC)) {
254 var entry = new RangeListEntry {
255 Offset = offset,
256 BaseAddress = baseAddress,
257 LowPC = lowPC,
258 HighPC = highPC
259 };
260 db_.RangeLists[offset].Add(lowPC, entry);
261 }
262 }
263 }
264
265 private ulong MakeFileKey(uint fileNum) {
266 return ((ulong) compilationUnitIndex_ << 32) | fileNum;
267 }
268
269 #endregion
270
271 #region Private Implementation
272
273 private readonly SymbolDatabase db_;
274
275 private readonly Dictionary<uint, string> dirs_ =
276 new Dictionary<uint, string>();
277
278 private readonly Stack<DebugInfoEntry> scopeStack_ =
279 new Stack<DebugInfoEntry>();
280
281 private ulong attributeIndex_;
282 private ushort compilationUnitIndex_;
283 private SymbolDatabase.CallFrame currentFrame_;
284 private ulong currentLocList_;
285
286 #endregion
287 }
288
289 internal class DwarfParseException : Exception {
290 public DwarfParseException(string msg) : base(msg) {}
291 }
292 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698