Something went wrong. Try again.
🌱 A minimal programming language and compiler. git.urbach.dev/cli/q
high-performance programming-language compiler
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384package elf
import ( "encoding/binary" "io"
"git.urbach.dev/cli/q/src/config" "git.urbach.dev/cli/q/src/exe")
// ELF represents an ELF file.type ELF struct { Header CodeHeader ProgramHeader DataHeader ProgramHeader SectionHeaders []SectionHeader}
// Write writes the ELF64 format to the given writer.func Write(writer io.WriteSeeker, build *config.Build, codeBytes []byte, dataBytes []byte, labels map[string]int) { x := exe.New(HeaderEnd, build.FileAlign(), build.MemoryAlign(), build.Congruent(), false) x.AddSections(codeBytes, dataBytes) code := x.Sections[0] data := x.Sections[1] symtab, strtab := buildSymbols(int64(code.MemoryOffset), len(code.Bytes), labels) symtabOffset := exe.Align(data.FileOffset+len(data.Bytes), 8) strtabOffset := symtabOffset + len(symtab)
elf := &ELF{ Header: Header{ Magic: [4]byte{0x7F, 'E', 'L', 'F'}, Class: 2, Endianness: LittleEndian, Version: 1, OSABI: 0, ABIVersion: 0, Type: TypeDynamic, Architecture: Arch(build.Arch), FileVersion: 1, EntryPointInMemory: int64(code.MemoryOffset), ProgramHeaderOffset: HeaderSize, SectionHeaderOffset: 0, Flags: 0, Size: HeaderSize, ProgramHeaderEntrySize: ProgramHeaderSize, ProgramHeaderEntryCount: 2, SectionHeaderEntrySize: 0, SectionHeaderEntryCount: 0, SectionNameStringTableIndex: 0, }, CodeHeader: ProgramHeader{ Type: ProgramTypeLOAD, Flags: ProgramFlagsExecutable | ProgramFlagsReadable, Offset: int64(code.FileOffset), VirtualAddress: int64(code.MemoryOffset), SizeInFile: int64(len(code.Bytes)), SizeInMemory: int64(len(code.Bytes)), Align: int64(build.MemoryAlign()), }, DataHeader: ProgramHeader{ Type: ProgramTypeLOAD, Flags: ProgramFlagsReadable | ProgramFlagsWritable, Offset: int64(data.FileOffset), VirtualAddress: int64(data.MemoryOffset), SizeInFile: int64(len(data.Bytes)), SizeInMemory: int64(len(data.Bytes)), Align: int64(build.MemoryAlign()), }, }
elf.AddSections(int64(symtabOffset), int64(len(symtab)), int64(strtabOffset), int64(len(strtab))) binary.Write(writer, binary.LittleEndian, &elf.Header) binary.Write(writer, binary.LittleEndian, &elf.CodeHeader) binary.Write(writer, binary.LittleEndian, &elf.DataHeader) writer.Write([]byte(StringTable)) binary.Write(writer, binary.LittleEndian, &elf.SectionHeaders) writer.Seek(int64(code.Padding), io.SeekCurrent) writer.Write(code.Bytes) writer.Seek(int64(data.Padding), io.SeekCurrent) writer.Write(data.Bytes) writer.Seek(int64(symtabOffset-(data.FileOffset+len(data.Bytes))), io.SeekCurrent) writer.Write(symtab) writer.Write(strtab)}