public void writeData(RelocatableBuffer buffer, BiFunction<Integer, String, ?> createSymbol) { assert isLayouted() : "Not layouted yet"; int start = buffer.getPosition(); assert IntStream.range(0, totalSize).allMatch(i -> buffer.getByte(i) == 0) : "Buffer must be zero-initialized"; for (CGlobalDataInfo info : map.values()) { byte[] bytes = info.getBytes(); if (bytes != null) { buffer.setPosition(start + info.getOffset()); buffer.putBytes(bytes, 0, bytes.length); } CGlobalDataImpl<?> data = info.getData(); if (data.symbolName != null && !info.isSymbolReference()) { createSymbol.apply(info.getOffset(), data.symbolName); } } } }
@Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (SubstrateUtil.HOSTED) { // AOT compilation: record patch that is fixed up later int before = masm.position(); AMD64Address address = masm.getPlaceholder(before); if (dataInfo.isSymbolReference()) { // Pure symbol reference: the data contains the symbol's address, load it masm.movq(asRegister(result), address); } else { // Data: load its address masm.leaq(asRegister(result), address); } crb.compilationResult.recordDataPatch(before, new CGlobalDataReference(dataInfo)); } else { // Runtime compilation: compute the actual address Pointer globalsBase = CGlobalDataInfo.CGLOBALDATA_RUNTIME_BASE_ADDRESS.get(); Pointer address = globalsBase.add(dataInfo.getOffset()); masm.movq(asRegister(result), address.rawValue()); if (dataInfo.isSymbolReference()) { // load data, which contains symbol's address masm.movq(asRegister(result), new AMD64Address(asRegister(result))); } } } }
long addend = RWDATA_CGLOBALS_PARTITION_OFFSET + dataInfo.getOffset() - info.getExplicitAddend(); sectionImpl.markRelocationSite(offset, info.getRelocationSize(), info.getRelocationKind(), rwDataSection.getName(), false, addend); if (dataInfo.isSymbolReference()) { // create relocation for referenced symbol if (objectFile.getSymbolTable().getSymbol(data.symbolName) == null) { objectFile.createUndefinedSymbol(data.symbolName, 0, true);