public void GenerateImports() { _imports.Clear(); Dictionary <uint, ImportData> data = new Dictionary <uint, ImportData>(); foreach (ModuleSectionNode s in _sections) { foreach (ImportData e in data.Values) { e._first = true; e._lastOffset = 0; } uint i = 0; uint offset = 0; List <RELLink> cmds; foreach (Relocation loc in s._relocations) { if (loc.Command != null) { RelCommand cmd = loc.Command; ImportData d; uint id = cmd._moduleID; if (_imports.ContainsKey(id)) { cmds = _imports[id]; d = data[id]; } else { _imports.Add(id, cmds = new List <RELLink>()); data.Add(id, d = new ImportData() { _first = true, _lastOffset = 0 }); } if (d._first) { cmds.Add(new RELLink() { _type = RELLinkType.Section, _section = (byte)s.Index }); d._first = false; } offset = i * 4 + (cmd.IsHalf ? 2u : 0); uint diff = offset - d._lastOffset; while (offset - d._lastOffset > 0xFFFF) { d._lastOffset += 0xFFFF; cmds.Add(new RELLink() { _type = RELLinkType.IncrementOffset, _section = 0, _value = 0, _prevOffset = 0xFFFF }); } byte targetSection = (byte)cmd._targetSectionId; RELLinkType type = (RELLinkType)cmd._command; uint val = cmd._addend; cmds.Add(new RELLink() { _type = type, _section = targetSection, _value = val, _prevOffset = (ushort)diff }); d._lastOffset = offset; } i++; } } foreach (List <RELLink> cmds in _imports.Values) { cmds.Add(new RELLink() { _type = RELLinkType.End }); } }
public void GenerateImports() { _imports.Clear(); Dictionary <uint, ImportData> tempImports = new Dictionary <uint, ImportData>(); foreach (ModuleSectionNode s in _sections) { foreach (ImportData e in tempImports.Values) { e._newSection = true; e._lastOffset = 0; } uint offset = 0; List <RELLink> links; //Iterate through each command in the section var commands = s._manager.GetCommands(); foreach (var r in commands) { RelCommand command = r.Value; int index = r.Key; ImportData impData; uint moduleID = command._moduleID; //Check if an import has been created for the target module. if (_imports.ContainsKey(moduleID)) { //An import already exists, so we'll add to it. links = _imports[moduleID]; impData = tempImports[moduleID]; } else { //An import does not exist, so it must be made. _imports.Add(moduleID, links = new List <RELLink>()); //Create new temporary import data tempImports.Add(moduleID, impData = new ImportData() { _newSection = true, _lastOffset = 0 }); } //This is true when a new section is being evaluated. if (impData._newSection) { links.Add(new RELLink() { _type = RELLinkType.Section, _section = (byte)s.Index }); impData._newSection = false; } //Get the offset of the command within the section. offset = (uint)index * 4 + (command.IsHalf ? 2u : 0); //Get the offset to this address relative to the last written link offset. uint diff = offset - impData._lastOffset; //If the difference is greater than ushort allows, //add increment links until the difference works while (diff > 0xFFFF) { impData._lastOffset += 0xFFFF; diff = offset - impData._lastOffset; links.Add(new RELLink() { _type = RELLinkType.IncrementOffset, _section = 0, _value = 0, _prevOffset = 0xFFFF }); } //Gather the link information byte targetSection = (byte)command._targetSectionId; RELLinkType type = (RELLinkType)command._command; uint val = command._addend; //Write command link links.Add(new RELLink() { _type = type, _section = targetSection, _value = val, _prevOffset = (ushort)diff }); //Don't bother adding the difference, //just set the exact offset as the last offset impData._lastOffset = offset; } } foreach (List <RELLink> cmds in _imports.Values) { cmds.Add(new RELLink() { _type = RELLinkType.End }); } }