/*
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.svm.hosted.image;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.nativeimage.c.function.RelocatedPointer;
import com.oracle.objectfile.ObjectFile;
Offers a ByteBuffer
with additional support for marking relocation sites within the buffer for later processing. /**
* Offers a {@link ByteBuffer} with additional support for marking relocation sites within the
* buffer for later processing.
*/
public final class RelocatableBuffer {
private final ByteBuffer byteBuffer;
private final SortedMap<Integer, Info> relocations;
public RelocatableBuffer(long size, ByteOrder byteOrder) {
int intSize = NumUtil.safeToInt(size);
this.byteBuffer = ByteBuffer.wrap(new byte[intSize]).order(byteOrder);
this.relocations = new TreeMap<>();
}
public void addRelocationWithoutAddend(int key, ObjectFile.RelocationKind relocationKind, Object targetObject) {
relocations.put(key, new Info(relocationKind, null, targetObject));
}
public void addRelocationWithAddend(int key, ObjectFile.RelocationKind relocationKind, Long explicitAddend, Object targetObject) {
relocations.put(key, new Info(relocationKind, explicitAddend, targetObject));
}
public boolean hasRelocations() {
return !relocations.isEmpty();
}
public Set<Map.Entry<Integer, RelocatableBuffer.Info>> getSortedRelocations() {
return Collections.unmodifiableSet(relocations.entrySet());
}
public byte[] getBackingArray() {
return byteBuffer.array();
}
public ByteBuffer getByteBuffer() {
return byteBuffer;
}
static final class Info {
private final ObjectFile.RelocationKind relocationKind;
private final Long explicitAddend;
The referenced object on the heap. If this is an instance of a RelocatedPointer
, than the relocation is not treated as a data relocation but has a special meaning, e.g. a code (text section) or constants (rodata section) relocation. /**
* The referenced object on the heap. If this is an instance of a {@link RelocatedPointer},
* than the relocation is not treated as a data relocation but has a special meaning, e.g. a
* code (text section) or constants (rodata section) relocation.
*/
private final Object targetObject;
Info(ObjectFile.RelocationKind kind, Long explicitAddend, Object targetObject) {
this.relocationKind = kind;
this.explicitAddend = explicitAddend;
this.targetObject = targetObject;
}
public int getRelocationSize() {
return ObjectFile.RelocationKind.getRelocationSize(relocationKind);
}
public ObjectFile.RelocationKind getRelocationKind() {
return relocationKind;
}
public boolean hasExplicitAddend() {
return (explicitAddend != null);
}
public Long getExplicitAddend() {
return explicitAddend;
}
public Object getTargetObject() {
return targetObject;
}
@Override
public String toString() {
return "RelocatableBuffer.Info(targetObject=" + targetObject + " relocationKind=" + relocationKind + " explicitAddend=" + explicitAddend + ")";
}
}
}