diff --git a/src/LibObjectFile.CodeGen/dwarf.h b/src/LibObjectFile.CodeGen/dwarf.h
index 3090c55..0a23ad0 100644
--- a/src/LibObjectFile.CodeGen/dwarf.h
+++ b/src/LibObjectFile.CodeGen/dwarf.h
@@ -338,7 +338,7 @@ extern "C" {
#define DW_AT_associated 0x4f /* DWARF3 */
#define DW_AT_data_location 0x50 /* DWARF3 */
#define DW_AT_byte_stride 0x51 /* DWARF3f */
-#define DW_AT_stride 0x51 /* DWARF3 (do not use) */
+#define DW_AT_stride 0x51 /* DWARF2 (do not use) */
#define DW_AT_entry_pc 0x52 /* DWARF3 */
#define DW_AT_use_UTF8 0x53 /* DWARF3 */
#define DW_AT_extension 0x54 /* DWARF3 */
diff --git a/src/LibObjectFile.Tests/Dwarf/DwarfTests.cs b/src/LibObjectFile.Tests/Dwarf/DwarfTests.cs
index ecdfccc..30624ac 100644
--- a/src/LibObjectFile.Tests/Dwarf/DwarfTests.cs
+++ b/src/LibObjectFile.Tests/Dwarf/DwarfTests.cs
@@ -15,6 +15,20 @@ namespace LibObjectFile.Tests.Dwarf;
public class DwarfTests : ElfTestBase
{
[TestMethod]
+ public void ReadDwarf_version2_should_be_successfull()
+ {
+ string ResourceName = Path.Combine(AppContext.BaseDirectory, "TestFiles", "TestDwarf2.elf");
+
+ ElfFile elf = OpenAndLoadElf(ResourceName);
+ var elfContext = new DwarfElfContext(elf);
+ var inputContext = new DwarfReaderContext(elfContext);
+ inputContext.DebugLinePrinter = Console.Out;
+ var dwarf = DwarfFile.Read(inputContext);
+
+ Assert.IsNotNull(dwarf);
+ }
+
+ [DataTestMethod]
[DataRow(0UL)]
[DataRow(1UL)]
[DataRow(50UL)]
@@ -301,7 +315,7 @@ public void TestDebugInfoSmall()
DebugAbbrevStream = new MemoryStream(),
DebugLineStream = new MemoryStream(),
DebugInfoStream = new MemoryStream(),
- DebugStringStream = new MemoryStream(),
+ DebugStringStream = new MemoryStream(),
DebugAddressRangeStream = new MemoryStream()
};
dwarf.Write(outputContext);
diff --git a/src/LibObjectFile.Tests/Elf/ElfTestBase.cs b/src/LibObjectFile.Tests/Elf/ElfTestBase.cs
index 92f6c58..bf4b315 100644
--- a/src/LibObjectFile.Tests/Elf/ElfTestBase.cs
+++ b/src/LibObjectFile.Tests/Elf/ElfTestBase.cs
@@ -71,6 +71,12 @@ protected async Task LoadAndVerifyElf(string name)
ByteArrayAssert.AreEqual(originalBinary, newBinary, "Invalid binary diff between write -> read -> write");
}
+ protected ElfFile OpenAndLoadElf(string absolutePath)
+ {
+ using var stream = File.OpenRead(absolutePath);
+ return ElfFile.Read(stream);
+ }
+
protected ElfFile LoadElf(string name)
{
var file = GetFile(name);
diff --git a/src/LibObjectFile.Tests/LibObjectFile.Tests.csproj b/src/LibObjectFile.Tests/LibObjectFile.Tests.csproj
index 671bc4d..77332fe 100644
--- a/src/LibObjectFile.Tests/LibObjectFile.Tests.csproj
+++ b/src/LibObjectFile.Tests/LibObjectFile.Tests.csproj
@@ -100,4 +100,10 @@
+
+
+ PreserveNewest
+
+
+
diff --git a/src/LibObjectFile.Tests/TestFiles/TestDwarf2.elf b/src/LibObjectFile.Tests/TestFiles/TestDwarf2.elf
new file mode 100644
index 0000000..e3a786f
Binary files /dev/null and b/src/LibObjectFile.Tests/TestFiles/TestDwarf2.elf differ
diff --git a/src/LibObjectFile/Dwarf/DwarfAbbreviation.cs b/src/LibObjectFile/Dwarf/DwarfAbbreviation.cs
index 2996406..e5b6acb 100644
--- a/src/LibObjectFile/Dwarf/DwarfAbbreviation.cs
+++ b/src/LibObjectFile/Dwarf/DwarfAbbreviation.cs
@@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+using System.Linq;
using LibObjectFile.Diagnostics;
namespace LibObjectFile.Dwarf;
@@ -13,15 +14,14 @@ namespace LibObjectFile.Dwarf;
[DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")]
public sealed class DwarfAbbreviation : DwarfObject
{
- private readonly List _items;
- private readonly Dictionary _mapItems; // Only used if code are non contiguous
+ private readonly Dictionary _mapUlongToItems;
+
private readonly Dictionary _mapKeyToItem;
private ulong _nextCode;
public DwarfAbbreviation()
{
- _items = new List();
- _mapItems = new Dictionary();
+ _mapUlongToItems = new Dictionary();
_mapKeyToItem = new Dictionary();
_nextCode = 1;
}
@@ -29,54 +29,30 @@ public DwarfAbbreviation()
public void Reset()
{
// Reset parent dependency
- foreach (var dwarfAbbreviationItem in _items)
- {
- dwarfAbbreviationItem.Parent = null;
- }
-
- if (_mapItems.Count > 0)
+ foreach (var keyPair in _mapUlongToItems.Values)
{
- foreach (var keyPair in _mapItems)
- {
- keyPair.Value.Parent = null;
- }
+ keyPair.Parent = null;
}
-
- _items.Clear();
- _mapItems.Clear();
+ _mapUlongToItems.Clear();
_mapKeyToItem.Clear();
_nextCode = 1;
}
- public IEnumerable Items => _mapItems.Count > 0 ? GetMapItems() : _items;
+ public IEnumerable Items => _mapUlongToItems.Values;
- private IEnumerable GetMapItems()
- {
- foreach (var item in _mapItems.Values)
- {
- yield return item;
- }
- }
-
public DwarfAbbreviationItem GetOrCreate(DwarfAbbreviationItemKey itemKey)
{
- if (!_mapKeyToItem.TryGetValue(itemKey, out var item))
+ if (!TryFindByKey(itemKey, out var item))
{
item = new DwarfAbbreviationItem(_nextCode, itemKey.Tag, itemKey.HasChildren, itemKey.Descriptors)
{
Parent = this
};
- if (_mapItems.Count > 0)
- {
-
- _mapItems[_nextCode] = item;
- }
- else
- {
- _items.Add(item);
- }
+ // insert or update new item
+ _mapUlongToItems[_nextCode] = item;
+ // not found insert new item
_mapKeyToItem[itemKey] = item;
_nextCode++;
@@ -93,24 +69,16 @@ public bool TryFindByCode(ulong code, [NotNullWhen(true)] out DwarfAbbreviationI
return false;
}
- code--;
-
- if (_mapItems.Count > 0)
- {
- return _mapItems.TryGetValue(code, out item);
- }
-
- if (code < int.MaxValue && (int)code < _items.Count)
- {
- item = _items[(int) code];
- return true;
- }
+ return _mapUlongToItems.TryGetValue(code, out item);
+ }
+ public bool TryFindByKey(DwarfAbbreviationItemKey key, [NotNullWhen(true)] out DwarfAbbreviationItem? item)
+ {
item = null;
- return false;
+ return _mapKeyToItem.TryGetValue(key, out item);
}
- private string DebuggerDisplay => $"Count = {(_mapItems.Count > 0 ? _mapItems.Count : _items.Count)}";
+ private string DebuggerDisplay => $"Count = {_mapUlongToItems.Count}";
private bool TryReadNext(DwarfReader reader)
{
@@ -123,45 +91,27 @@ private bool TryReadNext(DwarfReader reader)
var item = new DwarfAbbreviationItem
{
- Position = startOffset,
+ Position = startOffset,
Code = code
};
- var index = code - 1;
- bool canAddToList = _mapItems.Count == 0 && index < int.MaxValue && _items.Count == (int)index;
-
item.Read(reader);
- if (canAddToList)
+ if (_mapUlongToItems.ContainsKey(code))
{
- _items.Add(item);
- _nextCode++;
+ reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"Invalid code {code} found while another code already exists in this abbreviation.");
+ return false;
}
- else
- {
- if (_mapItems.Count == 0)
- {
- for (var i = 0; i < _items.Count; i++)
- {
- var previousItem = _items[i];
- _mapItems.Add((ulong)i + 1, previousItem);
- }
- _items.Clear();
- }
-
- // TODO: check collisions
- if (_mapItems.ContainsKey(code))
- {
- reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"Invalid code {code} found while another code already exists in this abbreviation.");
- return false;
- }
- _mapItems.Add(code, item);
- _nextCode = Math.Max(code, _nextCode) + 1;
- }
+ _mapUlongToItems.Add(code, item);
+ _nextCode = Math.Max(code, _nextCode) + 1;
var key = new DwarfAbbreviationItemKey(item.Tag, item.HasChildren, item.Descriptors);
- _mapKeyToItem.Add(key, item);
+
+ if (!_mapKeyToItem.ContainsKey(key))
+ {
+ _mapKeyToItem.Add(key, item);
+ }
return true;
}
@@ -180,24 +130,9 @@ public override void Write(DwarfWriter writer)
{
var startOffset = writer.Position;
Debug.Assert(startOffset == Position);
- if (_mapItems.Count > 0)
+ foreach (var item in _mapUlongToItems.Values)
{
- foreach (var itemPair in _mapItems)
- {
- var item = itemPair.Value;
- item.Write(writer);
- }
-
- }
- else
- {
- if (_items.Count > 0)
- {
- foreach (var item in _items)
- {
- item.Write(writer);
- }
- }
+ item.Write(writer);
}
// End of abbreviation item
@@ -210,28 +145,11 @@ protected override void UpdateLayoutCore(DwarfLayoutContext context)
{
var endOffset = Position;
- if (_mapItems.Count > 0)
+ foreach (var item in _mapUlongToItems.Values)
{
- foreach (var itemPair in _mapItems)
- {
- var item = itemPair.Value;
- item.Position = endOffset;
- item.UpdateLayout(context);
- endOffset += item.Size;
- }
-
- }
- else
- {
- if (_items.Count > 0)
- {
- foreach (var item in _items)
- {
- item.Position = endOffset;
- item.UpdateLayout(context);
- endOffset += item.Size;
- }
- }
+ item.Position = endOffset;
+ item.UpdateLayout(context);
+ endOffset += item.Size;
}
endOffset += DwarfHelper.SizeOfULEB128(0);
diff --git a/src/LibObjectFile/Dwarf/DwarfUnit.cs b/src/LibObjectFile/Dwarf/DwarfUnit.cs
index 102e284..9962da1 100644
--- a/src/LibObjectFile/Dwarf/DwarfUnit.cs
+++ b/src/LibObjectFile/Dwarf/DwarfUnit.cs
@@ -171,7 +171,7 @@ public override void Read(DwarfReader reader)
DwarfUnitKindEx unitKind = reader.DefaultUnitKind;
- if (version <= 2 || version > 5)
+ if (version < 2 || version > 5)
{
reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_VersionNotSupported, $"Version {version} is not supported");
return null;
diff --git a/src/LibObjectFile/generated/LibObjectFile.Dwarf.generated.cs b/src/LibObjectFile/generated/LibObjectFile.Dwarf.generated.cs
index 5edce90..28e4c09 100644
--- a/src/LibObjectFile/generated/LibObjectFile.Dwarf.generated.cs
+++ b/src/LibObjectFile/generated/LibObjectFile.Dwarf.generated.cs
@@ -759,7 +759,7 @@ public static unsafe partial class DwarfNative
public const ushort DW_AT_byte_stride = 81;
///
- /// DWARF3 (do not use)
+ /// DWARF2 (do not use)
///
public const ushort DW_AT_stride = 81;
@@ -4183,9 +4183,15 @@ public enum DwarfAttributeKind : ushort
ReturnAddr = DwarfNative.DW_AT_return_addr,
StartScope = DwarfNative.DW_AT_start_scope,
-
+
+ ///
+ /// DWARF3 name
+ ///
BitStride = DwarfNative.DW_AT_bit_stride,
-
+
+ ///
+ /// DWARF2 name
+ ///
StrideSize = DwarfNative.DW_AT_stride_size,
UpperBound = DwarfNative.DW_AT_upper_bound,
@@ -4253,9 +4259,15 @@ public enum DwarfAttributeKind : ushort
Associated = DwarfNative.DW_AT_associated,
DataLocation = DwarfNative.DW_AT_data_location,
-
+
+ ///
+ /// DWARF3f
+ ///
ByteStride = DwarfNative.DW_AT_byte_stride,
-
+
+ ///
+ /// DWARF2
+ ///
Stride = DwarfNative.DW_AT_stride,
EntryPC = DwarfNative.DW_AT_entry_pc,