Example #1
0
        internal static ResourceNode TryParse(DataSource source)
        {
            RELHeader *header = (RELHeader *)source.Address;

            return(header->_info._id <= 0x7E &&
                   header->_info._numSections <= 20 &&
                   header->_bssAlign == 8 &&
                   header->_moduleAlign == 32
                ? new RELNode() : null);
        }
Example #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;
            }
        }
Example #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];
                }
            }
        }