diff --git a/src/LibObjectFile/Elf/ElfSectionHeaderTable.cs b/src/LibObjectFile/Elf/ElfSectionHeaderTable.cs
index dd17f04..0185874 100644
--- a/src/LibObjectFile/Elf/ElfSectionHeaderTable.cs
+++ b/src/LibObjectFile/Elf/ElfSectionHeaderTable.cs
@@ -133,6 +133,7 @@ private static ElfSection CreateElfSection(ElfReader reader, uint sectionIndex,
ElfSectionType.Note => new ElfNoteTable(),
ElfSectionType.SymbolTableSectionHeaderIndices => new ElfSymbolTableSectionHeaderIndices(),
ElfSectionType.NoBits => new ElfNoBitsSection(),
+ ElfSectionType.DynamicLinking => new ElfDynamicLinkingTable(),
_ => new ElfStreamSection(sectionType)
};
}
diff --git a/src/LibObjectFile/Elf/Sections/ElfDynamic.cs b/src/LibObjectFile/Elf/Sections/ElfDynamic.cs
new file mode 100644
index 0000000..554e435
--- /dev/null
+++ b/src/LibObjectFile/Elf/Sections/ElfDynamic.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Alexandre Mutel. All rights reserved.
+// This file is licensed under the BSD-Clause 2 license.
+// See the license.txt file in the project root for more information.
+
+namespace LibObjectFile.Elf
+{
+ ///
+ /// Dynamic table entry for ELF.
+ ///
+ public record struct ElfDynamic
+ {
+ ///
+ /// Type of dynamic table entry.
+ ///
+ public long Tag { get; set; }
+
+ ///
+ /// Integer value of entry.
+ ///
+ public ulong Value { get; set; }
+
+ ///
+ /// Pointer value of entry.
+ ///
+ public ulong Pointer => Value;
+
+ ///
+ /// Dynamic Tag
+ ///
+ public ElfDynamicTag TagType => (ElfDynamicTag)Tag;
+ }
+}
\ No newline at end of file
diff --git a/src/LibObjectFile/Elf/Sections/ElfDynamicLinkingTable.cs b/src/LibObjectFile/Elf/Sections/ElfDynamicLinkingTable.cs
new file mode 100644
index 0000000..ef19012
--- /dev/null
+++ b/src/LibObjectFile/Elf/Sections/ElfDynamicLinkingTable.cs
@@ -0,0 +1,166 @@
+// Copyright (c) Alexandre Mutel. All rights reserved.
+// This file is licensed under the BSD-Clause 2 license.
+// See the license.txt file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using LibObjectFile.Diagnostics;
+using LibObjectFile.IO;
+
+namespace LibObjectFile.Elf
+{
+ public class ElfDynamicLinkingTable : ElfSection
+ {
+ private Stream _stream;
+ private bool _is32;
+
+ public Stream Stream
+ {
+ get => _stream;
+ set
+ {
+ ArgumentNullException.ThrowIfNull(value);
+ _stream = value;
+ Size = (ulong)_stream.Length;
+ }
+ }
+
+ public List Entries { get; }
+
+ public ElfDynamicLinkingTable() : base(ElfSectionType.DynamicLinking)
+ {
+ Name = ElfSectionSpecialType.Dynamic.GetDefaultName();
+ Flags = ElfSectionSpecialType.Dynamic.GetSectionFlags();
+ _stream = new MemoryStream();
+
+ Entries = [];
+ }
+
+ public override void Read(ElfReader reader)
+ {
+ reader.Position = Position;
+ Entries.Clear();
+
+ var numberOfEntries = (int)(base.Size / base.TableEntrySize);
+ var entries = Entries;
+ CollectionsMarshal.SetCount(entries, numberOfEntries);
+
+ if (_is32)
+ Read32(reader, numberOfEntries);
+ else
+ Read64(reader, numberOfEntries);
+ }
+
+ private void Read32(ElfReader reader, int numberOfEntries)
+ {
+ using var batch = new BatchDataReader(reader.Stream, numberOfEntries);
+ var span = CollectionsMarshal.AsSpan(Entries);
+ ref var entry = ref MemoryMarshal.GetReference(span);
+ while (batch.HasNext())
+ {
+ ref var dyn = ref batch.Read();
+
+ entry.Tag = reader.Decode(dyn.d_tag);
+ entry.Value = reader.Decode(dyn.d_un.d_val);
+
+ entry = ref Unsafe.Add(ref entry, 1);
+ }
+ }
+
+ private void Read64(ElfReader reader, int numberOfEntries)
+ {
+ using var batch = new BatchDataReader(reader.Stream, numberOfEntries);
+ var span = CollectionsMarshal.AsSpan(Entries);
+ ref var entry = ref MemoryMarshal.GetReference(span);
+ while (batch.HasNext())
+ {
+ ref var dyn = ref batch.Read();
+
+ entry.Tag = reader.Decode(dyn.d_tag);
+ entry.Value = reader.Decode(dyn.d_un.d_val);
+
+ entry = ref Unsafe.Add(ref entry, 1);
+ }
+ }
+
+ public override void Write(ElfWriter writer)
+ {
+ if (_is32)
+ Write32(writer);
+ else
+ Write64(writer);
+ }
+
+ private void Write32(ElfWriter writer)
+ {
+ var entries = CollectionsMarshal.AsSpan(Entries);
+ using var batch = new BatchDataWriter(writer.Stream, entries.Length);
+ var dyn = new ElfNative.Elf32_Dyn();
+ for (int i = 0; i < entries.Length; i++)
+ {
+ ref var entry = ref entries[i];
+
+ writer.Encode(out dyn.d_tag, (int)entry.Tag);
+ writer.Encode(out dyn.d_un.d_val, (uint)entry.Value);
+
+ batch.Write(dyn);
+ }
+ }
+
+ private void Write64(ElfWriter writer)
+ {
+ var entries = CollectionsMarshal.AsSpan(Entries);
+ using var batch = new BatchDataWriter(writer.Stream, entries.Length);
+ var dyn = new ElfNative.Elf64_Dyn();
+ for (int i = 0; i < entries.Length; i++)
+ {
+ ref var entry = ref entries[i];
+
+ writer.Encode(out dyn.d_tag, entry.Tag);
+ writer.Encode(out dyn.d_un.d_val, entry.Value);
+
+ batch.Write(dyn);
+ }
+ }
+
+ protected override unsafe void ValidateParent(ObjectElement parent)
+ {
+ base.ValidateParent(parent);
+
+ var elf = (ElfFile)parent;
+ _is32 = elf.FileClass == ElfFileClass.Is32;
+
+ BaseTableEntrySize = (uint)(_is32 ? sizeof(ElfNative.Elf32_Dyn) : sizeof(ElfNative.Elf64_Dyn));
+ AdditionalTableEntrySize = 0;
+ }
+
+ internal override unsafe void InitializeEntrySizeFromRead(DiagnosticBag diagnostics, ulong entrySize, bool is32)
+ {
+ _is32 = is32;
+
+ if (is32)
+ {
+ if (entrySize != (ulong)sizeof(ElfNative.Elf32_Dyn))
+ diagnostics.Error(DiagnosticId.ELF_ERR_InvalidSectionEntrySize, $"Invalid size [{entrySize}] for dynamic entry. Expecting to be equal to [{sizeof(ElfNative.Elf32_Dyn)}] bytes.");
+ else
+ {
+ BaseTableEntrySize = (uint)sizeof(ElfNative.Elf32_Dyn);
+ AdditionalTableEntrySize = (uint)(entrySize - AdditionalTableEntrySize);
+ }
+ }
+ else
+ {
+ if (entrySize != (ulong)sizeof(ElfNative.Elf64_Dyn))
+ diagnostics.Error(DiagnosticId.ELF_ERR_InvalidSectionEntrySize, $"Invalid size [{entrySize}] for dynamic entry. Expecting to be equal to [{sizeof(ElfNative.Elf64_Dyn)}] bytes.");
+ else
+ {
+ BaseTableEntrySize = (uint)sizeof(ElfNative.Elf64_Dyn);
+ AdditionalTableEntrySize = (uint)(entrySize - AdditionalTableEntrySize);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/LibObjectFile/Elf/Sections/ElfDynamicTag.cs b/src/LibObjectFile/Elf/Sections/ElfDynamicTag.cs
new file mode 100644
index 0000000..17c7eef
--- /dev/null
+++ b/src/LibObjectFile/Elf/Sections/ElfDynamicTag.cs
@@ -0,0 +1,202 @@
+// Copyright (c) Alexandre Mutel. All rights reserved.
+// This file is licensed under the BSD-Clause 2 license.
+// See the license.txt file in the project root for more information.
+
+namespace LibObjectFile.Elf
+{
+ ///
+ /// Dynamic table entry tags.
+ ///
+ public enum ElfDynamicTag : uint
+ {
+ ///
+ /// Null
+ ///
+ Null = ElfNative.DT_NULL,
+
+ ///
+ /// String table offset of needed library.
+ ///
+ Needed = ElfNative.DT_NEEDED,
+
+ ///
+ /// Size of relocation entries in PLT.
+ ///
+ PltRelSz = ElfNative.DT_PLTRELSZ,
+
+ ///
+ /// Address associated with linkage table.
+ ///
+ PltGot = ElfNative.DT_PLTGOT,
+
+ ///
+ /// Address of symbolic hash table.
+ ///
+ Hash = ElfNative.DT_HASH,
+
+ ///
+ /// Address of dynamic string table.
+ ///
+ StrTab = ElfNative.DT_STRTAB,
+
+ ///
+ /// Address of dynamic symbol table.
+ ///
+ SymTab = ElfNative.DT_SYMTAB,
+
+ ///
+ /// Address of relocation table (Rela entries).
+ ///
+ Rela = ElfNative.DT_RELA,
+
+ ///
+ /// Size of Rela relocation table.
+ ///
+ RelaSz = ElfNative.DT_RELASZ,
+
+ ///
+ /// Size of a Rela relocation entry.
+ ///
+ RelaEnt = ElfNative.DT_RELAENT,
+
+ ///
+ /// Total size of the string table.
+ ///
+ StrSz = ElfNative.DT_STRSZ,
+
+ ///
+ /// Size of a symbol table entry.
+ ///
+ SymEnt = ElfNative.DT_SYMENT,
+
+ ///
+ /// Address of initialization function.
+ ///
+ Init = ElfNative.DT_INIT,
+
+ ///
+ /// Address of termination function.
+ ///
+ Fini = ElfNative.DT_FINI,
+
+ ///
+ /// String table offset of a shared object's name.
+ ///
+ SoName = ElfNative.DT_SONAME,
+
+ ///
+ /// String table offset of library search path.
+ ///
+ RPath = ElfNative.DT_RPATH,
+
+ ///
+ /// Changes symbol resolution algorithm.
+ ///
+ Symbolic = ElfNative.DT_SYMBOLIC,
+
+ ///
+ /// Address of relocation table (Rel entries).
+ ///
+ Rel = ElfNative.DT_REL,
+
+ ///
+ /// Size of Rel relocation table.
+ ///
+ RelSz = ElfNative.DT_RELSZ,
+
+ ///
+ /// Size of a Rel relocation entry.
+ ///
+ RelEnt = ElfNative.DT_RELENT,
+
+ ///
+ /// Type of relocation entry used for linking.
+ ///
+ PltRel = ElfNative.DT_PLTREL,
+
+ ///
+ /// Reserved for debugger.
+ ///
+ Debug = ElfNative.DT_DEBUG,
+
+ ///
+ /// Relocations exist for non-writable segments.
+ ///
+ TextRel = ElfNative.DT_TEXTREL,
+
+ ///
+ /// Address of relocations associated with PLT.
+ ///
+ JmpRel = ElfNative.DT_JMPREL,
+
+ ///
+ /// Process all relocations before execution.
+ ///
+ BindNow = ElfNative.DT_BIND_NOW,
+
+ ///
+ /// Pointer to array of initialization functions.
+ ///
+ InitArray = ElfNative.DT_INIT_ARRAY,
+
+ ///
+ /// Pointer to array of termination functions.
+ ///
+ FiniArray = ElfNative.DT_FINI_ARRAY,
+
+ ///
+ /// Size of .
+ ///
+ InitArraySz = ElfNative.DT_INIT_ARRAYSZ,
+
+ ///
+ /// Size of .
+ ///
+ FiniArraySz = ElfNative.DT_FINI_ARRAYSZ,
+
+ ///
+ /// String table offset of library search path.
+ ///
+ RunPath = ElfNative.DT_RUNPATH,
+
+ ///
+ /// Flags.
+ ///
+ Flags = ElfNative.DT_FLAGS,
+
+ ///
+ /// Values from here to DT_LOOS follow the rules for the interpretation of the d_un union.
+ ///
+ Encoding = ElfNative.DT_ENCODING,
+
+ ///
+ /// Pointer to array of preinit functions.
+ ///
+ PreInitArray = ElfNative.DT_PREINIT_ARRAY,
+
+ ///
+ /// Size of the DT_PREINIT_ARRAY array.
+ ///
+ PreInitArraySz = ElfNative.DT_PREINIT_ARRAYSZ,
+
+ ///
+ /// Start of environment specific tags.
+ ///
+ LoOs = ElfNative.DT_LOOS,
+
+ ///
+ /// End of environment specific tags.
+ ///
+ HiOS = ElfNative.DT_HIOS,
+
+ ///
+ /// Start of processor specific tags.
+ ///
+ LoProc = ElfNative.DT_LOPROC,
+
+ ///
+ /// End of processor specific tags.
+ ///
+ HiProc = ElfNative.DT_HIPROC
+ }
+}
\ No newline at end of file
diff --git a/src/LibObjectFile/Elf/Sections/ElfStringTable.cs b/src/LibObjectFile/Elf/Sections/ElfStringTable.cs
index a54d9e0..abe0081 100644
--- a/src/LibObjectFile/Elf/Sections/ElfStringTable.cs
+++ b/src/LibObjectFile/Elf/Sections/ElfStringTable.cs
@@ -127,7 +127,7 @@ public ElfString Resolve(ElfString name)
return newName;
}
- internal bool TryGetString(uint index, out string text)
+ public bool TryGetString(uint index, out string text)
{
if (index == 0)
{