Skip to content

Commit b988a44

Browse files
authored
Merge pull request #47 from dupont-al-videotron-ca/master
Support to DWARF V2
2 parents 79a12ae + 84250a7 commit b988a44

8 files changed

Lines changed: 81 additions & 125 deletions

File tree

src/LibObjectFile.CodeGen/dwarf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ extern "C" {
338338
#define DW_AT_associated 0x4f /* DWARF3 */
339339
#define DW_AT_data_location 0x50 /* DWARF3 */
340340
#define DW_AT_byte_stride 0x51 /* DWARF3f */
341-
#define DW_AT_stride 0x51 /* DWARF3 (do not use) */
341+
#define DW_AT_stride 0x51 /* DWARF2 (do not use) */
342342
#define DW_AT_entry_pc 0x52 /* DWARF3 */
343343
#define DW_AT_use_UTF8 0x53 /* DWARF3 */
344344
#define DW_AT_extension 0x54 /* DWARF3 */

src/LibObjectFile.Tests/Dwarf/DwarfTests.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@ namespace LibObjectFile.Tests.Dwarf;
1515
public class DwarfTests : ElfTestBase
1616
{
1717
[TestMethod]
18+
public void ReadDwarf_version2_should_be_successfull()
19+
{
20+
string ResourceName = Path.Combine(AppContext.BaseDirectory, "TestFiles", "TestDwarf2.elf");
21+
22+
ElfFile elf = OpenAndLoadElf(ResourceName);
23+
var elfContext = new DwarfElfContext(elf);
24+
var inputContext = new DwarfReaderContext(elfContext);
25+
inputContext.DebugLinePrinter = Console.Out;
26+
var dwarf = DwarfFile.Read(inputContext);
27+
28+
Assert.IsNotNull(dwarf);
29+
}
30+
31+
[DataTestMethod]
1832
[DataRow(0UL)]
1933
[DataRow(1UL)]
2034
[DataRow(50UL)]
@@ -301,7 +315,7 @@ public void TestDebugInfoSmall()
301315
DebugAbbrevStream = new MemoryStream(),
302316
DebugLineStream = new MemoryStream(),
303317
DebugInfoStream = new MemoryStream(),
304-
DebugStringStream = new MemoryStream(),
318+
DebugStringStream = new MemoryStream(),
305319
DebugAddressRangeStream = new MemoryStream()
306320
};
307321
dwarf.Write(outputContext);

src/LibObjectFile.Tests/Elf/ElfTestBase.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ protected async Task LoadAndVerifyElf(string name)
7171
ByteArrayAssert.AreEqual(originalBinary, newBinary, "Invalid binary diff between write -> read -> write");
7272
}
7373

74+
protected ElfFile OpenAndLoadElf(string absolutePath)
75+
{
76+
using var stream = File.OpenRead(absolutePath);
77+
return ElfFile.Read(stream);
78+
}
79+
7480
protected ElfFile LoadElf(string name)
7581
{
7682
var file = GetFile(name);

src/LibObjectFile.Tests/LibObjectFile.Tests.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,10 @@
100100
<Folder Include="Verified\" />
101101
</ItemGroup>
102102

103+
<ItemGroup>
104+
<None Update=".\src\LibObjectFile.Tests\TestFiles\TestDwarf2.elf">
105+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
106+
</None>
107+
</ItemGroup>
108+
103109
</Project>
56.6 KB
Binary file not shown.

src/LibObjectFile/Dwarf/DwarfAbbreviation.cs

Lines changed: 35 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -6,77 +6,53 @@
66
using System.Collections.Generic;
77
using System.Diagnostics;
88
using System.Diagnostics.CodeAnalysis;
9+
using System.Linq;
910
using LibObjectFile.Diagnostics;
1011

1112
namespace LibObjectFile.Dwarf;
1213

1314
[DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")]
1415
public sealed class DwarfAbbreviation : DwarfObject<DwarfAbbreviationTable>
1516
{
16-
private readonly List<DwarfAbbreviationItem> _items;
17-
private readonly Dictionary<ulong, DwarfAbbreviationItem> _mapItems; // Only used if code are non contiguous
17+
private readonly Dictionary<ulong, DwarfAbbreviationItem> _mapUlongToItems;
18+
1819
private readonly Dictionary<DwarfAbbreviationItemKey, DwarfAbbreviationItem> _mapKeyToItem;
1920
private ulong _nextCode;
2021

2122
public DwarfAbbreviation()
2223
{
23-
_items = new List<DwarfAbbreviationItem>();
24-
_mapItems = new Dictionary<ulong, DwarfAbbreviationItem>();
24+
_mapUlongToItems = new Dictionary<ulong, DwarfAbbreviationItem>();
2525
_mapKeyToItem = new Dictionary<DwarfAbbreviationItemKey, DwarfAbbreviationItem>();
2626
_nextCode = 1;
2727
}
2828

2929
public void Reset()
3030
{
3131
// Reset parent dependency
32-
foreach (var dwarfAbbreviationItem in _items)
33-
{
34-
dwarfAbbreviationItem.Parent = null;
35-
}
36-
37-
if (_mapItems.Count > 0)
32+
foreach (var keyPair in _mapUlongToItems.Values)
3833
{
39-
foreach (var keyPair in _mapItems)
40-
{
41-
keyPair.Value.Parent = null;
42-
}
34+
keyPair.Parent = null;
4335
}
44-
45-
_items.Clear();
46-
_mapItems.Clear();
36+
_mapUlongToItems.Clear();
4737
_mapKeyToItem.Clear();
4838
_nextCode = 1;
4939
}
5040

51-
public IEnumerable<DwarfAbbreviationItem> Items => _mapItems.Count > 0 ? GetMapItems() : _items;
41+
public IEnumerable<DwarfAbbreviationItem> Items => _mapUlongToItems.Values;
5242

53-
private IEnumerable<DwarfAbbreviationItem> GetMapItems()
54-
{
55-
foreach (var item in _mapItems.Values)
56-
{
57-
yield return item;
58-
}
59-
}
60-
6143
public DwarfAbbreviationItem GetOrCreate(DwarfAbbreviationItemKey itemKey)
6244
{
63-
if (!_mapKeyToItem.TryGetValue(itemKey, out var item))
45+
if (!TryFindByKey(itemKey, out var item))
6446
{
6547
item = new DwarfAbbreviationItem(_nextCode, itemKey.Tag, itemKey.HasChildren, itemKey.Descriptors)
6648
{
6749
Parent = this
6850
};
6951

70-
if (_mapItems.Count > 0)
71-
{
72-
73-
_mapItems[_nextCode] = item;
74-
}
75-
else
76-
{
77-
_items.Add(item);
78-
}
52+
// insert or update new item
53+
_mapUlongToItems[_nextCode] = item;
7954

55+
// not found insert new item
8056
_mapKeyToItem[itemKey] = item;
8157

8258
_nextCode++;
@@ -93,24 +69,16 @@ public bool TryFindByCode(ulong code, [NotNullWhen(true)] out DwarfAbbreviationI
9369
return false;
9470
}
9571

96-
code--;
97-
98-
if (_mapItems.Count > 0)
99-
{
100-
return _mapItems.TryGetValue(code, out item);
101-
}
102-
103-
if (code < int.MaxValue && (int)code < _items.Count)
104-
{
105-
item = _items[(int) code];
106-
return true;
107-
}
72+
return _mapUlongToItems.TryGetValue(code, out item);
73+
}
10874

75+
public bool TryFindByKey(DwarfAbbreviationItemKey key, [NotNullWhen(true)] out DwarfAbbreviationItem? item)
76+
{
10977
item = null;
110-
return false;
78+
return _mapKeyToItem.TryGetValue(key, out item);
11179
}
11280

113-
private string DebuggerDisplay => $"Count = {(_mapItems.Count > 0 ? _mapItems.Count : _items.Count)}";
81+
private string DebuggerDisplay => $"Count = {_mapUlongToItems.Count}";
11482

11583
private bool TryReadNext(DwarfReader reader)
11684
{
@@ -123,45 +91,27 @@ private bool TryReadNext(DwarfReader reader)
12391

12492
var item = new DwarfAbbreviationItem
12593
{
126-
Position = startOffset,
94+
Position = startOffset,
12795
Code = code
12896
};
12997

130-
var index = code - 1;
131-
bool canAddToList = _mapItems.Count == 0 && index < int.MaxValue && _items.Count == (int)index;
132-
13398
item.Read(reader);
13499

135-
if (canAddToList)
100+
if (_mapUlongToItems.ContainsKey(code))
136101
{
137-
_items.Add(item);
138-
_nextCode++;
102+
reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"Invalid code {code} found while another code already exists in this abbreviation.");
103+
return false;
139104
}
140-
else
141-
{
142-
if (_mapItems.Count == 0)
143-
{
144-
for (var i = 0; i < _items.Count; i++)
145-
{
146-
var previousItem = _items[i];
147-
_mapItems.Add((ulong)i + 1, previousItem);
148-
}
149-
_items.Clear();
150-
}
151-
152-
// TODO: check collisions
153-
if (_mapItems.ContainsKey(code))
154-
{
155-
reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"Invalid code {code} found while another code already exists in this abbreviation.");
156-
return false;
157-
}
158-
_mapItems.Add(code, item);
159105

160-
_nextCode = Math.Max(code, _nextCode) + 1;
161-
}
106+
_mapUlongToItems.Add(code, item);
107+
_nextCode = Math.Max(code, _nextCode) + 1;
162108

163109
var key = new DwarfAbbreviationItemKey(item.Tag, item.HasChildren, item.Descriptors);
164-
_mapKeyToItem.Add(key, item);
110+
111+
if (!_mapKeyToItem.ContainsKey(key))
112+
{
113+
_mapKeyToItem.Add(key, item);
114+
}
165115

166116
return true;
167117
}
@@ -180,24 +130,9 @@ public override void Write(DwarfWriter writer)
180130
{
181131
var startOffset = writer.Position;
182132
Debug.Assert(startOffset == Position);
183-
if (_mapItems.Count > 0)
133+
foreach (var item in _mapUlongToItems.Values)
184134
{
185-
foreach (var itemPair in _mapItems)
186-
{
187-
var item = itemPair.Value;
188-
item.Write(writer);
189-
}
190-
191-
}
192-
else
193-
{
194-
if (_items.Count > 0)
195-
{
196-
foreach (var item in _items)
197-
{
198-
item.Write(writer);
199-
}
200-
}
135+
item.Write(writer);
201136
}
202137

203138
// End of abbreviation item
@@ -210,28 +145,11 @@ protected override void UpdateLayoutCore(DwarfLayoutContext context)
210145
{
211146
var endOffset = Position;
212147

213-
if (_mapItems.Count > 0)
148+
foreach (var item in _mapUlongToItems.Values)
214149
{
215-
foreach (var itemPair in _mapItems)
216-
{
217-
var item = itemPair.Value;
218-
item.Position = endOffset;
219-
item.UpdateLayout(context);
220-
endOffset += item.Size;
221-
}
222-
223-
}
224-
else
225-
{
226-
if (_items.Count > 0)
227-
{
228-
foreach (var item in _items)
229-
{
230-
item.Position = endOffset;
231-
item.UpdateLayout(context);
232-
endOffset += item.Size;
233-
}
234-
}
150+
item.Position = endOffset;
151+
item.UpdateLayout(context);
152+
endOffset += item.Size;
235153
}
236154

237155
endOffset += DwarfHelper.SizeOfULEB128(0);

src/LibObjectFile/Dwarf/DwarfUnit.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public override void Read(DwarfReader reader)
171171

172172
DwarfUnitKindEx unitKind = reader.DefaultUnitKind;
173173

174-
if (version <= 2 || version > 5)
174+
if (version < 2 || version > 5)
175175
{
176176
reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_VersionNotSupported, $"Version {version} is not supported");
177177
return null;

src/LibObjectFile/generated/LibObjectFile.Dwarf.generated.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ public static unsafe partial class DwarfNative
759759
public const ushort DW_AT_byte_stride = 81;
760760

761761
/// <summary>
762-
/// DWARF3 (do not use)
762+
/// DWARF2 (do not use)
763763
/// </summary>
764764
public const ushort DW_AT_stride = 81;
765765

@@ -4183,9 +4183,15 @@ public enum DwarfAttributeKind : ushort
41834183
ReturnAddr = DwarfNative.DW_AT_return_addr,
41844184

41854185
StartScope = DwarfNative.DW_AT_start_scope,
4186-
4186+
4187+
/// <summary>
4188+
/// DWARF3 name
4189+
/// </summary>
41874190
BitStride = DwarfNative.DW_AT_bit_stride,
4188-
4191+
4192+
/// <summary>
4193+
/// DWARF2 name
4194+
/// </summary>
41894195
StrideSize = DwarfNative.DW_AT_stride_size,
41904196

41914197
UpperBound = DwarfNative.DW_AT_upper_bound,
@@ -4253,9 +4259,15 @@ public enum DwarfAttributeKind : ushort
42534259
Associated = DwarfNative.DW_AT_associated,
42544260

42554261
DataLocation = DwarfNative.DW_AT_data_location,
4256-
4262+
4263+
/// <summary>
4264+
/// DWARF3f
4265+
/// </summary>
42574266
ByteStride = DwarfNative.DW_AT_byte_stride,
4258-
4267+
4268+
/// <summary>
4269+
/// DWARF2
4270+
/// </summary>
42594271
Stride = DwarfNative.DW_AT_stride,
42604272

42614273
EntryPC = DwarfNative.DW_AT_entry_pc,

0 commit comments

Comments
 (0)