Implemented dynamic section alignment
This commit is contained in:
@ -18,7 +18,7 @@ func Finalize(a asm.Assembler, dlls dll.List) ([]byte, []byte) {
|
||||
code: make([]byte, 0, len(a.Instructions)*8),
|
||||
codeLabels: make(map[string]Address, 32),
|
||||
codePointers: make([]*pointer, 0, len(a.Instructions)*8),
|
||||
codeStart: codeOffset(),
|
||||
codeStart: uint32(codeOffset()),
|
||||
data: data,
|
||||
dataLabels: dataLabels,
|
||||
dlls: dlls,
|
||||
|
@ -9,8 +9,8 @@ import (
|
||||
)
|
||||
|
||||
// codeOffset returns the file offset of the code section.
|
||||
func codeOffset() Address {
|
||||
headerEnd := Address(0)
|
||||
func codeOffset() int {
|
||||
headerEnd := 0
|
||||
|
||||
switch config.TargetOS {
|
||||
case config.Linux:
|
||||
|
@ -19,15 +19,14 @@ func (c *compiler) move(x asm.Instruction) {
|
||||
start := Address(len(c.code))
|
||||
c.code = x86.LoadAddress(c.code, operands.Register, 0x00_00_00_00)
|
||||
end := Address(len(c.code))
|
||||
size := uint32(4)
|
||||
position := end - size
|
||||
position := end - 4
|
||||
opSize := position - start
|
||||
|
||||
if strings.HasPrefix(operands.Label, "data ") {
|
||||
c.dataPointers = append(c.dataPointers, &pointer{
|
||||
Position: position,
|
||||
OpSize: uint8(opSize),
|
||||
Size: uint8(size),
|
||||
Size: uint8(4),
|
||||
Resolve: func() Address {
|
||||
destination, exists := c.dataLabels[operands.Label]
|
||||
|
||||
@ -44,7 +43,7 @@ func (c *compiler) move(x asm.Instruction) {
|
||||
c.codePointers = append(c.codePointers, &pointer{
|
||||
Position: position,
|
||||
OpSize: uint8(opSize),
|
||||
Size: uint8(size),
|
||||
Size: uint8(4),
|
||||
Resolve: func() Address {
|
||||
destination, exists := c.codeLabels[operands.Label]
|
||||
|
||||
|
@ -77,7 +77,7 @@ restart:
|
||||
}
|
||||
}
|
||||
|
||||
sections := exe.MakeSections(int(codeOffset()), c.code, c.data, nil)
|
||||
sections := exe.MakeSections(codeOffset(), c.code, c.data, nil)
|
||||
data := sections[1]
|
||||
c.dataStart = Address(data.MemoryOffset)
|
||||
|
||||
|
@ -53,9 +53,9 @@ func buildExecutable(args []string) (*build.Build, error) {
|
||||
|
||||
switch args[i] {
|
||||
case "arm":
|
||||
config.TargetArch = config.ARM
|
||||
config.SetTargetArch(config.ARM)
|
||||
case "x86":
|
||||
config.TargetArch = config.X86
|
||||
config.SetTargetArch(config.X86)
|
||||
default:
|
||||
return b, &InvalidValueError{Value: args[i], Parameter: "arch"}
|
||||
}
|
||||
@ -91,6 +91,10 @@ func buildExecutable(args []string) (*build.Build, error) {
|
||||
return b, &InvalidValueError{Value: runtime.GOOS, Parameter: "os"}
|
||||
}
|
||||
|
||||
if config.TargetArch == config.UnknownArch {
|
||||
return b, &InvalidValueError{Value: runtime.GOARCH, Parameter: "arch"}
|
||||
}
|
||||
|
||||
if len(b.Files) == 0 {
|
||||
b.Files = append(b.Files, ".")
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import "runtime"
|
||||
var (
|
||||
ConstantFold bool // Calculates the result of operations on constants at compile time.
|
||||
Dry bool // Skips writing the executable to disk.
|
||||
FileAlign int // FileAlign is the alignment of the sections in the file.
|
||||
MemoryAlign int // MemoryAlign is the alignment of the sections in memory.
|
||||
ShowAssembly bool // Shows assembly instructions at the end.
|
||||
ShowStatistics bool // Shows statistics at the end.
|
||||
Sections bool // Adds section headers to the executable.
|
||||
@ -21,11 +23,11 @@ func Reset() {
|
||||
|
||||
switch runtime.GOARCH {
|
||||
case "amd64":
|
||||
TargetArch = X86
|
||||
SetTargetArch(X86)
|
||||
case "arm64":
|
||||
TargetArch = ARM
|
||||
SetTargetArch(ARM)
|
||||
default:
|
||||
TargetArch = UnknownArch
|
||||
SetTargetArch(UnknownArch)
|
||||
}
|
||||
|
||||
switch runtime.GOOS {
|
||||
@ -46,3 +48,16 @@ func Reset() {
|
||||
func Optimize(enable bool) {
|
||||
ConstantFold = enable
|
||||
}
|
||||
|
||||
// SetTargetArch changes the target architecture and updates the alignment.
|
||||
func SetTargetArch(arch Arch) {
|
||||
TargetArch = arch
|
||||
|
||||
if TargetArch == ARM {
|
||||
FileAlign = 0x4000
|
||||
MemoryAlign = 0x4000
|
||||
} else {
|
||||
FileAlign = 0x1000
|
||||
MemoryAlign = 0x1000
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,4 @@ const (
|
||||
|
||||
// The base address is the virtual address for our ELF file.
|
||||
BaseAddress = 0x40 * MinAddress
|
||||
|
||||
// FileAlign is the alignment of the sections in the file.
|
||||
FileAlign = 0x4000
|
||||
|
||||
// MemoryAlign is the alignment of the sections in memory and it must be a multiple of the page size.
|
||||
MemoryAlign = 0x4000
|
||||
)
|
||||
|
@ -56,7 +56,7 @@ func Write(writer io.Writer, codeBytes []byte, dataBytes []byte) {
|
||||
VirtualAddress: int64(config.BaseAddress + code.MemoryOffset),
|
||||
SizeInFile: int64(len(code.Bytes)),
|
||||
SizeInMemory: int64(len(code.Bytes)),
|
||||
Align: config.MemoryAlign,
|
||||
Align: int64(config.MemoryAlign),
|
||||
},
|
||||
DataHeader: ProgramHeader{
|
||||
Type: ProgramTypeLOAD,
|
||||
@ -65,7 +65,7 @@ func Write(writer io.Writer, codeBytes []byte, dataBytes []byte) {
|
||||
VirtualAddress: int64(config.BaseAddress + data.MemoryOffset),
|
||||
SizeInFile: int64(len(data.Bytes)),
|
||||
SizeInMemory: int64(len(data.Bytes)),
|
||||
Align: config.MemoryAlign,
|
||||
Align: int64(config.MemoryAlign),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -73,8 +73,8 @@ func Write(writer io.Writer, codeBytes []byte, dataBytes []byte, dlls dll.List)
|
||||
AddressOfEntryPoint: uint32(code.MemoryOffset),
|
||||
BaseOfCode: uint32(code.MemoryOffset),
|
||||
ImageBase: config.BaseAddress,
|
||||
SectionAlignment: config.MemoryAlign, // power of 2, must be greater than or equal to FileAlignment
|
||||
FileAlignment: config.FileAlign, // power of 2
|
||||
SectionAlignment: uint32(config.MemoryAlign), // power of 2, must be greater than or equal to FileAlignment
|
||||
FileAlignment: uint32(config.FileAlign), // power of 2
|
||||
MajorOperatingSystemVersion: 0x06,
|
||||
MinorOperatingSystemVersion: 0,
|
||||
MajorImageVersion: 0,
|
||||
|
Reference in New Issue
Block a user