Skip to content

Commit f51d461

Browse files
committed
Update the entries in ElfSymbolTableSectionHeaderIndices.UpdateLayout; check it in unit test
1 parent 7886efc commit f51d461

2 files changed

Lines changed: 45 additions & 23 deletions

File tree

src/LibObjectFile.Tests/Elf/ElfSimpleTests.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,13 @@ public void TestManySections()
470470
Assert.True(elf.Sections[i + 2] is ElfBinarySection);
471471
Assert.AreEqual($".section{i}", elf.Sections[i + 2].Name.Value);
472472
}
473+
474+
Assert.True(elf.Sections[ushort.MaxValue + 3] is ElfSymbolTable);
475+
symbolTable = (ElfSymbolTable)elf.Sections[ushort.MaxValue + 3];
476+
for (int i = 0; i < ushort.MaxValue; i++)
477+
{
478+
Assert.AreEqual($".section{i}", symbolTable.Entries[i + 1].Section.Section.Name.Value);
479+
}
473480
}
474481
}
475482
}

src/LibObjectFile/Elf/Sections/ElfSymbolTableSectionHeaderIndices.cs

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
using System;
66
using System.Collections.Generic;
7+
using System.Reflection.PortableExecutable;
78

89
namespace LibObjectFile.Elf
910
{
@@ -14,12 +15,12 @@ public sealed class ElfSymbolTableSectionHeaderIndices : ElfSection
1415
{
1516
public const string DefaultName = ".symtab_shndx";
1617

17-
private readonly List<ElfSectionLink> _entries;
18+
private readonly List<uint> _entries;
1819

1920
public ElfSymbolTableSectionHeaderIndices() : base(ElfSectionType.SymbolTableSectionHeaderIndices)
2021
{
2122
Name = DefaultName;
22-
_entries = new List<ElfSectionLink>();
23+
_entries = new List<uint>();
2324
}
2425

2526
public override ElfSectionType Type
@@ -35,11 +36,6 @@ public override ElfSectionType Type
3536
}
3637
}
3738

38-
/// <summary>
39-
/// Gets a list of <see cref="ElfSectionLink"/> entries.
40-
/// </summary>
41-
public IReadOnlyList<ElfSectionLink> Entries => _entries;
42-
4339
public override unsafe ulong TableEntrySize => sizeof(uint);
4440

4541
protected override void Read(ElfReader reader)
@@ -49,16 +45,16 @@ protected override void Read(ElfReader reader)
4945
_entries.Capacity = (int)numberOfEntries;
5046
for (ulong i = 0; i < numberOfEntries; i++)
5147
{
52-
_entries.Add(new ElfSectionLink(reader.ReadU32()));
48+
_entries.Add(reader.ReadU32());
5349
}
5450
}
5551

5652
protected override void Write(ElfWriter writer)
5753
{
5854
// Write all entries
59-
for (int i = 0; i < Entries.Count; i++)
55+
for (int i = 0; i < _entries.Count; i++)
6056
{
61-
writer.WriteU32(Entries[i].GetIndex());
57+
writer.WriteU32(_entries[i]);
6258
}
6359
}
6460

@@ -70,14 +66,13 @@ protected override void AfterRead(ElfReader reader)
7066
for (int i = 0; i < _entries.Count; i++)
7167
{
7268
var entry = _entries[i];
73-
if (entry.SpecialIndex != 0)
69+
if (entry != 0)
7470
{
75-
entry = reader.ResolveLink(entry.Section, $"Invalid link section index {entry.SpecialIndex} for symbol table entry [{i}] from symbol table section [{this}]");
76-
_entries[i] = entry;
71+
var resolvedLink = reader.ResolveLink(new ElfSectionLink(entry), $"Invalid link section index {entry} for symbol table entry [{i}] from symbol table section [{this}]");
7772

7873
// Update the link in symbol table
7974
var symbolTableEntry = symbolTable.Entries[i];
80-
symbolTableEntry.Section = entry.Section;
75+
symbolTableEntry.Section = resolvedLink;
8176
symbolTable.Entries[i] = symbolTableEntry;
8277
}
8378
}
@@ -92,21 +87,41 @@ public override void Verify(DiagnosticBag diagnostics)
9287
{
9388
return;
9489
}
90+
}
9591

96-
for (int i = 0; i < _entries.Count; i++)
92+
public override unsafe void UpdateLayout(DiagnosticBag diagnostics)
93+
{
94+
if (diagnostics == null) throw new ArgumentNullException(nameof(diagnostics));
95+
96+
// Verify that the link is safe and configured as expected
97+
Link.TryGetSectionSafe<ElfSymbolTable>(nameof(ElfSymbolTableSectionHeaderIndices), nameof(Link), this, diagnostics, out var symbolTable, ElfSectionType.SymbolTable, ElfSectionType.DynamicLinkerSymbolTable);
98+
99+
int numberOfEntries = 0;
100+
for (int i = 0; i < symbolTable.Entries.Count; i++)
97101
{
98-
var entry = _entries[i];
99-
if (entry.SpecialIndex != 0 && entry.Section != null && entry.Section.Parent != Parent)
102+
if (symbolTable.Entries[i].Section.Section is { SectionIndex: >= ElfNative.SHN_LORESERVE })
100103
{
101-
diagnostics.Error(DiagnosticId.ELF_ERR_InvalidSymbolEntrySectionParent, $"Invalid section for the symbol entry #{i} in the {nameof(ElfSymbolTable)} section [{Index}]");
104+
numberOfEntries = i + 1;
102105
}
103106
}
104-
}
105107

106-
public override unsafe void UpdateLayout(DiagnosticBag diagnostics)
107-
{
108-
if (diagnostics == null) throw new ArgumentNullException(nameof(diagnostics));
109-
Size = Parent == null || Parent.FileClass == ElfFileClass.None ? 0 : (ulong)Entries.Count * sizeof(uint);
108+
_entries.Capacity = numberOfEntries;
109+
_entries.Clear();
110+
111+
for (int i = 0; i < numberOfEntries; i++)
112+
{
113+
var section = symbolTable.Entries[i].Section.Section;
114+
if (section is { SectionIndex: >= ElfNative.SHN_LORESERVE })
115+
{
116+
_entries.Add(section.SectionIndex);
117+
}
118+
else
119+
{
120+
_entries.Add(0);
121+
}
122+
}
123+
124+
Size = Parent == null || Parent.FileClass == ElfFileClass.None ? 0 : (ulong)numberOfEntries * sizeof(uint);
110125
}
111126
}
112127
}

0 commit comments

Comments
 (0)