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