Improved documentation
This commit is contained in:
parent
9df899cb52
commit
948d499231
@ -4,12 +4,12 @@ import "maps"
|
|||||||
|
|
||||||
// Assembler contains a list of instructions.
|
// Assembler contains a list of instructions.
|
||||||
type Assembler struct {
|
type Assembler struct {
|
||||||
Instructions []Instruction
|
|
||||||
Data map[string][]byte
|
Data map[string][]byte
|
||||||
|
Instructions []Instruction
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge combines the contents of this assembler with another one.
|
// Merge combines the contents of this assembler with another one.
|
||||||
func (a *Assembler) Merge(b Assembler) {
|
func (a *Assembler) Merge(b Assembler) {
|
||||||
a.Instructions = append(a.Instructions, b.Instructions...)
|
|
||||||
maps.Copy(a.Data, b.Data)
|
maps.Copy(a.Data, b.Data)
|
||||||
|
a.Instructions = append(a.Instructions, b.Instructions...)
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,8 @@ import (
|
|||||||
|
|
||||||
// RegisterLabel operates with a register and a label.
|
// RegisterLabel operates with a register and a label.
|
||||||
type RegisterLabel struct {
|
type RegisterLabel struct {
|
||||||
Register cpu.Register
|
|
||||||
Label string
|
Label string
|
||||||
|
Register cpu.Register
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a human readable version.
|
// String returns a human readable version.
|
||||||
|
@ -1,10 +1,17 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MinAddress = 0x10000
|
// This is the absolute virtual minimum address we can load a program at, see `sysctl vm.mmap_min_addr`.
|
||||||
|
MinAddress = 0x10000
|
||||||
|
|
||||||
|
// The base address is the virtual address for our ELF file.
|
||||||
BaseAddress = 0x40 * MinAddress
|
BaseAddress = 0x40 * MinAddress
|
||||||
CodeOffset = 0x80
|
|
||||||
Align = 0x10
|
// The code offset is the offset of the executable machine code within the file.
|
||||||
|
CodeOffset = 64 + 56 + 56
|
||||||
|
|
||||||
|
// Align decides the alignment of the sections and it must be a multiple of the page size.
|
||||||
|
Align = 0x1000
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -11,11 +11,12 @@ import (
|
|||||||
// ELF represents an ELF file.
|
// ELF represents an ELF file.
|
||||||
type ELF struct {
|
type ELF struct {
|
||||||
Header
|
Header
|
||||||
CodeHeader ProgramHeader
|
CodeHeader ProgramHeader
|
||||||
PadCode []byte
|
DataHeader ProgramHeader
|
||||||
Code []byte
|
CodePadding []byte
|
||||||
PadData []byte
|
Code []byte
|
||||||
Data []byte
|
DataPadding []byte
|
||||||
|
Data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new ELF binary.
|
// New creates a new ELF binary.
|
||||||
@ -24,7 +25,7 @@ func New(code []byte, data []byte) *ELF {
|
|||||||
dataPadding := Padding(dataOffset, config.Align)
|
dataPadding := Padding(dataOffset, config.Align)
|
||||||
dataOffset += dataPadding
|
dataOffset += dataPadding
|
||||||
|
|
||||||
elf := &ELF{
|
return &ELF{
|
||||||
Header: Header{
|
Header: Header{
|
||||||
Magic: [4]byte{0x7F, 'E', 'L', 'F'},
|
Magic: [4]byte{0x7F, 'E', 'L', 'F'},
|
||||||
Class: 2,
|
Class: 2,
|
||||||
@ -41,7 +42,7 @@ func New(code []byte, data []byte) *ELF {
|
|||||||
Flags: 0,
|
Flags: 0,
|
||||||
Size: HeaderSize,
|
Size: HeaderSize,
|
||||||
ProgramHeaderEntrySize: ProgramHeaderSize,
|
ProgramHeaderEntrySize: ProgramHeaderSize,
|
||||||
ProgramHeaderEntryCount: 1,
|
ProgramHeaderEntryCount: 2,
|
||||||
SectionHeaderEntrySize: SectionHeaderSize,
|
SectionHeaderEntrySize: SectionHeaderSize,
|
||||||
SectionHeaderEntryCount: 0,
|
SectionHeaderEntryCount: 0,
|
||||||
SectionNameStringTableIndex: 0,
|
SectionNameStringTableIndex: 0,
|
||||||
@ -56,25 +57,30 @@ func New(code []byte, data []byte) *ELF {
|
|||||||
SizeInMemory: int64(len(code)),
|
SizeInMemory: int64(len(code)),
|
||||||
Align: config.Align,
|
Align: config.Align,
|
||||||
},
|
},
|
||||||
PadCode: bytes.Repeat([]byte{0}, 8),
|
DataHeader: ProgramHeader{
|
||||||
Code: code,
|
Type: ProgramTypeLOAD,
|
||||||
PadData: bytes.Repeat([]byte{0}, int(dataPadding)),
|
Flags: ProgramFlagsReadable,
|
||||||
Data: data,
|
Offset: dataOffset,
|
||||||
|
VirtualAddress: config.BaseAddress + dataOffset,
|
||||||
|
PhysicalAddress: config.BaseAddress + dataOffset,
|
||||||
|
SizeInFile: int64(len(data)),
|
||||||
|
SizeInMemory: int64(len(data)),
|
||||||
|
Align: config.Align,
|
||||||
|
},
|
||||||
|
CodePadding: nil,
|
||||||
|
Code: code,
|
||||||
|
DataPadding: bytes.Repeat([]byte{0}, int(dataPadding)),
|
||||||
|
Data: data,
|
||||||
}
|
}
|
||||||
|
|
||||||
return elf
|
|
||||||
}
|
|
||||||
|
|
||||||
func Padding(n int64, align int64) int64 {
|
|
||||||
return align - (n % align)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write writes the ELF64 format to the given writer.
|
// Write writes the ELF64 format to the given writer.
|
||||||
func (elf *ELF) Write(writer io.Writer) {
|
func (elf *ELF) Write(writer io.Writer) {
|
||||||
binary.Write(writer, binary.LittleEndian, &elf.Header)
|
binary.Write(writer, binary.LittleEndian, &elf.Header)
|
||||||
binary.Write(writer, binary.LittleEndian, &elf.CodeHeader)
|
binary.Write(writer, binary.LittleEndian, &elf.CodeHeader)
|
||||||
writer.Write(elf.PadCode)
|
binary.Write(writer, binary.LittleEndian, &elf.DataHeader)
|
||||||
|
writer.Write(elf.CodePadding)
|
||||||
writer.Write(elf.Code)
|
writer.Write(elf.Code)
|
||||||
writer.Write(elf.PadData)
|
writer.Write(elf.DataPadding)
|
||||||
writer.Write(elf.Data)
|
writer.Write(elf.Data)
|
||||||
}
|
}
|
||||||
|
6
src/build/elf/Padding.go
Normal file
6
src/build/elf/Padding.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package elf
|
||||||
|
|
||||||
|
// Padding calculates the padding needed to align `n` bytes with the specified alignment.
|
||||||
|
func Padding(n int64, align int64) int64 {
|
||||||
|
return align - (n % align)
|
||||||
|
}
|
@ -23,4 +23,8 @@ Usually, this value is 65536 (0x1000).
|
|||||||
|
|
||||||
## Initialization in Linux
|
## Initialization in Linux
|
||||||
|
|
||||||
See `/lib/modules/$(uname -r)/build/arch/x86/include/asm/elf.h`.
|
ELF loader:
|
||||||
|
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/binfmt_elf.c
|
||||||
|
|
||||||
|
ELF register definitions:
|
||||||
|
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/include/asm/elf.h
|
||||||
|
Loading…
Reference in New Issue
Block a user