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.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263package elf
import ( "cmp" "encoding/binary" "slices")
const ( SymbolSize = 24 funcGlobal = 0x12)
// buildSymbols builds the symbol table and its string table from the function code offsets.func buildSymbols(virtualAddress int64, codeLength int, labels map[string]int) (symtab []byte, strtab []byte) { names := make([]string, 0, len(labels)) offsets := make(map[string]int, len(labels))
for name, offset := range labels { names = append(names, name) offsets[name] = offset }
slices.SortFunc(names, func(a, b string) int { aOffset := offsets[a] bOffset := offsets[b]
if aOffset != bOffset { return aOffset - bOffset }
return cmp.Compare(a, b) })
strtab = []byte{0} index := make(map[string]int32, len(names))
for _, name := range names { index[name] = int32(len(strtab)) strtab = append(strtab, name...) strtab = append(strtab, 0) }
symtab = make([]byte, SymbolSize*(len(names)+1))
for i, name := range names { base := SymbolSize * (i + 1) offset := offsets[name] size := codeLength - offset
if i+1 < len(names) { size = offsets[names[i+1]] - offset }
binary.LittleEndian.PutUint32(symtab[base:], uint32(index[name])) symtab[base+4] = funcGlobal binary.LittleEndian.PutUint16(symtab[base+6:], 1) binary.LittleEndian.PutUint64(symtab[base+8:], uint64(virtualAddress+int64(offset))) binary.LittleEndian.PutUint64(symtab[base+16:], uint64(size)) }
return symtab, strtab}