public void linkStage3(bool allowMissing) { for (uint i = 0; i < library.file.nreferences; i++) { if (library.file.referenceSection(i) == librarySection) { LinkedSymbol sym = library.symbols[library.file.referenceSymbol(i)]; ulong addr = startAddress + library.file.referenceOffset(i); Console.WriteLine("Fixing address at " + addr + " (offset " + library.file.referenceOffset(i) + ") to point to '" + sym.name() + "' (at " + sym.address + ")"); byte sz = library.file.referenceWidth(i); switch (sz) { case 0: // 1<<0 = 1 bytes (8 bits) library.linker.target.setU8(addr, (byte)sym.finalValue()); break; case 1: // 1<<1 = 2 bytes (16 bits) library.linker.target.setU16(addr, (ushort)sym.finalValue(), library.file.bigEndian); break; case 2: // 1<<2 = 4 bytes (32 bits) library.linker.target.setU32(addr, (uint)sym.finalValue(), library.file.bigEndian); break; case 3: // 1<<3 = 8 bytes (64 bits) library.linker.target.setU64(addr, sym.finalValue(), library.file.bigEndian); break; default: throw new LinkerException(library.file, "Bad reference size: " + sz); } } } }
public ulong finalValue() { if (isDummy()) { if (isConst()) { return(library.file.symbolOffset(index)); } else if (isExpr()) { LinkedSymbol l = library.symbols[library.file.symbolXLHS(index)]; LinkedSymbol o = library.symbols[library.file.symbolXOp(index)]; LinkedSymbol r = library.symbols[library.file.symbolXRHS(index)]; return(doexpr(l.finalValue(), o.name(), r.finalValue())); } else { throw new LinkerException(library.file, "Bad reference (this symbol can't be evaluated)"); } } else { return(address); } }