private static boolean checkEmbeddedOffset(ProgbitsSectionImpl sectionImpl, final int offset, final RelocatableBuffer.Info info) { final ByteBuffer dataBuf = ByteBuffer.wrap(sectionImpl.getContent()).order(sectionImpl.getElement().getOwner().getByteOrder()); if (info.getRelocationSize() == Long.BYTES) { long value = dataBuf.getLong(offset); assert value == 0 || value == 0xDEADDEADDEADDEADL : "unexpected embedded offset"; } else if (info.getRelocationSize() == Integer.BYTES) { int value = dataBuf.getInt(offset); assert value == 0 || value == 0xDEADDEAD : "unexpected embedded offset"; } else { shouldNotReachHere("unsupported relocation size: " + info.getRelocationSize()); } return true; }
@Override public MachORegularSection newProgbitsSection(Segment segment, String name, int alignment, boolean writable, boolean executable, ProgbitsSectionImpl impl) { assert segment != null; EnumSet<SectionFlag> sectionFlags = EnumSet.noneOf(SectionFlag.class); if (executable) { sectionFlags.add(SectionFlag.SOME_INSTRUCTIONS); } MachORegularSection regular = new MachORegularSection(this, name, alignment, (Segment64Command) segment, impl, sectionFlags); impl.setElement(regular); if (executable) { ((Segment64Command) segment).initprot.add(VMProt.EXECUTE); } if (writable) { ((Segment64Command) segment).initprot.add(VMProt.WRITE); } return regular; }
if (target instanceof DataSectionReference) { long addend = ((DataSectionReference) target).getOffset() - info.getExplicitAddend(); sectionImpl.markRelocationSite(offset, info.getRelocationSize(), info.getRelocationKind(), roDataSection.getName(), false, addend); } else if (target instanceof CGlobalDataReference) { CGlobalDataReference ref = (CGlobalDataReference) target; CGlobalDataImpl<?> data = dataInfo.getData(); 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) { baseSectionImpl.markRelocationSite(offsetInSection, wordSize, RelocationKind.DIRECT, data.symbolName, false, 0L);
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); } } } }
private static void markDataRelocationSite(final ProgbitsSectionImpl sectionImpl, final int offset, final RelocatableBuffer.Info info, final NativeImageHeap.ObjectInfo targetObjectInfo) { // References to objects are via relocations to offsets from the symbol // for the section the symbol is in. // Use the target object to find the partition and offset, and from the // partition the section and the partition offset. assert ((info.getRelocationSize() == 4) || (info.getRelocationSize() == 8)) : "Data relocation size should be 4 or 8 bytes."; assert targetObjectInfo != null; // Gather information about the target object. HeapPartition partition = targetObjectInfo.getPartition(); assert partition != null; final String targetSectionName = partition.getSectionName(); final long targetOffsetInSection = targetObjectInfo.getOffsetInSection(); final long relocationInfoAddend = info.hasExplicitAddend() ? info.getExplicitAddend().longValue() : 0L; final long relocationAddend = targetOffsetInSection + relocationInfoAddend; sectionImpl.markRelocationSite(offset, info.getRelocationSize(), info.getRelocationKind(), targetSectionName, false, relocationAddend); }
@Override public PECoffProgbitsSection newProgbitsSection(Segment segment, String name, int alignment, boolean writable, boolean executable, ProgbitsSectionImpl impl) { EnumSet<PECoffSectionFlag> flags = EnumSet.noneOf(PECoffSectionFlag.class); flags.add(PECoffSectionFlag.READ); if (executable) { flags.add(PECoffSectionFlag.EXECUTE); flags.add(PECoffSectionFlag.CODE); } else { flags.add(PECoffSectionFlag.INITIALIZED_DATA); } if (writable) { flags.add(PECoffSectionFlag.WRITE); } PECoffProgbitsSection progbits = new PECoffProgbitsSection(this, name, alignment, impl, flags); impl.setElement(progbits); return progbits; }
@Override public ELFProgbitsSection newProgbitsSection(Segment segment, String name, int alignment, boolean writable, boolean executable, ProgbitsSectionImpl impl) { EnumSet<ELFSectionFlag> flags = EnumSet.noneOf(ELFSectionFlag.class); flags.add(ELFSectionFlag.ALLOC); if (executable) { flags.add(ELFSectionFlag.EXECINSTR); } if (writable) { flags.add(ELFSectionFlag.WRITE); } ELFProgbitsSection progbits = new ELFProgbitsSection(this, name, alignment, impl, flags); impl.setElement(progbits); return progbits; }
@Override public byte[] getContent() { return ((ProgbitsSectionImpl) impl).getContent(); }
@Override public byte[] getContent() { return ((ProgbitsSectionImpl) impl).getContent(); }
@Override public byte[] getContent() { return ((ProgbitsSectionImpl) impl).getContent(); }
@Override public void setContent(byte[] c) { ((ProgbitsSectionImpl) impl).setContent(c); }
private static void markFunctionRelocationSite(final ProgbitsSectionImpl sectionImpl, final int offset, final RelocatableBuffer.Info info) { assert info.getTargetObject() instanceof CFunctionPointer : "Wrong type for FunctionPointer relocation: " + info.getTargetObject().toString(); final int functionPointerRelocationSize = 8; assert info.getRelocationSize() == functionPointerRelocationSize : "Function relocation: " + info.getRelocationSize() + " should be " + functionPointerRelocationSize + " bytes."; // References to functions are via relocations to the symbol for the function. ResolvedJavaMethod method = ((MethodPointer) info.getTargetObject()).getMethod(); // A reference to a method. Mark the relocation site using the symbol name. sectionImpl.markRelocationSite(offset, functionPointerRelocationSize, RelocationKind.DIRECT, localSymbolNameForMethod(method), false, 0L); }
@Override public void setContent(byte[] c) { ((ProgbitsSectionImpl) impl).setContent(c); }
@Override public void setContent(byte[] c) { ((ProgbitsSectionImpl) impl).setContent(c); }