public void AddBranched(int index, RelocationTarget target) { if (_linkedBranches.ContainsKey(index)) { if (_linkedBranches[index] == null) { _linkedBranches[index] = new List <RelocationTarget>() { target } } ; else { _linkedBranches[index].Add(target); } } else { _linkedBranches.Add(index, new List <RelocationTarget>() { target }); } }
public void LinkBranch(int index, bool isLinked) { PPCBranch branch = (PPCBranch)GetCode(index); int destIndex = -1; if (!branch.Absolute) { //TODO: check if the branch goes outside of the section, handle accordingly destIndex = (index * 4 + branch.DataOffset).RoundDown(4) / 4; RelocationTarget dest = CreateTarget(destIndex); if (dest.Section != null) { if (isLinked) { dest.Section._manager.AddBranched(dest._index, CreateTarget(index)); } else { dest.Section._manager.AddBranched(dest._index, CreateTarget(index)); } } } else { Console.Write("Absolute branch at " + CreateTarget(index).ToString()); } }
public void RemoveBranched(int index, RelocationTarget target) { if (_linkedBranches.ContainsKey(index) && _linkedBranches[index] != null && _linkedBranches[index].Contains(target)) { _linkedBranches[index].Remove(target); } }
public void RemoveLinked(int index, RelocationTarget target) { if (_linkedCommands.ContainsKey(index) && _linkedCommands[index] != null && _linkedCommands[index].Contains(target)) { _linkedCommands[index].Remove(target); } }
public void SetTargetRelocation(RelocationTarget e) { if (e == null) { return; } _addend = (uint)e._index * 4; }
public void AddLinked(int index, RelocationTarget target) { if (_linkedCommands.ContainsKey(index)) { if (_linkedCommands[index] == null) { _linkedCommands[index] = new List <RelocationTarget> { target }; } else { _linkedCommands[index].Add(target); } } else { _linkedCommands.Add(index, new List <RelocationTarget> { target }); } }
private void LinkCommand(int index, bool isLinked) { if (_commands[index] == null) { return; } RelocationTarget cmdTarget = _commands[index].GetTargetRelocation(); ModuleSectionNode targetSection; if (cmdTarget != null && (targetSection = cmdTarget.Section) != null) { RelocationTarget thisRelocation = CreateTarget(index); if (isLinked) { targetSection._manager.AddLinked(cmdTarget._index, thisRelocation); } else { targetSection._manager.RemoveLinked(cmdTarget._index, thisRelocation); } } }
public void SetTargetRelocation(int index, RelocationTarget target) { if (_reference != null) { _reference._manager.SetTargetRelocation(index + _referenceIndex, target); return; } if (_targetRelocations.ContainsKey(index)) { if (target != null) { _targetRelocations[index] = target; } else { _targetRelocations.Remove(index); } } else if (target != null) { _targetRelocations.Add(index, target); } }
public override void OnPopulate() { _sections = new ModuleSectionNode[_numSections]; int prevOffset = RELHeader.Size + RELSectionEntry.Size * (int)_numSections; for (int i = 0; i < _numSections; i++) { RELSectionEntry entry = Header->SectionInfo[i]; ModuleSectionNode section = _sections[i] = new ModuleSectionNode(); int dataOffset = entry.Offset, dataSize = (int)(uint)entry._size; section._isCodeSection = entry.IsCodeSection; section._dataOffset = dataOffset; section._dataSize = entry._size; section.Initialize(this, WorkingUncompressed.Address + dataOffset, dataSize); if (dataOffset > 0) { section._dataAlign = dataOffset - prevOffset; prevOffset = dataOffset + dataSize; } } //Larger modules may take slightly longer to relocate //Use a background worker so the UI thread isn't suspended Action <object, DoWorkEventArgs> work = (object sender, DoWorkEventArgs e) => { Stopwatch watch = Stopwatch.StartNew(); ApplyRelocations(); //Scan for branches, add extra tags foreach (ModuleSectionNode s in Sections) { if (s.HasCode) { PPCOpCode code; buint * opPtr = s.BufferAddress; for (int i = 0; i < s._dataBuffer.Length / 4; i++) { if ((code = (uint)*opPtr++) is PPCBranch && !(code is PPCblr || code is PPCbctr)) { s._manager.LinkBranch(i, true); } } var cmds = s._manager.GetCommands(); foreach (var x in cmds) { RelocationTarget target = x.Value.GetTargetRelocation(); string value = null; if (target.Section != null && target._sectionID == 5 && !String.IsNullOrEmpty(value = target.Section._manager.GetString(target._index))) { s._manager.AddTag(x.Key, value); } } } } Sections[5].Populate(); watch.Stop(); Console.WriteLine("Took {0} seconds to relocate {1} module", (double)watch.ElapsedMilliseconds / 1000d, Name); }; using (BackgroundWorker b = new BackgroundWorker()) { b.DoWork += new DoWorkEventHandler(work); b.RunWorkerAsync(); } // Stage module conversion byte *bptr = (byte *)WorkingUncompressed.Address; int offset = findStageIDOffset(); _stageID = offset < 0 ? (byte?)null : bptr[offset]; if (nodeContainsString("stOnlineTrainning")) { // File must be online training room .rel file _itemIDs = new byte[OTrainItemOffsets.Length]; for (int i = 0; i < OTrainItemOffsets.Length; i++) { _itemIDs[i] = bptr[OTrainItemOffsets[i]]; } } }
private unsafe RELType ParseDeclaration(int index) { if (_types.TryGetValue(index, out RELType type)) { return(type); } RelCommand cmd = Manager.GetCommand(index); RelocationTarget target = cmd?.GetTargetRelocation(); if (target == null || target._sectionID != _objectSection.Index) { return(null); } uint relOffset = cmd.Apply(Manager.GetUint(index), 0); if (relOffset > _objectSection._dataOffset + _objectSection._dataSize) { return(null); } string name = new string((sbyte *)(_objectSection.Header + relOffset)); if (string.IsNullOrWhiteSpace(name)) { return(null); } type = new RELType(name); //Get inheritances, if any. cmd = Manager.GetCommand(index + 1); if (cmd != null) { for (RelocationTarget r = cmd.GetTargetRelocation(); r != null && (cmd = Manager.GetCommand(r._index)) != null; r._index += 2) { RelocationTarget inheritTarget = cmd.GetTargetRelocation(); RELType inheritance = ParseDeclaration(inheritTarget._index); if (inheritance != null) { InheritanceItemNode typeNode = new InheritanceItemNode(inheritance, Manager.GetUint(r._index + 1)); typeNode.Initialize(null, _objectSection.Header + r._index * 4, 0); type.Inheritance.Add(typeNode); inheritance.Inherited = true; } else { break; } } } Manager.AddTag(index, type.FormalName + " Declaration"); Manager.AddTag(index + 1, type.FormalName + "->Inheritances"); _types.Add(index, type); return(type); }
private unsafe RELObjectNode ParseObject(ref int rel) { RelCommand cmd = Manager.GetCommand(rel); RelocationTarget target = cmd?.GetTargetRelocation(); if (target == null || target._sectionID != _objectSection.Index) { return(null); } if (!_types.TryGetValue(target._index, out RELType declaration) || declaration.Inherited) { return(null); } RELObjectNode obj = null; foreach (RELObjectNode node in _objects) { if (node._name == declaration.FullName) { obj = node; break; } } if (obj == null) { obj = new RELObjectNode(declaration) { _parent = _objectSection }; _objectSection._children.Add(obj); new RELGroupNode { _name = "Inheritance" }.Parent = obj; foreach (InheritanceItemNode n in declaration.Inheritance) { n.Parent = obj.Children[0]; } new RELGroupNode { _name = "Functions" }.Parent = obj; } int baseRel = rel; RelCommand baseCmd = Manager.GetCommand(baseRel); int methodIndex = 0; int setIndex = 0; //Read object methods. while ((cmd = Manager.GetCommand(rel)) != null) { RelocationTarget t = cmd.GetTargetRelocation(); if (cmd.Apply(Manager.GetUint(rel), 0) != baseCmd.Apply(Manager.GetUint(baseRel), 0)) { string methodName = $"Function[{setIndex}][{methodIndex}]"; VoidPtr addr = null; if (t != null && t._moduleID == (_objectSection.Root as ModuleNode).ID) { addr = _objectSection.Root.Children[t._sectionID].WorkingUncompressed.Address + t._index * 4; } new RELMethodNode { _name = methodName, _cmd = cmd } .Initialize(obj.Children[1], addr, 0); methodIndex++; } else { if (Manager.GetUint(rel + 1) != 0) { setIndex++; } methodIndex = 0; rel++; } rel++; } Manager.AddTag(baseRel, obj.Type.FullName); _objects.Add(obj); return(obj); }