Save ELF symbols in a hash table
This commit is contained in:
		@@ -59,36 +59,37 @@ int generate(string inFile, ref String outputFilename) @nogc
 | 
			
		||||
    auto program = writeNext(ir);
 | 
			
		||||
    auto elf = Elf!ELFCLASS32(move(handle));
 | 
			
		||||
    auto readOnlyData = Array!ubyte(cast(const(ubyte)[]) "%d\n".ptr[0 .. 4]); // With \0.
 | 
			
		||||
    Array!Relocation relocationData;
 | 
			
		||||
 | 
			
		||||
    elf.addReadOnlyData(String(".CL0"), readOnlyData);
 | 
			
		||||
    elf.addCode(program.name, program.text);
 | 
			
		||||
 | 
			
		||||
    elf.addExternSymbol(String("printf"));
 | 
			
		||||
    foreach (ref reference; program.symbols)
 | 
			
		||||
    {
 | 
			
		||||
        Relocation relocationEntry;
 | 
			
		||||
        elf.Rela relocationEntry = {
 | 
			
		||||
            r_offset: cast(elf.Addr) reference.offset
 | 
			
		||||
        };
 | 
			
		||||
        elf.Rela relocationSub = {
 | 
			
		||||
            r_offset: cast(elf.Addr) reference.offset,
 | 
			
		||||
            r_info: R_RISCV_RELAX
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        relocationEntry.symbol = reference;
 | 
			
		||||
        final switch (reference.target)
 | 
			
		||||
        {
 | 
			
		||||
            case Reference.Target.text:
 | 
			
		||||
                relocationEntry.typeInformation = R_RISCV_CALL;
 | 
			
		||||
                relocationEntry.r_info = R_RISCV_CALL;
 | 
			
		||||
                break;
 | 
			
		||||
            case Reference.Target.high20:
 | 
			
		||||
                relocationEntry.typeInformation = R_RISCV_HI20;
 | 
			
		||||
                relocationEntry.r_info = R_RISCV_HI20;
 | 
			
		||||
                break;
 | 
			
		||||
            case Reference.Target.lower12i:
 | 
			
		||||
                relocationEntry.typeInformation = R_RISCV_LO12_I;
 | 
			
		||||
                relocationEntry.r_info = R_RISCV_LO12_I;
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        relocationEntry.hasEntry = true;
 | 
			
		||||
        relocationData.insertBack(relocationEntry);
 | 
			
		||||
 | 
			
		||||
        relocationEntry.typeInformation = R_RISCV_RELAX;
 | 
			
		||||
        relocationEntry.hasEntry = false;
 | 
			
		||||
        relocationData.insertBack(relocationEntry);
 | 
			
		||||
        elf.relocate(reference.name, relocationEntry, relocationSub);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    elf.addReadOnlyData(readOnlyData);
 | 
			
		||||
    elf.addCode(program.name, program.text, relocationData);
 | 
			
		||||
 | 
			
		||||
    elf.finish();
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import elna.extended;
 | 
			
		||||
import elna.result;
 | 
			
		||||
import std.algorithm;
 | 
			
		||||
import tanya.container.array;
 | 
			
		||||
import tanya.container.hashtable;
 | 
			
		||||
import tanya.container.string;
 | 
			
		||||
 | 
			
		||||
/// Unsigned program address.
 | 
			
		||||
@@ -327,17 +328,17 @@ enum : Elf64_Xword
 | 
			
		||||
    SHF_MASKPROC = 0xF0000000,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
auto ELF64_R_SYM(I)(I i)
 | 
			
		||||
ubyte ELF64_R_SYM(Elf64_Xword i) @nogc nothrow pure @safe
 | 
			
		||||
{
 | 
			
		||||
    return i >> 32;
 | 
			
		||||
    return cast(ubyte) (i >> 32);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
auto ELF64_R_TYPE(I)(I i)
 | 
			
		||||
Elf64_Xword ELF64_R_TYPE(Elf64_Xword i) @nogc nothrow pure @safe
 | 
			
		||||
{
 | 
			
		||||
    return i & 0xffffffffL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Elf64_Word ELF64_R_INFO(S)(S s, ubyte t)
 | 
			
		||||
Elf64_Xword ELF64_R_INFO(Elf64_Xword s, Elf64_Xword t) @nogc nothrow pure @safe
 | 
			
		||||
{
 | 
			
		||||
    return (s << 32) + (t & 0xffffffffL);
 | 
			
		||||
}
 | 
			
		||||
@@ -352,24 +353,24 @@ ubyte ELF32_ST_TYPE(ubyte i) @nogc nothrow pure @safe
 | 
			
		||||
    return i & 0xf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ubyte ELF32_ST_INFO(ubyte b, ubyte t) @nogc nothrow pure @safe
 | 
			
		||||
ubyte ELF32_ST_INFO(Elf32_Word b, ubyte t) @nogc nothrow pure @safe
 | 
			
		||||
{
 | 
			
		||||
    return cast(ubyte) ((b << 4) + (t & 0xf));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
auto ELF32_R_SYMT(I)(I i)
 | 
			
		||||
Elf32_Word ELF32_R_SYM(Elf32_Word i) @nogc nothrow pure @safe
 | 
			
		||||
{
 | 
			
		||||
    return i >> 8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ubyte ELF32_R_TYPE(I)(I i)
 | 
			
		||||
ubyte ELF32_R_TYPE(Elf32_Word i) @nogc nothrow pure @safe
 | 
			
		||||
{
 | 
			
		||||
    return cast(ubyte) i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Elf32_Word ELF32_R_INFO(S)(S s, ubyte t)
 | 
			
		||||
Elf32_Word ELF32_R_INFO(Elf32_Word s, Elf32_Word t) @nogc nothrow pure @safe
 | 
			
		||||
{
 | 
			
		||||
    return cast(Elf32_Word) ((s << 8) + t);
 | 
			
		||||
    return (s << 8) + t;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum : uint
 | 
			
		||||
@@ -602,6 +603,12 @@ auto pad(ubyte elfClass)(size_t value) @nogc
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
private struct Relocation(Sym, Rel)
 | 
			
		||||
{
 | 
			
		||||
    Sym symbol;
 | 
			
		||||
    Array!Rel relocations;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct Elf(ubyte elfClass)
 | 
			
		||||
{
 | 
			
		||||
    static if (elfClass == ELFCLASS32)
 | 
			
		||||
@@ -620,7 +627,7 @@ struct Elf(ubyte elfClass)
 | 
			
		||||
        alias Rela = Elf32_Rela;
 | 
			
		||||
        alias Sym = Elf32_Sym;
 | 
			
		||||
 | 
			
		||||
        alias R_SYMT = ELF32_R_SYMT;
 | 
			
		||||
        alias R_SYM = ELF32_R_SYM;
 | 
			
		||||
        alias R_TYPE = ELF32_R_TYPE;
 | 
			
		||||
        alias R_INFO = ELF32_R_INFO;
 | 
			
		||||
        alias ST_BIND = ELF32_ST_BIND;
 | 
			
		||||
@@ -643,7 +650,7 @@ struct Elf(ubyte elfClass)
 | 
			
		||||
        alias Rela = Elf64_Rela;
 | 
			
		||||
        alias Sym = Elf64_Sym;
 | 
			
		||||
 | 
			
		||||
        alias R_SYMT = ELF64_R_SYMT;
 | 
			
		||||
        alias R_SYM = ELF64_R_SYM;
 | 
			
		||||
        alias R_TYPE = ELF64_R_TYPE;
 | 
			
		||||
        alias R_INFO = ELF64_R_INFO;
 | 
			
		||||
        alias ST_BIND = ELF64_ST_BIND;
 | 
			
		||||
@@ -655,16 +662,17 @@ struct Elf(ubyte elfClass)
 | 
			
		||||
        static assert(false, "Invalid ELF class");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private alias Relocation = .Relocation!(Sym, Rela);
 | 
			
		||||
 | 
			
		||||
    private Array!Shdr sectionHeaders;
 | 
			
		||||
    private Off currentOffset = Elf32_Ehdr.sizeof;
 | 
			
		||||
    private Array!Sym symbols;
 | 
			
		||||
    static immutable char[52] sections =
 | 
			
		||||
        "\0.symtab\0.strtab\0.shstrtab\0.text\0.rodata\0.rela.text\0";
 | 
			
		||||
    private String strings;
 | 
			
		||||
    private Word lastLocalSymbol;
 | 
			
		||||
    private File output;
 | 
			
		||||
    private Array!ubyte readOnly;
 | 
			
		||||
    private Array!Rela relocations;
 | 
			
		||||
 | 
			
		||||
    private HashTable!(String, Relocation) symbolTable;
 | 
			
		||||
 | 
			
		||||
    private enum HeaderName
 | 
			
		||||
    {
 | 
			
		||||
@@ -681,7 +689,6 @@ struct Elf(ubyte elfClass)
 | 
			
		||||
        Elf elf = Elf.init;
 | 
			
		||||
 | 
			
		||||
        elf.initializeSectionHeaders();
 | 
			
		||||
        elf.insertSymbols();
 | 
			
		||||
        elf.output = move(output);
 | 
			
		||||
 | 
			
		||||
        elf.output.seek(Ehdr.sizeof, File.Whence.set);
 | 
			
		||||
@@ -700,7 +707,6 @@ struct Elf(ubyte elfClass)
 | 
			
		||||
 | 
			
		||||
    void finish() @nogc
 | 
			
		||||
    {
 | 
			
		||||
        writeRelaTable();
 | 
			
		||||
        writeRoDataTable();
 | 
			
		||||
        writeSymbolTable();
 | 
			
		||||
        writeStringTables();
 | 
			
		||||
@@ -712,19 +718,18 @@ struct Elf(ubyte elfClass)
 | 
			
		||||
        writeFileHeader();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void insertSymbols() @nogc
 | 
			
		||||
    private Sym initializeSymbols() @nogc
 | 
			
		||||
    {
 | 
			
		||||
        // Zero symbol
 | 
			
		||||
        Elf32_Sym symbol;
 | 
			
		||||
        Sym symbol;
 | 
			
		||||
        symbol.st_name = 0; // Word
 | 
			
		||||
        symbol.st_value = 0; // Addr
 | 
			
		||||
        symbol.st_size = 0; // Word
 | 
			
		||||
        symbol.st_info = 0; // char
 | 
			
		||||
        symbol.st_other = 0; // char
 | 
			
		||||
        symbol.st_shndx = 0; // Half word
 | 
			
		||||
        this.symbols.insertBack(symbol);
 | 
			
		||||
        // All symbols are global.
 | 
			
		||||
        this.lastLocalSymbol = cast(Elf32_Word) this.symbols.length;
 | 
			
		||||
 | 
			
		||||
        return symbol;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void makeStringHeader(HeaderName position)() @nogc
 | 
			
		||||
@@ -791,25 +796,64 @@ struct Elf(ubyte elfClass)
 | 
			
		||||
 | 
			
		||||
    private void writeSymbolTable() @nogc
 | 
			
		||||
    {
 | 
			
		||||
        auto index = findHeader!(HeaderName.symbol)();
 | 
			
		||||
        auto stringIndex = findHeader!(HeaderName.string_)();
 | 
			
		||||
        const index = findHeader!(HeaderName.symbol)();
 | 
			
		||||
        const stringIndex = findHeader!(HeaderName.string_)();
 | 
			
		||||
        const relaIndex = findHeader!(HeaderName.rela);
 | 
			
		||||
        const textIndex = findHeader!(HeaderName.text)();
 | 
			
		||||
 | 
			
		||||
        assert(index != -1);
 | 
			
		||||
        assert(stringIndex != -1);
 | 
			
		||||
        assert(relaIndex != -1);
 | 
			
		||||
        assert(textIndex != -1);
 | 
			
		||||
 | 
			
		||||
        this.sectionHeaders[index].sh_offset = this.currentOffset;
 | 
			
		||||
        this.sectionHeaders[index].sh_info = this.lastLocalSymbol;
 | 
			
		||||
        this.sectionHeaders[index].sh_link = cast(Word) stringIndex;
 | 
			
		||||
        this.sectionHeaders[index].sh_size = cast(Word) (this.symbols.length * Sym.sizeof);
 | 
			
		||||
        this.sectionHeaders[index].sh_size = cast(Word) ((1 + symbolTable.length) * Sym.sizeof);
 | 
			
		||||
 | 
			
		||||
        foreach (symbol; this.symbols)
 | 
			
		||||
        this.sectionHeaders[relaIndex].sh_link = cast(Word) index;
 | 
			
		||||
        this.sectionHeaders[relaIndex].sh_info = cast(Word) textIndex;
 | 
			
		||||
        this.sectionHeaders[relaIndex].sh_offset = this.sectionHeaders[index].sh_offset
 | 
			
		||||
            + this.sectionHeaders[index].sh_size;
 | 
			
		||||
 | 
			
		||||
        auto initialSymbol = initializeSymbols();
 | 
			
		||||
        output.write((cast(ubyte*) &initialSymbol)[0 .. Sym.sizeof]);
 | 
			
		||||
        this.currentOffset += Sym.sizeof;
 | 
			
		||||
 | 
			
		||||
        int i = 1;
 | 
			
		||||
        Array!Relocation symbols = Array!Relocation(this.symbolTable.byValue());
 | 
			
		||||
        auto rightRange = symbols[].partition!(symbol => ST_BIND(symbol.symbol.st_info) != STB_GLOBAL);
 | 
			
		||||
 | 
			
		||||
        // Greater than last local symbol.
 | 
			
		||||
        this.sectionHeaders[index].sh_info = cast(Word) (symbols.length - rightRange.length + 1);
 | 
			
		||||
 | 
			
		||||
        foreach (ref symbol; symbols[])
 | 
			
		||||
        {
 | 
			
		||||
            this.output.seek(this.sectionHeaders[relaIndex].sh_offset + this.sectionHeaders[relaIndex].sh_size,
 | 
			
		||||
                    File.Whence.set);
 | 
			
		||||
 | 
			
		||||
            if (!symbol.relocations.empty)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (ref relocation; symbol.relocations[])
 | 
			
		||||
                {
 | 
			
		||||
                    relocation.r_info = R_INFO(i, R_TYPE(relocation.r_info));
 | 
			
		||||
                }
 | 
			
		||||
                this.sectionHeaders[relaIndex].sh_flags = SHF_ALLOC;
 | 
			
		||||
                const size = cast(Word) (Rela.sizeof * symbol.relocations.length);
 | 
			
		||||
 | 
			
		||||
                this.output.write((cast(ubyte*) symbol.relocations.get)[0 .. size]);
 | 
			
		||||
                this.sectionHeaders[relaIndex].sh_size += size;
 | 
			
		||||
                this.currentOffset += size;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.output.seek(this.sectionHeaders[index].sh_offset + i * Sym.sizeof, File.Whence.set);
 | 
			
		||||
            output.write((cast(ubyte*) &symbol)[0 .. Sym.sizeof]);
 | 
			
		||||
            this.currentOffset += Sym.sizeof;
 | 
			
		||||
            ++i;
 | 
			
		||||
        }
 | 
			
		||||
        this.output.seek(0, File.Whence.end);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void addCode(ref String name, ref Array!ubyte text, Array!Relocation usedSymbols)
 | 
			
		||||
    void addCode(String name, ref Array!ubyte text)
 | 
			
		||||
    @nogc
 | 
			
		||||
    {
 | 
			
		||||
        this.output.write(text.get);
 | 
			
		||||
@@ -828,57 +872,15 @@ struct Elf(ubyte elfClass)
 | 
			
		||||
        symbol.st_other = 0; // char
 | 
			
		||||
         // .text header index, half word
 | 
			
		||||
        symbol.st_shndx = cast(Half) textHeaderIndex;
 | 
			
		||||
        this.symbols.insertBack(symbol);
 | 
			
		||||
        this.symbolTable[name] = Relocation(symbol);
 | 
			
		||||
 | 
			
		||||
        this.strings.insertBack(name[]);
 | 
			
		||||
 | 
			
		||||
        this.sectionHeaders[textHeaderIndex].sh_size += text.length;
 | 
			
		||||
        this.currentOffset += text.length;
 | 
			
		||||
 | 
			
		||||
        foreach (usedSymbol; usedSymbols)
 | 
			
		||||
        {
 | 
			
		||||
            Rela relocationEntry;
 | 
			
		||||
 | 
			
		||||
            relocationEntry.r_offset = cast(Addr) usedSymbol.symbol.offset;
 | 
			
		||||
            if (usedSymbol.hasEntry)
 | 
			
		||||
            {
 | 
			
		||||
                if (usedSymbol.symbol.target == Reference.Target.text)
 | 
			
		||||
                {
 | 
			
		||||
                    relocationEntry.r_info = R_INFO(this.symbols.length, usedSymbol.typeInformation);
 | 
			
		||||
                    this.relocations.insertBack(relocationEntry);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    relocationEntry.r_info = R_INFO(1, usedSymbol.typeInformation);
 | 
			
		||||
                    this.relocations.insertBack(relocationEntry);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                relocationEntry.r_info = R_INFO(0, usedSymbol.typeInformation);
 | 
			
		||||
                this.relocations.insertBack(relocationEntry);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (usedSymbol.symbol.target == Reference.Target.text)
 | 
			
		||||
            {
 | 
			
		||||
                Sym usedSymbolEntry;
 | 
			
		||||
 | 
			
		||||
                this.strings.insertBack("\0");
 | 
			
		||||
                usedSymbolEntry.st_name = cast(Word) this.strings.length;
 | 
			
		||||
                usedSymbolEntry.st_value = 0;
 | 
			
		||||
                usedSymbolEntry.st_size = 0;
 | 
			
		||||
                usedSymbolEntry.st_info = ST_INFO(STB_GLOBAL, STT_NOTYPE);
 | 
			
		||||
                usedSymbolEntry.st_other = 0;
 | 
			
		||||
                usedSymbolEntry.st_shndx = SHN_UNDEF;
 | 
			
		||||
 | 
			
		||||
                this.strings.insertBack(usedSymbol.symbol.name[]);
 | 
			
		||||
                this.strings.insertBack("\0");
 | 
			
		||||
                this.symbols.insertBack(usedSymbolEntry);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void addReadOnlyData(ref Array!ubyte data) @nogc
 | 
			
		||||
    void addReadOnlyData(String name, ref Array!ubyte data) @nogc
 | 
			
		||||
    {
 | 
			
		||||
        auto roDataIndex = findHeader!(HeaderName.roData)();
 | 
			
		||||
        assert(roDataIndex != -1);
 | 
			
		||||
@@ -894,13 +896,40 @@ struct Elf(ubyte elfClass)
 | 
			
		||||
        symbol.st_other = 0; // char
 | 
			
		||||
         // .text header index, half word
 | 
			
		||||
        symbol.st_shndx = cast(Half) roDataIndex;
 | 
			
		||||
        this.symbols.insertBack(symbol);
 | 
			
		||||
        ++this.lastLocalSymbol;
 | 
			
		||||
        this.symbolTable[name] = Relocation(symbol);
 | 
			
		||||
 | 
			
		||||
        this.strings.insertBack(".CL0");
 | 
			
		||||
        this.strings.insertBack(name[]);
 | 
			
		||||
        this.readOnly.insertBack(data[]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void addExternSymbol(String name) @nogc
 | 
			
		||||
    {
 | 
			
		||||
        Sym usedSymbolEntry;
 | 
			
		||||
 | 
			
		||||
        this.strings.insertBack("\0");
 | 
			
		||||
        usedSymbolEntry.st_name = cast(Word) this.strings.length;
 | 
			
		||||
        usedSymbolEntry.st_value = 0;
 | 
			
		||||
        usedSymbolEntry.st_size = 0;
 | 
			
		||||
        usedSymbolEntry.st_info = ST_INFO(STB_GLOBAL, STT_NOTYPE);
 | 
			
		||||
        usedSymbolEntry.st_other = 0;
 | 
			
		||||
        usedSymbolEntry.st_shndx = SHN_UNDEF;
 | 
			
		||||
 | 
			
		||||
        this.strings.insertBack(name[]);
 | 
			
		||||
        this.strings.insertBack("\0");
 | 
			
		||||
        this.symbolTable[name] = Relocation(usedSymbolEntry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void relocate(String name, Rela[] usedSymbols...) @nogc
 | 
			
		||||
    {
 | 
			
		||||
        foreach (usedSymbol; usedSymbols)
 | 
			
		||||
        {
 | 
			
		||||
            Rela relocationEntry = usedSymbol;
 | 
			
		||||
 | 
			
		||||
            relocationEntry.r_info = usedSymbol.r_info;
 | 
			
		||||
            this.symbolTable[name].relocations.insertBack(relocationEntry);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ptrdiff_t findHeader(HeaderName position)()
 | 
			
		||||
    {
 | 
			
		||||
        return countUntil!(header => header.sh_name == position)(this.sectionHeaders[]);
 | 
			
		||||
@@ -1028,24 +1057,4 @@ struct Elf(ubyte elfClass)
 | 
			
		||||
 | 
			
		||||
        this.sectionHeaders.insertBack(table);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void writeRelaTable() @nogc
 | 
			
		||||
    {
 | 
			
		||||
        auto index = findHeader!(HeaderName.rela);
 | 
			
		||||
        auto textIndex = findHeader!(HeaderName.text)();
 | 
			
		||||
        auto symbolIndex = findHeader!(HeaderName.symbol)();
 | 
			
		||||
 | 
			
		||||
        assert(index != -1);
 | 
			
		||||
        assert(textIndex != -1);
 | 
			
		||||
        assert(symbolIndex != -1);
 | 
			
		||||
 | 
			
		||||
        this.sectionHeaders[index].sh_link = cast(Word) symbolIndex;
 | 
			
		||||
        this.sectionHeaders[index].sh_info = cast(Word) textIndex;
 | 
			
		||||
        this.sectionHeaders[index].sh_flags = this.relocations.length == 0 ? 0 : SHF_ALLOC;
 | 
			
		||||
        this.sectionHeaders[index].sh_offset = this.currentOffset;
 | 
			
		||||
        this.sectionHeaders[index].sh_size = cast(Word) (Rela.sizeof * this.relocations.length);
 | 
			
		||||
 | 
			
		||||
        this.output.write((cast(ubyte*) this.relocations.get)[0 .. Rela.sizeof * this.relocations.length]);
 | 
			
		||||
        this.currentOffset += Rela.sizeof * this.relocations.length;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -105,10 +105,3 @@ struct Symbol
 | 
			
		||||
    Array!ubyte text;
 | 
			
		||||
    Array!Reference symbols;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct Relocation
 | 
			
		||||
{
 | 
			
		||||
    Reference symbol;
 | 
			
		||||
    ubyte typeInformation;
 | 
			
		||||
    bool hasEntry = true;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user