Improved documentation

This commit is contained in:
Eduard Urbach 2024-07-13 14:18:55 +02:00
parent 9df899cb52
commit 948d499231
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
6 changed files with 49 additions and 26 deletions

View File

@ -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...)
} }

View File

@ -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.

View File

@ -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 (

View File

@ -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
View 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)
}

View File

@ -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