public static RelocatableBuffer factory(final String name, final long size, final ByteOrder byteOrder) { return new RelocatableBuffer(name, size, byteOrder); }
public RelocatableBuffer putInt(final int index, final int value) { getBuffer().putInt(index, value); return this; }
protected NativeTextSectionImpl(RelocatableBuffer relocatableBuffer, ObjectFile objectFile, NativeImageCodeCache codeCache) { // TODO: Do not separate the byte[] from the RelocatableBuffer. super(relocatableBuffer.getBytes()); this.textBuffer = relocatableBuffer; this.objectFile = objectFile; this.codeCache = codeCache; }
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); } } } }
buffer.putByte(index, (byte) (buffer.getByte(index) | mask)); buffer.putInt(info.getIntIndexInSection(hub.getHashCodeOffset()), info.getIdentityHashCode()); buffer.putInt(info.getIntIndexInSection(layout.getArrayLengthOffset()), length); for (int i = 0; i < length; i++) { final int elementIndex = info.getIntIndexInSection(hybridLayout.getArrayElementOffset(i)); Object array = info.getObject(); int length = Array.getLength(array); buffer.putInt(info.getIntIndexInSection(layout.getArrayLengthOffset()), length); buffer.putInt(info.getIntIndexInSection(layout.getArrayHashCodeOffset()), info.getIdentityHashCode()); if (array instanceof Object[]) { Object[] oarray = (Object[]) array;
@Override public void relocate(Reference ref, RelocatableBuffer relocs, int compStart) { /* * The relocation site is some offset into the instruction, which is some offset into the * method, which is some offset into the text section (a.k.a. code cache). The offset we get * out of the RelocationSiteInfo accounts for the first two, since we pass it the whole * method. We add the method start to get the section-relative offset. */ long siteOffset = compStart + annotation.operandPosition; if (ref instanceof DataSectionReference || ref instanceof CGlobalDataReference) { /* * Do we have an addend? Yes; it's constStart. BUT x86/x86-64 PC-relative references are * relative to the *next* instruction. So, if the next instruction starts n bytes from * the relocation site, we want to subtract n bytes from our addend. */ long addend = (annotation.nextInstructionPosition - annotation.operandPosition); relocs.addPCRelativeRelocationWithAddend((int) siteOffset, annotation.operandSize, addend, ref); } else if (ref instanceof ConstantReference) { assert SubstrateOptions.SpawnIsolates.getValue() : "Inlined object references must be base-relative"; relocs.addDirectRelocationWithoutAddend((int) siteOffset, annotation.operandSize, ref); } else { throw VMError.shouldNotReachHere("Unknown type of reference in code"); } } }
final RelocatableBuffer textBuffer = RelocatableBuffer.factory("text", textSectionSize, objectFile.getByteOrder()); final NativeTextSectionImpl textImpl = NativeTextSectionImpl.factory(textBuffer, objectFile, codeCache); final String textSectionName = SectionName.TEXT.getFormatDependentName(objectFile.getFormat()); final RelocatableBuffer roDataBuffer = RelocatableBuffer.factory("roData", roSectionSize, objectFile.getByteOrder()); final ProgbitsSectionImpl roDataImpl = new BasicProgbitsSectionImpl(roDataBuffer.getBytes()); final String roDataSectionName = SectionName.RODATA.getFormatDependentName(objectFile.getFormat()); roDataSection = objectFile.newProgbitsSection(roDataSectionName, objectFile.getPageSize(), false, false, roDataImpl); final RelocatableBuffer rwDataBuffer = RelocatableBuffer.factory("rwData", rwSectionSize, objectFile.getByteOrder()); final ProgbitsSectionImpl rwDataImpl = new BasicProgbitsSectionImpl(rwDataBuffer.getBytes()); final String rwDataSectionName = SectionName.DATA.getFormatDependentName(objectFile.getFormat()); rwDataSection = objectFile.newProgbitsSection(rwDataSectionName, objectFile.getPageSize(), true, false, rwDataImpl); final long heapSize = heap.getReadOnlySectionSize() + heap.getWritableSectionSize(); heapSectionBuffer = RelocatableBuffer.factory("heap", heapSize, objectFile.getByteOrder()); heapSectionImpl = new BasicProgbitsSectionImpl(heapSectionBuffer.getBytes()); final String heapSectionName = SectionName.SVM_HEAP.getFormatDependentName(objectFile.getFormat()); heapSection = objectFile.newProgbitsSection(heapSectionName, objectFile.getPageSize(), writable, false, heapSectionImpl);
/** Raw map access. */ private RelocatableBuffer.Info putInfo(final int key, final RelocatableBuffer.Info value) { return getMap().put(key, value); }
private void addDirectRelocationWithoutAddend(RelocatableBuffer buffer, int index, int size, Object target) { assert !spawnIsolates() || index >= readOnlyRelocatable.offsetInSection() && index < readOnlyRelocatable.offsetInSection(readOnlyRelocatable.getSize()); buffer.addDirectRelocationWithoutAddend(index, size, target); if (firstRelocatablePointerOffsetInSection == -1) { firstRelocatablePointerOffsetInSection = index; } }
private void addDirectRelocationWithAddend(RelocatableBuffer buffer, int index, DynamicHub target, long objectHeaderBits) { assert !spawnIsolates() || index >= readOnlyRelocatable.offsetInSection() && index < readOnlyRelocatable.offsetInSection(readOnlyRelocatable.getSize()); buffer.addDirectRelocationWithAddend(index, referenceSize(), objectHeaderBits, target); if (firstRelocatablePointerOffsetInSection == -1) { firstRelocatablePointerOffsetInSection = index; } }
private void markRelocationSitesFromMaps(RelocatableBuffer relocationMap, ProgbitsSectionImpl sectionImpl, Map<Object, NativeImageHeap.ObjectInfo> objectMap) { // Create relocation records from a map. // TODO: Should this be a visitor to the map entries, // TODO: so I don't have to expose the entrySet() method? for (Map.Entry<Integer, RelocatableBuffer.Info> entry : relocationMap.entrySet()) { final int offset = entry.getKey(); final RelocatableBuffer.Info info = entry.getValue(); assert checkEmbeddedOffset(sectionImpl, offset, info); // Figure out what kind of relocation site it is. if (info.getTargetObject() instanceof CFunctionPointer) { // References to functions are via relocations to the symbol for the function. markFunctionRelocationSite(sectionImpl, offset, info); } else { // A data relocation. if (sectionImpl.getElement() == textSection) { // A wrinkle on relocations *from* the text section: they are *always* to // constants (in the "constant partition" of the roDataSection). markDataRelocationSiteFromText(relocationMap, sectionImpl, offset, info, objectMap); } else { // Relocations from other sections go to the section containing the target. // Pass along the information about the target. final Object targetObject = info.getTargetObject(); final NativeImageHeap.ObjectInfo targetObjectInfo = objectMap.get(targetObject); markDataRelocationSite(sectionImpl, offset, info, targetObjectInfo); } } } }
public RelocatableBuffer.Info getInfo(final int key) { return getMap().get(key); }
public byte getByte(final int index) { return getBuffer().get(index); }
public Set<Map.Entry<Integer, RelocatableBuffer.Info>> entrySet() { return getMap().entrySet(); }
protected byte[] getBytes() { return getBuffer().array(); }
public int mapSize() { return getMap().size(); }
public RelocatableBuffer setPosition(final int newPosition) { getBuffer().position(newPosition); return this; }
public RelocatableBuffer putByte(final byte value) { getBuffer().put(value); return this; }
public RelocatableBuffer putBytes(final byte[] source, final int offset, final int length) { getBuffer().put(source, offset, length); return this; }
public RelocatableBuffer putByte(final int index, final byte value) { getBuffer().put(index, value); return this; }