in src/Microsoft.Diagnostics.Runtime/src/Linux/ElfCoreFile.cs [153:222]
private ImmutableDictionary<ulong, ElfLoadedImage> LoadFileTable()
{
ElfNote fileNote = GetNotes(ElfNoteType.File).Single();
ulong position = 0;
ulong entryCount = 0;
if (ElfFile.Header.Is64Bit)
{
ElfFileTableHeader64 header = fileNote.ReadContents<ElfFileTableHeader64>(ref position);
entryCount = header.EntryCount;
}
else
{
ElfFileTableHeader32 header = fileNote.ReadContents<ElfFileTableHeader32>(ref position);
entryCount = header.EntryCount;
}
ElfFileTableEntryPointers64[] fileTable = new ElfFileTableEntryPointers64[entryCount];
Dictionary<string, ElfLoadedImage> lookup = new Dictionary<string, ElfLoadedImage>(fileTable.Length);
for (int i = 0; i < fileTable.Length; i++)
{
if (ElfFile.Header.Is64Bit)
{
fileTable[i] = fileNote.ReadContents<ElfFileTableEntryPointers64>(ref position);
}
else
{
ElfFileTableEntryPointers32 entry = fileNote.ReadContents<ElfFileTableEntryPointers32>(ref position);
fileTable[i].Start = entry.Start;
fileTable[i].Stop = entry.Stop;
fileTable[i].PageOffset = entry.PageOffset;
}
}
int size = (int)(fileNote.Header.ContentSize - position);
byte[] bytes = ArrayPool<byte>.Shared.Rent(size);
try
{
int read = fileNote.ReadContents((ulong)position, bytes);
int start = 0;
for (int i = 0; i < fileTable.Length; i++)
{
int end = start;
while (bytes[end] != 0)
end++;
string path = Encoding.UTF8.GetString(bytes, start, end - start);
start = end + 1;
if (!lookup.TryGetValue(path, out ElfLoadedImage? image))
image = lookup[path] = new ElfLoadedImage(ElfFile.VirtualAddressReader, ElfFile.Header.Is64Bit, path);
image.AddTableEntryPointers(fileTable[i]);
}
}
finally
{
ArrayPool<byte>.Shared.Return(bytes);
}
ImmutableDictionary<ulong, ElfLoadedImage>.Builder result = ImmutableDictionary.CreateBuilder<ulong, ElfLoadedImage>();
foreach (ElfLoadedImage image in lookup.Values)
{
image.FixBaseAddress();
result.Add(image.BaseAddress, image);
}
return result.ToImmutable();
}