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

Unified Diff: experimental/visual_studio_plugin/src/NaClVsx.Package/DebugSupport/DWARF/SymbolDatabase.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 side-by-side diff with in-line comments
Download patch
Index: experimental/visual_studio_plugin/src/NaClVsx.Package/DebugSupport/DWARF/SymbolDatabase.cs
diff --git a/experimental/visual_studio_plugin/src/NaClVsx.Package/DebugSupport/DWARF/SymbolDatabase.cs b/experimental/visual_studio_plugin/src/NaClVsx.Package/DebugSupport/DWARF/SymbolDatabase.cs
deleted file mode 100644
index 290a8f5546119a8f4099785282306898d77aa1b9..0000000000000000000000000000000000000000
--- a/experimental/visual_studio_plugin/src/NaClVsx.Package/DebugSupport/DWARF/SymbolDatabase.cs
+++ /dev/null
@@ -1,514 +0,0 @@
-// Copyright (c) 2011 The Native Client Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#region
-
-using System.Collections.Generic;
-using System.Linq;
-using NaClVsx;
-
-#endregion
-
-namespace Google.NaClVsx.DebugSupport.DWARF {
- public class SymbolDatabase {
- // Tables
- public Dictionary<ulong, DebugInfoAttribute> Attributes {
- get { return attributes_; }
- }
-
- public Dictionary<ulong, CallFrame> CallFrames {
- get { return callFrames_; }
- }
-
- public Dictionary<ulong, DebugInfoEntry> Entries {
- get { return entries_; }
- }
-
- public Dictionary<ulong, SourceFile> Files {
- get { return files_; }
- }
-
- public Dictionary<ulong, SourceLocation> Locations {
- get { return locations_; }
- }
-
- public Dictionary<ulong, List<LocListEntry>> LocLists {
- get { return locLists_; }
- }
-
- /// <summary>
- /// Described from the inside out:
- /// A rangelist is a dictionary mapping lowPC values to the RangeListEntries in which they
- /// occur. The "RangeLists" field is another dictionary mapping offsets to Rangelists.
- /// </summary>
- public Dictionary<ulong, Dictionary<ulong, RangeListEntry>> RangeLists {
- get { return rangeLists_; }
- }
-
- public Dictionary<ulong, ScopeTransition> ScopeTransitions {
- get { return scopeTransitions_; }
- }
-
- public Dictionary<ulong, List<DebugInfoEntry>> EntriesByParent {
- get { return entriesByParent_; }
- }
-
- public Dictionary<ulong, List<SourceLocation>> LocationsByFile {
- get { return locationsByFile_; }
- }
-
- /// <summary>
- /// For most lookups, range lists have to be matched to a DIE. This mapping exists in order
- /// to make that easier. It is generated by BuildIndices().
- /// </summary>
- public Dictionary<ulong, Dictionary<ulong, RangeListEntry>> RangeListsByDIE {
- get { return rangeListsByDIE_; }
- }
-
- public Dictionary<string, List<SourceFile>> SourceFilesByFilename {
- get { return sourceFilesByFilename_; }
- }
-
- // Query methods
- public SourceLocation GetLocationForAddress(ulong address) {
- return GetRowForAddress(address, locations_, locationAddresses_);
- }
-
- /// <summary>
- /// This function returns a list of code locations that occur in the given
- /// scope, sorted by their line numbers.
- /// </summary>
- /// <param name = "scope">
- /// The scope for which lines are being required.
- /// </param>
- /// <param name = "address">
- /// The address within the scope, for which lines are being required.
- /// This is used to disambiguate between range list entries.
- /// </param>
- /// <returns>
- /// A list of source locations.
- /// </returns>
- public IEnumerable<SourceLocation> GetLocationsByLine(
- DebugInfoEntry scope, ulong address) {
- IEnumerable<SourceLocation> locationsByLine = null;
-
- if (scope.HasAttribute(DwarfAttribute.DW_AT_low_pc)) {
- var scopeAddress = scope.GetLowPC();
- if (scopeToLocationsByLine_.ContainsKey(scopeAddress)) {
- locationsByLine = scopeToLocationsByLine_[scopeAddress];
- }
- } else if (scope.HasAttribute(DwarfAttribute.DW_AT_ranges)) {
- var range = GetRangeForAddress(address, scope);
- var absoluteRangeAddress = ulong.MaxValue;
- // We need to add either the range's base address or the compilation unit's lowPC address.
- if (ulong.MaxValue != range.BaseAddress) {
- absoluteRangeAddress = range.BaseAddress + range.LowPC;
- } else {
- var compilationUnitEntry =
- scope.GetNearestAncestorWithTag(DwarfTag.DW_TAG_compile_unit);
- if (null != compilationUnitEntry &&
- compilationUnitEntry.HasAttribute(DwarfAttribute.DW_AT_low_pc)) {
- absoluteRangeAddress = compilationUnitEntry.GetLowPC() + range.LowPC;
- }
- }
- if (absoluteRangeAddress != ulong.MaxValue) {
- locationsByLine = scopeToLocationsByLine_[absoluteRangeAddress];
- }
- }
-
- return locationsByLine ?? (new List<SourceLocation>());
- }
-
- /// <summary>
- /// Returns the rangelist entry that contains the given address, provided there is one.
- /// Note that this function will always try to return a rangelist entry so it is up to the
- /// caller to first verify that the address is contained in a rangelist.
- /// </summary>
- /// <param name = "address">An address which is thought to be contained in a rangelist.</param>
- /// <returns>A RangeListEntry whose LowPC's absolute address is less than |address|.</returns>
- public RangeListEntry GetRangeForAddress(ulong address, DebugInfoEntry scope) {
- RangeListEntry range = null;
- if (scope.HasAttribute(DwarfAttribute.DW_AT_ranges)) {
- var rangeListKeys = new List<ulong>();
- rangeListKeys.AddRange(scope.RangeListsByAddress.Keys);
- rangeListKeys.Sort();
- range = GetRowForAddress(address, scope.RangeListsByAddress, rangeListKeys);
- }
- return range;
- }
-
- /// <summary>
- /// Locates the scope entry which contains a given address and returns the scope entry
- /// point.
- /// </summary>
- /// <param name = "address">The address for which a scope is needed.</param>
- public ulong GetScopeAddress(ulong address) {
- var row = GetRowForAddress(address, scopeTransitions_, scopeTransitionAddresses_);
- return row.Address;
- }
-
- public DebugInfoEntry GetScopeForAddress(ulong address) {
- var row = GetRowForAddress(address, scopeTransitions_, scopeTransitionAddresses_);
- return row.Entry;
- }
-
- public CallFrame GetCallFrameForAddress(ulong address) {
- return GetRowForAddress(address, callFrames_, callFrameAddresses_);
- }
-
- public IEnumerable<DebugInfoEntry> GetChildrenForEntry(ulong entryKey) {
- List<DebugInfoEntry> result;
- if (!entriesByParent_.TryGetValue(entryKey, out result)) {
- result = new List<DebugInfoEntry>();
- }
- return result;
- }
-
- /// <summary>
- /// This function generates all the "secondary" look-up tables that constitute the
- /// SymbolDatabase. This is basically a post-processing step for the binary data. The
- /// lookup structures that are generated here are as follows:
- /// - entriesByParent: For finding the children of any given DIE.
- /// - sourceFilesByFilename: For locating source files.
- /// - locationsByFile: For retrieving all of the SourceLocations in any given file. This
- /// is used for setting breakpoints.
- /// - locationAddresses: The addresses of the SourceLocations, sorted to allow quick
- /// inexact lookups at runtime. They are used as keys into locations_.
- /// - scopeTransitionAddresses: The addresses of the scope transitions. Used to allow
- /// quick inexact lookups by address into the scopeTransitions table at runtime.
- /// - callFrameAddresses: The addresses of the call frames. Used to allow quick inexact
- /// lookups by address into the callFrames_ table at runtime.
- /// - scopeToLocationsByLine: A mapping of scope addresses to lists of code locations that
- /// are sorted by line number. This is to quickly find the right line of code within a
- /// given scope at runtime.
- /// The function also post-processes the RangeLists to add them scope transitions and make
- /// them searchable by the Address of the DIE to which they belong.
- /// </summary>
- public void BuildIndices() {
- BuildIndex(entries_, entriesByParent_, r => r.ParentKey);
- BuildIndex(files_, sourceFilesByFilename_, r => r.Filename);
- BuildIndex(locations_, locationsByFile_, r => r.SourceFileKey);
-
- locationAddresses_.AddRange(locations_.Keys);
- locationAddresses_.Sort();
-
- scopeTransitionAddresses_.AddRange(scopeTransitions_.Keys);
- scopeTransitionAddresses_.Sort();
-
- callFrameAddresses_.AddRange(callFrames_.Keys);
- callFrameAddresses_.Sort();
-
- // This must be called after scopeTransitionAddresses is created.
- BuildRangeListsByDIE();
- AddRangesToScopeTransitions();
-
- var scopeToLocations = new Dictionary<ulong, List<SourceLocation>>();
- foreach (var sourceLocation in locations_) {
- var scopeStart = GetScopeAddress(sourceLocation.Key);
- if (!scopeToLocations.ContainsKey(scopeStart)) {
- scopeToLocations.Add(scopeStart, new List<SourceLocation>());
- }
- scopeToLocations[scopeStart].Add(sourceLocation.Value);
- }
-
- foreach (var entry in scopeToLocations) {
- if (!scopeToLocationsByLine_.ContainsKey(entry.Key)) {
- scopeToLocationsByLine_.Add(entry.Key, null);
- }
- scopeToLocationsByLine_[entry.Key] = entry.Value.OrderBy(r => r.Line);
- }
- }
-
- #region Private Implementation
-
- private readonly Dictionary<ulong, DebugInfoAttribute> attributes_ =
- new Dictionary<ulong, DebugInfoAttribute>();
-
- private readonly List<ulong> callFrameAddresses_ = new List<ulong>();
-
- private readonly Dictionary<ulong, CallFrame> callFrames_ =
- new Dictionary<ulong, CallFrame>();
-
- // Indices
- private readonly Dictionary<ulong, List<DebugInfoEntry>> entriesByParent_ =
- new Dictionary<ulong, List<DebugInfoEntry>>();
-
- private readonly Dictionary<ulong, DebugInfoEntry> entries_ =
- new Dictionary<ulong, DebugInfoEntry>();
-
- private readonly Dictionary<ulong, SourceFile> files_ =
- new Dictionary<ulong, SourceFile>();
-
- private readonly Dictionary<ulong, List<LocListEntry>> locLists_ =
- new Dictionary<ulong, List<LocListEntry>>();
-
- private readonly List<ulong> locationAddresses_ = new List<ulong>();
-
- private readonly Dictionary<ulong, List<SourceLocation>> locationsByFile_ =
- new Dictionary<ulong, List<SourceLocation>>();
-
- private readonly Dictionary<ulong, SourceLocation> locations_ =
- new Dictionary<ulong, SourceLocation>();
-
- private readonly Dictionary<ulong, Dictionary<ulong, RangeListEntry>> rangeListsByDIE_ =
- new Dictionary<ulong, Dictionary<ulong, RangeListEntry>>();
-
- private readonly Dictionary<ulong, Dictionary<ulong, RangeListEntry>> rangeLists_ =
- new Dictionary<ulong, Dictionary<ulong, RangeListEntry>>();
-
- private readonly Dictionary<ulong, IEnumerable<SourceLocation>>
- scopeToLocationsByLine_ =
- new Dictionary<ulong, IEnumerable<SourceLocation>>();
-
- // Sorted address lists
- private readonly List<ulong> scopeTransitionAddresses_ = new List<ulong>();
-
- private readonly Dictionary<ulong, ScopeTransition> scopeTransitions_ =
- new Dictionary<ulong, ScopeTransition>();
-
- private readonly Dictionary<string, List<SourceFile>> sourceFilesByFilename_
- = new Dictionary<string, List<SourceFile>>();
-
- #endregion
-
- #region Private Implementation
-
- private static void BuildIndex<TRow, TColumn>(
- IEnumerable<KeyValuePair<ulong, TRow>> table,
- IDictionary<TColumn, List<TRow>> index,
- FieldAccessor<TRow, TColumn> accessor) {
- // Clear out the index so we can rebuild it
- index.Clear();
-
- // Iterate over each row in the table and insert it
- // into the appropriate entry in the index.
- foreach (var pair in table) {
- List<TRow> indexList;
- var columnValue = accessor(pair.Value);
-
- // If the index doesn't yet have a list for this value,
- // add one.
- if (!index.TryGetValue(columnValue, out indexList)) {
- indexList = new List<TRow>();
- index.Add(columnValue, indexList);
- }
- indexList.Add(pair.Value);
- }
- }
-
- /// <summary>
- /// Retrieves a row in a table for a given address.
- /// TODO(mlinck): This does not recognize when a value is out of bounds.
- /// </summary>
- /// <typeparam name = "T">The type of the lookup table to use.</typeparam>
- /// <param name = "address">The address to use as key.</param>
- /// <param name = "table">The lookup table to use.</param>
- /// <param name = "index">The index to allow for quicker lookup.</param>
- /// <returns>An entry in the table that frames the address or the last
- /// value in the table if the address is out of bounds.</returns>
- private static T GetRowForAddress<T>(ulong address,
- IDictionary<ulong, T> table,
- List<ulong> index) where T : class {
- T result = null;
-
- var pos = index.BinarySearch(address);
- if (pos < 0) {
- // a negative value means there was no exact match. The
- // value is the two's complement of the next largest match
- // (which is not what we want; we want the next smaller match)
- pos = (~pos) - 1;
- }
- if (pos >= 0) {
- var closestAddress = index[pos];
- result = table[closestAddress];
- }
- return result;
- }
-
- /// <summary>
- /// This function goes through each DIE that has a RangeList and adds
- /// scope entries for each range in the list. BuildRangeListsByDIE has to
- /// be run in order for this to succeed.
- /// </summary>
- private void AddRangesToScopeTransitions() {
- foreach (var dieToRangeList in RangeListsByDIE) {
- var rangeList = dieToRangeList.Value;
- foreach (var range in rangeList.Values) {
- var scopeAddress = range.LowPC;
- var scopeEndAddress = range.HighPC;
- var die = Entries[dieToRangeList.Key];
- if (range.BaseAddress != ulong.MaxValue) {
- scopeAddress += range.BaseAddress;
- scopeEndAddress += range.BaseAddress;
- } else {
- var compileUnit =
- die.GetNearestAncestorWithTag(DwarfTag.DW_TAG_compile_unit);
- if (compileUnit != null &&
- compileUnit.HasAttribute(DwarfAttribute.DW_AT_low_pc) &&
- compileUnit.GetLowPC() != 0) {
- scopeAddress += compileUnit.GetLowPC();
- scopeEndAddress += compileUnit.GetLowPC();
- }
- }
- die.AddRangeListEntryByAddress(scopeAddress, range);
- var scopeTransition = new ScopeTransition {
- Address = scopeAddress,
- Entry = die
- };
- if (ScopeTransitions.ContainsKey(scopeAddress)) {
- // If the DIE that has this Key is a child of this DIE, don't add
- // our own entry. Otherwise, overwrite it since the current DIE
- // is a more specific scope.
- var collidingTransition = ScopeTransitions[scopeAddress];
- if (die.HasAsAncestor(collidingTransition.Entry.Key)) {
- InsertRangeScopeTransition(scopeTransition, scopeEndAddress, false);
- }
- } else {
- InsertRangeScopeTransition(scopeTransition, scopeEndAddress, true);
- }
- }
- }
- }
-
- /// <summary>
- /// This mapping is useful because it allows us to skip the step where we
- /// always have to search DIEs for the correct range list offset.
- /// </summary>
- private void BuildRangeListsByDIE() {
- var entriesWithRanges =
- from entry in Entries
- where entry.Value.HasAttribute(DwarfAttribute.DW_AT_ranges)
- select entry.Value;
- foreach (var entry in entriesWithRanges) {
- var rangesKey = entry.GetRangesOffset();
- var rangeList = RangeLists[rangesKey];
- RangeListsByDIE.Add(entry.Key, rangeList);
- }
- }
-
- /// <summary>
- /// This function assumes that the decision to add the scope transition
- /// has been finalized. It will only make sure that the transition is
- /// added in the correct order and that, if appropriate, a transition back
- /// to the parent scope is added as well.
- /// </summary>
- private void InsertRangeScopeTransition(ScopeTransition scopeTransition,
- ulong highPC,
- bool isNewEntry) {
- var previousScopeAddress = GetScopeAddress(scopeTransition.Address);
- var nextScopeIndex =
- scopeTransitionAddresses_.IndexOf(previousScopeAddress) + 1;
- var nextScopeAddress = scopeTransitionAddresses_[nextScopeIndex];
-
- // If the range and its parent entry end on the same address, we need to
- // add a transition back to the parent.
- var needsReturnScope = (nextScopeAddress >= highPC);
- ScopeTransitions[scopeTransition.Address] = scopeTransition;
- if (isNewEntry) {
- // Since we needed this sorted in order to proceed, we keep it sorted
- // to save time.
- scopeTransitionAddresses_.Insert(
- nextScopeIndex++, scopeTransition.Address);
- }
- if (needsReturnScope) {
- var parentDIE = ScopeTransitions[previousScopeAddress].Entry;
- var parentScopeTransition = new ScopeTransition {
- Address = highPC,
- Entry = parentDIE
- };
- ScopeTransitions[highPC] = parentScopeTransition;
- scopeTransitionAddresses_.Insert(
- nextScopeIndex, parentScopeTransition.Address);
- }
- }
-
- #endregion
-
- #region Private Implementation
-
- private delegate TColumn FieldAccessor<TRow, TColumn>(TRow row);
-
- #endregion
-
- #region Nested type: CallFrame
-
- public class CallFrame {
- public ulong Address; //use as key
-
- public List<Rule> Rules = new List<Rule>();
-
- #region Nested type: Rule
-
- public class Rule {
- public ulong Address;
- public int RegisterId;
-
- public IDwarfReader.CfiRuleType RuleType;
- public int BaseRegister;
- public int Offset;
- public byte[] Expression;
- }
-
- #endregion
- }
-
- #endregion
-
- #region Nested type: DebugInfoAttribute
-
- public class DebugInfoAttribute {
- // Offset from beginning of dwarf section.
- public ulong Key;
- // Key of the DebugInfoEntry that this attribute helps describe.
- public ulong ParentKey;
- public DwarfAttribute Tag;
- public object Value;
- }
-
- #endregion
-
- #region Nested type: LocListEntry
-
- public class LocListEntry {
- public ulong StartAddress;
- public ulong EndAddress;
- public byte[] Data;
- }
-
- #endregion
-
- #region Nested type: ScopeTransition
-
- public class ScopeTransition {
- public ulong Address;
- public DebugInfoEntry Entry;
- }
-
- #endregion
-
- #region Nested type: SourceFile
-
- public class SourceFile {
- public ulong Key;
- public string Filename;
- public string RelativePath;
- public string CurrentAbsolutePath;
- }
-
- #endregion
-
- #region Nested type: SourceLocation
-
- public class SourceLocation {
- public ulong StartAddress; // Use as key, since it is unique
- public ulong Length;
-
- public ulong SourceFileKey;
- public uint Line;
- public uint Column;
- }
-
- #endregion
- }
-}

Powered by Google App Engine
This is Rietveld 408576698