Added optional section headers
This commit is contained in:
@ -28,16 +28,19 @@ func buildExecutable(args []string) (*build.Build, error) {
|
||||
|
||||
for i := 0; i < len(args); i++ {
|
||||
switch args[i] {
|
||||
case "-a", "--assembly":
|
||||
case "--assembly", "-a":
|
||||
config.ShowAssembly = true
|
||||
|
||||
case "-d", "--dry":
|
||||
case "--dry":
|
||||
config.Dry = true
|
||||
|
||||
case "-s", "--statistics":
|
||||
case "--sections":
|
||||
config.Sections = true
|
||||
|
||||
case "--statistics":
|
||||
config.ShowStatistics = true
|
||||
|
||||
case "-v", "--verbose":
|
||||
case "--verbose", "-v":
|
||||
config.ShowAssembly = true
|
||||
config.ShowStatistics = true
|
||||
|
||||
|
@ -14,11 +14,12 @@ func Help(w io.Writer, code int) int {
|
||||
Commands:
|
||||
|
||||
build [directory | file] build an executable from a file or directory
|
||||
--arch [arch] cross-compile for another CPU architecture [x86|arm]
|
||||
--arch [arch] cross-compile for CPU: [x86|arm]
|
||||
--assembly, -a show assembly instructions
|
||||
--dry, -d skip writing the executable to disk
|
||||
--os [os] cross-compile for another OS [linux|mac|windows]
|
||||
--statistics, -s show statistics
|
||||
--dry skip writing the executable to disk
|
||||
--os [os] cross-compile for OS: [linux|mac|windows]
|
||||
--sections add sections to the executable
|
||||
--statistics show statistics
|
||||
--verbose, -v show everything
|
||||
|
||||
run [directory | file] build and run the executable
|
||||
|
@ -28,7 +28,7 @@ func TestCLI(t *testing.T) {
|
||||
{[]string{"build", "../../examples/hello", "--dry", "--os", "mac"}, 0},
|
||||
{[]string{"build", "../../examples/hello", "--dry", "--os", "windows"}, 0},
|
||||
{[]string{"build", "../../examples/hello/hello.q", "--dry"}, 0},
|
||||
{[]string{"build", "../../examples/hello"}, 0},
|
||||
{[]string{"build", "../../examples/hello", "--sections"}, 0},
|
||||
{[]string{"run", "../../examples/hello", "--invalid"}, 2},
|
||||
{[]string{"run", "../../examples/hello"}, 0},
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ var (
|
||||
Dry bool // Skips writing the executable to disk.
|
||||
ShowAssembly bool // Shows assembly instructions at the end.
|
||||
ShowStatistics bool // Shows statistics at the end.
|
||||
Sections bool // Adds section headers to the executable.
|
||||
TargetArch Arch // Target architecture.
|
||||
TargetOS OS // Target platform.
|
||||
)
|
||||
@ -15,6 +16,7 @@ var (
|
||||
func Reset() {
|
||||
ShowAssembly = false
|
||||
ShowStatistics = false
|
||||
Sections = false
|
||||
Dry = false
|
||||
|
||||
switch runtime.GOARCH {
|
||||
|
35
src/elf/AddSections.go
Normal file
35
src/elf/AddSections.go
Normal file
@ -0,0 +1,35 @@
|
||||
package elf
|
||||
|
||||
// AddSections adds section headers to the ELF file.
|
||||
func (elf *ELF) AddSections() {
|
||||
elf.StringTable = []byte("\000.text\000.shstrtab\000")
|
||||
stringTableStart := elf.DataHeader.Offset + elf.DataHeader.SizeInFile
|
||||
sectionHeaderStart := stringTableStart + int64(len(elf.StringTable))
|
||||
|
||||
elf.SectionHeaders = []SectionHeader{
|
||||
{
|
||||
Type: SectionTypeNULL,
|
||||
},
|
||||
{
|
||||
NameIndex: 1,
|
||||
Type: SectionTypePROGBITS,
|
||||
Flags: SectionFlagsAllocate | SectionFlagsExecutable,
|
||||
VirtualAddress: elf.CodeHeader.VirtualAddress,
|
||||
Offset: elf.CodeHeader.Offset,
|
||||
SizeInFile: elf.CodeHeader.SizeInFile,
|
||||
Align: elf.CodeHeader.Align,
|
||||
},
|
||||
{
|
||||
NameIndex: 7,
|
||||
Type: SectionTypeSTRTAB,
|
||||
Offset: int64(stringTableStart),
|
||||
SizeInFile: int64(len(elf.StringTable)),
|
||||
Align: 1,
|
||||
},
|
||||
}
|
||||
|
||||
elf.SectionHeaderEntrySize = SectionHeaderSize
|
||||
elf.SectionHeaderEntryCount = int16(len(elf.SectionHeaders))
|
||||
elf.SectionHeaderOffset = int64(sectionHeaderStart)
|
||||
elf.SectionNameStringTableIndex = 2
|
||||
}
|
@ -14,8 +14,10 @@ const HeaderEnd = HeaderSize + ProgramHeaderSize*2
|
||||
// ELF represents an ELF file.
|
||||
type ELF struct {
|
||||
Header
|
||||
CodeHeader ProgramHeader
|
||||
DataHeader ProgramHeader
|
||||
CodeHeader ProgramHeader
|
||||
DataHeader ProgramHeader
|
||||
SectionHeaders []SectionHeader
|
||||
StringTable []byte
|
||||
}
|
||||
|
||||
// Write writes the ELF64 format to the given writer.
|
||||
@ -77,14 +79,20 @@ func Write(writer io.Writer, code []byte, data []byte) {
|
||||
},
|
||||
}
|
||||
|
||||
if config.Sections {
|
||||
elf.AddSections()
|
||||
}
|
||||
|
||||
binary.Write(writer, binary.LittleEndian, &elf.Header)
|
||||
binary.Write(writer, binary.LittleEndian, &elf.CodeHeader)
|
||||
binary.Write(writer, binary.LittleEndian, &elf.DataHeader)
|
||||
writer.Write(bytes.Repeat([]byte{0x00}, codePadding))
|
||||
writer.Write(code)
|
||||
writer.Write(bytes.Repeat([]byte{0x00}, dataPadding))
|
||||
writer.Write(data)
|
||||
|
||||
if len(data) > 0 {
|
||||
writer.Write(bytes.Repeat([]byte{0x00}, dataPadding))
|
||||
writer.Write(data)
|
||||
if config.Sections {
|
||||
writer.Write(elf.StringTable)
|
||||
binary.Write(writer, binary.LittleEndian, &elf.SectionHeaders)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user