public override bool Apply(KamekFile file) { switch (Id) { case Ids.Rel24: if ((Address.IsAbsolute && Target.IsAbsolute) || (Address.IsRelative && Target.IsRelative)) { long delta = Target - Address; uint insn = file.ReadUInt32(Address) & 0xFC000003; insn |= ((uint)delta & 0x3FFFFFC); file.WriteUInt32(Address, insn); return(true); } break; case Ids.Addr32: if (Target.IsAbsolute) { file.WriteUInt32(Address, Target.Value); return(true); } break; case Ids.Addr16Lo: if (Target.IsAbsolute) { file.WriteUInt16(Address, (ushort)(Target.Value & 0xFFFF)); return(true); } break; case Ids.Addr16Hi: if (Target.IsAbsolute) { file.WriteUInt16(Address, (ushort)(Target.Value >> 16)); return(true); } break; case Ids.Addr16Ha: if (Target.IsAbsolute) { ushort v = (ushort)(Target.Value >> 16); if ((Target.Value & 0x8000) == 0x8000) { v++; } file.WriteUInt16(Address, v); return(true); } break; default: throw new NotImplementedException("unrecognised relocation type"); } return(false); }
public override bool Apply(KamekFile file) { switch (Id) { case Ids.Rel24: if (Address.Type == WordType.AbsoluteAddr && Target.Type == WordType.AbsoluteAddr) { long delta = Target - Address; uint insn = file.ReadUInt32(Address) & 0xFC000003; insn |= ((uint)delta & 0x3FFFFFC); file.WriteUInt32(Address, insn); return true; } break; case Ids.Addr32: if (Target.IsAbsolute) { file.WriteUInt32(Address, Target.Value); return true; } break; case Ids.Addr16Lo: if (Target.IsAbsolute) { file.WriteUInt16(Address, (ushort)(Target.Value & 0xFFFF)); return true; } break; case Ids.Addr16Hi: if (Target.IsAbsolute) { file.WriteUInt16(Address, (ushort)(Target.Value >> 16)); return true; } break; case Ids.Addr16Ha: if (Target.IsAbsolute) { ushort v = (ushort)(Target.Value >> 16); if ((Target.Value & 0x8000) == 0x8000) v++; file.WriteUInt16(Address, v); return true; } break; default: throw new NotImplementedException("unrecognised relocation type"); } return false; }
public override bool Apply(KamekFile file) { // Do some reasonableness checks. // For now, we'll only work on functions ending in a blr var functionSize = file.QuerySymbolSize(Address); if (functionSize < 4) { throw new InvalidOperationException("Function too small!"); } var functionEnd = Address + (functionSize - 4); if (file.ReadUInt32(functionEnd) != 0x4E800020) { throw new InvalidOperationException("Function does not end in blr"); } // Just to be extra sure, are there any other returns in this function? for (var check = Address; check < functionEnd; check += 4) { var insn = file.ReadUInt32(check); if ((insn & 0xFC00FFFF) == 0x4C000020) { throw new InvalidOperationException("Function contains a return partway through"); } } EndAddress = functionEnd; if (EndAddress.IsAbsolute && Target.IsAbsolute && file.Contains(Address)) { file.WriteUInt32(EndAddress, GenerateInstruction()); return(true); } return(false); }