summaryrefslogtreecommitdiff
path: root/chapter21/src/main/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'chapter21/src/main/java/com')
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/codegen/ElfFile.java90
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java7
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java12
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java3
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();
}
}