Files
ipsw/pkg/devicetree/pmgr.go

142 lines
3.2 KiB
Go

package devicetree
import (
"bytes"
"encoding/binary"
"encoding/json"
"fmt"
"io"
"strings"
"github.com/blacktop/go-macho/types"
)
// CREDIT: https://github.com/Siguza/dt/blob/master/src/pmgr.c
type pmgr_reg struct {
Addr uint64 `json:"addr,omitempty"`
Size uint64 `json:"size,omitempty"`
}
type pmgr_map struct {
Reg uint32 `json:"reg,omitempty"`
Off uint32 `json:"off,omitempty"`
Unk uint32 `json:"unk,omitempty"`
}
func parsePmgrMap(value []byte) any {
var maps []pmgr_map
r := bytes.NewReader(value)
for {
var m pmgr_map
err := binary.Read(r, binary.LittleEndian, &m)
if err != nil {
if err == io.EOF {
break
}
return parseValue(value)
}
maps = append(maps, m)
}
return maps
}
type pmgr_dev struct {
FlagAndID1 uint32
Alias uint32
IndexAndMap uint32
Unk1 uint32
Unk2 uint32
Unk3 uint32
UnkAndID2 uint32
Unk4 uint32
Name [0x10]byte
}
func (p pmgr_dev) Flag() uint8 {
return uint8(types.ExtractBits(uint64(p.FlagAndID1), 0, 8))
}
func (p pmgr_dev) ID1() uint8 {
return uint8(types.ExtractBits(uint64(p.FlagAndID1), 24, 8))
}
func (p pmgr_dev) Index() uint8 {
return uint8(types.ExtractBits(uint64(p.IndexAndMap), 16, 8))
}
func (p pmgr_dev) Map() uint8 {
return uint8(types.ExtractBits(uint64(p.IndexAndMap), 24, 8))
}
func (p pmgr_dev) ID2() uint16 {
return uint16(types.ExtractBits(uint64(p.UnkAndID2), 16, 16))
}
func (p pmgr_dev) String(padding int) string {
return fmt.Sprintf(
"%sname: \"%s\"\n"+
"%sindex: %d\n"+
"%sflag: %d\n"+
"%sid1: %d\n"+
"%sid2: %d\n"+
"%salias: %d\n"+
"%smap: %d\n"+
"%sunk1: %d\n"+
"%sunk2: %d\n"+
"%sunk3: %d\n"+
"%sunk4: %d",
strings.Repeat(" ", padding), string(bytes.TrimRight(p.Name[:], "\x00")),
strings.Repeat(" ", padding), p.Index(),
strings.Repeat(" ", padding), p.Flag(),
strings.Repeat(" ", padding), p.ID1(),
strings.Repeat(" ", padding), p.ID2(),
strings.Repeat(" ", padding), p.Alias,
strings.Repeat(" ", padding), p.Map(),
strings.Repeat(" ", padding), p.Unk1,
strings.Repeat(" ", padding), p.Unk2,
strings.Repeat(" ", padding), p.Unk3,
strings.Repeat(" ", padding), p.Unk4,
)
}
func (p *pmgr_dev) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
Flag uint8 `json:"flag,omitempty"`
ID1 uint8 `json:"id1,omitempty"`
Alias uint32 `json:"alias,omitempty"`
Index uint8 `json:"index"`
Map uint8 `json:"map,omitempty"`
Unk1 uint32 `json:"unk1,omitempty"`
Unk2 uint32 `json:"unk2,omitempty"`
Unk3 uint32 `json:"unk3,omitempty"`
ID2 uint16 `json:"id2,omitempty"`
Unk4 uint32 `json:"unk4,omitempty"`
Name string `json:"name,omitempty"`
}{
Flag: p.Flag(),
ID1: p.ID1(),
Alias: p.Alias,
Index: p.Index(),
Map: p.Map(),
Unk1: p.Unk1,
Unk2: p.Unk2,
Unk3: p.Unk3,
ID2: p.ID2(),
Unk4: p.Unk4,
Name: string(bytes.TrimRight(p.Name[:], "\x00")),
})
}
func parsePmgrDevices(value []byte) any {
var devs []pmgr_dev
r := bytes.NewReader(value)
for {
var d pmgr_dev
err := binary.Read(r, binary.LittleEndian, &d)
if err != nil {
if err == io.EOF {
break
}
return parseValue(value)
}
devs = append(devs, d)
}
return devs
}