mirror of
https://wiilab.wiimart.org/wiimart/WiiMart-Patcher
synced 2025-09-03 20:11:19 +02:00
Support b/bl instructions
This commit is contained in:
parent
4eb530b71e
commit
c8559722ea
@ -54,7 +54,7 @@ func generateTag(tag Tag, tagContents []byte) []byte {
|
||||
byte(tag),
|
||||
}
|
||||
// Tag length
|
||||
contents = append(contents, toLength(len(tagContents))...)
|
||||
contents = append(contents, fourByte(uint32(len(tagContents)))...)
|
||||
// Tag contents
|
||||
contents = append(contents, tagContents...)
|
||||
|
||||
@ -120,9 +120,9 @@ func generateOperaCertStore() {
|
||||
file.Write(append(header, caCertTag...))
|
||||
}
|
||||
|
||||
// toLength returns 4 bytes, suitable for the given length.
|
||||
func toLength(value int) []byte {
|
||||
// fourByte returns 4 bytes, suitable for the given length.
|
||||
func fourByte(value uint32) []byte {
|
||||
holder := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(holder, uint32(value))
|
||||
binary.BigEndian.PutUint32(holder, value)
|
||||
return holder
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ func LoadCustomCA() PatchSet {
|
||||
LWZ(R3, 0xac, R28),
|
||||
LWZ(R5, 0xc4, R28),
|
||||
// SSLSetRootCA(ssl_fd, ca_cert, cert_index)
|
||||
Instruction{0x48, 0x01, 0x59, 0x49},
|
||||
BL(0x800acae4, 0x800c242c),
|
||||
|
||||
// Check if successful
|
||||
CMPWI(R3, 0),
|
||||
@ -46,7 +46,7 @@ func LoadCustomCA() PatchSet {
|
||||
// Return error -1004 if failed
|
||||
LI(R3, 0xfc14),
|
||||
// b FUNCTION_PROLOG
|
||||
Instruction{0x48, 0x00, 0x00, 0xbc},
|
||||
B(0x800acaf4, 0x800acbb0),
|
||||
|
||||
// ----
|
||||
|
||||
@ -56,7 +56,7 @@ func LoadCustomCA() PatchSet {
|
||||
LWZ(R3, 0xac, R28),
|
||||
LWZ(R4, 0xd8, R28),
|
||||
// SSLSetBuiltinRootCA(ssl_fd, cert_index)
|
||||
Instruction{0x48, 0x01, 0x5a, 0x75},
|
||||
BL(0x800acb00, 0x800c2574),
|
||||
|
||||
// Check if successful
|
||||
CMPWI(R3, 0),
|
||||
@ -66,7 +66,7 @@ func LoadCustomCA() PatchSet {
|
||||
// Return error -1004 if failed
|
||||
LI(R3, 0xfc14),
|
||||
// b FUNCTION_PROLOG
|
||||
Instruction{0x48, 0x00, 0x00, 0xa0},
|
||||
B(0x800acb10, 0x800acbb0),
|
||||
}.toBytes(),
|
||||
After: Instructions{
|
||||
// Our certificate is present at 0x802e97b8.
|
||||
@ -84,7 +84,7 @@ func LoadCustomCA() PatchSet {
|
||||
LWZ(R3, 0xac, R28),
|
||||
|
||||
// SSLSetRootCA(ssl_fd, ca_cert, cert_index)
|
||||
Instruction{0x48, 0x01, 0x59, 0x49},
|
||||
BL(0x800acae4, 0x800c242c),
|
||||
|
||||
// Check for errors
|
||||
CMPWI(R3, 0),
|
||||
@ -94,7 +94,7 @@ func LoadCustomCA() PatchSet {
|
||||
// Return error -1004 if failed
|
||||
LI(R3, 0xfc14),
|
||||
// b FUNCTION_PROLOG
|
||||
Instruction{0x48, 0x00, 0x00, 0xbc},
|
||||
B(0x800acaf4, 0x800acbb0),
|
||||
|
||||
// NOP the rest in order to allow execution to continue.
|
||||
NOP(), NOP(), NOP(), NOP(), NOP(), NOP(), NOP(),
|
||||
|
35
powerpc.go
35
powerpc.go
@ -1,5 +1,15 @@
|
||||
package main
|
||||
|
||||
// uint24 returns
|
||||
func uint24(num uint32) [3]byte {
|
||||
if num > 0x00FFFFFF {
|
||||
panic("invalid uint24 passed")
|
||||
}
|
||||
|
||||
result := fourByte(num)
|
||||
return [3]byte{result[1], result[2], result[3]}
|
||||
}
|
||||
|
||||
// Instruction represents a 4-byte PowerPC instruction.
|
||||
type Instruction [4]byte
|
||||
|
||||
@ -102,3 +112,28 @@ func MFSPR() Instruction {
|
||||
func STWU(rS Register, rA Register, offset uint16) Instruction {
|
||||
return EncodeInstrDForm(37, rS, rA, offset)
|
||||
}
|
||||
|
||||
// calcDestination determines the proper offset from a given
|
||||
// calling address and target address.
|
||||
func calcDestination(from uint, target uint) [3]byte {
|
||||
// TODO(spotlightishere): Handle negative offsets properly
|
||||
offset := target - from
|
||||
|
||||
// Sign-extend by two bytes
|
||||
calc := uint32(offset >> 2)
|
||||
return uint24(calc)
|
||||
}
|
||||
|
||||
// BL represents the bl PowerPC instruction.
|
||||
// It calculates the offset from the given current address and the given
|
||||
// target address, saving the current address in the link register. It then branches.
|
||||
func BL(current uint, target uint) Instruction {
|
||||
return EncodeInstrIForm(18, calcDestination(current, target), false, true)
|
||||
}
|
||||
|
||||
// B represents the b PowerPC instruction.
|
||||
// It calculates the offset from the given current address
|
||||
// and the given target address, and then branches.
|
||||
func B(current uint, target uint) Instruction {
|
||||
return EncodeInstrIForm(18, calcDestination(current, target), false, false)
|
||||
}
|
||||
|
@ -116,6 +116,42 @@ func EncodeInstrDForm(opcode byte, rT Register, rA Register, value uint16) Instr
|
||||
return Instruction{firstInstr, secondInstr, valByte[0], valByte[1]}
|
||||
}
|
||||
|
||||
// EncodeInstrIForm handles encoding a given opcode, LI, AA and LK.
|
||||
// I-form assumes:
|
||||
// - 6 bits for the opcode
|
||||
// - 24 bits for LI
|
||||
// - 1 bit for absolute (AA)
|
||||
// - 1 bit for should store in link register (LK)
|
||||
func EncodeInstrIForm(opcode byte, LI [3]byte, AA bool, LK bool) Instruction {
|
||||
opBits := getBits(opcode)
|
||||
liOne := getBits(LI[0])
|
||||
liTwo := getBits(LI[1])
|
||||
liThree := getBits(LI[2])
|
||||
|
||||
instr := [4]Bits{
|
||||
{
|
||||
// We need the upper six bits for our opcode.
|
||||
opBits[2], opBits[3], opBits[4], opBits[5], opBits[6], opBits[7],
|
||||
// Otherwise, copy LI as-is.
|
||||
liOne[0], liOne[1],
|
||||
},
|
||||
{
|
||||
liOne[2], liOne[3], liOne[4], liOne[5], liOne[6], liOne[7], liTwo[0], liTwo[1],
|
||||
},
|
||||
{
|
||||
liTwo[2], liTwo[3], liTwo[4], liTwo[5], liTwo[6], liTwo[7], liThree[0], liThree[1],
|
||||
},
|
||||
{
|
||||
liThree[2], liThree[3], liThree[4], liThree[5], liThree[6], liThree[7],
|
||||
// Copy AA and LK as-is.
|
||||
AA,
|
||||
LK,
|
||||
},
|
||||
}
|
||||
|
||||
return Instruction{instr[0].getByte(), instr[1].getByte(), instr[2].getByte(), instr[3].getByte()}
|
||||
}
|
||||
|
||||
// twoByte converts a uint16 to two big-endian bytes.
|
||||
func twoByte(passed uint16) [2]byte {
|
||||
result := make([]byte, 2)
|
||||
|
Loading…
x
Reference in New Issue
Block a user