Simplified build struct
All checks were successful
/ test (push) Successful in 17s

This commit is contained in:
Eduard Urbach 2025-07-03 17:24:42 +02:00
parent 3f481d0bd3
commit 85cea5cbee
Signed by: akyoto
GPG key ID: 49226B848C78F6C8
15 changed files with 48 additions and 47 deletions

View file

@ -59,7 +59,7 @@ func (a *Assembler) Compile(b *build.Build) (code []byte, data []byte, libs dll.
} }
} }
x := exe.New(elf.HeaderEnd, b.FileAlign, b.MemoryAlign) x := exe.New(elf.HeaderEnd, b.FileAlign(), b.MemoryAlign())
x.InitSections(c.code, c.data, nil) x.InitSections(c.code, c.data, nil)
dataSectionOffset := x.Sections[1].MemoryOffset - x.Sections[0].MemoryOffset dataSectionOffset := x.Sections[1].MemoryOffset - x.Sections[0].MemoryOffset

View file

@ -7,18 +7,4 @@ const (
UnknownArch Arch = iota UnknownArch Arch = iota
ARM ARM
X86 X86
) )
// SetArch sets the architecture which also influences the default alignment.
func (build *Build) SetArch(arch Arch) {
build.Arch = arch
switch arch {
case ARM:
build.MemoryAlign = 0x4000
default:
build.MemoryAlign = 0x1000
}
build.FileAlign = build.MemoryAlign
}

View file

@ -2,11 +2,9 @@ package build
// Build describes the parameters for the "build" command. // Build describes the parameters for the "build" command.
type Build struct { type Build struct {
Files []string Files []string
Arch Arch Arch Arch
OS OS OS OS
FileAlign int Dry bool
MemoryAlign int ShowSSA bool
Dry bool
ShowSSA bool
} }

6
src/build/FileAlign.go Normal file
View file

@ -0,0 +1,6 @@
package build
// FileAlign returns the file alignment.
func (build *Build) FileAlign() int {
return build.MemoryAlign()
}

11
src/build/MemoryAlign.go Normal file
View file

@ -0,0 +1,11 @@
package build
// MemoryAlign returns the memory alignment.
func (build *Build) MemoryAlign() int {
switch build.Arch {
case ARM:
return 0x4000
default:
return 0x1000
}
}

View file

@ -12,9 +12,9 @@ func New(files ...string) *Build {
switch global.Arch { switch global.Arch {
case "amd64": case "amd64":
b.SetArch(X86) b.Arch = X86
case "arm64": case "arm64":
b.SetArch(ARM) b.Arch = ARM
} }
switch global.OS { switch global.OS {

View file

@ -46,9 +46,9 @@ func newBuildFromArgs(args []string) (*build.Build, error) {
switch args[i] { switch args[i] {
case "arm": case "arm":
b.SetArch(build.ARM) b.Arch = build.ARM
case "x86": case "x86":
b.SetArch(build.X86) b.Arch = build.X86
default: default:
return b, &invalidValueError{Value: args[i], Parameter: "arch"} return b, &invalidValueError{Value: args[i], Parameter: "arch"}
} }

View file

@ -18,7 +18,7 @@ type ELF struct {
// Write writes the ELF64 format to the given writer. // Write writes the ELF64 format to the given writer.
func Write(writer io.WriteSeeker, b *build.Build, codeBytes []byte, dataBytes []byte) { func Write(writer io.WriteSeeker, b *build.Build, codeBytes []byte, dataBytes []byte) {
x := exe.New(HeaderEnd, b.FileAlign, b.MemoryAlign) x := exe.New(HeaderEnd, b.FileAlign(), b.MemoryAlign())
x.InitSections(codeBytes, dataBytes) x.InitSections(codeBytes, dataBytes)
code := x.Sections[0] code := x.Sections[0]
data := x.Sections[1] data := x.Sections[1]
@ -52,7 +52,7 @@ func Write(writer io.WriteSeeker, b *build.Build, codeBytes []byte, dataBytes []
VirtualAddress: int64(code.MemoryOffset), VirtualAddress: int64(code.MemoryOffset),
SizeInFile: int64(len(code.Bytes)), SizeInFile: int64(len(code.Bytes)),
SizeInMemory: int64(len(code.Bytes)), SizeInMemory: int64(len(code.Bytes)),
Align: int64(b.MemoryAlign), Align: int64(b.MemoryAlign()),
}, },
DataHeader: ProgramHeader{ DataHeader: ProgramHeader{
Type: ProgramTypeLOAD, Type: ProgramTypeLOAD,
@ -61,7 +61,7 @@ func Write(writer io.WriteSeeker, b *build.Build, codeBytes []byte, dataBytes []
VirtualAddress: int64(data.MemoryOffset), VirtualAddress: int64(data.MemoryOffset),
SizeInFile: int64(len(data.Bytes)), SizeInFile: int64(len(data.Bytes)),
SizeInMemory: int64(len(data.Bytes)), SizeInMemory: int64(len(data.Bytes)),
Align: int64(b.MemoryAlign), Align: int64(b.MemoryAlign()),
}, },
} }

View file

@ -9,7 +9,7 @@ import (
) )
func TestWrite(t *testing.T) { func TestWrite(t *testing.T) {
elf.Write(&exe.Discard{}, &build.Build{Arch: build.ARM, FileAlign: 0x4000, MemoryAlign: 0x4000}, nil, nil) elf.Write(&exe.Discard{}, &build.Build{Arch: build.ARM}, nil, nil)
elf.Write(&exe.Discard{}, &build.Build{Arch: build.X86, FileAlign: 0x1000, MemoryAlign: 0x1000}, nil, nil) elf.Write(&exe.Discard{}, &build.Build{Arch: build.X86}, nil, nil)
elf.Write(&exe.Discard{}, &build.Build{Arch: build.UnknownArch, FileAlign: 0x1000, MemoryAlign: 0x1000}, nil, nil) elf.Write(&exe.Discard{}, &build.Build{Arch: build.UnknownArch}, nil, nil)
} }

View file

@ -28,11 +28,11 @@ func TestWriteFile(t *testing.T) {
env, err := compiler.Compile(b) env, err := compiler.Compile(b)
assert.Nil(t, err) assert.Nil(t, err)
b.SetArch(build.ARM) b.Arch = build.ARM
err = linker.WriteFile(b.Executable(), b, env) err = linker.WriteFile(b.Executable(), b, env)
assert.Nil(t, err) assert.Nil(t, err)
b.SetArch(build.X86) b.Arch = build.X86
err = linker.WriteFile(b.Executable(), b, env) err = linker.WriteFile(b.Executable(), b, env)
assert.Nil(t, err) assert.Nil(t, err)
} }

View file

@ -19,7 +19,7 @@ type MachO struct {
// Write writes the Mach-O format to the given writer. // Write writes the Mach-O format to the given writer.
func Write(writer io.WriteSeeker, b *build.Build, codeBytes []byte, dataBytes []byte) { func Write(writer io.WriteSeeker, b *build.Build, codeBytes []byte, dataBytes []byte) {
x := exe.New(HeaderEnd, b.FileAlign, b.MemoryAlign) x := exe.New(HeaderEnd, b.FileAlign(), b.MemoryAlign())
x.InitSections(codeBytes, dataBytes) x.InitSections(codeBytes, dataBytes)
code := x.Sections[0] code := x.Sections[0]
data := x.Sections[1] data := x.Sections[1]

View file

@ -9,7 +9,7 @@ import (
) )
func TestWrite(t *testing.T) { func TestWrite(t *testing.T) {
macho.Write(&exe.Discard{}, &build.Build{Arch: build.ARM, FileAlign: 0x4000, MemoryAlign: 0x4000}, nil, nil) macho.Write(&exe.Discard{}, &build.Build{Arch: build.ARM}, nil, nil)
macho.Write(&exe.Discard{}, &build.Build{Arch: build.X86, FileAlign: 0x1000, MemoryAlign: 0x1000}, nil, nil) macho.Write(&exe.Discard{}, &build.Build{Arch: build.X86}, nil, nil)
macho.Write(&exe.Discard{}, &build.Build{Arch: build.UnknownArch, FileAlign: 0x1000, MemoryAlign: 0x1000}, nil, nil) macho.Write(&exe.Discard{}, &build.Build{Arch: build.UnknownArch}, nil, nil)
} }

View file

@ -20,7 +20,7 @@ type EXE struct {
// Write writes the EXE file to the given writer. // Write writes the EXE file to the given writer.
func Write(writer io.WriteSeeker, b *build.Build, codeBytes []byte, dataBytes []byte, libs dll.List) { func Write(writer io.WriteSeeker, b *build.Build, codeBytes []byte, dataBytes []byte, libs dll.List) {
x := exe.New(HeaderEnd, b.FileAlign, b.MemoryAlign) x := exe.New(HeaderEnd, b.FileAlign(), b.MemoryAlign())
x.InitSections(codeBytes, dataBytes, nil) x.InitSections(codeBytes, dataBytes, nil)
code := x.Sections[0] code := x.Sections[0]
data := x.Sections[1] data := x.Sections[1]
@ -36,7 +36,7 @@ func Write(writer io.WriteSeeker, b *build.Build, codeBytes []byte, dataBytes []
imports.Bytes = buffer.Bytes() imports.Bytes = buffer.Bytes()
importDirectoryStart := dllDataStart + len(dllData) importDirectoryStart := dllDataStart + len(dllData)
importDirectorySize := DLLImportSize * len(dllImports) importDirectorySize := DLLImportSize * len(dllImports)
imageSize := exe.Align(imports.MemoryOffset+len(imports.Bytes), b.MemoryAlign) imageSize := exe.Align(imports.MemoryOffset+len(imports.Bytes), b.MemoryAlign())
if libs.Contains("user32") { if libs.Contains("user32") {
subSystem = IMAGE_SUBSYSTEM_WINDOWS_GUI subSystem = IMAGE_SUBSYSTEM_WINDOWS_GUI
@ -67,8 +67,8 @@ func Write(writer io.WriteSeeker, b *build.Build, codeBytes []byte, dataBytes []
AddressOfEntryPoint: uint32(code.MemoryOffset), AddressOfEntryPoint: uint32(code.MemoryOffset),
BaseOfCode: uint32(code.MemoryOffset), BaseOfCode: uint32(code.MemoryOffset),
ImageBase: BaseAddress, ImageBase: BaseAddress,
SectionAlignment: uint32(b.MemoryAlign), // power of 2, must be greater than or equal to FileAlignment SectionAlignment: uint32(b.MemoryAlign()), // power of 2, must be greater than or equal to FileAlignment
FileAlignment: uint32(b.FileAlign), // power of 2 FileAlignment: uint32(b.FileAlign()), // power of 2
MajorOperatingSystemVersion: 0x06, MajorOperatingSystemVersion: 0x06,
MinorOperatingSystemVersion: 0, MinorOperatingSystemVersion: 0,
MajorImageVersion: 0, MajorImageVersion: 0,

View file

@ -9,7 +9,7 @@ import (
) )
func TestWrite(t *testing.T) { func TestWrite(t *testing.T) {
pe.Write(&exe.Discard{}, &build.Build{Arch: build.ARM, FileAlign: 0x4000, MemoryAlign: 0x4000}, nil, nil, nil) pe.Write(&exe.Discard{}, &build.Build{Arch: build.ARM}, nil, nil, nil)
pe.Write(&exe.Discard{}, &build.Build{Arch: build.X86, FileAlign: 0x1000, MemoryAlign: 0x1000}, nil, nil, nil) pe.Write(&exe.Discard{}, &build.Build{Arch: build.X86}, nil, nil, nil)
pe.Write(&exe.Discard{}, &build.Build{Arch: build.UnknownArch, FileAlign: 0x1000, MemoryAlign: 0x1000}, nil, nil, nil) pe.Write(&exe.Discard{}, &build.Build{Arch: build.UnknownArch}, nil, nil, nil)
} }

View file

@ -17,7 +17,7 @@ func TestHelloExample(t *testing.T) {
b.OS = os b.OS = os
for _, arch := range architectures { for _, arch := range architectures {
b.SetArch(arch) b.Arch = arch
_, err := compiler.Compile(b) _, err := compiler.Compile(b)
assert.Nil(t, err) assert.Nil(t, err)
} }