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