in src/Microsoft.Diagnostics.Runtime/MacOS/MachOModule.cs [42:100]
private MachOModule(MachOCoreDump? parent, IDataReader reader, in MachHeader64 header, ulong address, string path)
{
BaseAddress = address;
FileName = path;
Parent = parent;
_header = header;
DataReader = reader;
if (header.Magic != MachHeader64.Magic64)
throw new InvalidDataException($"Module at {address:x} does not contain the expected Mach-O header.");
// Since MachO segments are not contiguous the image size is just the headers/commands
ImageSize = MachHeader64.Size + _header.SizeOfCommands;
List<MachOSegment> segments = new((int)_header.NumberCommands);
uint offset = (uint)sizeof(MachHeader64);
for (int i = 0; i < _header.NumberCommands; i++)
{
ulong cmdAddress = BaseAddress + offset;
LoadCommandHeader cmd = DataReader.Read<LoadCommandHeader>(cmdAddress);
switch (cmd.Kind)
{
case LoadCommandType.Segment64:
Segment64LoadCommand seg64LoadCmd = DataReader.Read<Segment64LoadCommand>(cmdAddress + (uint)sizeof(LoadCommandHeader));
segments.Add(new MachOSegment(seg64LoadCmd));
if (seg64LoadCmd.Name.Equals("__TEXT"))
{
LoadBias = BaseAddress - seg64LoadCmd.VMAddr;
}
break;
case LoadCommandType.SymTab:
_symtab = DataReader.Read<SymtabLoadCommand>(cmdAddress);
break;
case LoadCommandType.DysymTab:
_dysymtab = DataReader.Read<DysymtabLoadCommand>(cmdAddress);
break;
case LoadCommandType.Uuid:
UuidLoadCommand uuid = DataReader.Read<UuidLoadCommand>(cmdAddress);
if (uuid.Header.Kind == LoadCommandType.Uuid)
{
BuildId = uuid.BuildId.ToImmutableArray();
}
break;
}
offset += cmd.Size;
}
segments.Sort((x, y) => x.Address.CompareTo(y.Address));
_segments = segments.ToArray();
if (_symtab.StrOff != 0)
_stringTableAddress = GetAddressFromFileOffset(_symtab.StrOff);
}