diff options
Diffstat (limited to 'chapter21/src/main/java/com')
4 files changed, 55 insertions, 57 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/codegen/ElfFile.java b/chapter21/src/main/java/com/seaofnodes/simple/codegen/ElfFile.java index 6c8a1fc1..654d6678 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/codegen/ElfFile.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/codegen/ElfFile.java @@ -69,6 +69,10 @@ public class ElfFile { // top 4bits are the "bind", bottom 4 are "type" int _info; + // bind 1011 + // 00001111 + // 10110000 + Symbol(String name, int parent, int bind, int type) { _name = name; _parent = parent; @@ -78,6 +82,7 @@ public class ElfFile { void writeHeader(ByteBuffer out) { out.putInt(_name_pos); // name out.put((byte) _info); // info + // default visibility out.put((byte) 0); // other out.putShort((short) _parent); // shndx out.putLong(_value); // value @@ -140,7 +145,7 @@ public class ElfFile { } @Override - void writeHeader(ByteBuffer out) { + void writeHeader(ByteBuffer out) { // points to string table section _link = 1; @@ -160,16 +165,15 @@ public class ElfFile { @Override void write(ByteBuffer out) { + // Index 0 both designates the first entry in the table and serves as the undefined symbol index for( int i = 0; i < SYMBOL_SIZE/4; i++ ) { out.putInt(0); } - int num=1; + // index is already set for( Symbol s : _loc ) { - s._index = num++; s.writeHeader(out); } for( Symbol s : _symbols ) { - s._index = num++; s.writeHeader(out); } } @@ -210,6 +214,7 @@ public class ElfFile { s._index = _sections._len; } + /* creates function and stores where it starts*/ private final HashMap<TypeFunPtr,Symbol> _funcs = new HashMap<>(); private void encodeFunctions(SymbolSection symbols, DataSection text) { int func_start = 0; @@ -236,31 +241,6 @@ public class ElfFile { } } - public final HashMap<Type,Symbol> _bigCons = new HashMap<>(); - private void encodeConstants(SymbolSection symbols, DataSection rdata) { - int cnt = 0; - for (Map.Entry<Node,Type> e : _code._encoding._bigCons.entrySet()) { - if (_bigCons.get(e.getValue()) != null) { - continue; - } - - Symbol glob = new Symbol("GLOB$"+cnt, rdata._index, SYM_BIND_GLOBAL, SYM_TYPE_FUNC); - glob._value = rdata._contents.size(); - symbols.push(glob); - - Type t = e.getValue(); - if ( t instanceof TypeFloat tf ) { - write8(rdata._contents, Double.doubleToLongBits(tf._con)); - } else { - throw Utils.TODO(); - } - - glob._size = rdata._contents.size() - glob._value; - _bigCons.put(e.getValue(), glob); - cnt++; - } - } - public void export(String fname) throws IOException { DataSection strtab = new DataSection(".strtab", 3 /* SHT_SYMTAB */); // first byte is reserved for an empty string @@ -271,6 +251,7 @@ public class ElfFile { SymbolSection symbols = new SymbolSection(".symtab", 2 /* SHT_STRTAB */); pushSection(symbols); + // zero flag by default // we've already constructed this entire section in the encoding phase DataSection text = new DataSection(".text", 1 /* SHT_PROGBITS */, _code._encoding._bits); text._flags = SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR; @@ -282,15 +263,34 @@ public class ElfFile { // populate function symbols encodeFunctions(symbols, text); - // populate big constants - // encodeConstants(symbols, rdata); + int idx = 1; + for( Section s : _sections ) { + Symbol sym = new Symbol(s._name, idx++, SYM_BIND_LOCAL, SYM_TYPE_SECTION); + // we can reuse the same name pos from the actual section + sym._name_pos = s._name_pos; + sym._size = s.size(); + symbols.push(sym); + } + + // calculate local index + int num = 1; + for( Symbol s : symbols._loc ) { + s._index = num++; + } + int start_global = symbols._loc.size(); + for(Symbol a: symbols._symbols) { + a._index = start_global++; + } // create .text relocations DataSection text_rela = new DataSection(".rela.text", 4 /* SHT_RELA */); for( Node n : _code._encoding._externals.keySet()) { int nid = n._nid; String extern = _code._encoding._externals.get(n); - int sym_id = _funcs.get(extern)._index; + if(!extern.isEmpty()) throw Utils.TODO(); + // Todo: fix this up later when external functions will be in TU + //int sym_id = _funcs.get(extern)._index; + int sym_id = 0; int offset = _code._encoding._opStart[nid] + _code._encoding._opLen[nid] - 4; // u64 offset @@ -300,38 +300,22 @@ public class ElfFile { // i64 addend write8(text_rela._contents, -4); } - // relocations to constants - if (false) for (Map.Entry<Node,Type> e : _code._encoding._bigCons.entrySet()) { - int nid = e.getKey()._nid; - int sym_id = _bigCons.get(e.getValue())._index; - int offset = _code._encoding._opStart[nid] + _code._encoding._opLen[nid] - 4; - // u64 offset - write8(text_rela._contents, offset); - // u64 info - write8(text_rela._contents, ((long)sym_id << 32L) | 1L /* PC32 */); - // i64 addend - write8(text_rela._contents, -4); - } text_rela._flags = SHF_INFO_LINK; text_rela._link = 2; text_rela._info = text._index; pushSection(text_rela); + Symbol sym = new Symbol(text_rela._name, idx++, SYM_BIND_LOCAL, SYM_TYPE_SECTION); + sym._name_pos = text_rela._name_pos; + sym._size = text_rela.size(); + symbols.push(sym); + // populate string table for( Section s : _sections ) { s._name_pos = writeCString(strtab, s._name); } for( Symbol s : symbols._symbols ) { s._name_pos = writeCString(strtab, s._name); } for( Symbol s : symbols._loc ) { s._name_pos = writeCString(strtab, s._name); } - int idx = 1; - for( Section s : _sections ) { - Symbol sym = new Symbol(s._name, idx++, SYM_BIND_LOCAL, SYM_TYPE_SECTION); - // we can reuse the same name pos from the actual section - sym._name_pos = s._name_pos; - sym._size = s.size(); - symbols.push(sym); - } - int size = 64; // ELF header // size of all section data for( Section s : _sections ) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java index f42dae75..8aae5911 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java @@ -20,8 +20,8 @@ public class TFPARM extends ConstantNode implements MachNode, RIPRelSize { // adrp x0, 0 int adrp = arm.adrp(1,0, 0b10000, 0,self); // add x0, x0, 0 - arm.imm_inst(enc,this,0b1001000100,0); enc.add4(adrp); + arm.imm_inst(enc,0b1001000100,0, 0); } @Override public byte encSize(int delta) { @@ -32,15 +32,16 @@ public class TFPARM extends ConstantNode implements MachNode, RIPRelSize { // Delta is from opcode start @Override public void patch( Encoding enc, int opStart, int opLen, int delta ) { short rpc = enc.reg(this); - if(opLen ==4 ) { + if(opLen == 8 ) { // opstart of add int next = opStart + opLen; int adrp_delta = delta >> 12; // patch upper 20 bits via adrp enc.patch4(opStart, arm.adrp(1, adrp_delta & 0b11, 0b10000, adrp_delta >> 2, rpc)); // low 12 bits via add - enc.patch4(next, arm.imm_inst_l(enc, this, 0b1001000100, delta & 0xfff)); + enc.patch4(next, arm.imm_inst_l(0b1001000100, delta & 0xfff, rpc)); } else { + // should not happen as one instruction is 4 byte, and TFP arm encodes 2. throw Utils.TODO(); } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java index 9ac5a718..ce78f85b 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java @@ -225,6 +225,12 @@ public class arm extends Machine { enc.add4(body); } + // for cases where rs1 and dst are the same, eg add x0, x0, 1 + public static void imm_inst(Encoding enc, int opcode, int imm12, int self) { + int body = imm_inst(opcode, imm12&0xFFF, self, self); + enc.add4(body); + } + public static void imm_inst_n(Encoding enc, Node n, int opcode, int imm13) { short self = enc.reg(n); short reg1 = enc.reg(n.in(1)); @@ -239,6 +245,12 @@ public class arm extends Machine { return (opcode << 23) | (imm13 << 10) | (rn << 5) | rd; } + public static int imm_inst_l(int opcode, int imm12, int self) { + int body = imm_inst(opcode, imm12&0xFFF, self, self); + return body; + } + + // for cases where rs1 and dst are the same, eg add x0, x0, 1 public static int imm_inst_l(Encoding enc, Node n, int opcode, int imm12) { short self = enc.reg(n); short reg1 = enc.reg(n.in(1)); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java index 6cb219df..1eef56e9 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java @@ -34,7 +34,7 @@ public class TFPRISC extends ConstantNode implements MachNode, RIPRelSize { // Delta is from opcode start @Override public void patch( Encoding enc, int opStart, int opLen, int delta ) { short rpc = enc.reg(this); - if( opLen==4 ) { + if( opLen==8 ) { // AUIPC (upper 20 bits) // opstart of add int next = opStart + opLen; @@ -43,6 +43,7 @@ public class TFPRISC extends ConstantNode implements MachNode, RIPRelSize { enc.patch4(next,riscv.i_type(0b0010011, rpc, 0, rpc, delta & 0xFFF)); // addi } else { + // should not happen as one instruction is 4 byte, and TFP arm encodes 2. throw Utils.TODO(); } } |
