This commit is contained in:
parent
3f481d0bd3
commit
85cea5cbee
15 changed files with 48 additions and 47 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -8,17 +8,3 @@ const (
|
||||||
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
|
|
||||||
}
|
|
|
@ -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
6
src/build/FileAlign.go
Normal 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
11
src/build/MemoryAlign.go
Normal 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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 {
|
||||||
|
|
|
@ -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"}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
|
@ -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)
|
||||||
}
|
}
|
|
@ -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]
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue