private MachOModule()

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);
        }