Added exe package to manage sections

This commit is contained in:
2025-03-08 22:14:24 +01:00
parent 919d94e0f4
commit b67f3b0977
16 changed files with 207 additions and 134 deletions

View File

@ -6,7 +6,7 @@ import (
"io"
"git.urbach.dev/cli/q/src/config"
"git.urbach.dev/cli/q/src/fs"
"git.urbach.dev/cli/q/src/exe"
)
const (
@ -24,22 +24,11 @@ type MachO struct {
}
// Write writes the Mach-O format to the given writer.
func Write(writer io.Writer, code []byte, data []byte) {
var (
codeStart, codePadding = fs.Align(HeaderEnd, config.Align)
dataStart, dataPadding = fs.Align(codeStart+len(code), config.Align)
arch CPU
microArch uint32
)
switch config.TargetArch {
case config.ARM:
arch = CPU_ARM_64
microArch = CPU_SUBTYPE_ARM64_ALL | 0x80000000
case config.X86:
arch = CPU_X86_64
microArch = CPU_SUBTYPE_X86_64_ALL | 0x80000000
}
func Write(writer io.Writer, codeBytes []byte, dataBytes []byte) {
sections := exe.MakeSections(HeaderEnd, codeBytes, dataBytes)
code := sections[0]
data := sections[1]
arch, microArch := cpu()
m := &MachO{
Header: Header{
@ -70,9 +59,9 @@ func Write(writer io.Writer, code []byte, data []byte) {
Length: Segment64Size,
Name: [16]byte{'_', '_', 'T', 'E', 'X', 'T'},
Address: config.BaseAddress,
SizeInMemory: uint64(codeStart + len(code)),
SizeInMemory: uint64(code.MemoryOffset + len(code.Bytes)),
Offset: 0,
SizeInFile: uint64(codeStart + len(code)),
SizeInFile: uint64(code.FileOffset + len(code.Bytes)),
NumSections: 0,
Flag: 0,
MaxProt: ProtReadable | ProtExecutable,
@ -82,10 +71,10 @@ func Write(writer io.Writer, code []byte, data []byte) {
LoadCommand: LcSegment64,
Length: Segment64Size,
Name: [16]byte{'_', '_', 'D', 'A', 'T', 'A'},
Address: uint64(config.BaseAddress + dataStart),
SizeInMemory: uint64(len(data)),
Offset: uint64(dataStart),
SizeInFile: uint64(len(data)),
Address: uint64(config.BaseAddress + data.MemoryOffset),
SizeInMemory: uint64(len(data.Bytes)),
Offset: uint64(data.FileOffset),
SizeInFile: uint64(len(data.Bytes)),
NumSections: 0,
Flag: 0,
MaxProt: ProtReadable,
@ -113,7 +102,7 @@ func Write(writer io.Writer, code []byte, data []byte) {
0, 0,
0, 0,
0, 0,
uint32(config.BaseAddress + codeStart), 0,
uint32(config.BaseAddress + code.MemoryOffset), 0,
0, 0,
0, 0,
0, 0,
@ -127,8 +116,8 @@ func Write(writer io.Writer, code []byte, data []byte) {
binary.Write(writer, binary.LittleEndian, &m.CodeHeader)
binary.Write(writer, binary.LittleEndian, &m.DataHeader)
binary.Write(writer, binary.LittleEndian, &m.UnixThread)
writer.Write(bytes.Repeat([]byte{0x00}, codePadding))
writer.Write(code)
writer.Write(bytes.Repeat([]byte{0x00}, dataPadding))
writer.Write(data)
writer.Write(bytes.Repeat([]byte{0x00}, code.Padding))
writer.Write(code.Bytes)
writer.Write(bytes.Repeat([]byte{0x00}, data.Padding))
writer.Write(data.Bytes)
}

15
src/macho/cpu.go Normal file
View File

@ -0,0 +1,15 @@
package macho
import "git.urbach.dev/cli/q/src/config"
// cpu returns the CPU architecture used in the Mach-O header.
func cpu() (CPU, uint32) {
switch config.TargetArch {
case config.ARM:
return CPU_ARM_64, CPU_SUBTYPE_ARM64_ALL | 0x80000000
case config.X86:
return CPU_X86_64, CPU_SUBTYPE_X86_64_ALL | 0x80000000
default:
panic("unknown architecture")
}
}