public override bool OnInitialize()
        {
            _id          = Header->_info._id;
            _linkNext    = Header->_info._link._linkNext; //0
            _linkPrev    = Header->_info._link._linkPrev; //0
            _numSections = Header->_info._numSections;
            _infoOffset  = Header->_info._sectionInfoOffset;
            _nameOffset  = Header->_info._nameOffset;
            _nameSize    = Header->_info._nameSize;
            _version     = Header->_info._version;

            _bssSize           = Header->_bssSize;
            _relOffset         = Header->_relOffset;
            _impOffset         = Header->_impOffset;
            _impSize           = Header->_impSize;
            _prologSection     = Header->_prologSection;
            _epilogSection     = Header->_epilogSection;
            _unresolvedSection = Header->_unresolvedSection;
            _bssSection        = Header->_bssSection;
            _prologOffset      = Header->_prologOffset;
            _epilogOffset      = Header->_epilogOffset;
            _unresolvedOffset  = Header->_unresolvedOffset;

            _moduleAlign = Header->_moduleAlign;
            _bssAlign    = Header->_bssAlign;
            _fixSize     = Header->_commandOffset;

            _imports = new SortedDictionary <uint, List <RELLink> >();
            for (int i = 0; i < Header->ImportListCount; i++)
            {
                RELImportEntry *entry = (RELImportEntry *)&Header->Imports[i];
                uint            id    = (uint)entry->_moduleId;
                _imports.Add(id, new List <RELLink>());

                RELLink *link = (RELLink *)(WorkingUncompressed.Address + (uint)entry->_offset);
                do
                {
                    _imports[id].Add(*link);
                }while ((link++)->_type != RELLinkType.End);
            }

            if (_name == null)
            {
                _name = _idNames.ContainsKey(_id) ? _idNames[_id] : Path.GetFileName(_origPath);
            }

            if (!_files.ContainsKey(ModuleID))
            {
                _files.Add(ModuleID, this);
            }
            else
            {
                _files[ModuleID] = this;
            }

            return(true);
        }
Esempio n. 2
0
        public override void OnRebuild(VoidPtr address, int length, bool force)
        {
            RELHeader *header = (RELHeader *)address;

            header->_info._id                = _id;
            header->_info._link._linkNext    = 0;
            header->_info._link._linkPrev    = 0;
            header->_info._numSections       = (uint)Children.Count;
            header->_info._sectionInfoOffset = RELHeader.Size;
            header->_info._nameOffset        = _nameOffset;
            header->_info._nameSize          = _nameSize;
            header->_info._version           = _version;

            header->_moduleAlign   = 0x20;
            header->_bssAlign      = 0x8;
            header->_commandOffset = 0;

            bool             bssFound = false;
            RELSectionEntry *sections = (RELSectionEntry *)(address + RELHeader.Size);
            VoidPtr          dataAddr = address + RELHeader.Size + Children.Count * RELSectionEntry.Size;

            foreach (ModuleSectionNode s in Children)
            {
                if (s._dataBuffer.Length != 0)
                {
                    int i = s.Index;

                    if (i > 3)
                    {
                        int off     = (int)(dataAddr - address);
                        int aligned = off.Align(8);
                        int diff    = aligned - off;
                        dataAddr += diff;
                    }

                    if (!s._isBSSSection)
                    {
                        sections[i]._offset       = (uint)(dataAddr - address);
                        sections[i].IsCodeSection = s.HasCode;

                        s.Rebuild(dataAddr, s._calcSize, true);
                        dataAddr += s._calcSize;
                    }
                    else
                    {
                        bssFound            = true;
                        sections[i]._offset = 0;
                        header->_bssSize    = (uint)s._calcSize;

                        //This is always 0 it seems
                        header->_bssSection = 0;
                    }
                    sections[i]._size = (uint)s._calcSize;
                }
            }

            if (!bssFound)
            {
                header->_bssSize    = 0;
                header->_bssSection = 0;
            }

            if (_prologReloc != null)
            {
                header->_prologSection = (byte)_prologReloc._section.Index;
                header->_prologOffset  = (uint)sections[_prologReloc._section.Index].Offset + (uint)_prologReloc._index * 4;
            }
            else
            {
                header->_prologOffset  = 0;
                header->_prologSection = 0;
            }

            if (_epilogReloc != null)
            {
                header->_epilogSection = (byte)_epilogReloc._section.Index;
                header->_epilogOffset  = (uint)sections[_epilogReloc._section.Index].Offset + (uint)_epilogReloc._index * 4;
            }
            else
            {
                header->_epilogSection = 0;
                header->_epilogOffset  = 0;
            }

            if (_unresReloc != null)
            {
                header->_unresolvedSection = (byte)_unresReloc._section.Index;
                header->_unresolvedOffset  = (uint)sections[_unresReloc._section.Index].Offset + (uint)_unresReloc._index * 4;
            }
            else
            {
                header->_unresolvedSection = 0;
                header->_unresolvedOffset  = 0;
            }

            RELImportEntry *imports = (RELImportEntry *)dataAddr;

            header->_impOffset = (uint)(dataAddr - address);
            dataAddr           = (VoidPtr)imports + (header->_impSize = (uint)_imports.Keys.Count * RELImportEntry.Size);
            header->_relOffset = (uint)(dataAddr - address);

            List <uint> k = new List <uint>();

            foreach (uint s in _imports.Keys)
            {
                if (s != ModuleID && s != 0)
                {
                    k.Add(s);
                }
            }

            k.Sort();

            foreach (uint s in _imports.Keys)
            {
                if (s == ModuleID)
                {
                    k.Add(s);
                    break;
                }
            }

            foreach (uint s in _imports.Keys)
            {
                if (s == 0)
                {
                    k.Add(s);
                    break;
                }
            }

            for (int i = 0; i < k.Count; i++)
            {
                uint id     = k[i];
                uint offset = (uint)(dataAddr - address);
                if (id == ModuleID)
                {
                    header->_commandOffset = offset;
                }

                imports[i]._moduleId = id;
                imports[i]._offset   = offset;

                RELLink *link = (RELLink *)dataAddr;
                foreach (RELLink n in _imports[k[i]])
                {
                    *link++ = n;
                }
                dataAddr = link;
            }
        }
Esempio n. 3
0
        public override void OnRebuild(VoidPtr address, int length, bool force)
        {
            RELHeader *header = (RELHeader *)address;

            header->_info._id                = _id;
            header->_info._link._linkNext    = 0;
            header->_info._link._linkPrev    = 0;
            header->_info._numSections       = (uint)Children.Count;
            header->_info._sectionInfoOffset = RELHeader.Size;
            header->_info._nameOffset        = _nameOffset;
            header->_info._nameSize          = _nameSize;
            header->_info._version           = _version;

            header->_moduleAlign   = 0x20;
            header->_bssAlign      = 0x8;
            header->_commandOffset = 0;

            header->_bssSize    = 0;
            header->_bssSection = 0;

            RELSectionEntry *sections = (RELSectionEntry *)(address + RELHeader.Size);
            VoidPtr          dataAddr = address + RELHeader.Size + Children.Count * RELSectionEntry.Size;

            foreach (ModuleSectionNode s in Children)
            {
                if (s._dataBuffer.Length != 0)
                {
                    int i = s.Index;

                    sections[i]._size = (uint)s._calcSize;

                    //Align sections 4 and 5?
                    //if (i > 3)
                    //{
                    //    int off = (int)(dataAddr - address);
                    //    int aligned = off.Align(8);
                    //    int diff = aligned - off;
                    //    dataAddr += diff;
                    //}

                    if (!s._isBSSSection)
                    {
                        sections[i]._offset       = (uint)(dataAddr - address);
                        sections[i].IsCodeSection = s.HasCode;

                        s.Rebuild(dataAddr, s._calcSize, true);

                        dataAddr += s._calcSize;
                    }
                    else
                    {
                        sections[i]._offset = 0;

                        header->_bssSection = 0; //This is always 0 it seems
                        header->_bssSize    = (uint)s._calcSize;
                    }
                }
            }

            if (_prologSect != -1)
            {
                header->_prologSection = (byte)_prologSect;
                header->_prologOffset  = (uint)sections[_prologSect].Offset + (uint)_prologIndex * 4;
            }
            else
            {
                header->_prologOffset  = 0;
                header->_prologSection = 0;
            }

            if (_epilogSect != -1)
            {
                header->_epilogSection = (byte)_epilogSect;
                header->_epilogOffset  = (uint)sections[_epilogSect].Offset + (uint)_epilogIndex * 4;
            }
            else
            {
                header->_epilogSection = 0;
                header->_epilogOffset  = 0;
            }

            if (_unresSect != -1)
            {
                header->_unresolvedSection = (byte)_unresSect;
                header->_unresolvedOffset  = (uint)sections[_unresSect].Offset + (uint)_unresIndex * 4;
            }
            else
            {
                header->_unresolvedSection = 0;
                header->_unresolvedOffset  = 0;
            }

            RELImportEntry *imports = (RELImportEntry *)dataAddr;

            header->_impOffset = (uint)(dataAddr - address);
            dataAddr           = (VoidPtr)imports + (header->_impSize = (uint)_imports.Keys.Count * RELImportEntry.Size);
            header->_relOffset = (uint)(dataAddr - address);

            List <uint> k = new List <uint>();

            foreach (uint s in _imports.Keys)
            {
                if (s != ModuleID && s != 0)
                {
                    k.Add(s);
                }
            }

            k.Sort();

            foreach (uint s in _imports.Keys)
            {
                if (s == ModuleID)
                {
                    k.Add(s);
                    break;
                }
            }

            foreach (uint s in _imports.Keys)
            {
                if (s == 0)
                {
                    k.Add(s);
                    break;
                }
            }

            for (int i = 0; i < k.Count; i++)
            {
                uint id     = k[i];
                uint offset = (uint)(dataAddr - address);
                if (id == ModuleID)
                {
                    header->_commandOffset = offset;
                }

                imports[i]._moduleId = id;
                imports[i]._offset   = offset;

                RELLink *link = (RELLink *)dataAddr;
                foreach (RELLink n in _imports[k[i]])
                {
                    *link++ = n;
                }
                dataAddr = link;
            }

            // Stage module conversion
            byte *bptr = (byte *)address;

            if (_stageID != null)
            {
                bptr[findStageIDOffset()] = _stageID.Value;
            }

            if (_itemIDs != null)
            {
                // File must be online training room .rel file
                for (int i = 0; i < _itemIDs.Length; i++)
                {
                    int offset = OTrainItemOffsets[i];
                    if (bptr[offset - 3] != 0x38 || bptr[offset - 2] != 0x80 || bptr[offset - 1] != 0x00)
                    {
                        throw new Exception("Rebuilding st_otrain module file has moved the item IDs");
                    }
                    bptr[offset] = _itemIDs[i];
                }
            }
        }