diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/reloc/ElfRelocationFixupHandler.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/reloc/ElfRelocationFixupHandler.java new file mode 100644 index 0000000000..015b01c41c --- /dev/null +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/reloc/ElfRelocationFixupHandler.java @@ -0,0 +1,65 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.reloc; + +import java.util.HashMap; +import java.util.Map; + +import ghidra.app.util.bin.format.elf.relocation.ElfRelocationType; + +public abstract class ElfRelocationFixupHandler extends RelocationFixupHandler { + + private Map relocationTypesMap; + + /** + * Abstract constructor for an {@link ElfRelocationFixupHandler}. + * + * @param relocationEnumClass specifies the {@link ElfRelocationType} enum which defines + * all supported relocation types for this relocation handler. + */ + protected ElfRelocationFixupHandler(Class relocationEnumClass) { + initRelocationTypeMap(relocationEnumClass); + } + + private void initRelocationTypeMap(Class relocationEnumClass) { + if (!relocationEnumClass.isEnum() || + !ElfRelocationType.class.isAssignableFrom(relocationEnumClass)) { + throw new IllegalArgumentException( + "Invalid class specified - expected enum which implements ElfRelocationType: " + + relocationEnumClass.getName()); + } + relocationTypesMap = new HashMap<>(); + for (ElfRelocationType t : relocationEnumClass.getEnumConstants()) { + relocationTypesMap.put(t.typeId(), t); + } + } + + /** + * Get the relocation type enum value which corresponds to the specified type value. + * + * @param type relocation type value + * @return relocation type enum value or null if type not found or this handler was not + * constructed with a {@link ElfRelocationType} enum class. The returned value may be + * safely cast to the relocation enum class specified during handler construction. + */ + public ElfRelocationType getRelocationType(int type) { + if (relocationTypesMap == null) { + return null; + } + return relocationTypesMap.get(type); + } + +} diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/reloc/RelocationFixupHandler.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/reloc/RelocationFixupHandler.java index 460175dd6b..6102ae7579 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/reloc/RelocationFixupHandler.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/reloc/RelocationFixupHandler.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,15 +25,21 @@ import ghidra.util.classfinder.ExtensionPoint; public abstract class RelocationFixupHandler implements ExtensionPoint { + /** + * Default abstract constructor for an {@link RelocationFixupHandler}. + */ + protected RelocationFixupHandler() { + } + public abstract boolean processRelocation(Program program, Relocation relocation, - Address oldImageBase, Address newImageBase) throws MemoryAccessException, - CodeUnitInsertionException; + Address oldImageBase, Address newImageBase) + throws MemoryAccessException, CodeUnitInsertionException; public abstract boolean handlesProgram(Program program); protected boolean process32BitRelocation(Program program, Relocation relocation, - Address oldImageBase, Address newImageBase) throws MemoryAccessException, - CodeUnitInsertionException { + Address oldImageBase, Address newImageBase) + throws MemoryAccessException, CodeUnitInsertionException { long diff = newImageBase.subtract(oldImageBase); Address address = relocation.getAddress(); @@ -52,8 +57,8 @@ public abstract class RelocationFixupHandler implements ExtensionPoint { } public boolean process64BitRelocation(Program program, Relocation relocation, - Address oldImageBase, Address newImageBase) throws MemoryAccessException, - CodeUnitInsertionException { + Address oldImageBase, Address newImageBase) + throws MemoryAccessException, CodeUnitInsertionException { long diff = newImageBase.subtract(oldImageBase); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfRelocation.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfRelocation.java index 1d38232847..9dcddf8ee6 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfRelocation.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfRelocation.java @@ -22,7 +22,7 @@ import ghidra.app.util.bin.BinaryReader; import ghidra.app.util.bin.StructConverter; import ghidra.app.util.bin.format.elf.extend.ElfLoadAdapter; import ghidra.app.util.bin.format.elf.relocation.ElfRelocationContext; -import ghidra.app.util.bin.format.elf.relocation.ElfRelocationHandler; +import ghidra.app.util.bin.format.elf.relocation.AbstractElfRelocationHandler; import ghidra.program.model.data.*; /** @@ -62,7 +62,7 @@ import ghidra.program.model.data.*; * * RELR entry (see SHT_RELR, DT_RELR): * NOTE: Relocation type is data relative and must be specified by appropriate relocation handler - * (see {@link ElfRelocationHandler#getRelrRelocationType()}) since it is not contained within the + * (see {@link AbstractElfRelocationHandler#getRelrRelocationType()}) since it is not contained within the * relocation table which only specifies r_offset for each entry. * * @@ -272,27 +272,27 @@ public class ElfRelocation implements StructConverter { } /** - * The type of relocation to apply. - * NOTE 1: Relocation types are processor-specific (see {@link ElfRelocationHandler}). - * NOTE 2: A type of 0 is returned by default for RELR relocations and must be updated + * The type ID value for this relocation + * NOTE 1: Relocation types are processor-specific (see {@link AbstractElfRelocationHandler}). + * NOTE 2: A type ID of 0 is returned by default for RELR relocations and must be updated * during relocation processing (see {@link #setType(long)}). The appropriate RELR * relocation type can be obtained from the appropriate - * {@link ElfRelocationHandler#getRelrRelocationType()} or + * {@link AbstractElfRelocationHandler#getRelrRelocationType()} or * {@link ElfRelocationContext#getRelrRelocationType()} if available. - * @return type of relocation to apply + * @return type ID for this relocation */ public int getType() { return (int) (is32bit ? (r_info & BYTE_MASK) : (r_info & INT_MASK)); } /** - * Set the relocation type associated with this relocation. + * Set the relocation type ID associated with this relocation. * Updating the relocation type is required for RELR relocations. - * @param type relocation type to be applied + * @param typeId relocation type ID value for this relocation */ - public void setType(long type) { + public void setType(long typeId) { long mask = is32bit ? BYTE_MASK : INT_MASK; - r_info = (r_info & ~mask) + (type & mask); + r_info = (r_info & ~mask) + (typeId & mask); } /** diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/AbstractElfRelocationHandler.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/AbstractElfRelocationHandler.java new file mode 100644 index 0000000000..af8e17c231 --- /dev/null +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/AbstractElfRelocationHandler.java @@ -0,0 +1,237 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +import java.util.HashMap; +import java.util.Map; + +import ghidra.app.util.bin.format.elf.ElfRelocation; +import ghidra.app.util.bin.format.elf.ElfSymbol; +import ghidra.app.util.importer.MessageLog; +import ghidra.program.model.address.Address; +import ghidra.program.model.listing.BookmarkType; +import ghidra.program.model.listing.Program; +import ghidra.program.model.mem.MemoryAccessException; +import ghidra.program.model.reloc.RelocationResult; +import ghidra.util.classfinder.ClassSearcher; + +/** + * ElfRelocationHandler provides the base class for processor specific + * ELF relocation handlers. Implementations may only specify a public default constructor + * as they will be identified and instatiated by the {@link ClassSearcher}. As such their + * name must end with "ElfRelocationHandler" (e.g., MyProc_ElfRelocationHandler). + * + * @param ELF relocation type enum class + * @param ELF relocation context class + */ +abstract public class AbstractElfRelocationHandler> + extends ElfRelocationHandler { + + private Map relocationTypesMap; + + /** + * Abstract constructor for an {@link AbstractElfRelocationHandler}. + * + * @param relocationEnumClass specifies the {@link ElfRelocationType} enum which defines + * all supported relocation types for this relocation handler. + */ + protected AbstractElfRelocationHandler(Class relocationEnumClass) { + super(); // must continue to use ElfRelocationHandler until eliminated + initRelocationTypeMap(relocationEnumClass); + } + + private void initRelocationTypeMap(Class relocationEnumClass) { + if (!relocationEnumClass.isEnum() || + !ElfRelocationType.class.isAssignableFrom(relocationEnumClass)) { + throw new IllegalArgumentException( + "Invalid class specified - expected enum which implements ElfRelocationType: " + + relocationEnumClass.getName()); + } + relocationTypesMap = new HashMap<>(); + for (T t : relocationEnumClass.getEnumConstants()) { + relocationTypesMap.put(t.typeId(), t); + } + } + + /** + * Get the relocation type enum object which corresponds to the specified type ID value. + * + * @param typeId relocation type ID value + * @return relocation type enum value or null if type not found or this handler was not + * constructed with a {@link ElfRelocationType} enum class. The returned value may be + * safely cast to the relocation enum class specified during handler construction. + */ + public T getRelocationType(int typeId) { + if (relocationTypesMap == null) { + return null; + } + return relocationTypesMap.get(typeId); + } + + /** + * Perform relocation fixup. + * + * @param elfRelocationContext relocation context + * @param relocation ELF relocation + * @param relocationAddress relocation target address (fixup location) + * @return applied relocation result (conveys status and applied byte-length) + * @throws MemoryAccessException memory access failure + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + protected final RelocationResult relocate(ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, Address relocationAddress) throws MemoryAccessException { + + Program program = elfRelocationContext.getProgram(); + + int symbolIndex = relocation.getSymbolIndex(); + + ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); + Address symbolAddr = elfRelocationContext.getSymbolAddress(sym); + long symbolValue = elfRelocationContext.getSymbolValue(sym); + String symbolName = elfRelocationContext.getSymbolName(symbolIndex); + + int typeId = relocation.getType(); + if (typeId == 0) { + return RelocationResult.SKIPPED; + } + + T type = getRelocationType(typeId); + if (type == null) { + markAsUndefined(program, relocationAddress, typeId, symbolName, symbolIndex, + elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; + } + + return relocate((C) elfRelocationContext, relocation, type, relocationAddress, sym, + symbolAddr, symbolValue, symbolName); + } + + /** + * Perform relocation fixup. + * + * @param elfRelocationContext relocation context + * @param relocation ELF relocation + * @param relocationType ELF relocation type enum value + * @param relocationAddress relocation target address (fixup location) + * @param elfSymbol relocation symbol (may be null) + * @param symbolAddr elfSymbol memory address (may be null) + * @param symbolValue unadjusted elfSymbol value (0 if no symbol) + * @param symbolName elfSymbol name (may be null) + * @return applied relocation result (conveys status and applied byte-length) + * @throws MemoryAccessException memory access failure + */ + protected abstract RelocationResult relocate(C elfRelocationContext, ElfRelocation relocation, + T relocationType, Address relocationAddress, ElfSymbol elfSymbol, Address symbolAddr, + long symbolValue, String symbolName) throws MemoryAccessException; + + // + // Error and Warning markup methods + // + +// private String getRelocationTypeDetail(int typeId) { +// T relocationType = relocationTypesMap.get(typeId); +// if (relocationType == null) { +// return getDefaultRelocationTypeDetail(typeId); +// } +// return getRelocationTypeDetail(relocationType); +// } + + private String getRelocationTypeDetail(T relocationType) { + int typeId = relocationType.typeId(); + return relocationType.name() + " (" + typeId + ", 0x" + Integer.toHexString(typeId) + ")"; + } + + /** + * Generate error log entry and bookmark at relocationAddress indicating + * an unhandled relocation. + * + * @param program program + * @param relocationAddress relocation address to be bookmarked + * @param typeId relocation type ID value + * @param symbolIndex associated symbol index within symbol table + * @param symbolName associated symbol name + * @param log import log + */ + protected void markAsUndefined(Program program, Address relocationAddress, int typeId, + String symbolName, int symbolIndex, MessageLog log) { + markupErrorOrWarning(program, "Undefined ELF Relocation", null, relocationAddress, + getDefaultRelocationTypeDetail(typeId), symbolIndex, symbolName, BookmarkType.ERROR, + log); + } + + /** + * Generate error log entry and bookmark at relocationAddress indicating + * an unhandled relocation. + * + * @param program program + * @param relocationAddress relocation address to be bookmarked + * @param relocationType relocation type + * @param symbolIndex associated symbol index within symbol table + * @param symbolName associated symbol name + * @param log import log + */ + protected void markAsUnhandled(Program program, Address relocationAddress, T relocationType, + int symbolIndex, String symbolName, MessageLog log) { + markupErrorOrWarning(program, "Unhandled ELF Relocation", null, relocationAddress, + getRelocationTypeDetail(relocationType), symbolIndex, symbolName, BookmarkType.ERROR, + log); + } + + /** + * Generate relocation warning log entry and bookmark at relocationAddress. + * + * @param program program + * @param relocationAddress relocation address to be bookmarked + * @param relocationType relocation type + * @param symbolName symbol name + * @param symbolIndex symbol index (-1 to ignore) + * @param msg message associated with warning + * @param log import log + */ + protected void markAsWarning(Program program, Address relocationAddress, T relocationType, + String symbolName, int symbolIndex, String msg, MessageLog log) { + markupErrorOrWarning(program, "ELF Relocation Failure", msg, relocationAddress, + getRelocationTypeDetail(relocationType), symbolIndex, symbolName, BookmarkType.WARNING, + log); + } + + /** + * Generate relocation error log entry and bookmark at relocationAddress. + * + * @param program program + * @param relocationAddress relocation address to be bookmarked + * @param relocationType relocation type + * @param symbolName associated symbol name + * @param symbolIndex symbol index (-1 to ignore) + * @param msg additional error message + * @param log import log + */ + protected void markAsError(Program program, Address relocationAddress, T relocationType, + String symbolName, int symbolIndex, String msg, MessageLog log) { + markupErrorOrWarning(program, "Elf Relocation Failure", msg, relocationAddress, + getRelocationTypeDetail(relocationType), symbolIndex, symbolName, BookmarkType.ERROR, + log); + } + +// @Override +// protected void markAsError(Program program, Address relocationAddress, int typeId, +// String symbolName, int symbolIndex, String msg, MessageLog log) { +// markupErrorOrWarning(program, "ELF Relocation Error", msg, relocationAddress, +// getRelocationTypeDetail(typeId), symbolIndex, symbolName, BookmarkType.ERROR, log); +// } + +} diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationContext.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationContext.java index dd248ec24f..1414d0cf97 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationContext.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationContext.java @@ -17,8 +17,6 @@ package ghidra.app.util.bin.format.elf.relocation; import java.util.Map; -import org.apache.commons.lang3.StringUtils; - import ghidra.app.util.bin.format.elf.*; import ghidra.app.util.bin.format.elf.extend.ElfLoadAdapter; import ghidra.app.util.importer.MessageLog; @@ -32,10 +30,12 @@ import ghidra.util.exception.*; /** * ElfRelocationContext provides a relocation handler context related * to the processing of entries contained within a specific relocation table. + * + * @param ELF relocation handler class */ -public class ElfRelocationContext { +public class ElfRelocationContext { - protected final ElfRelocationHandler handler; + protected final H handler; protected final ElfLoadHelper loadHelper; protected final Map symbolMap; protected final Program program; @@ -51,12 +51,16 @@ public class ElfRelocationContext { * @param loadHelper the elf load helper * @param symbolMap Elf symbol placement map */ - protected ElfRelocationContext(ElfRelocationHandler handler, ElfLoadHelper loadHelper, + protected ElfRelocationContext(H handler, ElfLoadHelper loadHelper, Map symbolMap) { this.handler = handler; this.loadHelper = loadHelper; this.symbolMap = symbolMap; this.program = loadHelper.getProgram(); + + if (handler == null) { + loadHelper.log("Unable to process ELF relocations: relocation handler not found"); + } } /** @@ -83,7 +87,7 @@ public class ElfRelocationContext { /** * Process a relocation from the relocation table which corresponds to this context. - * All relocation entries must be processed in the order they appear within the table. + * All relocation entries will be processed in the order they appear within the table. * @param relocation relocation to be processed * @param relocationAddress relocation address where it should be applied * @return applied relocation result @@ -91,81 +95,104 @@ public class ElfRelocationContext { public final RelocationResult processRelocation(ElfRelocation relocation, Address relocationAddress) { + int symbolIndex = relocation.getSymbolIndex(); + ElfSymbol sym = getSymbol(symbolIndex); + if (handler == null) { - handleNoHandlerError(relocation, relocationAddress); + String symbolName = sym != null ? sym.getNameAsString() : null; + ElfRelocationHandler.bookmarkNoHandlerError(program, relocationAddress, + relocation.getType(), symbolIndex, symbolName); return RelocationResult.FAILURE; } - int symbolIndex = relocation.getSymbolIndex(); - ElfSymbol sym = getSymbol(symbolIndex); if (sym == null) { - ElfRelocationHandler.markAsError(program, relocationAddress, relocation.getType(), null, - "invalid symbol index (" + symbolIndex + ")", getLog()); + handler.markAsError(program, relocationAddress, relocation.getType(), null, -1, + "Invalid symbol index (" + symbolIndex + ")", getLog()); return RelocationResult.FAILURE; } if (sym.isTLS()) { - handleUnsupportedTLSRelocation(relocation, relocationAddress, sym); - return RelocationResult.FAILURE; + handler.markAsWarning(program, relocationAddress, relocation.getType(), + sym.getNameAsString(), symbolIndex, "Relocation for TLS Symbol not supported", + getLog()); + return RelocationResult.UNSUPPORTED; } try { - return handler.relocate(this, relocation, relocationAddress); + return processRelocation(relocation, sym, relocationAddress); } catch (MemoryAccessException | NotFoundException e) { loadHelper.log(e); - ElfRelocationHandler.markAsUnhandled(program, relocationAddress, relocation.getType(), - symbolIndex, sym.getNameAsString(), getLog()); + handler.markAsError(program, relocationAddress, relocation.getType(), + sym.getNameAsString(), symbolIndex, "Processing Failure - " + e.getMessage(), + getLog()); } return RelocationResult.FAILURE; } + /** + * Process a relocation from the relocation table which corresponds to this context + * after preliminary checks have been performed and ELF symbol resolved. + * All relocation entries will be processed in the order they appear within the table. + * + * @param relocation relocation to be processed + * @param elfSymbol resolved ELF symbol (not null) + * @param relocationAddress relocation address where it should be applied + * @return applied relocation result + * @throws MemoryAccessException if a memory access error occurs + * @throws NotFoundException NOTE: use of this exception is deprecated and should not be thrown + */ + protected RelocationResult processRelocation(ElfRelocation relocation, ElfSymbol elfSymbol, + Address relocationAddress) throws MemoryAccessException, NotFoundException { + return handler.relocate(this, relocation, relocationAddress); + } + + /** + * Generate relocation error log entry and bookmark. + * + * @param relocationAddress relocation address + * @param typeId relocation type ID value (will get mapped to {@link ElfRelocationType#name()} + * if possible). + * @param symbolIndex associated symbol index within symbol table (-1 to ignore) + * @param symbolName relocation symbol name or null if unknown + * @param msg error message + */ + public final void markRelocationError(Address relocationAddress, int typeId, int symbolIndex, + String symbolName, String msg) { + if (handler != null) { + handler.markAsError(program, relocationAddress, typeId, symbolName, -1, msg, getLog()); + } + else { + // must use static method without relocation type resolution + ElfRelocationHandler.markAsError(program, relocationAddress, typeId, symbolIndex, + symbolName, msg, getLog()); + } + } + /** * Get the RELR relocation type associated with the underlying * relocation handler. * @return RELR relocation type or 0 if not supported */ - public long getRelrRelocationType() { + public int getRelrRelocationType() { return handler != null ? handler.getRelrRelocationType() : 0; } - private void handleUnsupportedTLSRelocation(ElfRelocation relocation, Address relocationAddress, - ElfSymbol sym) { - ElfRelocationHandler.markAsError(program, relocationAddress, relocation.getType(), - sym.getNameAsString(), "TLS symbol relocation not yet supported", getLog()); - } - - private void handleNoHandlerError(ElfRelocation relocation, Address relocationAddress) { - - String symName = getSymbolName(relocation.getSymbolIndex()); - - String nameMsg = ""; - if (!StringUtils.isBlank(symName)) { - nameMsg = " to: " + symName; - } - program.getBookmarkManager() - .setBookmark(relocationAddress, BookmarkType.ERROR, "Relocation", - "No handler to process ELF Relocation" + nameMsg); - - loadHelper.log( - "WARNING: At " + relocationAddress + " no handler to process ELF Relocation" + nameMsg); - } - /** * Get a relocation context for a specfic Elf image and relocation table * @param loadHelper Elf load helper * @param symbolMap Elf symbol placement map - * @return relocation context or null + * @return relocation context object */ - public static ElfRelocationContext getRelocationContext(ElfLoadHelper loadHelper, + public static ElfRelocationContext getRelocationContext(ElfLoadHelper loadHelper, Map symbolMap) { ElfHeader elf = loadHelper.getElfHeader(); - ElfRelocationContext context = null; + ElfRelocationContext context = null; ElfRelocationHandler handler = ElfRelocationHandlerFactory.getHandler(elf); if (handler != null) { context = handler.createRelocationContext(loadHelper, symbolMap); } if (context == null) { - context = new ElfRelocationContext(handler, loadHelper, symbolMap); + context = new ElfRelocationContext<>(handler, loadHelper, symbolMap); } return context; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationHandler.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationHandler.java index 849decf402..ca68b04a57 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationHandler.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationHandler.java @@ -31,12 +31,20 @@ import ghidra.program.model.mem.MemoryBlock; import ghidra.program.model.reloc.RelocationResult; import ghidra.program.model.util.CodeUnitInsertionException; import ghidra.util.Msg; +import ghidra.util.classfinder.ClassSearcher; import ghidra.util.classfinder.ExtensionPoint; import ghidra.util.exception.NotFoundException; /** + * NOTE: ELF relocation handler implementations should extend {@link AbstractElfRelocationHandler} + * which now uses {@link ElfRelocationType} enum values instead of simple constants. This class may + * transition to an interface in the future. This abstract class remains exposed for backward + * compatibility with older implementations. + *
* ElfRelocationHandler provides the base class for processor specific - * ELF relocation handlers. + * ELF relocation handlers. Implementations may only specify a public default constructor + * as they will be identified and instatiated by the {@link ClassSearcher}. As such their + * name must end with "ElfRelocationHandler" (e.g., MyProc_ElfRelocationHandler). */ abstract public class ElfRelocationHandler implements ExtensionPoint { @@ -46,14 +54,24 @@ abstract public class ElfRelocationHandler implements ExtensionPoint { */ public static final String GOT_BLOCK_NAME = "%got"; + /** + * Default abstract constructor for an {@link ElfRelocationHandler}. + * + * @deprecated extending {@link AbstractElfRelocationHandler} in conjunction with the use of + * a processor-specific {@link ElfRelocationType} enum is now preferred. + */ + @Deprecated(since = "11.1", forRemoval = true) + protected ElfRelocationHandler() { + // enumTypesMap use is not supported + } + abstract public boolean canRelocate(ElfHeader elf); /** - * Get the architecture-specific relative relocation type - * which should be applied to RELR relocations. The - * default implementation returns 0 which indicates - * RELR is unsupported. - * @return RELR relocation type + * Get the architecture-specific relative relocation type which should be applied to + * RELR relocations. The default implementation returns 0 which indicates RELR is unsupported. + * + * @return RELR relocation type ID value */ public int getRelrRelocationType() { return 0; @@ -62,31 +80,103 @@ abstract public class ElfRelocationHandler implements ExtensionPoint { /** * Relocation context for a specific Elf image and relocation table. The relocation context * is used to process relocations and manage any data required to process relocations. + * * @param loadHelper Elf load helper * @param symbolMap Elf symbol placement map * @return relocation context or null if unsupported */ - public ElfRelocationContext createRelocationContext(ElfLoadHelper loadHelper, + @SuppressWarnings("rawtypes") + protected ElfRelocationContext createRelocationContext(ElfLoadHelper loadHelper, Map symbolMap) { return null; } /** - * Perform relocation fixup + * Perform relocation fixup. + *
+ * IMPORTANT: this class must be overriden if this implementation does not specify an + * {@link ElfRelocationType} enum class (see {@link #ElfRelocationHandler()}). + * * @param elfRelocationContext relocation context * @param relocation ELF relocation * @param relocationAddress relocation target address (fixup location) * @return applied relocation result (conveys status and applied byte-length) * @throws MemoryAccessException memory access failure - * @throws NotFoundException required relocation data not found + * @throws NotFoundException NOTE: use of this exception is deprecated and should not be thrown */ - abstract public RelocationResult relocate(ElfRelocationContext elfRelocationContext, + @SuppressWarnings("rawtypes") + protected abstract RelocationResult relocate(ElfRelocationContext elfRelocationContext, ElfRelocation relocation, Address relocationAddress) throws MemoryAccessException, NotFoundException; + // + // Error and Warning markup methods + // + + /** + * Generate error log entry and bookmark at relocationAddress indicating + * an unhandled relocation. + * + * @param program program + * @param relocationAddress relocation address to be bookmarked + * @param typeId relocation type ID value + * @param symbolName associated symbol name + * @param symbolIndex symbol index within symbol table (-1 to ignore) + * @param log import log + */ + protected void markAsUnhandled(Program program, Address relocationAddress, int typeId, + String symbolName, int symbolIndex, MessageLog log) { + markupErrorOrWarning(program, "Unhandled ELF Relocation", null, relocationAddress, + getDefaultRelocationTypeDetail(typeId), symbolIndex, symbolName, BookmarkType.ERROR, + log); + } + + /** + * Generate error log entry and bookmark at relocationAddress where relocation failed to + * be applied. + * + * @param program program + * @param relocationAddress relocation address to be bookmarked + * @param typeId relocation type ID value + * @param symbolName associated symbol name + * @param symbolIndex symbol index within symbol table (-1 to ignore) + * @param msg error message + * @param log import log + */ + protected void markAsError(Program program, Address relocationAddress, int typeId, + String symbolName, int symbolIndex, String msg, MessageLog log) { + markupErrorOrWarning(program, "ELF Relocation Error", msg, relocationAddress, + getDefaultRelocationTypeDetail(typeId), symbolIndex, symbolName, BookmarkType.ERROR, + log); + } + + /** + * Generate warning log entry and bookmark at relocationAddress where relocation failed to + * be applied. + * + * @param program program + * @param relocationAddress relocation address to be bookmarked + * @param typeId relocation type ID value + * @param symbolName associated symbol name + * @param symbolIndex symbol index within symbol table (-1 to ignore) + * @param msg error message + * @param log import log + */ + protected void markAsWarning(Program program, Address relocationAddress, int typeId, + String symbolName, int symbolIndex, String msg, MessageLog log) { + markupErrorOrWarning(program, "ELF Relocation Warning", msg, relocationAddress, + getDefaultRelocationTypeDetail(typeId), symbolIndex, symbolName, BookmarkType.WARNING, + log); + } + + // + // Static methods + // + /** * Apply a pointer-typedef with a specified component-offset if specified address * is not contained within an execute block. + * * @param program program * @param addr address where data should be applied * @param componentOffset component offset @@ -116,8 +206,10 @@ abstract public class ElfRelocationHandler implements ExtensionPoint { * If so, relocationAddress will be marked with a EXTERNAL Data Elf Relocation with pointer-offset * warning or error bookmark. Bookmark and logged message will be conveyed as an error if * relocationAddress resides within an executable memory block. + *
* NOTE: This method should only be invoked when the symbol offset will be adjusted with a non-zero * value (i.e., addend). + * * @param program program * @param relocationAddress relocation address to be bookmarked if EXTERNAL block relocation * @param symbolAddr symbol address correspondng to relocation (may be null) @@ -125,9 +217,8 @@ abstract public class ElfRelocationHandler implements ExtensionPoint { * @param adjustment relocation symbol offset adjustment/addend * @param log import log */ - public static void warnExternalOffsetRelocation(Program program, - Address relocationAddress, Address symbolAddr, String symbolName, long adjustment, - MessageLog log) { + public static void warnExternalOffsetRelocation(Program program, Address relocationAddress, + Address symbolAddr, String symbolName, long adjustment, MessageLog log) { if (symbolAddr == null || adjustment == 0 || !program.getMemory().isExternalBlockAddress(symbolAddr)) { @@ -146,7 +237,7 @@ abstract public class ElfRelocationHandler implements ExtensionPoint { String adjStr = sign + "0x" + Long.toHexString(adjustment); symbolName = StringUtils.isEmpty(symbolName) ? ElfSymbol.FORMATTED_NO_NAME : symbolName; - String msg1 = "EXTERNAL Data Elf Relocation with offset: at " + relocationAddress + + String msg1 = "EXTERNAL Data ELF Relocation with offset: at " + relocationAddress + " (External Location = " + symbolName + adjStr + ")"; if (showAsError) { Msg.error(ElfRelocationHandler.class, msg1); @@ -158,146 +249,195 @@ abstract public class ElfRelocationHandler implements ExtensionPoint { BookmarkManager bookmarkManager = program.getBookmarkManager(); bookmarkManager.setBookmark(relocationAddress, BookmarkType.WARNING, "EXTERNAL Relocation", - "EXTERNAL Data Elf Relocation with offset: External Location = " + symbolName + + "EXTERNAL Data ELF Relocation with offset: External Location = " + symbolName + adjStr); } } /** - * Generate error log entry and bookmark at relocationAddress indicating - * an unhandled relocation. + * Get default relocation type details. This will not provide the name of the relocation + * type and must be used for static method invocations or a specific relocation enum type + * is not found. + * + * @param typeId relocation type ID value + * @return formatted relocation type detail for logging + */ + static String getDefaultRelocationTypeDetail(int typeId) { + return "Type = " + Integer.toUnsignedLong(typeId) + " (0x" + Integer.toHexString(typeId) + + ")"; + } + + /** + * Generate error bookmark at relocationAddress indicating a missing relocation handler. + * * @param program program * @param relocationAddress relocation address to be bookmarked - * @param type relocation type - * @param symbolIndex associated symbol index within symbol table + * @param typeId relocation type ID value + * @param symbolIndex associated symbol index within symbol table (-1 to ignore) * @param symbolName associated symbol name - * @param log import log */ - public static void markAsUnhandled(Program program, Address relocationAddress, long type, - long symbolIndex, String symbolName, MessageLog log) { - - symbolName = StringUtils.isEmpty(symbolName) ? ElfSymbol.FORMATTED_NO_NAME : symbolName; - log.appendMsg("Unhandled Elf Relocation: Type = " + type + " (0x" + Long.toHexString(type) + - ") at " + relocationAddress + " (Symbol = " + symbolName + ")"); - BookmarkManager bookmarkManager = program.getBookmarkManager(); - bookmarkManager.setBookmark(relocationAddress, BookmarkType.ERROR, - "Relocation Type " + type, - "Unhandled Elf Relocation: Type = " + type + " (0x" + Long.toHexString(type) + - ") Symbol = " + symbolName + " (0x" + Long.toHexString(symbolIndex) + ")."); + public static void bookmarkNoHandlerError(Program program, Address relocationAddress, + int typeId, int symbolIndex, String symbolName) { + markupErrorOrWarning(program, "No relocation handler", null, relocationAddress, + getDefaultRelocationTypeDetail(typeId), symbolIndex, symbolName, BookmarkType.ERROR, + null); // null log to prevent logging } /** - * Generate error log entry and bookmark at relocationAddress indicating - * an unsupported RELR relocation. + * Generate error bookmark at relocationAddress indicating an unsupported RELR relocation. + * * @param program program * @param relocationAddress relocation address to be bookmarked - */ - public static void markAsUnsupportedRelr(Program program, Address relocationAddress) { - BookmarkManager bookmarkManager = program.getBookmarkManager(); - bookmarkManager.setBookmark(relocationAddress, BookmarkType.ERROR, - "Unsupported RELR Relocation", "ELF Extension does not specify type"); - } - - /** - * Generate error log entry and bookmark at relocationAddress where - * import failed to transition block to initialized while processing relocation. - * @param program program - * @param relocationAddress relocation address to be bookmarked - * @param type relocation type - * @param symbolIndex associated symbol index within symbol table + * @param symbolIndex associated symbol index within symbol table (-1 to ignore) * @param symbolName associated symbol name - * @param log import log */ - public static void markAsUninitializedMemory(Program program, Address relocationAddress, - long type, long symbolIndex, String symbolName, MessageLog log) { - + public static void bookmarkUnsupportedRelr(Program program, Address relocationAddress, + int symbolIndex, String symbolName) { symbolName = StringUtils.isEmpty(symbolName) ? ElfSymbol.FORMATTED_NO_NAME : symbolName; - log.appendMsg("Unable to perform relocation: Type = " + type + " (0x" + - Long.toHexString(type) + ") at " + relocationAddress + " (Symbol = " + symbolName + - ") - uninitialized memory"); + String symbolIndexStr = + symbolIndex < 0 ? "" : (" (0x" + Integer.toHexString(symbolIndex) + ")"); BookmarkManager bookmarkManager = program.getBookmarkManager(); - bookmarkManager.setBookmark(relocationAddress, BookmarkType.ERROR, - "Relocation_Type_" + type, - "Unable to perform relocation: Type = " + type + " (0x" + Long.toHexString(type) + - ") Symbol = " + symbolName + " (0x" + Long.toHexString(symbolIndex) + - ") - uninitialized memory."); + bookmarkManager.setBookmark(relocationAddress, BookmarkType.ERROR, "Relocation", + "Unsupported RELR Relocation: Symbol = " + symbolName + symbolIndexStr + + " - ELF Extension does not specify type"); } /** - * Generate error log entry and bookmark at relocationAddress where - * import failed to be applied. + * Generate error log entry and bookmark at relocationAddress + * * @param program program * @param relocationAddress relocation address to be bookmarked - * @param type relocation type + * @param typeId relocation type + * @param symbolIndex associated symbol index within symbol table (-1 to ignore) * @param symbolName associated symbol name * @param msg error messge * @param log import log */ - public static void markAsError(Program program, Address relocationAddress, long type, + public static void markAsError(Program program, Address relocationAddress, int typeId, + int symbolIndex, String symbolName, String msg, MessageLog log) { + markupErrorOrWarning(program, "Elf Relocation Error", msg, relocationAddress, + getDefaultRelocationTypeDetail(typeId), symbolIndex, symbolName, BookmarkType.ERROR, + log); + } + + /** + * Generate error or warning log entry and bookmark at relocationAddress indicating a + * relocation failure. + * + * @param program program + * @param mainMsg relocation error message (required) + * @param tailMsg relocation error cause (optional, may be null) + * @param relocationAddress relocation address to be bookmarked + * @param relocTypeDetail relocation type detail + * @param symbolIndex associated symbol index within symbol table (-1 to ignore) + * @param symbolName associated symbol name + * @param bookmarkType bookmark type: ({@link BookmarkType#ERROR} or ({@link BookmarkType#WARNING} + * @param log import log or null if no logging required + */ + static void markupErrorOrWarning(Program program, String mainMsg, String tailMsg, + Address relocationAddress, String relocTypeDetail, int symbolIndex, String symbolName, + String bookmarkType, MessageLog log) { + tailMsg = StringUtils.isEmpty(tailMsg) ? "" : (" - " + tailMsg); + symbolName = StringUtils.isEmpty(symbolName) ? ElfSymbol.FORMATTED_NO_NAME : symbolName; + String symbolIndexStr = + symbolIndex < 0 ? "" : (" (0x" + Integer.toHexString(symbolIndex) + ")"); + if (log != null) { + log.appendMsg(mainMsg + ": " + relocTypeDetail + " at " + relocationAddress + + " (Symbol = " + symbolName + ")" + tailMsg); + } + BookmarkManager bookmarkManager = program.getBookmarkManager(); + bookmarkManager.setBookmark(relocationAddress, bookmarkType, "Relocation", mainMsg + ": " + + relocTypeDetail + " Symbol = " + symbolName + symbolIndexStr + tailMsg); + } + + // + // Deprecated methods + // + + /** + * Generate error log entry and bookmark at relocationAddress indicating + * an unhandled relocation. + * + * @param program program + * @param relocationAddress relocation address to be bookmarked + * @param typeId relocation type ID value (limited to int value). + * @param symbolIndex associated symbol index within symbol table (limited to int value). + * @param symbolName associated symbol name + * @param log import log + */ + @Deprecated + public static void markAsUnhandled(Program program, Address relocationAddress, long typeId, + long symbolIndex, String symbolName, MessageLog log) { + markupErrorOrWarning(program, "Unhandled ELF Relocation", null, relocationAddress, + getDefaultRelocationTypeDetail((int) typeId), (int) symbolIndex, symbolName, + BookmarkType.ERROR, log); + } + + /** + * Generate warning log entry and bookmark at relocationAddress + * + * @param program program + * @param relocationAddress relocation address to be bookmarked + * @param type relocation type ID name + * @param msg message associated with warning + * @param log import log + */ + @Deprecated + public static void markAsWarning(Program program, Address relocationAddress, String type, + String msg, MessageLog log) { + markAsWarning(program, relocationAddress, type, null, -1, msg, log); + } + + /** + * Generate warning log entry and bookmark at relocationAddress + * + * @param program program + * @param relocationAddress relocation address to be bookmarked + * @param type relocation type ID name + * @param symbolName symbol name + * @param symbolIndex symbol index (-1 to ignore) + * @param msg message associated with warning + * @param log import log + */ + @Deprecated + public static void markAsWarning(Program program, Address relocationAddress, String type, + String symbolName, int symbolIndex, String msg, MessageLog log) { + markupErrorOrWarning(program, "Elf Relocation Warning", msg, relocationAddress, + "Type = " + type, symbolIndex, symbolName, BookmarkType.WARNING, log); + } + + /** + * Generate error log entry and bookmark at relocationAddress + * + * @param program program + * @param relocationAddress relocation address to be bookmarked + * @param typeId relocation type ID value + * @param symbolName associated symbol name + * @param msg error messge + * @param log import log + */ + @Deprecated + public static void markAsError(Program program, Address relocationAddress, long typeId, String symbolName, String msg, MessageLog log) { - markAsError(program, relocationAddress, type + " (0x" + Long.toHexString(type) + ")", + markAsError(program, relocationAddress, typeId + " (0x" + Long.toHexString(typeId) + ")", symbolName, msg, log); } /** - * Generate error log entry and bookmark at relocationAddress where - * import failed to be applied. + * Generate error log entry and bookmark at relocationAddress + * * @param program program * @param relocationAddress relocation address to be bookmarked - * @param type relocation type + * @param type relocation type ID name * @param symbolName associated symbol name * @param msg additional error message * @param log import log */ + @Deprecated public static void markAsError(Program program, Address relocationAddress, String type, String symbolName, String msg, MessageLog log) { - - symbolName = StringUtils.isEmpty(symbolName) ? ElfSymbol.FORMATTED_NO_NAME : symbolName; - log.appendMsg("Elf Relocation Error: Type = " + type + " at " + relocationAddress + - ", Symbol = " + symbolName + ": " + msg); - BookmarkManager bookmarkManager = program.getBookmarkManager(); - bookmarkManager.setBookmark(relocationAddress, BookmarkType.ERROR, "Relocation_" + type, - "Elf Relocation Error: Symbol = " + symbolName + ": " + msg); - } - - /** - * Generate warning log entry and bookmark at relocationAddress where - * import issue occurred. - * @param program program - * @param relocationAddress relocation address to be bookmarked - * @param type relocation type - * @param msg message associated with warning - * @param log import log - */ - public static void markAsWarning(Program program, Address relocationAddress, String type, - String msg, MessageLog log) { - - markAsWarning(program, relocationAddress, type, null, 0, msg, log); - } - - /** - * Generate warning log entry and bookmark at relocationAddress where - * import issue occurred. - * @param program program - * @param relocationAddress relocation address to be bookmarked - * @param type relocation type - * @param symbolName symbol name - * @param symbolIndex symbol index - * @param msg message associated with warning - * @param log import log - */ - public static void markAsWarning(Program program, Address relocationAddress, String type, - String symbolName, long symbolIndex, String msg, MessageLog log) { - - symbolName = StringUtils.isEmpty(symbolName) ? ElfSymbol.FORMATTED_NO_NAME : symbolName; - log.appendMsg("Elf Relocation Warning: Type = " + type + " at " + relocationAddress + - ", Symbol = " + symbolName + ": " + msg); - BookmarkManager bookmarkManager = program.getBookmarkManager(); - bookmarkManager.setBookmark(relocationAddress, BookmarkType.WARNING, - "Relocation_Type_" + type, - "Unhandled Elf relocation ("+type+") at address: " + relocationAddress + - ". Symbol = " + symbolName + " (" + Long.toHexString(symbolIndex) + ")" + - ". " + msg); + markupErrorOrWarning(program, "Elf Relocation Error", msg, relocationAddress, + "Type = " + type, -1, symbolName, BookmarkType.ERROR, log); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationHandlerFactory.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationHandlerFactory.java index a4760862df..ec9ca2dca3 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationHandlerFactory.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationHandlerFactory.java @@ -15,12 +15,12 @@ */ package ghidra.app.util.bin.format.elf.relocation; -import ghidra.app.util.bin.format.elf.ElfHeader; -import ghidra.util.classfinder.ClassSearcher; - import java.util.ArrayList; import java.util.List; +import ghidra.app.util.bin.format.elf.ElfHeader; +import ghidra.util.classfinder.ClassSearcher; + public final class ElfRelocationHandlerFactory { public final static List getHandlers() { diff --git a/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationConstants.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationType.java similarity index 55% rename from Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationConstants.java rename to Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationType.java index 3849de55c0..40f7cbc4e9 100644 --- a/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationConstants.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfRelocationType.java @@ -15,22 +15,18 @@ */ package ghidra.app.util.bin.format.elf.relocation; -public class eBPF_ElfRelocationConstants { +public interface ElfRelocationType { - /** No operation needed */ - public static final int R_BPF_NONE = 0; - /** S + A */ - public static final int R_BPF_64_64 = 1; - /** S + A */ - public static final int R_BPF_64_ABS64 = 2; - /** S + A */ - public static final int R_BPF_64_ABS32 = 3; - /** S + A */ - public static final int R_BPF_64_NODYLD32 = 4; - /** (S + A) / 8 - 1 */ - public static final int R_BPF_64_32 = 10; + /** + * Get the name of this relocation type (i.e., enum name) + * @return name of this relocation type + */ + public String name(); + + /** + * Get the value associated with this relocation type. + * @return relocation type value. + */ + public int typeId(); - private eBPF_ElfRelocationConstants() { - // no construct - } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java index b930d0f08d..186a116582 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java @@ -879,10 +879,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper { } monitor.initialize(totalCount); - ElfRelocationContext context = null; - if (processRelocations) { - context = ElfRelocationContext.getRelocationContext(this, symbolMap); - } + ElfRelocationContext context = ElfRelocationContext.getRelocationContext(this, symbolMap); try { for (ElfRelocationTable relocationTable : relocationTables) { monitor.checkCancelled(); @@ -979,7 +976,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper { } boolean relrTypeUnknown = false; - long relrRelocationType = 0; + int relrRelocationType = 0; if (relocationTable.isRelrTable() && context != null) { relrRelocationType = context.getRelrRelocationType(); if (relrRelocationType == 0) { @@ -993,7 +990,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper { monitor.checkCancelled(); monitor.incrementProgress(1); - long type = reloc.getType(); + int type = reloc.getType(); if (type == 0) { continue; // ignore relocation type 0 (i.e., ..._NONE) } @@ -1023,8 +1020,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper { try { if (unableToApplyRelocs) { status = Status.FAILURE; - ElfRelocationHandler.markAsError(program, relocAddr, type, symbolName, - "missing symbol table", log); + context.markRelocationError(relocAddr, type, symbolIndex, symbolName, + "Missing symbol table"); continue; } @@ -1039,9 +1036,10 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper { catch (Exception e) { status = Status.FAILURE; Msg.error(this, - "Unexpected exception while converting block to initialized", e); - ElfRelocationHandler.markAsUninitializedMemory(program, relocAddr, type, - reloc.getSymbolIndex(), symbolName, log); + "Unexpected exception while converting block to initialized for relocations", + e); + context.markRelocationError(relocAddr, type, symbolIndex, symbolName, + "Uninitialized memory"); continue; } } @@ -1049,7 +1047,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper { if (context != null) { if (relrTypeUnknown) { status = Status.UNSUPPORTED; - ElfRelocationHandler.markAsUnsupportedRelr(program, relocAddr); + ElfRelocationHandler.bookmarkUnsupportedRelr(program, relocAddr, + symbolIndex, symbolName); } else { RelocationResult result = context.processRelocation(reloc, relocAddr); diff --git a/Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationConstants.java b/Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationConstants.java deleted file mode 100644 index 7b01bfc19d..0000000000 --- a/Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationConstants.java +++ /dev/null @@ -1,349 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.util.bin.format.elf.relocation; - -public class AARCH64_ElfRelocationConstants { - - public static final int R_AARCH64_NONE = 0; - - // .word: (S+A) - public static final int R_AARCH64_P32_ABS32 = 1; - - // .half: (S+A) - public static final int R_AARCH64_P32_ABS16 = 2; - - // .word: (S+A-P) - public static final int R_AARCH64_P32_PREL32 = 3; - - // .half: (S+A-P) - public static final int R_AARCH64_P32_PREL16 = 4; - - // MOV[ZK]: ((S+A) >> 0) & 0xffff - public static final int R_AARCH64_P32_MOVW_UABS_G0 = 5; - - // MOV[ZK]: ((S+A) >> 0) & 0xffff - public static final int R_AARCH64_P32_MOVW_UABS_G0_NC = 6; - - // MOV[ZK]: ((S+A) >> 16) & 0xffff - public static final int R_AARCH64_P32_MOVW_UABS_G1 = 7; - - // MOV[ZN]: ((S+A) >> 0) & 0xffff - public static final int R_AARCH64_P32_MOVW_SABS_G0 = 8; - - // LD-lit: ((S+A-P) >> 2) & 0x7ffff - public static final int R_AARCH64_P32_LD_PREL_LO19 = 9; - - // ADR: (S+A-P) & 0x1fffff - public static final int R_AARCH64_P32_ADR_PREL_LO21 = 10; - - // ADRH: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff - public static final int R_AARCH64_P32_ADR_PREL_PG_HI21 = 11; - - // ADD: (S+A) & 0xfff - public static final int R_AARCH64_P32_ADD_ABS_LO12_NC = 12; - - // LD/ST8: (S+A) & 0xfff - public static final int R_AARCH64_P32_LDST8_ABS_LO12_NC = 13; - - // LD/ST16: (S+A) & 0xffe - public static final int R_AARCH64_P32_LDST16_ABS_LO12_NC = 14; - - // LD/ST32: (S+A) & 0xffc - public static final int R_AARCH64_P32_LDST32_ABS_LO12_NC = 15; - - // LD/ST64: (S+A) & 0xff8 - public static final int R_AARCH64_P32_LDST64_ABS_LO12_NC = 16; - - // LD/ST128: (S+A) & 0xff0 - public static final int R_AARCH64_P32_LDST128_ABS_LO12_NC = 17; - - // TBZ/NZ: ((S+A-P) >> 2) & 0x3fff. - public static final int R_AARCH64_P32_TSTBR14 = 18; - - // B.cond: ((S+A-P) >> 2) & 0x7ffff. - public static final int R_AARCH64_P32_CONDBR19 = 19; - - // B: ((S+A-P) >> 2) & 0x3ffffff. - public static final int R_AARCH64_P32_JUMP26 = 20; - - // BL: ((S+A-P) >> 2) & 0x3ffffff. - public static final int R_AARCH64_P32_CALL26 = 21; - - - public static final int R_AARCH64_P32_GOT_LD_PREL19 = 25; - public static final int R_AARCH64_P32_ADR_GOT_PAGE = 26; - public static final int R_AARCH64_P32_LD32_GOT_LO12_NC = 27; - public static final int R_AARCH64_P32_LD32_GOTPAGE_LO14 = 28; - - public static final int R_AARCH64_P32_TLSGD_ADR_PREL21 = 80; - public static final int R_AARCH64_P32_TLSGD_ADR_PAGE21 = 81; - public static final int R_AARCH64_P32_TLSGD_ADD_LO12_NC = 82; - public static final int R_AARCH64_P32_TLSLD_ADR_PREL21 = 83; - public static final int R_AARCH64_P32_TLSLD_ADR_PAGE21 = 84; - public static final int R_AARCH64_P32_TLSLD_ADD_LO12_NC = 85; - public static final int R_AARCH64_P32_TLSLD_MOVW_DTPREL_G1 = 87; - public static final int R_AARCH64_P32_TLSLD_MOVW_DTPREL_G0 = 88; - public static final int R_AARCH64_P32_TLSLD_MOVW_DTPREL_G0_NC = 89; - public static final int R_AARCH64_P32_TLSLD_ADD_DTPREL_HI12 = 90; - public static final int R_AARCH64_P32_TLSLD_ADD_DTPREL_LO12 = 91; - public static final int R_AARCH64_P32_TLSLD_ADD_DTPREL_LO12_NC = 92; - public static final int R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21 = 103; - public static final int R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC = 104; - public static final int R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19 = 105; - public static final int R_AARCH64_P32_TLSLE_MOVW_TPREL_G1 = 106; - public static final int R_AARCH64_P32_TLSLE_MOVW_TPREL_G0 = 107; - public static final int R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC = 108; - public static final int R_AARCH64_P32_TLSLE_ADD_TPREL_HI12 = 109; - public static final int R_AARCH64_P32_TLSLE_ADD_TPREL_LO12 = 110; - public static final int R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC = 111; - - public static final int R_AARCH64_P32_TLSDESC_LD_PREL19 = 122; - public static final int R_AARCH64_P32_TLSDESC_ADR_PREL21 = 123; - public static final int R_AARCH64_P32_TLSDESC_ADR_PAGE21 = 124; - public static final int R_AARCH64_P32_TLSDESC_LD32_LO12_NC = 125; - public static final int R_AARCH64_P32_TLSDESC_ADD_LO12_NC = 126; - public static final int R_AARCH64_P32_TLSDESC_CALL = 127; - - // Copy symbol at runtime. - public static final int R_AARCH64_P32_COPY = 180; - - // Create GOT entry. - public static final int R_AARCH64_P32_GLOB_DAT = 181; - - // Create PLT entry. - public static final int R_AARCH64_P32_JUMP_SLOT = 182; - - // Adjust by program base. - public static final int R_AARCH64_P32_RELATIVE = 183; - public static final int R_AARCH64_P32_TLS_DTPMOD = 184; - public static final int R_AARCH64_P32_TLS_DTPREL = 185; - public static final int R_AARCH64_P32_TLS_TPREL = 186; - public static final int R_AARCH64_P32_TLSDESC = 187; - public static final int R_AARCH64_P32_IRELATIVE = 188; - - public static final int R_AARCH64_NULL = 256; // No reloc - - // Basic data relocations. - - // .xword: (S+A) - public static final int R_AARCH64_ABS64 = 257; - - // .word: (S+A) - public static final int R_AARCH64_ABS32 = 258; - - // .half: (S+A) - public static final int R_AARCH64_ABS16 = 259; - - // .xword: (S+A-P) - public static final int R_AARCH64_PREL64 = 260; - - // .word: (S+A-P) - public static final int R_AARCH64_PREL32 = 261; - - // .half: (S+A-P) - public static final int R_AARCH64_PREL16 = 262; - - // MOV[ZK]: ((S+A) >> 0) & 0xffff - public static final int R_AARCH64_MOVW_UABS_G0 = 263; - - // MOV[ZK]: ((S+A) >> 0) & 0xffff - public static final int R_AARCH64_MOVW_UABS_G0_NC = 264; - - // MOV[ZK]: ((S+A) >> 16) & 0xffff - public static final int R_AARCH64_MOVW_UABS_G1 = 265; - - // MOV[ZK]: ((S+A) >> 16) & 0xffff - public static final int R_AARCH64_MOVW_UABS_G1_NC = 266; - - // MOV[ZK]: ((S+A) >> 32) & 0xffff - public static final int R_AARCH64_MOVW_UABS_G2 = 267; - - // MOV[ZK]: ((S+A) >> 32) & 0xffff - public static final int R_AARCH64_MOVW_UABS_G2_NC = 268; - - // MOV[ZK]: ((S+A) >> 48) & 0xffff - public static final int R_AARCH64_MOVW_UABS_G3 = 269; - - // MOV[ZN]: ((S+A) >> 0) & 0xffff - public static final int R_AARCH64_MOVW_SABS_G0 = 270; - - // MOV[ZN]: ((S+A) >> 16) & 0xffff - public static final int R_AARCH64_MOVW_SABS_G1 = 271; - - // MOV[ZN]: ((S+A) >> 32) & 0xffff - public static final int R_AARCH64_MOVW_SABS_G2 = 272; - - // LD-lit: ((S+A-P) >> 2) & 0x7ffff - public static final int R_AARCH64_LD_PREL_LO19 = 273; - - // ADR: (S+A-P) & 0x1fffff - public static final int R_AARCH64_ADR_PREL_LO21 = 274; - - // ADRH: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff - public static final int R_AARCH64_ADR_PREL_PG_HI21 = 275; - - // ADRH: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff - public static final int R_AARCH64_ADR_PREL_PG_HI21_NC = 276; - - // ADD: (S+A) & 0xfff - public static final int R_AARCH64_ADD_ABS_LO12_NC = 277; - - // LD/ST8: (S+A) & 0xfff - public static final int R_AARCH64_LDST8_ABS_LO12_NC = 278; - - // TBZ/NZ: ((S+A-P) >> 2) & 0x3fff. - public static final int R_AARCH64_TSTBR14 = 279; - - // B.cond: ((S+A-P) >> 2) & 0x7ffff. - public static final int R_AARCH64_CONDBR19 = 280; - - // B: ((S+A-P) >> 2) & 0x3ffffff. - public static final int R_AARCH64_JUMP26 = 282; - - // BL: ((S+A-P) >> 2) & 0x3ffffff. - public static final int R_AARCH64_CALL26 = 283; - - // LD/ST16: (S+A) & 0xffe - public static final int R_AARCH64_LDST16_ABS_LO12_NC = 284; - - // LD/ST32: (S+A) & 0xffc - public static final int R_AARCH64_LDST32_ABS_LO12_NC = 285; - - // LD/ST64: (S+A) & 0xff8 - public static final int R_AARCH64_LDST64_ABS_LO12_NC = 286; - - public static final int R_AARCH64_MOVW_PREL_G0 = 287; - public static final int R_AARCH64_MOVW_PREL_G0_NC = 288; - public static final int R_AARCH64_MOVW_PREL_G1 = 289; - public static final int R_AARCH64_MOVW_PREL_G1_NC = 290; - public static final int R_AARCH64_MOVW_PREL_G2 = 291; - public static final int R_AARCH64_MOVW_PREL_G2_NC = 292; - public static final int R_AARCH64_MOVW_PREL_G3 = 293; - - // LD/ST128: (S+A) & 0xff0 - public static final int R_AARCH64_LDST128_ABS_LO12_NC = 299; - - public static final int R_AARCH64_MOVW_GOTOFF_G0 = 300; - public static final int R_AARCH64_MOVW_GOTOFF_G0_NC = 301; - public static final int R_AARCH64_MOVW_GOTOFF_G1 = 302; - public static final int R_AARCH64_MOVW_GOTOFF_G1_NC = 303; - public static final int R_AARCH64_MOVW_GOTOFF_G2 = 304; - public static final int R_AARCH64_MOVW_GOTOFF_G2_NC = 305; - public static final int R_AARCH64_MOVW_GOTOFF_G3 = 306; - - public static final int R_AARCH64_GOTREL64 = 307; - public static final int R_AARCH64_GOTREL32 = 308; - - public static final int R_AARCH64_GOT_LD_PREL19 = 309; - public static final int R_AARCH64_LD64_GOTOFF_LO15 = 310; - public static final int R_AARCH64_ADR_GOT_PAGE = 311; - public static final int R_AARCH64_LD64_GOT_LO12_NC = 312; - public static final int R_AARCH64_LD64_GOTPAGE_LO15 = 313; - - public static final int R_AARCH64_TLSGD_ADR_PREL21 = 512; - public static final int R_AARCH64_TLSGD_ADR_PAGE21 = 513; - public static final int R_AARCH64_TLSGD_ADD_LO12_NC = 514; - public static final int R_AARCH64_TLSGD_MOVW_G1 = 515; - public static final int R_AARCH64_TLSGD_MOVW_G0_NC = 516; - - public static final int R_AARCH64_TLSLD_ADR_PREL21 = 517; - public static final int R_AARCH64_TLSLD_ADR_PAGE21 = 518; - public static final int R_AARCH64_TLSLD_ADD_LO12_NC = 519; - public static final int R_AARCH64_TLSLD_MOVW_G1 = 520; - public static final int R_AARCH64_TLSLD_MOVW_G0_NC = 521; - public static final int R_AARCH64_TLSLD_LD_PREL19 = 522; - public static final int R_AARCH64_TLSLD_MOVW_DTPREL_G2 = 523; - public static final int R_AARCH64_TLSLD_MOVW_DTPREL_G1 = 524; - public static final int R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC = 525; - public static final int R_AARCH64_TLSLD_MOVW_DTPREL_G0 = 526; - public static final int R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC = 527; - public static final int R_AARCH64_TLSLD_ADD_DTPREL_HI12 = 528; - public static final int R_AARCH64_TLSLD_ADD_DTPREL_LO12 = 529; - public static final int R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC = 530; - public static final int R_AARCH64_TLSLD_LDST8_DTPREL_LO12 = 531; - public static final int R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC = 532; - public static final int R_AARCH64_TLSLD_LDST16_DTPREL_LO12 = 533; - public static final int R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC = 534; - public static final int R_AARCH64_TLSLD_LDST32_DTPREL_LO12 = 535; - public static final int R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC = 536; - public static final int R_AARCH64_TLSLD_LDST64_DTPREL_LO12 = 537; - public static final int R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC = 538; - - public static final int R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 = 539; - public static final int R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC = 540; - public static final int R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 = 541; - public static final int R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC = 542; - public static final int R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 = 543; - - public static final int R_AARCH64_TLSLE_MOVW_TPREL_G2 = 544; - public static final int R_AARCH64_TLSLE_MOVW_TPREL_G1 = 545; - public static final int R_AARCH64_TLSLE_MOVW_TPREL_G1_NC = 546; - public static final int R_AARCH64_TLSLE_MOVW_TPREL_G0 = 547; - public static final int R_AARCH64_TLSLE_MOVW_TPREL_G0_NC = 548; - public static final int R_AARCH64_TLSLE_ADD_TPREL_HI12 = 549; - public static final int R_AARCH64_TLSLE_ADD_TPREL_LO12 = 550; - public static final int R_AARCH64_TLSLE_ADD_TPREL_LO12_NC = 551; - public static final int R_AARCH64_TLSLE_LDST8_TPREL_LO12 = 552; - public static final int R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC = 553; - public static final int R_AARCH64_TLSLE_LDST16_TPREL_LO12 = 554; - public static final int R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC = 555; - public static final int R_AARCH64_TLSLE_LDST32_TPREL_LO12 = 556; - public static final int R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC = 557; - public static final int R_AARCH64_TLSLE_LDST64_TPREL_LO12 = 558; - public static final int R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC = 559; - - public static final int R_AARCH64_TLSDESC_LD_PREL19 = 560; - public static final int R_AARCH64_TLSDESC_ADR_PREL21 = 561; - public static final int R_AARCH64_TLSDESC_ADR_PAGE21 = 562; - public static final int R_AARCH64_TLSDESC_LD64_LO12_NC = 563; - public static final int R_AARCH64_TLSDESC_ADD_LO12_NC = 564; - public static final int R_AARCH64_TLSDESC_OFF_G1 = 565; - public static final int R_AARCH64_TLSDESC_OFF_G0_NC = 566; - public static final int R_AARCH64_TLSDESC_LDR = 567; - public static final int R_AARCH64_TLSDESC_ADD = 568; - public static final int R_AARCH64_TLSDESC_CALL = 569; - - public static final int R_AARCH64_TLSLE_LDST128_TPREL_LO12 = 570; - public static final int R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC = 571; - public static final int R_AARCH64_TLSLD_LDST128_DTPREL_LO12 = 572; - public static final int R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC = 573; - - // Copy symbol at runtime. - public static final int R_AARCH64_COPY = 1024; - - // Create GOT entry. - public static final int R_AARCH64_GLOB_DAT = 1025; - - // Create PLT entry. - public static final int R_AARCH64_JUMP_SLOT = 1026; - - // Adjust by program base. - public static final int R_AARCH64_RELATIVE = 1027; - public static final int R_AARCH64_TLS_DTPMOD64 = 1028; - public static final int R_AARCH64_TLS_DTPREL64 = 1029; - public static final int R_AARCH64_TLS_TPREL64 = 1030; - - public static final int R_AARCH64_TLS_DTPMOD = 1028; - public static final int R_AARCH64_TLS_DTPREL = 1029; - public static final int R_AARCH64_TLS_TPREL = 1030; - - public static final int R_AARCH64_TLSDESC = 1031; - public static final int R_AARCH64_IRELATIVE = 1032; - - private AARCH64_ElfRelocationConstants() { - // no construct - } -} diff --git a/Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationHandler.java b/Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationHandler.java index 04d6998bdc..cb8ffb6d27 100644 --- a/Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationHandler.java +++ b/Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationHandler.java @@ -24,9 +24,16 @@ import ghidra.program.model.listing.Program; import ghidra.program.model.mem.*; import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.reloc.RelocationResult; -import ghidra.util.exception.NotFoundException; -public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { +public class AARCH64_ElfRelocationHandler + extends AbstractElfRelocationHandler> { + + /** + * Constructor + */ + public AARCH64_ElfRelocationHandler() { + super(AARCH64_ElfRelocationType.class); + } @Override public boolean canRelocate(ElfHeader elf) { @@ -35,58 +42,37 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { @Override public int getRelrRelocationType() { - return AARCH64_ElfRelocationConstants.R_AARCH64_RELATIVE; + return AARCH64_ElfRelocationType.R_AARCH64_RELATIVE.typeId; } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, - Address relocationAddress) throws MemoryAccessException, NotFoundException { - - ElfHeader elf = elfRelocationContext.getElfHeader(); - if (elf.e_machine() != ElfConstants.EM_AARCH64) { - return RelocationResult.FAILURE; - } + protected RelocationResult relocate(ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, AARCH64_ElfRelocationType type, Address relocationAddress, + ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); - - int type = relocation.getType(); - if (type == AARCH64_ElfRelocationConstants.R_AARCH64_NONE) { - return RelocationResult.SKIPPED; - } - int symbolIndex = relocation.getSymbolIndex(); - - long addend = relocation.getAddend(); // will be 0 for REL case - - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); - String symbolName = sym.getNameAsString(); - - //boolean isThumb = isThumb(sym); - - long offset = (int) relocationAddress.getOffset(); - boolean isBigEndianInstructions = program.getLanguage().getLanguageDescription().getInstructionEndian().isBigEndian(); + long addend = relocation.getAddend(); // will be 0 for REL case + + long offset = relocationAddress.getOffset(); + int symbolIndex = relocation.getSymbolIndex(); boolean is64bit = true; - boolean overflowCheck = true; // *_NC type relocations specify "no overflow check" - - Address symbolAddr = elfRelocationContext.getSymbolAddress(sym); - long symbolValue = elfRelocationContext.getSymbolValue(sym); long newValue = 0; - int byteLength = 4; // most relocations affect 4-bytes (change if different) switch (type) { // .xword: (S+A) - case AARCH64_ElfRelocationConstants.R_AARCH64_ABS64: { + case R_AARCH64_ABS64: { newValue = (symbolValue + addend); memory.setLong(relocationAddress, newValue); if (symbolIndex != 0 && addend != 0 && !sym.isSection()) { - warnExternalOffsetRelocation(program, relocationAddress, - symbolAddr, symbolName, addend, elfRelocationContext.getLog()); + warnExternalOffsetRelocation(program, relocationAddress, symbolAddr, symbolName, + addend, elfRelocationContext.getLog()); applyComponentOffsetPointer(program, relocationAddress, addend); } byteLength = 8; @@ -94,17 +80,17 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { } // .word: (S+A) - case AARCH64_ElfRelocationConstants.R_AARCH64_ABS32: - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_ABS32:{ + case R_AARCH64_ABS32: + case R_AARCH64_P32_ABS32: { newValue = (symbolValue + addend); memory.setInt(relocationAddress, (int) (newValue & 0xffffffff)); break; } // .half: (S+A) - - case AARCH64_ElfRelocationConstants.R_AARCH64_ABS16: - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_ABS16: { + + case R_AARCH64_ABS16: + case R_AARCH64_P32_ABS16: { newValue = (symbolValue + addend); memory.setShort(relocationAddress, (short) (newValue & 0xffff)); byteLength = 2; @@ -112,7 +98,7 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { } // .xword: (S+A-P) - case AARCH64_ElfRelocationConstants.R_AARCH64_PREL64: { + case R_AARCH64_PREL64: { newValue = (symbolValue + addend); newValue -= (offset); // PC relative memory.setLong(relocationAddress, newValue); @@ -121,8 +107,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { } // .word: (S+A-P) - case AARCH64_ElfRelocationConstants.R_AARCH64_PREL32: - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_PREL32: { + case R_AARCH64_PREL32: + case R_AARCH64_P32_PREL32: { newValue = (symbolValue + addend); newValue -= (offset); // PC relative memory.setInt(relocationAddress, (int) (newValue & 0xffffffff)); @@ -130,8 +116,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { } // .half: (S+A-P) - case AARCH64_ElfRelocationConstants.R_AARCH64_PREL16: - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_PREL16: { + case R_AARCH64_PREL16: + case R_AARCH64_P32_PREL16: { newValue = (symbolValue + addend); newValue -= (offset); // PC relative memory.setShort(relocationAddress, (short) (newValue & 0xffff)); @@ -140,11 +126,11 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { } // MOV[ZK]: ((S+A) >> 0) & 0xffff - case AARCH64_ElfRelocationConstants.R_AARCH64_MOVW_UABS_G0_NC: { + case R_AARCH64_MOVW_UABS_G0_NC: { overflowCheck = false; // fall-through } - case AARCH64_ElfRelocationConstants.R_AARCH64_MOVW_UABS_G0: { + case R_AARCH64_MOVW_UABS_G0: { int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions); long imm = (symbolValue + addend) >> 0; @@ -155,19 +141,18 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { if (overflowCheck && imm > 0xffffL) { // relocation already applied; report overflow condition - markAsError(program, relocationAddress, "R_AARCH64_MOVW_UABS_G0", symbolName, - "Failed overflow check for R_AARCH64_MOVW_UABS_G0 immediate value", - elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed overflow check for immediate value", elfRelocationContext.getLog()); } break; } // MOV[ZK]: ((S+A) >> 16) & 0xffff - case AARCH64_ElfRelocationConstants.R_AARCH64_MOVW_UABS_G1_NC: { + case R_AARCH64_MOVW_UABS_G1_NC: { overflowCheck = false; // fall-through } - case AARCH64_ElfRelocationConstants.R_AARCH64_MOVW_UABS_G1: { + case R_AARCH64_MOVW_UABS_G1: { int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions); long imm = (symbolValue + addend) >> 16; @@ -178,19 +163,18 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { if (overflowCheck && imm > 0xffffL) { // relocation already applied; report overflow condition - markAsError(program, relocationAddress, "R_AARCH64_MOVW_UABS_G0", symbolName, - "Failed overflow check for R_AARCH64_MOVW_UABS_G0 immediate value", - elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed overflow check for immediate value", elfRelocationContext.getLog()); } break; } // MOV[ZK]: ((S+A) >> 32) & 0xffff - case AARCH64_ElfRelocationConstants.R_AARCH64_MOVW_UABS_G2_NC: { + case R_AARCH64_MOVW_UABS_G2_NC: { overflowCheck = false; // fall-through } - case AARCH64_ElfRelocationConstants.R_AARCH64_MOVW_UABS_G2: { + case R_AARCH64_MOVW_UABS_G2: { int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions); long imm = (symbolValue + addend) >> 32; @@ -201,15 +185,14 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { if (overflowCheck && imm > 0xffffL) { // relocation already applied; report overflow condition - markAsError(program, relocationAddress, "R_AARCH64_MOVW_UABS_G0", symbolName, - "Failed overflow check for R_AARCH64_MOVW_UABS_G0 immediate value", - elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed overflow check for immediate value", elfRelocationContext.getLog()); } break; } // MOV[ZK]: ((S+A) >> 48) & 0xffff - case AARCH64_ElfRelocationConstants.R_AARCH64_MOVW_UABS_G3: { + case R_AARCH64_MOVW_UABS_G3: { int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions); long imm = (symbolValue + addend) >> 48; @@ -221,8 +204,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { } // ADRH: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff - case AARCH64_ElfRelocationConstants.R_AARCH64_ADR_PREL_PG_HI21: - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_ADR_PREL_PG_HI21: { + case R_AARCH64_ADR_PREL_PG_HI21: + case R_AARCH64_P32_ADR_PREL_PG_HI21: { int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions); newValue = ((PG(symbolValue + addend) - PG(offset)) >> 12) & 0x1fffff; @@ -234,8 +217,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { } // ADD: (S+A) & 0xfff - case AARCH64_ElfRelocationConstants.R_AARCH64_ADD_ABS_LO12_NC: - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_ADD_ABS_LO12_NC: { + case R_AARCH64_ADD_ABS_LO12_NC: + case R_AARCH64_P32_ADD_ABS_LO12_NC: { int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions); newValue = (int) (symbolValue + addend) & 0xfff; @@ -246,8 +229,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { } // LD/ST8: (S+A) & 0xfff - case AARCH64_ElfRelocationConstants.R_AARCH64_LDST8_ABS_LO12_NC: - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_LDST8_ABS_LO12_NC: { + case R_AARCH64_LDST8_ABS_LO12_NC: + case R_AARCH64_P32_LDST8_ABS_LO12_NC: { int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions); newValue = (int) (symbolValue + addend) & 0xfff; @@ -259,10 +242,10 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { // B: ((S+A-P) >> 2) & 0x3ffffff. // BL: ((S+A-P) >> 2) & 0x3ffffff - case AARCH64_ElfRelocationConstants.R_AARCH64_JUMP26: - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_JUMP26: - case AARCH64_ElfRelocationConstants.R_AARCH64_CALL26: - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_CALL26: { + case R_AARCH64_JUMP26: + case R_AARCH64_P32_JUMP26: + case R_AARCH64_CALL26: + case R_AARCH64_P32_CALL26: { int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions); newValue = (symbolValue + addend); @@ -275,8 +258,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { } // LD/ST16: (S+A) & 0xffe - case AARCH64_ElfRelocationConstants.R_AARCH64_LDST16_ABS_LO12_NC: - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_LDST16_ABS_LO12_NC: { + case R_AARCH64_LDST16_ABS_LO12_NC: + case R_AARCH64_P32_LDST16_ABS_LO12_NC: { int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions); newValue = (int) ((symbolValue + addend) & 0xffe) >> 1; @@ -287,8 +270,8 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { } // LD/ST32: (S+A) & 0xffc - case AARCH64_ElfRelocationConstants.R_AARCH64_LDST32_ABS_LO12_NC: - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_LDST32_ABS_LO12_NC: { + case R_AARCH64_LDST32_ABS_LO12_NC: + case R_AARCH64_P32_LDST32_ABS_LO12_NC: { int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions); newValue = (int) ((symbolValue + addend) & 0xffc) >> 2; @@ -299,9 +282,9 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { } // LD/ST64: (S+A) & 0xff8 - case AARCH64_ElfRelocationConstants.R_AARCH64_LDST64_ABS_LO12_NC: - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_LDST64_ABS_LO12_NC: - case AARCH64_ElfRelocationConstants.R_AARCH64_LD64_GOT_LO12_NC: { + case R_AARCH64_LDST64_ABS_LO12_NC: + case R_AARCH64_P32_LDST64_ABS_LO12_NC: + case R_AARCH64_LD64_GOT_LO12_NC: { int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions); newValue = (int) ((symbolValue + addend) & 0xff8) >> 3; @@ -312,7 +295,7 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { } // LD/ST128: (S+A) & 0xff0 - case AARCH64_ElfRelocationConstants.R_AARCH64_LDST128_ABS_LO12_NC: { + case R_AARCH64_LDST128_ABS_LO12_NC: { int oldValue = memory.getInt(relocationAddress, isBigEndianInstructions); newValue = (int) ((symbolValue + addend) & 0xff0) >> 4; @@ -322,9 +305,9 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { break; } - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_GLOB_DAT: + case R_AARCH64_P32_GLOB_DAT: is64bit = false; - case AARCH64_ElfRelocationConstants.R_AARCH64_GLOB_DAT: { + case R_AARCH64_GLOB_DAT: { // Corresponds to resolved local/EXTERNAL symbols within GOT if (elfRelocationContext.extractAddend()) { addend = getValue(memory, relocationAddress, is64bit); @@ -334,9 +317,9 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { break; } - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_JUMP_SLOT: + case R_AARCH64_P32_JUMP_SLOT: is64bit = false; - case AARCH64_ElfRelocationConstants.R_AARCH64_JUMP_SLOT: { + case R_AARCH64_JUMP_SLOT: { // Corresponds to lazy dynamically linked external symbols within // GOT/PLT symbolValue corresponds to PLT entry for which we need to // create and external function location. Don't bother changing @@ -352,22 +335,20 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { setValue(memory, relocationAddress, symAddress.getOffset(), is64bit); } if ((isPltSym || isExternalSym) && !StringUtils.isBlank(symbolName)) { - Function extFunction = - elfRelocationContext.getLoadHelper().createExternalFunctionLinkage( - symbolName, symAddress, null); + Function extFunction = elfRelocationContext.getLoadHelper() + .createExternalFunctionLinkage(symbolName, symAddress, null); if (extFunction == null) { - markAsError(program, relocationAddress, "R_AARCH64_JUMP_SLOT", symbolName, - "Failed to create R_AARCH64_JUMP_SLOT external function", - elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to create external function", elfRelocationContext.getLog()); // relocation already applied above } } break; } - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_RELATIVE: + case R_AARCH64_P32_RELATIVE: is64bit = false; - case AARCH64_ElfRelocationConstants.R_AARCH64_RELATIVE: { + case R_AARCH64_RELATIVE: { if (elfRelocationContext.extractAddend()) { addend = getValue(memory, relocationAddress, is64bit); } @@ -376,9 +357,9 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { break; } - case AARCH64_ElfRelocationConstants.R_AARCH64_P32_COPY: - case AARCH64_ElfRelocationConstants.R_AARCH64_COPY: { - markAsWarning(program, relocationAddress, "R_AARCH64_COPY", symbolName, symbolIndex, + case R_AARCH64_P32_COPY: + case R_AARCH64_COPY: { + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, "Runtime copy not supported", elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; } @@ -418,7 +399,7 @@ public class AARCH64_ElfRelocationHandler extends ElfRelocationHandler { * @param addr address in memory * @param is64bit true if 64 bit value, false if 32 bit value * @return value from memory as a long - * @throws MemoryAccessException + * @throws MemoryAccessException if memory access failed */ private long getValue(Memory memory, Address addr, boolean is64bit) throws MemoryAccessException { diff --git a/Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationType.java b/Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationType.java new file mode 100644 index 0000000000..73e70d8b96 --- /dev/null +++ b/Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationType.java @@ -0,0 +1,237 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum AARCH64_ElfRelocationType implements ElfRelocationType { + + R_AARCH64_NONE(0), + R_AARCH64_P32_ABS32(1), // .word: (S+A) + R_AARCH64_P32_ABS16(2), // .half: (S+A) + R_AARCH64_P32_PREL32(3), // .word: (S+A-P) + R_AARCH64_P32_PREL16(4), // .half: (S+A-P) + R_AARCH64_P32_MOVW_UABS_G0(5), // MOV[ZK]: ((S+A) >> 0) & 0xffff + R_AARCH64_P32_MOVW_UABS_G0_NC(6), // MOV[ZK]: ((S+A) >> 0) & 0xffff + R_AARCH64_P32_MOVW_UABS_G1(7), // MOV[ZK]: ((S+A) >> 16) & 0xffff + R_AARCH64_P32_MOVW_SABS_G0(8), // MOV[ZN]: ((S+A) >> 0) & 0xffff + R_AARCH64_P32_LD_PREL_LO19(9), // LD-lit: ((S+A-P) >> 2) & 0x7ffff + R_AARCH64_P32_ADR_PREL_LO21(10), // ADR: (S+A-P) & 0x1fffff + R_AARCH64_P32_ADR_PREL_PG_HI21(11), // ADRH: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff + R_AARCH64_P32_ADD_ABS_LO12_NC(12), // ADD: (S+A) & 0xfff + R_AARCH64_P32_LDST8_ABS_LO12_NC(13), // LD/ST8: (S+A) & 0xfff + R_AARCH64_P32_LDST16_ABS_LO12_NC(14), // LD/ST16: (S+A) & 0xffe + R_AARCH64_P32_LDST32_ABS_LO12_NC(15), // LD/ST32: (S+A) & 0xffc + R_AARCH64_P32_LDST64_ABS_LO12_NC(16), // LD/ST64: (S+A) & 0xff8 + R_AARCH64_P32_LDST128_ABS_LO12_NC(17), // LD/ST128: (S+A) & 0xff0 + R_AARCH64_P32_TSTBR14(18), // TBZ/NZ: ((S+A-P) >> 2) & 0x3fff. + R_AARCH64_P32_CONDBR19(19), // B.cond: ((S+A-P) >> 2) & 0x7ffff. + R_AARCH64_P32_JUMP26(20), // B: ((S+A-P) >> 2) & 0x3ffffff. + R_AARCH64_P32_CALL26(21), // BL: ((S+A-P) >> 2) & 0x3ffffff. + + R_AARCH64_P32_GOT_LD_PREL19(25), + R_AARCH64_P32_ADR_GOT_PAGE(26), + R_AARCH64_P32_LD32_GOT_LO12_NC(27), + R_AARCH64_P32_LD32_GOTPAGE_LO14(28), + + R_AARCH64_P32_TLSGD_ADR_PREL21(80), + R_AARCH64_P32_TLSGD_ADR_PAGE21(81), + R_AARCH64_P32_TLSGD_ADD_LO12_NC(82), + R_AARCH64_P32_TLSLD_ADR_PREL21(83), + R_AARCH64_P32_TLSLD_ADR_PAGE21(84), + R_AARCH64_P32_TLSLD_ADD_LO12_NC(85), + R_AARCH64_P32_TLSLD_MOVW_DTPREL_G1(87), + R_AARCH64_P32_TLSLD_MOVW_DTPREL_G0(88), + R_AARCH64_P32_TLSLD_MOVW_DTPREL_G0_NC(89), + R_AARCH64_P32_TLSLD_ADD_DTPREL_HI12(90), + R_AARCH64_P32_TLSLD_ADD_DTPREL_LO12(91), + R_AARCH64_P32_TLSLD_ADD_DTPREL_LO12_NC(92), + R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21(103), + R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC(104), + R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19(105), + R_AARCH64_P32_TLSLE_MOVW_TPREL_G1(106), + R_AARCH64_P32_TLSLE_MOVW_TPREL_G0(107), + R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC(108), + R_AARCH64_P32_TLSLE_ADD_TPREL_HI12(109), + R_AARCH64_P32_TLSLE_ADD_TPREL_LO12(110), + R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC(111), + + R_AARCH64_P32_TLSDESC_LD_PREL19(122), + R_AARCH64_P32_TLSDESC_ADR_PREL21(123), + R_AARCH64_P32_TLSDESC_ADR_PAGE21(124), + R_AARCH64_P32_TLSDESC_LD32_LO12_NC(125), + R_AARCH64_P32_TLSDESC_ADD_LO12_NC(126), + R_AARCH64_P32_TLSDESC_CALL(127), + + R_AARCH64_P32_COPY(180), // Copy symbol at runtime. + R_AARCH64_P32_GLOB_DAT(181), // Create GOT entry. + R_AARCH64_P32_JUMP_SLOT(182), // Create PLT entry. + + // Adjust by program base. + R_AARCH64_P32_RELATIVE(183), + R_AARCH64_P32_TLS_DTPMOD(184), + R_AARCH64_P32_TLS_DTPREL(185), + R_AARCH64_P32_TLS_TPREL(186), + R_AARCH64_P32_TLSDESC(187), + R_AARCH64_P32_IRELATIVE(188), + + R_AARCH64_NULL(256), // No reloc + + // Basic data relocations. + R_AARCH64_ABS64(257), // .xword: (S+A) + R_AARCH64_ABS32(258), // .word: (S+A) + R_AARCH64_ABS16(259), // .half: (S+A) + R_AARCH64_PREL64(260), // .xword: (S+A-P) + R_AARCH64_PREL32(261), // .word: (S+A-P) + R_AARCH64_PREL16(262), // .half: (S+A-P) + + R_AARCH64_MOVW_UABS_G0(263), // MOV[ZK]: ((S+A) >> 0) & 0xffff + R_AARCH64_MOVW_UABS_G0_NC(264), // MOV[ZK]: ((S+A) >> 0) & 0xffff + R_AARCH64_MOVW_UABS_G1(265), // MOV[ZK]: ((S+A) >> 16) & 0xffff + R_AARCH64_MOVW_UABS_G1_NC(266), // MOV[ZK]: ((S+A) >> 16) & 0xffff + R_AARCH64_MOVW_UABS_G2(267), // MOV[ZK]: ((S+A) >> 32) & 0xffff + R_AARCH64_MOVW_UABS_G2_NC(268), // MOV[ZK]: ((S+A) >> 32) & 0xffff + R_AARCH64_MOVW_UABS_G3(269), // MOV[ZK]: ((S+A) >> 48) & 0xffff + R_AARCH64_MOVW_SABS_G0(270), // MOV[ZN]: ((S+A) >> 0) & 0xffff + R_AARCH64_MOVW_SABS_G1(271), // MOV[ZN]: ((S+A) >> 16) & 0xffff + R_AARCH64_MOVW_SABS_G2(272), // MOV[ZN]: ((S+A) >> 32) & 0xffff + R_AARCH64_LD_PREL_LO19(273), // LD-lit: ((S+A-P) >> 2) & 0x7ffff + R_AARCH64_ADR_PREL_LO21(274), // ADR: (S+A-P) & 0x1fffff + R_AARCH64_ADR_PREL_PG_HI21(275), // ADRH: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff + R_AARCH64_ADR_PREL_PG_HI21_NC(276), // ADRH: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff + R_AARCH64_ADD_ABS_LO12_NC(277), // ADD: (S+A) & 0xfff + R_AARCH64_LDST8_ABS_LO12_NC(278), // LD/ST8: (S+A) & 0xfff + R_AARCH64_TSTBR14(279), // TBZ/NZ: ((S+A-P) >> 2) & 0x3fff. + R_AARCH64_CONDBR19(280), // B.cond: ((S+A-P) >> 2) & 0x7ffff. + R_AARCH64_JUMP26(282), // B: ((S+A-P) >> 2) & 0x3ffffff. + R_AARCH64_CALL26(283), // BL: ((S+A-P) >> 2) & 0x3ffffff. + R_AARCH64_LDST16_ABS_LO12_NC(284), // LD/ST16: (S+A) & 0xffe + R_AARCH64_LDST32_ABS_LO12_NC(285), // LD/ST32: (S+A) & 0xffc + R_AARCH64_LDST64_ABS_LO12_NC(286), // LD/ST64: (S+A) & 0xff8 + R_AARCH64_MOVW_PREL_G0(287), + R_AARCH64_MOVW_PREL_G0_NC(288), + R_AARCH64_MOVW_PREL_G1(289), + R_AARCH64_MOVW_PREL_G1_NC(290), + R_AARCH64_MOVW_PREL_G2(291), + R_AARCH64_MOVW_PREL_G2_NC(292), + R_AARCH64_MOVW_PREL_G3(293), + R_AARCH64_LDST128_ABS_LO12_NC(299), // LD/ST128: (S+A) & 0xff0 + R_AARCH64_MOVW_GOTOFF_G0(300), + R_AARCH64_MOVW_GOTOFF_G0_NC(301), + R_AARCH64_MOVW_GOTOFF_G1(302), + R_AARCH64_MOVW_GOTOFF_G1_NC(303), + R_AARCH64_MOVW_GOTOFF_G2(304), + R_AARCH64_MOVW_GOTOFF_G2_NC(305), + R_AARCH64_MOVW_GOTOFF_G3(306), + R_AARCH64_GOTREL64(307), + R_AARCH64_GOTREL32(308), + R_AARCH64_GOT_LD_PREL19(309), + R_AARCH64_LD64_GOTOFF_LO15(310), + R_AARCH64_ADR_GOT_PAGE(311), + R_AARCH64_LD64_GOT_LO12_NC(312), + R_AARCH64_LD64_GOTPAGE_LO15(313), + + R_AARCH64_TLSGD_ADR_PREL21(512), + R_AARCH64_TLSGD_ADR_PAGE21(513), + R_AARCH64_TLSGD_ADD_LO12_NC(514), + R_AARCH64_TLSGD_MOVW_G1(515), + R_AARCH64_TLSGD_MOVW_G0_NC(516), + + R_AARCH64_TLSLD_ADR_PREL21(517), + R_AARCH64_TLSLD_ADR_PAGE21(518), + R_AARCH64_TLSLD_ADD_LO12_NC(519), + R_AARCH64_TLSLD_MOVW_G1(520), + R_AARCH64_TLSLD_MOVW_G0_NC(521), + R_AARCH64_TLSLD_LD_PREL19(522), + R_AARCH64_TLSLD_MOVW_DTPREL_G2(523), + R_AARCH64_TLSLD_MOVW_DTPREL_G1(524), + R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC(525), + R_AARCH64_TLSLD_MOVW_DTPREL_G0(526), + R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC(527), + R_AARCH64_TLSLD_ADD_DTPREL_HI12(528), + R_AARCH64_TLSLD_ADD_DTPREL_LO12(529), + R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC(530), + R_AARCH64_TLSLD_LDST8_DTPREL_LO12(531), + R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC(532), + R_AARCH64_TLSLD_LDST16_DTPREL_LO12(533), + R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC(534), + R_AARCH64_TLSLD_LDST32_DTPREL_LO12(535), + R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC(536), + R_AARCH64_TLSLD_LDST64_DTPREL_LO12(537), + R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC(538), + + R_AARCH64_TLSIE_MOVW_GOTTPREL_G1(539), + R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC(540), + R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21(541), + R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC(542), + R_AARCH64_TLSIE_LD_GOTTPREL_PREL19(543), + + R_AARCH64_TLSLE_MOVW_TPREL_G2(544), + R_AARCH64_TLSLE_MOVW_TPREL_G1(545), + R_AARCH64_TLSLE_MOVW_TPREL_G1_NC(546), + R_AARCH64_TLSLE_MOVW_TPREL_G0(547), + R_AARCH64_TLSLE_MOVW_TPREL_G0_NC(548), + R_AARCH64_TLSLE_ADD_TPREL_HI12(549), + R_AARCH64_TLSLE_ADD_TPREL_LO12(550), + R_AARCH64_TLSLE_ADD_TPREL_LO12_NC(551), + R_AARCH64_TLSLE_LDST8_TPREL_LO12(552), + R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC(553), + R_AARCH64_TLSLE_LDST16_TPREL_LO12(554), + R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC(555), + R_AARCH64_TLSLE_LDST32_TPREL_LO12(556), + R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC(557), + R_AARCH64_TLSLE_LDST64_TPREL_LO12(558), + R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC(559), + + R_AARCH64_TLSDESC_LD_PREL19(560), + R_AARCH64_TLSDESC_ADR_PREL21(561), + R_AARCH64_TLSDESC_ADR_PAGE21(562), + R_AARCH64_TLSDESC_LD64_LO12_NC(563), + R_AARCH64_TLSDESC_ADD_LO12_NC(564), + R_AARCH64_TLSDESC_OFF_G1(565), + R_AARCH64_TLSDESC_OFF_G0_NC(566), + R_AARCH64_TLSDESC_LDR(567), + R_AARCH64_TLSDESC_ADD(568), + R_AARCH64_TLSDESC_CALL(569), + + R_AARCH64_TLSLE_LDST128_TPREL_LO12(570), + R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC(571), + + R_AARCH64_TLSLD_LDST128_DTPREL_LO12(572), + R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC(573), + + R_AARCH64_COPY(1024), // Copy symbol at runtime. + R_AARCH64_GLOB_DAT(1025), // Create GOT entry. + R_AARCH64_JUMP_SLOT(1026), // Create PLT entry. + R_AARCH64_RELATIVE(1027), // Adjust by program base. + R_AARCH64_TLS_DTPMOD64(1028), + R_AARCH64_TLS_DTPREL64(1029), + R_AARCH64_TLS_TPREL64(1030), + R_AARCH64_TLS_DTPMOD(1028), + R_AARCH64_TLS_DTPREL(1029), + R_AARCH64_TLS_TPREL(1030), + R_AARCH64_TLSDESC(1031), + R_AARCH64_IRELATIVE(1032); + + public final int typeId; + + private AARCH64_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } +} diff --git a/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationConstants.java b/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationConstants.java deleted file mode 100644 index 7e79867c3e..0000000000 --- a/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationConstants.java +++ /dev/null @@ -1,285 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.util.bin.format.elf.relocation; - -public class ARM_ElfRelocationConstants { - - /** No operation needed */ - public static final int R_ARM_NONE = 0; - /** ((S + A) | T) - P [DEPRECATED] */ - public static final int R_ARM_PC24 = 1; - /** (S + A) | T */ - public static final int R_ARM_ABS32 = 2; - /** ((S + A) | T) - P */ - public static final int R_ARM_REL32 = 3; - /** S + A - P */ - public static final int R_ARM_LDR_PC_G0 = 4; - /** S + A */ - public static final int R_ARM_ABS16 = 5; - /** S + A */ - public static final int R_ARM_ABS12 = 6; - /** S + A */ - public static final int R_ARM_THM_ABS5 = 7; - /** S + A */ - public static final int R_ARM_ABS_8 = 8; - /** ((S + A) | T) - B(S) */ - public static final int R_ARM_SBREL32 = 9; - /** ((S + A) | T) - P */ - public static final int R_ARM_THM_CALL = 10; - /** S + A - Pa */ - public static final int R_ARM_THM_PC8 = 11; - /** DELTA(B(S)) + A */ - public static final int R_ARM_BREL_ADJ = 12; - public static final int R_ARM_TLS_DESC = 13; - /** [OBSOLETE] */ - public static final int R_ARM_THM_SWI8 = 14; - /** [OBSOLETE] */ - public static final int R_ARM_XPC25 = 15; - /** [OBSOLETE] */ - public static final int R_ARM_THM_XPC22 = 16; - /** Module[S] */ - public static final int R_ARM_TLS_DTPMOD32 = 17; - /** S + A - TLS */ - public static final int R_ARM_TLS_DTPOFF32 = 18; - /** S + A - TLS */ - public static final int R_ARM_TLS_TPOFF32 = 19; - /** Miscellaneous */ - public static final int R_ARM_COPY = 20; - /** (S + A) | T */ - public static final int R_ARM_GLOB_DAT = 21; - /** (S + A) | T */ - public static final int R_ARM_JUMP_SLOT = 22; - /** B(S) + A [Note: see Table 4-16] */ - public static final int R_ARM_RELATIVE = 23; - /** ((S + A) | T) - GOT_ORG */ - public static final int R_ARM_GOTOFF32 = 24; - /** B(S) + A - P */ - public static final int R_ARM_BASE_PREL = 25; - /** GOT(S) + A - GOT_ORG */ - public static final int R_ARM_GOT_BREL = 26; - /** ((S + A) | T) - P */ - public static final int R_ARM_PLT32 = 27; - /** ((S + A) | T) - P */ - public static final int R_ARM_CALL = 28; - /** ((S + A) | T) - P */ - public static final int R_ARM_JUMP24 = 29; - /** ((S + A) | T) - P */ - public static final int R_ARM_THM_JUMP24 = 30; - /** B(S) + A */ - public static final int R_ARM_BASE_ABS = 31; - /** Obsolete */ - public static final int R_ARM_ALU_PCREL_7_0 = 32; - /** Obsolete */ - public static final int R_ARM_ALU_PCREL_15_8 = 33; - /** Obsolete */ - public static final int R_ARM_ALU_PCREL_23_15 = 34; - /** S + A - B(S) */ - public static final int R_ARM_LDR_SBREL_11_0_NC = 35; - /** S + A - B(S) */ - public static final int R_ARM_ALU_SBREL_19_12_NC = 36; - /** S + A - B(S) */ - public static final int R_ARM_ALU_SBREL_27_20_CK = 37; - /** (S + A) | T or ((S + A) | T) - P */ - public static final int R_ARM_TARGET1 = 38; - /** ((S + A) | T) - B(S) */ - public static final int R_ARM_SBREL31 = 39; - /** Miscellaneous */ - public static final int R_ARM_V4BX = 40; - /** Miscellaneous */ - public static final int R_ARM_TARGET2 = 41; - /** ((S + A) | T) - P */ - public static final int R_ARM_PREL31 = 42; - /** (S + A) | T */ - public static final int R_ARM_MOVW_ABS_NC = 43; - /** S + A */ - public static final int R_ARM_MOVT_ABS = 44; - /** ((S + A) | T) - P */ - public static final int R_ARM_MOVW_PREL_NC = 45; - /** S + A - P */ - public static final int R_ARM_MOVT_PREL = 46; - /** (S + A) | T */ - public static final int R_ARM_THM_MOVW_ABS_NC = 47; - /** S + A */ - public static final int R_ARM_THM_MOVT_ABS = 48; - /** ((S + A) | T) - P */ - public static final int R_ARM_THM_MOVW_PREL_NC = 49; - /** S + A - P */ - public static final int R_ARM_THM_MOVT_PREL = 50; - /** ((S + A) | T) - P */ - public static final int R_ARM_THM_JUMP19 = 51; - /** S + A - P */ - public static final int R_ARM_THM_JUMP6 = 52; - /** ((S + A) | T) - Pa */ - public static final int R_ARM_THM_ALU_PREL_11_0 = 53; - /** S + A - Pa */ - public static final int R_ARM_THM_PC12 = 54; - /** S + A */ - public static final int R_ARM_ABS32_NOI = 55; - /** S + A - P */ - public static final int R_ARM_REL32_NOI = 56; - /** ((S + A) | T) - P */ - public static final int R_ARM_ALU_PC_G0_NC = 57; - /** ((S + A) | T) - P */ - public static final int R_ARM_ALU_PC_G0 = 58; - /** ((S + A) | T) - P */ - public static final int R_ARM_ALU_PC_G1_NC = 59; - /** ((S + A) | T) - P */ - public static final int R_ARM_ALU_PC_G1 = 60; - /** ((S + A) | T) - P */ - public static final int R_ARM_ALU_PC_G2 = 61; - /** S + A - P */ - public static final int R_ARM_LDR_PC_G1 = 62; - /** S + A - P */ - public static final int R_ARM_LDR_PC_G2 = 63; - /** S + A - P */ - public static final int R_ARM_LDRS_PC_G0 = 64; - /** S + A - P */ - public static final int R_ARM_LDRS_PC_G1 = 65; - /** S + A - P */ - public static final int R_ARM_LDRS_PC_G2 = 66; - /** S + A - P */ - public static final int R_ARM_LDC_PC_G0 = 67; - /** S + A - P */ - public static final int R_ARM_LDC_PC_G1 = 68; - /** S + A - P */ - public static final int R_ARM_LDC_PC_G2 = 69; - /** ((S + A) | T) - B(S) */ - public static final int R_ARM_ALU_SB_G0_NC = 70; - /** ((S + A) | T) - B(S) */ - public static final int R_ARM_ALU_SB_G0 = 71; - /** ((S + A) | T) - B(S) */ - public static final int R_ARM_ALU_SB_G1_NC = 72; - /** ((S + A) | T) - B(S) */ - public static final int R_ARM_ALU_SB_G1 = 73; - /** ((S + A) | T) - B(S) */ - public static final int R_ARM_ALU_SB_G2 = 74; - /** S + A - B(S) */ - public static final int R_ARM_LDR_SB_G0 = 75; - /** S + A - B(S) */ - public static final int R_ARM_LDR_SB_G1 = 76; - /** S + A - B(S) */ - public static final int R_ARM_LDR_SB_G2 = 77; - /** S + A - B(S) */ - public static final int R_ARM_LDRS_SB_G0 = 78; - /** S + A - B(S) */ - public static final int R_ARM_LDRS_SB_G1 = 79; - /** S + A - B(S) */ - public static final int R_ARM_LDRS_SB_G2 = 80; - /** S + A - B(S) */ - public static final int R_ARM_LDC_SB_G0 = 81; - /** S + A - B(S) */ - public static final int R_ARM_LDC_SB_G1 = 82; - /** S + A - B(S) */ - public static final int R_ARM_LDC_SB_G2 = 83; - /** ((S + A) | T) - B(S) */ - public static final int R_ARM_MOVW_BREL_NC = 84; - /** S + A - B(S) */ - public static final int R_ARM_MOVT_BREL = 85; - /** ((S + A) | T) - B(S) */ - public static final int R_ARM_MOVW_BREL = 86; - /** ((S + A) | T) - B(S) */ - public static final int R_ARM_THM_MOVW_BREL_NC = 87; - /** S + A - B(S) */ - public static final int R_ARM_THM_MOVT_BREL = 88; - /** ((S + A) | T) - B(S) */ - public static final int R_ARM_THM_MOVW_BREL = 89; - /** ? */ - public static final int R_ARM_TLS_GOTDESC = 90; - /** ? */ - public static final int R_ARM_TLS_CALL = 91; - /** TLS relaxation */ - public static final int R_ARM_TLS_DESCSEQ = 92; - /** ? */ - public static final int R_ARM_THM_TLS_CALL = 93; - /** PLT(S) + A */ - public static final int R_ARM_PLT32_ABS = 94; - /** GOT(S) + A */ - public static final int R_ARM_GOT_ABS = 95; - /** GOT(S) + A - P */ - public static final int R_ARM_GOT_PREL = 96; - /** GOT(S) + A - GOT_ORG */ - public static final int R_ARM_GOT_BREL12 = 97; - /** S + A - GOT_ORG */ - public static final int R_ARM_GOTOFF12 = 98; - /** ? */ - public static final int R_ARM_GOTRELAX = 99; - /** ? */ - public static final int R_ARM_GNU_VTENTRY = 100; - /** ? */ - public static final int R_ARM_GNU_VTINHERIT = 101; - /** S + A - P */ - public static final int R_ARM_THM_JUMP11 = 102; - /** S + A - P */ - public static final int R_ARM_THM_JUMP8 = 103; - /** GOT(S) + A - P */ - public static final int R_ARM_TLS_GD32 = 104; - /** GOT(S) + A - P */ - public static final int R_ARM_TLS_LDM32 = 105; - /** S + A - TLS */ - public static final int R_ARM_TLS_LDO32 = 106; - /** GOT(S) + A - P */ - public static final int R_ARM_TLS_IE32 = 107; - /** S + A - tp */ - public static final int R_ARM_TLS_LE32 = 108; - /** S + A - TLS */ - public static final int R_ARM_TLS_LDO12 = 109; - /** S + A - tp */ - public static final int R_ARM_TLS_LE12 = 110; - /** GOT(S) + A - GOT_ORG */ - public static final int R_ARM_TLS_IE12GP = 111; - /** ? */ - public static final int R_ARM_PRIVATE_0 = 112; - /** ? */ - public static final int R_ARM_PRIVATE_1 = 113; - /** ? */ - public static final int R_ARM_PRIVATE_2 = 114; - /** ? */ - public static final int R_ARM_PRIVATE_3 = 115; - /** ? */ - public static final int R_ARM_PRIVATE_4 = 116; - /** ? */ - public static final int R_ARM_PRIVATE_5 = 117; - /** ? */ - public static final int R_ARM_PRIVATE_6 = 118; - /** ? */ - public static final int R_ARM_PRIVATE_7 = 119; - /** ? */ - public static final int R_ARM_PRIVATE_8 = 120; - /** ? */ - public static final int R_ARM_PRIVATE_9 = 121; - /** ? */ - public static final int R_ARM_PRIVATE_10 = 122; - /** ? */ - public static final int R_ARM_PRIVATE_11 = 123; - /** ? */ - public static final int R_ARM_PRIVATE_12 = 124; - /** ? */ - public static final int R_ARM_PRIVATE_13 = 125; - /** ? */ - public static final int R_ARM_PRIVATE_14 = 126; - /** ? */ - public static final int R_ARM_PRIVATE_15 = 127; - /** ? */ - public static final int R_ARM_ME_TOO = 128; - /** ? */ - public static final int R_ARM_THM_TLS_DESCSEQ16 = 129; - /** ? */ - public static final int R_ARM_THM_TLS_DESCSEQ32 = 130; - - private ARM_ElfRelocationConstants() { - // no construct - } -} diff --git a/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationContext.java b/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationContext.java index 6e050c8ce3..17b433ee20 100644 --- a/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationContext.java +++ b/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationContext.java @@ -22,11 +22,11 @@ import ghidra.app.util.bin.format.elf.ElfSymbol; import ghidra.app.util.bin.format.elf.extend.ARM_ElfExtension; import ghidra.program.model.address.Address; -class ARM_ElfRelocationContext extends ElfRelocationContext { +class ARM_ElfRelocationContext extends ElfRelocationContext { private final boolean applyPcBiasToRelativeRelocations; - protected ARM_ElfRelocationContext(ElfRelocationHandler handler, ElfLoadHelper loadHelper, + protected ARM_ElfRelocationContext(ARM_ElfRelocationHandler handler, ElfLoadHelper loadHelper, Map symbolMap) { super(handler, loadHelper, symbolMap); diff --git a/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationHandler.java b/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationHandler.java index 3108210d94..aead9bc021 100644 --- a/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationHandler.java +++ b/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationHandler.java @@ -24,9 +24,16 @@ import ghidra.program.model.listing.Program; import ghidra.program.model.mem.*; import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.reloc.RelocationResult; -import ghidra.util.exception.NotFoundException; -public class ARM_ElfRelocationHandler extends ElfRelocationHandler { +public class ARM_ElfRelocationHandler + extends AbstractElfRelocationHandler { + + /** + * Constructor + */ + public ARM_ElfRelocationHandler() { + super(ARM_ElfRelocationType.class); + } @Override public ARM_ElfRelocationContext createRelocationContext(ElfLoadHelper loadHelper, @@ -41,51 +48,31 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { @Override public int getRelrRelocationType() { - return ARM_ElfRelocationConstants.R_ARM_RELATIVE; + return ARM_ElfRelocationType.R_ARM_RELATIVE.typeId; } @Override - public RelocationResult relocate(ElfRelocationContext context, ElfRelocation relocation, - Address relocationAddress) throws MemoryAccessException, NotFoundException { - - ElfHeader elf = context.getElfHeader(); - if (elf.e_machine() != ElfConstants.EM_ARM || - !(context instanceof ARM_ElfRelocationContext)) { - return RelocationResult.FAILURE; - } - - ARM_ElfRelocationContext elfRelocationContext = (ARM_ElfRelocationContext) context; + protected RelocationResult relocate(ARM_ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, ARM_ElfRelocationType type, Address relocationAddress, + ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { Program program = elfRelocationContext.getProgram(); - Memory memory = program.getMemory(); - - boolean instructionBigEndian = program.getLanguage().getLanguageDescription().getInstructionEndian().isBigEndian(); - - int type = relocation.getType(); - if (type == ARM_ElfRelocationConstants.R_ARM_NONE) { - return RelocationResult.SKIPPED; - } - int symbolIndex = relocation.getSymbolIndex(); + + boolean instructionBigEndian = + program.getLanguage().getLanguageDescription().getInstructionEndian().isBigEndian(); + boolean isThumb = isThumb(sym); long addend = relocation.getAddend(); // will be 0 for REL case - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null - String symbolName = elfRelocationContext.getSymbolName(symbolIndex); - - boolean isThumb = isThumb(sym); - - long offset = (int) relocationAddress.getOffset(); - - Address symbolAddr = elfRelocationContext.getSymbolAddress(sym); - long symbolValue = elfRelocationContext.getSymbolValue(sym); - + long offset = Integer.toUnsignedLong((int) relocationAddress.getOffset()); + int symbolIndex = relocation.getSymbolIndex(); int newValue = 0; - int byteLength = 4; // most relocations affect 4-bytes (change if different) switch (type) { - case ARM_ElfRelocationConstants.R_ARM_PC24: { // Target class: ARM Instruction + case R_ARM_PC24: { // Target class: ARM Instruction int oldValue = memory.getInt(relocationAddress, instructionBigEndian); if (elfRelocationContext.extractAddend()) { addend = (oldValue << 8) >> 6; // extract addend and sign-extend with *4 factor @@ -104,7 +91,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, newValue, instructionBigEndian); break; } - case ARM_ElfRelocationConstants.R_ARM_ABS32: { // Target class: Data + case R_ARM_ABS32: { // Target class: Data if (elfRelocationContext.extractAddend()) { addend = memory.getInt(relocationAddress); } @@ -114,13 +101,13 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { } memory.setInt(relocationAddress, newValue); if (symbolIndex != 0 && addend != 0 && !sym.isSection()) { - warnExternalOffsetRelocation(program, relocationAddress, - symbolAddr, symbolName, addend, elfRelocationContext.getLog()); + warnExternalOffsetRelocation(program, relocationAddress, symbolAddr, symbolName, + addend, elfRelocationContext.getLog()); applyComponentOffsetPointer(program, relocationAddress, addend); } break; } - case ARM_ElfRelocationConstants.R_ARM_REL32: { // Target class: Data + case R_ARM_REL32: { // Target class: Data if (elfRelocationContext.extractAddend()) { addend = memory.getInt(relocationAddress); } @@ -132,7 +119,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, newValue); break; } - case ARM_ElfRelocationConstants.R_ARM_PREL31: { // Target class: Data + case R_ARM_PREL31: { // Target class: Data int oldValue = memory.getInt(relocationAddress); if (elfRelocationContext.extractAddend()) { addend = (oldValue << 1) >> 1; @@ -146,7 +133,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, newValue); break; } - case ARM_ElfRelocationConstants.R_ARM_LDR_PC_G0: { // Target class: ARM Instruction + case R_ARM_LDR_PC_G0: { // Target class: ARM Instruction int oldValue = memory.getInt(relocationAddress, instructionBigEndian); newValue = (int) (symbolValue + addend); newValue -= (offset + elfRelocationContext.getPcBias(false)); @@ -155,13 +142,13 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, newValue, instructionBigEndian); break; } - case ARM_ElfRelocationConstants.R_ARM_ABS16: { // Target class: Data + case R_ARM_ABS16: { // Target class: Data short sValue = (short) (symbolValue + addend); memory.setShort(relocationAddress, sValue); byteLength = 2; break; } - case ARM_ElfRelocationConstants.R_ARM_ABS12: { // Target class: ARM Instruction + case R_ARM_ABS12: { // Target class: ARM Instruction int oldValue = memory.getInt(relocationAddress, instructionBigEndian); newValue = (int) (symbolValue + addend); newValue = (oldValue & 0xfffff000) | (newValue & 0x00000fff); @@ -169,23 +156,23 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { break; } /* - case ARM_ElfRelocationConstants.R_ARM_THM_ABS5: { + case R_ARM_THM_ABS5: { break; } */ - case ARM_ElfRelocationConstants.R_ARM_ABS_8: { // Target class: Data + case R_ARM_ABS_8: { // Target class: Data byte bValue = (byte) (symbolValue + addend); memory.setByte(relocationAddress, bValue); byteLength = 1; break; } /* - case ARM_ElfRelocationConstants.R_ARM_SBREL32: { + case R_ARM_SBREL32: { break; } */ - case ARM_ElfRelocationConstants.R_ARM_THM_JUMP24: // // Target class: Thumb32 Instruction - case ARM_ElfRelocationConstants.R_ARM_THM_CALL: { + case R_ARM_THM_JUMP24: // // Target class: Thumb32 Instruction + case R_ARM_THM_CALL: { newValue = (int) (symbolValue + addend); // since it is adding in the oldvalue below, don't need to add in 4 for pc offset @@ -220,7 +207,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress.add(2), newValueL, instructionBigEndian); break; } - case ARM_ElfRelocationConstants.R_ARM_THM_PC8: { // Target class: Thumb16 Instruction + case R_ARM_THM_PC8: { // Target class: Thumb16 Instruction short oldValue = memory.getShort(relocationAddress, instructionBigEndian); newValue = (int) (symbolValue + addend); newValue -= (offset + elfRelocationContext.getPcBias(true)); @@ -231,33 +218,33 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { break; } /* - case ARM_ElfRelocationConstants.R_ARM_BREL_ADJ: { + case R_ARM_BREL_ADJ: { break; } - case ARM_ElfRelocationConstants.R_ARM_TLS_DESC: { + case R_ARM_TLS_DESC: { break; } - case ARM_ElfRelocationConstants.R_ARM_THM_SWI8: { + case R_ARM_THM_SWI8: { break; } - case ARM_ElfRelocationConstants.R_ARM_XPC25: { + case R_ARM_XPC25: { break; } - case ARM_ElfRelocationConstants.R_ARM_THM_XPC22: { + case R_ARM_THM_XPC22: { break; } - case ARM_ElfRelocationConstants.R_ARM_TLS_DTPMOD32: { + case R_ARM_TLS_DTPMOD32: { break; } - case ARM_ElfRelocationConstants.R_ARM_TLS_DTPOFF32: { + case R_ARM_TLS_DTPOFF32: { break; } - case ARM_ElfRelocationConstants.R_ARM_TLS_TPOFF32: { + case R_ARM_TLS_TPOFF32: { break; } */ - case ARM_ElfRelocationConstants.R_ARM_GLOB_DAT: { + case R_ARM_GLOB_DAT: { // Corresponds to resolved local/EXTERNAL symbols within GOT if (elfRelocationContext.extractAddend()) { addend = memory.getInt(relocationAddress); @@ -270,7 +257,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { break; } - case ARM_ElfRelocationConstants.R_ARM_JUMP_SLOT: { // Target class: Data + case R_ARM_JUMP_SLOT: { // Target class: Data // Corresponds to lazy dynamically linked external symbols within // GOT/PLT symbolValue corresponds to PLT entry for which we need to // create and external function location. Don't bother changing @@ -285,20 +272,18 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, (int) symAddress.getOffset()); } if (isPltSym || isExternalSym) { - Function extFunction = - elfRelocationContext.getLoadHelper().createExternalFunctionLinkage( - symbolName, symAddress, null); + Function extFunction = elfRelocationContext.getLoadHelper() + .createExternalFunctionLinkage(symbolName, symAddress, null); if (extFunction == null) { - markAsError(program, relocationAddress, "R_ARM_JUMP_SLOT", symbolName, - "Failed to create R_ARM_JUMP_SLOT external function", - elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to create external function", elfRelocationContext.getLog()); // relocation already applied above } } break; } - case ARM_ElfRelocationConstants.R_ARM_RELATIVE: { // Target class: Data + case R_ARM_RELATIVE: { // Target class: Data if (elfRelocationContext.extractAddend()) { addend = memory.getInt(relocationAddress); } @@ -308,20 +293,20 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { break; } /* - case ARM_ElfRelocationConstants.R_ARM_GOTOFF32: { + case R_ARM_GOTOFF32: { break; } - case ARM_ElfRelocationConstants.R_ARM_BASE_PREL: { + case R_ARM_BASE_PREL: { break; } - case ARM_ElfRelocationConstants.R_ARM_GOT_BREL: { + case R_ARM_GOT_BREL: { break; } */ - case ARM_ElfRelocationConstants.R_ARM_JUMP24: // Target class: ARM Instruction - case ARM_ElfRelocationConstants.R_ARM_CALL: - case ARM_ElfRelocationConstants.R_ARM_PLT32: + case R_ARM_JUMP24: // Target class: ARM Instruction + case R_ARM_CALL: + case R_ARM_PLT32: int oldValue = memory.getInt(relocationAddress, instructionBigEndian); if (elfRelocationContext.extractAddend()) { addend = (oldValue << 8) >> 6; // extract addend and sign-extend with *4 factor @@ -342,96 +327,95 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { break; /* - case ARM_ElfRelocationConstants.R_ARM_BASE_ABS: { + case R_ARM_BASE_ABS: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_PCREL_7_0: { + case R_ARM_ALU_PCREL_7_0: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_PCREL_15_8: { + case R_ARM_ALU_PCREL_15_8: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_PCREL_23_15: { + case R_ARM_ALU_PCREL_23_15: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDR_SBREL_11_0_NC: { + case R_ARM_LDR_SBREL_11_0_NC: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_SBREL_19_12_NC: { + case R_ARM_ALU_SBREL_19_12_NC: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_SBREL_27_20_CK: { + case R_ARM_ALU_SBREL_27_20_CK: { break; } - case ARM_ElfRelocationConstants.R_ARM_TARGET1: { + case R_ARM_TARGET1: { break; } - case ARM_ElfRelocationConstants.R_ARM_SBREL31: { + case R_ARM_SBREL31: { break; } - case ARM_ElfRelocationConstants.R_ARM_V4BX: { + case R_ARM_V4BX: { break; } - case ARM_ElfRelocationConstants.R_ARM_TARGET2: { + case R_ARM_TARGET2: { break; } - case ARM_ElfRelocationConstants.R_ARM_PREL31: { + case R_ARM_PREL31: { break; } -*/ - case ARM_ElfRelocationConstants.R_ARM_MOVW_ABS_NC: - case ARM_ElfRelocationConstants.R_ARM_MOVT_ABS: { // Target Class: ARM Instruction + */ + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: { // Target Class: ARM Instruction oldValue = memory.getInt(relocationAddress, instructionBigEndian); newValue = oldValue; - + oldValue = ((oldValue & 0xf0000) >> 4) | (oldValue & 0xfff); oldValue = (oldValue ^ 0x8000) - 0x8000; oldValue += symbolValue; - if (type == ARM_ElfRelocationConstants.R_ARM_MOVT_ABS) { + if (type == ARM_ElfRelocationType.R_ARM_MOVT_ABS) { oldValue >>= 16; } newValue &= 0xfff0f000; - newValue |= ((oldValue & 0xf000) << 4) | - (oldValue & 0x0fff); + newValue |= ((oldValue & 0xf000) << 4) | (oldValue & 0x0fff); memory.setInt(relocationAddress, newValue, instructionBigEndian); break; } /* - case ARM_ElfRelocationConstants.R_ARM_MOVW_PREL_NC: { + case R_ARM_MOVW_PREL_NC: { break; } */ - case ARM_ElfRelocationConstants.R_ARM_THM_MOVW_ABS_NC: - case ARM_ElfRelocationConstants.R_ARM_THM_MOVT_ABS: - case ARM_ElfRelocationConstants.R_ARM_THM_MOVW_PREL_NC: - case ARM_ElfRelocationConstants.R_ARM_THM_MOVT_PREL: - case ARM_ElfRelocationConstants.R_ARM_THM_MOVW_BREL_NC: - case ARM_ElfRelocationConstants.R_ARM_THM_MOVW_BREL: - case ARM_ElfRelocationConstants.R_ARM_THM_MOVT_BREL: { + case R_ARM_THM_MOVW_ABS_NC: + case R_ARM_THM_MOVT_ABS: + case R_ARM_THM_MOVW_PREL_NC: + case R_ARM_THM_MOVT_PREL: + case R_ARM_THM_MOVW_BREL_NC: + case R_ARM_THM_MOVW_BREL: + case R_ARM_THM_MOVT_BREL: { oldValue = memory.getShort(relocationAddress, instructionBigEndian) << 16; oldValue |= memory.getShort(relocationAddress.add(2), instructionBigEndian); if (elfRelocationContext.extractAddend()) { - addend = ((oldValue >> 4) & 0xf000); + addend = ((oldValue >> 4) & 0xf000); addend |= ((oldValue >> 15) & 0x0800); addend |= ((oldValue >> 4) & 0x0700); addend |= (oldValue & 0x00ff); addend = (addend ^ 0x8000) - 0x8000; } int value = (int) (symbolValue + addend); - - if (type == ARM_ElfRelocationConstants.R_ARM_THM_MOVW_PREL_NC || - type == ARM_ElfRelocationConstants.R_ARM_THM_MOVT_PREL) { + + if (type == ARM_ElfRelocationType.R_ARM_THM_MOVW_PREL_NC || + type == ARM_ElfRelocationType.R_ARM_THM_MOVT_PREL) { value -= (offset + elfRelocationContext.getPcBias(true)); } - if (type == ARM_ElfRelocationConstants.R_ARM_THM_MOVT_ABS || - type == ARM_ElfRelocationConstants.R_ARM_THM_MOVT_PREL || - type == ARM_ElfRelocationConstants.R_ARM_THM_MOVT_BREL) { + if (type == ARM_ElfRelocationType.R_ARM_THM_MOVT_ABS || + type == ARM_ElfRelocationType.R_ARM_THM_MOVT_PREL || + type == ARM_ElfRelocationType.R_ARM_THM_MOVT_BREL) { value >>= 16; } @@ -440,158 +424,158 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { newValue |= (value & 0x0800) << 15; newValue |= (value & 0x0700) << 4; newValue |= (value & 0x00ff); - - memory.setShort(relocationAddress, (short)(newValue >> 16), instructionBigEndian); - memory.setShort(relocationAddress.add(2), (short)newValue, instructionBigEndian); + + memory.setShort(relocationAddress, (short) (newValue >> 16), instructionBigEndian); + memory.setShort(relocationAddress.add(2), (short) newValue, instructionBigEndian); break; } /* - case ARM_ElfRelocationConstants.R_ARM_THM_JUMP19: { + case R_ARM_THM_JUMP19: { break; } - case ARM_ElfRelocationConstants.R_ARM_THM_JUMP6: { + case R_ARM_THM_JUMP6: { break; } - case ARM_ElfRelocationConstants.R_ARM_THM_ALU_PREL_11_0: { + case R_ARM_THM_ALU_PREL_11_0: { break; } - case ARM_ElfRelocationConstants.R_ARM_THM_PC12: { + case R_ARM_THM_PC12: { break; } - case ARM_ElfRelocationConstants.R_ARM_ABS32_NOI: { + case R_ARM_ABS32_NOI: { break; } - case ARM_ElfRelocationConstants.R_ARM_REL32_NOI: { + case R_ARM_REL32_NOI: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_PC_G0_NC: { + case R_ARM_ALU_PC_G0_NC: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_PC_G0: { + case R_ARM_ALU_PC_G0: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_PC_G1_NC: { + case R_ARM_ALU_PC_G1_NC: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_PC_G1: { + case R_ARM_ALU_PC_G1: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_PC_G2: { + case R_ARM_ALU_PC_G2: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDR_PC_G1: { + case R_ARM_LDR_PC_G1: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDR_PC_G2: { + case R_ARM_LDR_PC_G2: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDRS_PC_G0: { + case R_ARM_LDRS_PC_G0: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDRS_PC_G1: { + case R_ARM_LDRS_PC_G1: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDRS_PC_G2: { + case R_ARM_LDRS_PC_G2: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDC_PC_G0: { + case R_ARM_LDC_PC_G0: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDC_PC_G1: { + case R_ARM_LDC_PC_G1: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDC_PC_G2: { + case R_ARM_LDC_PC_G2: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_SB_G0_NC: { + case R_ARM_ALU_SB_G0_NC: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_SB_G0: { + case R_ARM_ALU_SB_G0: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_SB_G1_NC: { + case R_ARM_ALU_SB_G1_NC: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_SB_G1: { + case R_ARM_ALU_SB_G1: { break; } - case ARM_ElfRelocationConstants.R_ARM_ALU_SB_G2: { + case R_ARM_ALU_SB_G2: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDR_SB_G0: { + case R_ARM_LDR_SB_G0: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDR_SB_G1: { + case R_ARM_LDR_SB_G1: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDR_SB_G2: { + case R_ARM_LDR_SB_G2: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDRS_SB_G0: { + case R_ARM_LDRS_SB_G0: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDRS_SB_G1: { + case R_ARM_LDRS_SB_G1: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDRS_SB_G2: { + case R_ARM_LDRS_SB_G2: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDC_SB_G0: { + case R_ARM_LDC_SB_G0: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDC_SB_G1: { + case R_ARM_LDC_SB_G1: { break; } - case ARM_ElfRelocationConstants.R_ARM_LDC_SB_G2: { + case R_ARM_LDC_SB_G2: { break; } - case ARM_ElfRelocationConstants.R_ARM_MOVW_BREL_NC: { + case R_ARM_MOVW_BREL_NC: { break; } - case ARM_ElfRelocationConstants.R_ARM_MOVT_BREL: { + case R_ARM_MOVT_BREL: { break; } - case ARM_ElfRelocationConstants.R_ARM_MOVW_BREL: { + case R_ARM_MOVW_BREL: { break; } - case ARM_ElfRelocationConstants.R_ARM_TLS_GOTDESC: { + case R_ARM_TLS_GOTDESC: { break; } - case ARM_ElfRelocationConstants.R_ARM_TLS_CALL: { + case R_ARM_TLS_CALL: { break; } - case ARM_ElfRelocationConstants.R_ARM_TLS_DESCSEQ: { + case R_ARM_TLS_DESCSEQ: { break; } - case ARM_ElfRelocationConstants.R_ARM_THM_TLS_CALL: { + case R_ARM_THM_TLS_CALL: { break; } - case ARM_ElfRelocationConstants.R_ARM_PLT32_ABS: { + case R_ARM_PLT32_ABS: { break; } - case ARM_ElfRelocationConstants.R_ARM_GOT_ABS: { + case R_ARM_GOT_ABS: { break; } - case ARM_ElfRelocationConstants.R_ARM_GOT_PREL: { + case R_ARM_GOT_PREL: { break; } - case ARM_ElfRelocationConstants.R_ARM_GOT_BREL12: { + case R_ARM_GOT_BREL12: { break; } - case ARM_ElfRelocationConstants.R_ARM_GOTOFF12: { + case R_ARM_GOTOFF12: { break; } - case ARM_ElfRelocationConstants.R_ARM_GOTRELAX: { + case R_ARM_GOTRELAX: { break; } - case ARM_ElfRelocationConstants.R_ARM_GNU_VTENTRY: { + case R_ARM_GNU_VTENTRY: { break; } - case ARM_ElfRelocationConstants.R_ARM_GNU_VTINHERIT: { + case R_ARM_GNU_VTINHERIT: { break; } */ - case ARM_ElfRelocationConstants.R_ARM_THM_JUMP11: { + case R_ARM_THM_JUMP11: { oldValue = memory.getShort(relocationAddress, instructionBigEndian); if (elfRelocationContext.extractAddend()) { addend = (oldValue << 21 >> 20); // extract addend and sign-extend with *2 factor @@ -603,7 +587,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 2; break; } - case ARM_ElfRelocationConstants.R_ARM_THM_JUMP8: { + case R_ARM_THM_JUMP8: { oldValue = memory.getShort(relocationAddress, instructionBigEndian); if (elfRelocationContext.extractAddend()) { addend = (oldValue << 24 >> 23); // extract addend and sign-extend with *2 factor @@ -616,88 +600,88 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { break; } /* - case ARM_ElfRelocationConstants.R_ARM_TLS_GD32: { + case R_ARM_TLS_GD32: { break; } - case ARM_ElfRelocationConstants.R_ARM_TLS_LDM32: { + case R_ARM_TLS_LDM32: { break; } - case ARM_ElfRelocationConstants.R_ARM_TLS_LDO32: { + case R_ARM_TLS_LDO32: { break; } - case ARM_ElfRelocationConstants.R_ARM_TLS_IE32: { + case R_ARM_TLS_IE32: { break; } - case ARM_ElfRelocationConstants.R_ARM_TLS_LE32: { + case R_ARM_TLS_LE32: { break; } - case ARM_ElfRelocationConstants.R_ARM_TLS_LDO12: { + case R_ARM_TLS_LDO12: { break; } - case ARM_ElfRelocationConstants.R_ARM_TLS_LE12: { + case R_ARM_TLS_LE12: { break; } - case ARM_ElfRelocationConstants.R_ARM_TLS_IE12GP: { + case R_ARM_TLS_IE12GP: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_0: { + case R_ARM_PRIVATE_0: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_1: { + case R_ARM_PRIVATE_1: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_2: { + case R_ARM_PRIVATE_2: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_3: { + case R_ARM_PRIVATE_3: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_4: { + case R_ARM_PRIVATE_4: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_5: { + case R_ARM_PRIVATE_5: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_6: { + case R_ARM_PRIVATE_6: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_7: { + case R_ARM_PRIVATE_7: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_8: { + case R_ARM_PRIVATE_8: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_9: { + case R_ARM_PRIVATE_9: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_10: { + case R_ARM_PRIVATE_10: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_11: { + case R_ARM_PRIVATE_11: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_12: { + case R_ARM_PRIVATE_12: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_13: { + case R_ARM_PRIVATE_13: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_14: { + case R_ARM_PRIVATE_14: { break; } - case ARM_ElfRelocationConstants.R_ARM_PRIVATE_15: { + case R_ARM_PRIVATE_15: { break; } - case ARM_ElfRelocationConstants.R_ARM_THM_TLS_DESCSEQ16: { + case R_ARM_THM_TLS_DESCSEQ16: { break; } - case ARM_ElfRelocationConstants.R_ARM_THM_TLS_DESCSEQ32: { + case R_ARM_THM_TLS_DESCSEQ32: { break; } */ - case ARM_ElfRelocationConstants.R_ARM_COPY: { - markAsWarning(program, relocationAddress, "R_ARM_COPY", symbolName, symbolIndex, + case R_ARM_COPY: { + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, "Runtime copy not supported", elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; } diff --git a/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationType.java b/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationType.java new file mode 100644 index 0000000000..91a672aa96 --- /dev/null +++ b/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationType.java @@ -0,0 +1,162 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum ARM_ElfRelocationType implements ElfRelocationType { + + R_ARM_NONE(0), // No operation needed + R_ARM_PC24(1), // ((S + A) | T) - P [DEPRECATED] + R_ARM_ABS32(2), // (S + A) | T + R_ARM_REL32(3), // ((S + A) | T) - P + R_ARM_LDR_PC_G0(4), // S + A - P + R_ARM_ABS16(5), // S + A + R_ARM_ABS12(6), // S + A + R_ARM_THM_ABS5(7), // S + A + R_ARM_ABS_8(8), // S + A + R_ARM_SBREL32(9), // ((S + A) | T) - B(S) + R_ARM_THM_CALL(10), // ((S + A) | T) - P + R_ARM_THM_PC8(11), // S + A - Pa + R_ARM_BREL_ADJ(12), // DELTA(B(S)) + A + R_ARM_TLS_DESC(13), + R_ARM_THM_SWI8(14), // [OBSOLETE] + R_ARM_XPC25(15), // [OBSOLETE] + R_ARM_THM_XPC22(16), // [OBSOLETE] + R_ARM_TLS_DTPMOD32(17), // Module[S] + R_ARM_TLS_DTPOFF32(18), // S + A - TLS + R_ARM_TLS_TPOFF32(19), // S + A - TLS + R_ARM_COPY(20), // Miscellaneous + R_ARM_GLOB_DAT(21), // (S + A) | T + R_ARM_JUMP_SLOT(22), // (S + A) | T + R_ARM_RELATIVE(23), // B(S) + A [Note: see Table 4-16] + R_ARM_GOTOFF32(24), // ((S + A) | T) - GOT_ORG + R_ARM_BASE_PREL(25), // B(S) + A - P + R_ARM_GOT_BREL(26), // GOT(S) + A - GOT_ORG + R_ARM_PLT32(27), // ((S + A) | T) - P + R_ARM_CALL(28), // ((S + A) | T) - P + R_ARM_JUMP24(29), // ((S + A) | T) - P + R_ARM_THM_JUMP24(30), // ((S + A) | T) - P + R_ARM_BASE_ABS(31), // B(S) + A + R_ARM_ALU_PCREL_7_0(32), // Obsolete + R_ARM_ALU_PCREL_15_8(33), // Obsolete + R_ARM_ALU_PCREL_23_15(34), // Obsolete + R_ARM_LDR_SBREL_11_0_NC(35), // S + A - B(S) + R_ARM_ALU_SBREL_19_12_NC(36), // S + A - B(S) + R_ARM_ALU_SBREL_27_20_CK(37), // S + A - B(S) + R_ARM_TARGET1(38), // (S + A) | T or ((S + A) | T) - P + R_ARM_SBREL31(39), // ((S + A) | T) - B(S) + R_ARM_V4BX(40), // Miscellaneous + R_ARM_TARGET2(41), // Miscellaneous + R_ARM_PREL31(42), // ((S + A) | T) - P + R_ARM_MOVW_ABS_NC(43), // (S + A) | T + R_ARM_MOVT_ABS(44), // S + A + R_ARM_MOVW_PREL_NC(45), // ((S + A) | T) - P + R_ARM_MOVT_PREL(46), // S + A - P + R_ARM_THM_MOVW_ABS_NC(47), // (S + A) | T + R_ARM_THM_MOVT_ABS(48), // S + A + R_ARM_THM_MOVW_PREL_NC(49), // ((S + A) | T) - P + R_ARM_THM_MOVT_PREL(50), // S + A - P + R_ARM_THM_JUMP19(51), // ((S + A) | T) - P + R_ARM_THM_JUMP6(52), // S + A - P + R_ARM_THM_ALU_PREL_11_0(53),// ((S + A) | T) - Pa + R_ARM_THM_PC12(54), // S + A - Pa + R_ARM_ABS32_NOI(55), // S + A + R_ARM_REL32_NOI(56), // S + A - P + R_ARM_ALU_PC_G0_NC(57), // ((S + A) | T) - P + R_ARM_ALU_PC_G0(58), // ((S + A) | T) - P + R_ARM_ALU_PC_G1_NC(59), // ((S + A) | T) - P + R_ARM_ALU_PC_G1(60), // ((S + A) | T) - P + R_ARM_ALU_PC_G2(61), // ((S + A) | T) - P + R_ARM_LDR_PC_G1(62), // S + A - P + R_ARM_LDR_PC_G2(63), // S + A - P + R_ARM_LDRS_PC_G0(64), // S + A - P + R_ARM_LDRS_PC_G1(65), // S + A - P + R_ARM_LDRS_PC_G2(66), // S + A - P + R_ARM_LDC_PC_G0(67), // S + A - P + R_ARM_LDC_PC_G1(68), // S + A - P + R_ARM_LDC_PC_G2(69), // S + A - P + R_ARM_ALU_SB_G0_NC(70), // ((S + A) | T) - B(S) + R_ARM_ALU_SB_G0(71), // ((S + A) | T) - B(S) + R_ARM_ALU_SB_G1_NC(72), // ((S + A) | T) - B(S) + R_ARM_ALU_SB_G1(73), // ((S + A) | T) - B(S) + R_ARM_ALU_SB_G2(74), // ((S + A) | T) - B(S) + R_ARM_LDR_SB_G0(75), // S + A - B(S) + R_ARM_LDR_SB_G1(76), // S + A - B(S) + R_ARM_LDR_SB_G2(77), // S + A - B(S) + R_ARM_LDRS_SB_G0(78), // S + A - B(S) + R_ARM_LDRS_SB_G1(79), // S + A - B(S) + R_ARM_LDRS_SB_G2(80), // S + A - B(S) + R_ARM_LDC_SB_G0(81), // S + A - B(S) + R_ARM_LDC_SB_G1(82), // S + A - B(S) + R_ARM_LDC_SB_G2(83), // S + A - B(S) + R_ARM_MOVW_BREL_NC(84), // ((S + A) | T) - B(S) + R_ARM_MOVT_BREL(85), // S + A - B(S) + R_ARM_MOVW_BREL(86), // ((S + A) | T) - B(S) + R_ARM_THM_MOVW_BREL_NC(87), // ((S + A) | T) - B(S) + R_ARM_THM_MOVT_BREL(88), // S + A - B(S) + R_ARM_THM_MOVW_BREL(89), // ((S + A) | T) - B(S) + R_ARM_TLS_GOTDESC(90), + R_ARM_TLS_CALL(91), + R_ARM_TLS_DESCSEQ(92), // TLS relaxation + R_ARM_THM_TLS_CALL(93), + R_ARM_PLT32_ABS(94), // PLT(S) + A + R_ARM_GOT_ABS(95), // GOT(S) + A + R_ARM_GOT_PREL(96), // GOT(S) + A - P + R_ARM_GOT_BREL12(97), // GOT(S) + A - GOT_ORG + R_ARM_GOTOFF12(98), // S + A - GOT_ORG + R_ARM_GOTRELAX(99), + R_ARM_GNU_VTENTRY(100), + R_ARM_GNU_VTINHERIT(101), + R_ARM_THM_JUMP11(102), // S + A - P + R_ARM_THM_JUMP8(103), // S + A - P + R_ARM_TLS_GD32(104), // GOT(S) + A - P + R_ARM_TLS_LDM32(105), // GOT(S) + A - P + R_ARM_TLS_LDO32(106), // S + A - TLS + R_ARM_TLS_IE32(107), // GOT(S) + A - P + R_ARM_TLS_LE32(108), // S + A - tp + R_ARM_TLS_LDO12(109), // S + A - TLS + R_ARM_TLS_LE12(110), // S + A - tp + R_ARM_TLS_IE12GP(111), // GOT(S) + A - GOT_ORG + R_ARM_PRIVATE_0(112), + R_ARM_PRIVATE_1(113), + R_ARM_PRIVATE_2(114), + R_ARM_PRIVATE_3(115), + R_ARM_PRIVATE_4(116), + R_ARM_PRIVATE_5(117), + R_ARM_PRIVATE_6(118), + R_ARM_PRIVATE_7(119), + R_ARM_PRIVATE_8(120), + R_ARM_PRIVATE_9(121), + R_ARM_PRIVATE_10(122), + R_ARM_PRIVATE_11(123), + R_ARM_PRIVATE_12(124), + R_ARM_PRIVATE_13(125), + R_ARM_PRIVATE_14(126), + R_ARM_PRIVATE_15(127), + R_ARM_ME_TOO(128), + R_ARM_THM_TLS_DESCSEQ16(129), + R_ARM_THM_TLS_DESCSEQ32(130); + + public final int typeId; + + private ARM_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } +} diff --git a/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfArmRelocationFixupHandler.java b/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfArmRelocationFixupHandler.java index d7481d13f5..85d27128ac 100644 --- a/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfArmRelocationFixupHandler.java +++ b/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfArmRelocationFixupHandler.java @@ -15,7 +15,7 @@ */ package ghidra.app.util.bin.format.elf.relocation; -import ghidra.app.plugin.core.reloc.RelocationFixupHandler; +import ghidra.app.plugin.core.reloc.ElfRelocationFixupHandler; import ghidra.app.util.opinion.ElfLoader; import ghidra.program.model.address.Address; import ghidra.program.model.lang.Language; @@ -23,152 +23,167 @@ import ghidra.program.model.lang.Processor; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.reloc.Relocation; +import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.util.CodeUnitInsertionException; -public class ElfArmRelocationFixupHandler extends RelocationFixupHandler { +public class ElfArmRelocationFixupHandler extends ElfRelocationFixupHandler { + + public ElfArmRelocationFixupHandler() { + super(ARM_ElfRelocationType.class); + } @Override public boolean processRelocation(Program program, Relocation relocation, Address oldImageBase, Address newImageBase) throws MemoryAccessException, CodeUnitInsertionException { - switch (relocation.getType()) { + if (relocation.getStatus() != Status.APPLIED) { + return false; + } + + ARM_ElfRelocationType type = + (ARM_ElfRelocationType) getRelocationType(relocation.getType()); + if (type == null) { + return false; + } + + switch (type) { // TODO: This over simplified relocation fixup is flawed and does not properly // handle post-import image base change for supported relocations - case ARM_ElfRelocationConstants.R_ARM_NONE: - case ARM_ElfRelocationConstants.R_ARM_ABS32: - case ARM_ElfRelocationConstants.R_ARM_REL32: - case ARM_ElfRelocationConstants.R_ARM_GLOB_DAT: -// case ARM_ElfRelocationConstants.R_ARM_JUMP_SLOT: - case ARM_ElfRelocationConstants.R_ARM_RELATIVE: - case ARM_ElfRelocationConstants.R_ARM_PLT32: - case ARM_ElfRelocationConstants.R_ARM_CALL: - case ARM_ElfRelocationConstants.R_ARM_JUMP24: - case ARM_ElfRelocationConstants.R_ARM_THM_JUMP24: + case R_ARM_NONE: + case R_ARM_ABS32: + case R_ARM_REL32: + case R_ARM_GLOB_DAT: +// case R_ARM_JUMP_SLOT: + case R_ARM_RELATIVE: + case R_ARM_PLT32: + case R_ARM_CALL: + case R_ARM_JUMP24: + case R_ARM_THM_JUMP24: return process32BitRelocation(program, relocation, oldImageBase, newImageBase); -// case ARM_ElfRelocationConstants.R_ARM_PC24: -// case ARM_ElfRelocationConstants.R_ARM_LDR_PC_G0: -// case ARM_ElfRelocationConstants.R_ARM_ABS16: -// case ARM_ElfRelocationConstants.R_ARM_ABS12: -// case ARM_ElfRelocationConstants.R_ARM_THM_ABS5: -// case ARM_ElfRelocationConstants.R_ARM_ABS_8: -// case ARM_ElfRelocationConstants.R_ARM_SBREL32: -// case ARM_ElfRelocationConstants.R_ARM_THM_CALL: -// case ARM_ElfRelocationConstants.R_ARM_THM_PC8: -// case ARM_ElfRelocationConstants.R_ARM_BREL_ADJ: -// case ARM_ElfRelocationConstants.R_ARM_TLS_DESC: -// case ARM_ElfRelocationConstants.R_ARM_THM_SWI8: -// case ARM_ElfRelocationConstants.R_ARM_XPC25: -// case ARM_ElfRelocationConstants.R_ARM_THM_XPC22: -// case ARM_ElfRelocationConstants.R_ARM_TLS_DTPMOD32: -// case ARM_ElfRelocationConstants.R_ARM_TLS_DTPOFF32: -// case ARM_ElfRelocationConstants.R_ARM_TLS_TPOFF32: -// case ARM_ElfRelocationConstants.R_ARM_COPY: -// case ARM_ElfRelocationConstants.R_ARM_GOTOFF32: -// case ARM_ElfRelocationConstants.R_ARM_BASE_PREL: -// case ARM_ElfRelocationConstants.R_ARM_GOT_BREL: -// case ARM_ElfRelocationConstants.R_ARM_BASE_ABS: -// case ARM_ElfRelocationConstants.R_ARM_ALU_PCREL_7_0: -// case ARM_ElfRelocationConstants.R_ARM_ALU_PCREL_15_8: -// case ARM_ElfRelocationConstants.R_ARM_ALU_PCREL_23_15: -// case ARM_ElfRelocationConstants.R_ARM_LDR_SBREL_11_0_NC: -// case ARM_ElfRelocationConstants.R_ARM_ALU_SBREL_19_12_NC: -// case ARM_ElfRelocationConstants.R_ARM_ALU_SBREL_27_20_CK: -// case ARM_ElfRelocationConstants.R_ARM_TARGET1: -// case ARM_ElfRelocationConstants.R_ARM_SBREL31: -// case ARM_ElfRelocationConstants.R_ARM_V4BX: -// case ARM_ElfRelocationConstants.R_ARM_TARGET2: -// case ARM_ElfRelocationConstants.R_ARM_PREL31: -// case ARM_ElfRelocationConstants.R_ARM_MOVW_ABS_NC: -// case ARM_ElfRelocationConstants.R_ARM_MOVT_ABS: -// case ARM_ElfRelocationConstants.R_ARM_MOVW_PREL_NC: -// case ARM_ElfRelocationConstants.R_ARM_MOVT_PREL: -// case ARM_ElfRelocationConstants.R_ARM_THM_MOVW_ABS_NC: -// case ARM_ElfRelocationConstants.R_ARM_THM_MOVT_ABS: -// case ARM_ElfRelocationConstants.R_ARM_THM_MOVW_PREL_NC: -// case ARM_ElfRelocationConstants.R_ARM_THM_MOVT_PREL: -// case ARM_ElfRelocationConstants.R_ARM_THM_JUMP19: -// case ARM_ElfRelocationConstants.R_ARM_THM_JUMP6: -// case ARM_ElfRelocationConstants.R_ARM_THM_ALU_PREL_11_0: -// case ARM_ElfRelocationConstants.R_ARM_THM_PC12: -// case ARM_ElfRelocationConstants.R_ARM_ABS32_NOI: -// case ARM_ElfRelocationConstants.R_ARM_REL32_NOI: -// case ARM_ElfRelocationConstants.R_ARM_ALU_PC_G0_NC: -// case ARM_ElfRelocationConstants.R_ARM_ALU_PC_G0: -// case ARM_ElfRelocationConstants.R_ARM_ALU_PC_G1_NC: -// case ARM_ElfRelocationConstants.R_ARM_ALU_PC_G1: -// case ARM_ElfRelocationConstants.R_ARM_ALU_PC_G2: -// case ARM_ElfRelocationConstants.R_ARM_LDR_PC_G1: -// case ARM_ElfRelocationConstants.R_ARM_LDR_PC_G2: -// case ARM_ElfRelocationConstants.R_ARM_LDRS_PC_G0: -// case ARM_ElfRelocationConstants.R_ARM_LDRS_PC_G1: -// case ARM_ElfRelocationConstants.R_ARM_LDRS_PC_G2: -// case ARM_ElfRelocationConstants.R_ARM_LDC_PC_G0: -// case ARM_ElfRelocationConstants.R_ARM_LDC_PC_G1: -// case ARM_ElfRelocationConstants.R_ARM_LDC_PC_G2: -// case ARM_ElfRelocationConstants.R_ARM_ALU_SB_G0_NC: -// case ARM_ElfRelocationConstants.R_ARM_ALU_SB_G0: -// case ARM_ElfRelocationConstants.R_ARM_ALU_SB_G1_NC: -// case ARM_ElfRelocationConstants.R_ARM_ALU_SB_G1: -// case ARM_ElfRelocationConstants.R_ARM_ALU_SB_G2: -// case ARM_ElfRelocationConstants.R_ARM_LDR_SB_G0: -// case ARM_ElfRelocationConstants.R_ARM_LDR_SB_G1: -// case ARM_ElfRelocationConstants.R_ARM_LDR_SB_G2: -// case ARM_ElfRelocationConstants.R_ARM_LDRS_SB_G0: -// case ARM_ElfRelocationConstants.R_ARM_LDRS_SB_G1: -// case ARM_ElfRelocationConstants.R_ARM_LDRS_SB_G2: -// case ARM_ElfRelocationConstants.R_ARM_LDC_SB_G0: -// case ARM_ElfRelocationConstants.R_ARM_LDC_SB_G1: -// case ARM_ElfRelocationConstants.R_ARM_LDC_SB_G2: -// case ARM_ElfRelocationConstants.R_ARM_MOVW_BREL_NC: -// case ARM_ElfRelocationConstants.R_ARM_MOVT_BREL: -// case ARM_ElfRelocationConstants.R_ARM_MOVW_BREL: -// case ARM_ElfRelocationConstants.R_ARM_THM_MOVW_BREL_NC: -// case ARM_ElfRelocationConstants.R_ARM_THM_MOVT_BREL: -// case ARM_ElfRelocationConstants.R_ARM_THM_MOVW_BREL: -// case ARM_ElfRelocationConstants.R_ARM_TLS_GOTDESC: -// case ARM_ElfRelocationConstants.R_ARM_TLS_CALL: -// case ARM_ElfRelocationConstants.R_ARM_TLS_DESCSEQ: -// case ARM_ElfRelocationConstants.R_ARM_THM_TLS_CALL: -// case ARM_ElfRelocationConstants.R_ARM_PLT32_ABS: -// case ARM_ElfRelocationConstants.R_ARM_GOT_ABS: -// case ARM_ElfRelocationConstants.R_ARM_GOT_PREL: -// case ARM_ElfRelocationConstants.R_ARM_GOT_BREL12: -// case ARM_ElfRelocationConstants.R_ARM_GOTOFF12: -// case ARM_ElfRelocationConstants.R_ARM_GOTRELAX: -// case ARM_ElfRelocationConstants.R_ARM_GNU_VTENTRY: -// case ARM_ElfRelocationConstants.R_ARM_GNU_VTINHERIT: -// case ARM_ElfRelocationConstants.R_ARM_THM_JUMP11: -// case ARM_ElfRelocationConstants.R_ARM_THM_JUMP8: -// case ARM_ElfRelocationConstants.R_ARM_TLS_GD32: -// case ARM_ElfRelocationConstants.R_ARM_TLS_LDM32: -// case ARM_ElfRelocationConstants.R_ARM_TLS_LDO32: -// case ARM_ElfRelocationConstants.R_ARM_TLS_IE32: -// case ARM_ElfRelocationConstants.R_ARM_TLS_LE32: -// case ARM_ElfRelocationConstants.R_ARM_TLS_LDO12: -// case ARM_ElfRelocationConstants.R_ARM_TLS_LE12: -// case ARM_ElfRelocationConstants.R_ARM_TLS_IE12GP: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_0: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_1: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_2: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_3: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_4: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_5: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_6: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_7: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_8: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_9: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_10: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_11: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_12: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_13: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_14: -// case ARM_ElfRelocationConstants.R_ARM_PRIVATE_15: -// case ARM_ElfRelocationConstants.R_ARM_THM_TLS_DESCSEQ16: -// case ARM_ElfRelocationConstants.R_ARM_THM_TLS_DESCSEQ32: -// return false; +// case R_ARM_PC24: +// case R_ARM_LDR_PC_G0: +// case R_ARM_ABS16: +// case R_ARM_ABS12: +// case R_ARM_THM_ABS5: +// case R_ARM_ABS_8: +// case R_ARM_SBREL32: +// case R_ARM_THM_CALL: +// case R_ARM_THM_PC8: +// case R_ARM_BREL_ADJ: +// case R_ARM_TLS_DESC: +// case R_ARM_THM_SWI8: +// case R_ARM_XPC25: +// case R_ARM_THM_XPC22: +// case R_ARM_TLS_DTPMOD32: +// case R_ARM_TLS_DTPOFF32: +// case R_ARM_TLS_TPOFF32: +// case R_ARM_COPY: +// case R_ARM_GOTOFF32: +// case R_ARM_BASE_PREL: +// case R_ARM_GOT_BREL: +// case R_ARM_BASE_ABS: +// case R_ARM_ALU_PCREL_7_0: +// case R_ARM_ALU_PCREL_15_8: +// case R_ARM_ALU_PCREL_23_15: +// case R_ARM_LDR_SBREL_11_0_NC: +// case R_ARM_ALU_SBREL_19_12_NC: +// case R_ARM_ALU_SBREL_27_20_CK: +// case R_ARM_TARGET1: +// case R_ARM_SBREL31: +// case R_ARM_V4BX: +// case R_ARM_TARGET2: +// case R_ARM_PREL31: +// case R_ARM_MOVW_ABS_NC: +// case R_ARM_MOVT_ABS: +// case R_ARM_MOVW_PREL_NC: +// case R_ARM_MOVT_PREL: +// case R_ARM_THM_MOVW_ABS_NC: +// case R_ARM_THM_MOVT_ABS: +// case R_ARM_THM_MOVW_PREL_NC: +// case R_ARM_THM_MOVT_PREL: +// case R_ARM_THM_JUMP19: +// case R_ARM_THM_JUMP6: +// case R_ARM_THM_ALU_PREL_11_0: +// case R_ARM_THM_PC12: +// case R_ARM_ABS32_NOI: +// case R_ARM_REL32_NOI: +// case R_ARM_ALU_PC_G0_NC: +// case R_ARM_ALU_PC_G0: +// case R_ARM_ALU_PC_G1_NC: +// case R_ARM_ALU_PC_G1: +// case R_ARM_ALU_PC_G2: +// case R_ARM_LDR_PC_G1: +// case R_ARM_LDR_PC_G2: +// case R_ARM_LDRS_PC_G0: +// case R_ARM_LDRS_PC_G1: +// case R_ARM_LDRS_PC_G2: +// case R_ARM_LDC_PC_G0: +// case R_ARM_LDC_PC_G1: +// case R_ARM_LDC_PC_G2: +// case R_ARM_ALU_SB_G0_NC: +// case R_ARM_ALU_SB_G0: +// case R_ARM_ALU_SB_G1_NC: +// case R_ARM_ALU_SB_G1: +// case R_ARM_ALU_SB_G2: +// case R_ARM_LDR_SB_G0: +// case R_ARM_LDR_SB_G1: +// case R_ARM_LDR_SB_G2: +// case R_ARM_LDRS_SB_G0: +// case R_ARM_LDRS_SB_G1: +// case R_ARM_LDRS_SB_G2: +// case R_ARM_LDC_SB_G0: +// case R_ARM_LDC_SB_G1: +// case R_ARM_LDC_SB_G2: +// case R_ARM_MOVW_BREL_NC: +// case R_ARM_MOVT_BREL: +// case R_ARM_MOVW_BREL: +// case R_ARM_THM_MOVW_BREL_NC: +// case R_ARM_THM_MOVT_BREL: +// case R_ARM_THM_MOVW_BREL: +// case R_ARM_TLS_GOTDESC: +// case R_ARM_TLS_CALL: +// case R_ARM_TLS_DESCSEQ: +// case R_ARM_THM_TLS_CALL: +// case R_ARM_PLT32_ABS: +// case R_ARM_GOT_ABS: +// case R_ARM_GOT_PREL: +// case R_ARM_GOT_BREL12: +// case R_ARM_GOTOFF12: +// case R_ARM_GOTRELAX: +// case R_ARM_GNU_VTENTRY: +// case R_ARM_GNU_VTINHERIT: +// case R_ARM_THM_JUMP11: +// case R_ARM_THM_JUMP8: +// case R_ARM_TLS_GD32: +// case R_ARM_TLS_LDM32: +// case R_ARM_TLS_LDO32: +// case R_ARM_TLS_IE32: +// case R_ARM_TLS_LE32: +// case R_ARM_TLS_LDO12: +// case R_ARM_TLS_LE12: +// case R_ARM_TLS_IE12GP: +// case R_ARM_PRIVATE_0: +// case R_ARM_PRIVATE_1: +// case R_ARM_PRIVATE_2: +// case R_ARM_PRIVATE_3: +// case R_ARM_PRIVATE_4: +// case R_ARM_PRIVATE_5: +// case R_ARM_PRIVATE_6: +// case R_ARM_PRIVATE_7: +// case R_ARM_PRIVATE_8: +// case R_ARM_PRIVATE_9: +// case R_ARM_PRIVATE_10: +// case R_ARM_PRIVATE_11: +// case R_ARM_PRIVATE_12: +// case R_ARM_PRIVATE_13: +// case R_ARM_PRIVATE_14: +// case R_ARM_PRIVATE_15: +// case R_ARM_THM_TLS_DESCSEQ16: +// case R_ARM_THM_TLS_DESCSEQ32: + default: + return false; } - return false; } @Override diff --git a/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/AVR8_ElfRelocationConstants.java b/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/AVR8_ElfRelocationConstants.java deleted file mode 100644 index dcceba4e83..0000000000 --- a/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/AVR8_ElfRelocationConstants.java +++ /dev/null @@ -1,57 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.util.bin.format.elf; - -public class AVR8_ElfRelocationConstants { - - public static final int R_AVR_NONE = 0; - public static final int R_AVR_32 = 1; - public static final int R_AVR_7_PCREL = 2; - public static final int R_AVR_13_PCREL = 3; - public static final int R_AVR_16 = 4; - public static final int R_AVR_16_PM = 5; - public static final int R_AVR_LO8_LDI = 6; - public static final int R_AVR_HI8_LDI = 7; - public static final int R_AVR_HH8_LDI = 8; - public static final int R_AVR_LO8_LDI_NEG = 9; - public static final int R_AVR_HI8_LDI_NEG = 10; - public static final int R_AVR_HH8_LDI_NEG = 11; - public static final int R_AVR_LO8_LDI_PM = 12; - public static final int R_AVR_HI8_LDI_PM = 13; - public static final int R_AVR_HH8_LDI_PM = 14; - public static final int R_AVR_LO8_LDI_PM_NEG = 15; - public static final int R_AVR_HI8_LDI_PM_NEG = 16; - public static final int R_AVR_HH8_LDI_PM_NEG = 17; - public static final int R_AVR_CALL = 18; - public static final int R_AVR_LDI = 19; - public static final int R_AVR_6 = 20; - public static final int R_AVR_6_ADIW = 21; - public static final int R_AVR_MS8_LDI = 22; - public static final int R_AVR_MS8_LDI_NEG = 23; - public static final int R_AVR_LO8_LDI_GS = 24; - public static final int R_AVR_HI8_LDI_GS = 25; - public static final int R_AVR_8 = 26; - public static final int R_AVR_8_LO8 = 27; - public static final int R_AVR_8_HI8 = 28; - public static final int R_AVR_8_HLO8 = 29; - public static final int R_AVR_DIFF8 = 30; - public static final int R_AVR_DIFF16 = 31; - public static final int R_AVR_DIFF32 = 32; - public static final int R_AVR_LDS_STS_16 = 33; - public static final int R_AVR_PORT6 = 34; - public static final int R_AVR_PORT5 = 35; - -} diff --git a/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR32_ElfRelocationHandler.java b/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR32_ElfRelocationHandler.java index 9e3859e22e..72772252ef 100644 --- a/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR32_ElfRelocationHandler.java +++ b/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR32_ElfRelocationHandler.java @@ -24,12 +24,19 @@ import ghidra.program.model.listing.Listing; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryAccessException; -import ghidra.program.model.reloc.RelocationResult; import ghidra.program.model.reloc.Relocation.Status; +import ghidra.program.model.reloc.RelocationResult; import ghidra.program.model.util.CodeUnitInsertionException; -import ghidra.util.exception.NotFoundException; -public class AVR32_ElfRelocationHandler extends ElfRelocationHandler { +public class AVR32_ElfRelocationHandler + extends AbstractElfRelocationHandler> { + + /** + * Constructor + */ + public AVR32_ElfRelocationHandler() { + super(AVR32_ElfRelocationType.class); + } @Override public boolean canRelocate(ElfHeader elf) { @@ -37,292 +44,278 @@ public class AVR32_ElfRelocationHandler extends ElfRelocationHandler { } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, - Address relocationAddress) throws MemoryAccessException, NotFoundException { + protected RelocationResult relocate(ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, AVR32_ElfRelocationType type, Address relocationAddress, + ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { Program program = elfRelocationContext.getProgram(); - Memory memory = program.getMemory(); AddressSpace space = program.getAddressFactory().getDefaultAddressSpace(); - int type = relocation.getType(); - int symbolIndex = relocation.getSymbolIndex(); - long addend = relocation.getAddend(); // will be 0 for REL case - ElfHeader elf = elfRelocationContext.getElfHeader(); - long offset = (int) relocationAddress.getOffset(); - - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null - long symbolValue = elfRelocationContext.getSymbolValue(sym); + int symbolIndex = relocation.getSymbolIndex(); int oldValue = memory.getInt(relocationAddress); int byteLength = 4; // most relocations affect 4-bytes (change if different) + int newValueShiftToAligntoUpper = 0; - if (elf.e_machine() == ElfConstants.EM_AVR32) { - int newValueShiftToAligntoUpper = 0; - switch (type) { - case AVR32_ElfRelocationConstants.R_AVR32_NONE: - return RelocationResult.SKIPPED; - case AVR32_ElfRelocationConstants.R_AVR32_32: - int newValue = (((int) symbolValue + (int) addend) & 0xffffffff); - memory.setInt(relocationAddress, newValue); - break; + switch (type) { + case R_AVR32_NONE: + return RelocationResult.SKIPPED; + case R_AVR32_32: + int newValue = (((int) symbolValue + (int) addend) & 0xffffffff); + memory.setInt(relocationAddress, newValue); + break; - case AVR32_ElfRelocationConstants.R_AVR32_DIFF32: - newValue = (((int) symbolValue + (int) addend + oldValue) & 0xffffffff); - memory.setInt(relocationAddress, newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_22H_PCREL://(BR{cond4}) - newValue = (int) ((symbolValue + (int) addend - offset) >> 1); - int nVpart1 = (newValue & 0x0000ffff); - int nVpart2 = (newValue & 0x00010000); - int nVpart3 = (newValue & 0x001e0000); - int newValueParts = - (((nVpart3 << 8) | (nVpart2 << 4) | (nVpart1)) & 0x1e10ffff); - int newValueSet = (oldValue | newValueParts); - memory.setInt(relocationAddress, newValueSet); - break; - case AVR32_ElfRelocationConstants.R_AVR32_11H_PCREL: //WORKING! (RJMP) - newValue = (int) (((symbolValue + (int) addend - offset) >> 1) << 4); - int tempNewValHold = (newValue & 0x00000ff3); - int tempDispHold = ((newValue & 0x00003000) >> 12); - newValueShiftToAligntoUpper = ((tempNewValHold << 16) | (tempDispHold << 16)); - newValue = ((oldValue | newValueShiftToAligntoUpper) & 0xffffffff); - memory.setInt(relocationAddress, newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_9H_PCREL://WORKING! (BR{cond3}) - newValue = - (int) ((((symbolValue + (int) addend - offset) >> 1) << 4) & 0x00000ff0); - newValueShiftToAligntoUpper = (newValue << 16); - newValue = ((oldValue | newValueShiftToAligntoUpper) & 0xffffffff); - memory.setInt(relocationAddress, newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_32_CPENT: //WORKING! (POINTER_SYMBOL_PLACEMENT) - newValue = (((int) symbolValue + (int) addend) & 0xffffffff); - memory.setInt(relocationAddress, newValue); + case R_AVR32_DIFF32: + newValue = (((int) symbolValue + (int) addend + oldValue) & 0xffffffff); + memory.setInt(relocationAddress, newValue); + break; + case R_AVR32_22H_PCREL://(BR{cond4}) + newValue = (int) ((symbolValue + (int) addend - offset) >> 1); + int nVpart1 = (newValue & 0x0000ffff); + int nVpart2 = (newValue & 0x00010000); + int nVpart3 = (newValue & 0x001e0000); + int newValueParts = (((nVpart3 << 8) | (nVpart2 << 4) | (nVpart1)) & 0x1e10ffff); + int newValueSet = (oldValue | newValueParts); + memory.setInt(relocationAddress, newValueSet); + break; + case R_AVR32_11H_PCREL: //WORKING! (RJMP) + newValue = (int) (((symbolValue + (int) addend - offset) >> 1) << 4); + int tempNewValHold = (newValue & 0x00000ff3); + int tempDispHold = ((newValue & 0x00003000) >> 12); + newValueShiftToAligntoUpper = ((tempNewValHold << 16) | (tempDispHold << 16)); + newValue = ((oldValue | newValueShiftToAligntoUpper) & 0xffffffff); + memory.setInt(relocationAddress, newValue); + break; + case R_AVR32_9H_PCREL://WORKING! (BR{cond3}) + newValue = (int) ((((symbolValue + (int) addend - offset) >> 1) << 4) & 0x00000ff0); + newValueShiftToAligntoUpper = (newValue << 16); + newValue = ((oldValue | newValueShiftToAligntoUpper) & 0xffffffff); + memory.setInt(relocationAddress, newValue); + break; + case R_AVR32_32_CPENT: //WORKING! (POINTER_SYMBOL_PLACEMENT) + newValue = (((int) symbolValue + (int) addend) & 0xffffffff); + memory.setInt(relocationAddress, newValue); - Address currNewAddress = space.getAddress(newValue); + Address currNewAddress = space.getAddress(newValue); - if (!memory.contains(currNewAddress) && sym != null) { - int currElfSymbolInfoBind = sym.getBind(); - int currElfSymbolInfoType = sym.getType(); + if (!memory.contains(currNewAddress) && sym != null) { + int currElfSymbolInfoBind = sym.getBind(); + int currElfSymbolInfoType = sym.getType(); - if ((currElfSymbolInfoBind == ElfSymbol.STB_GLOBAL) && - ((currElfSymbolInfoType == ElfSymbol.STT_OBJECT) || - (currElfSymbolInfoType == ElfSymbol.STT_NOTYPE))) { - String currElfSymbolName = sym.getNameAsString(); + if ((currElfSymbolInfoBind == ElfSymbol.STB_GLOBAL) && + ((currElfSymbolInfoType == ElfSymbol.STT_OBJECT) || + (currElfSymbolInfoType == ElfSymbol.STT_NOTYPE))) { + String currElfSymbolName = sym.getNameAsString(); - long currElfSymbolSize = sym.getSize(); - if (currElfSymbolSize == 0) { - currElfSymbolSize = 2; - } - - StringBuffer newSectionNameBuff = new StringBuffer(); - newSectionNameBuff.append("cpool."); - newSectionNameBuff.append(currElfSymbolName); - - StringBuffer newSectionTypeBuff = new StringBuffer(); - newSectionTypeBuff.append("Constant Pool "); - boolean isReadable = true; - boolean isWritable = true; - boolean isExecutable = true; - - if (currElfSymbolInfoType == ElfSymbol.STT_OBJECT) { - isReadable = true; - isWritable = true; - isExecutable = false; - newSectionTypeBuff.append("Global Variable Object"); - } - else { - isReadable = true; - isWritable = false; - isExecutable = true; - newSectionTypeBuff.append("Global External Function"); - } - ElfLoadHelper loadHelper = elfRelocationContext.getLoadHelper(); - MemoryBlockUtils.createInitializedBlock(program, false, - newSectionNameBuff.toString(), currNewAddress, currElfSymbolSize, - newSectionTypeBuff.toString(), "AVR32-ELF Loader", isReadable, - isWritable, isExecutable, loadHelper.getLog()); + long currElfSymbolSize = sym.getSize(); + if (currElfSymbolSize == 0) { + currElfSymbolSize = 2; } - } - try { - Listing listing = program.getListing(); - listing.createData(relocationAddress, StructConverter.POINTER, - relocationAddress.getPointerSize()); - } - catch (CodeUnitInsertionException cuie) { - System.out.println("Attempting to create Pointer Data: " + cuie); - } - break; - case AVR32_ElfRelocationConstants.R_AVR32_CPCALL: //WORKING! (MCALL) - int checkForPC = (oldValue & 0x000f0000); - if (checkForPC == 0xf0000) { - newValue = - (int) (((symbolValue + (int) addend - (offset & 0xfffffffc)) >> 2) & - 0x0000ffff); - } - else { - newValue = - (int) (((symbolValue + (int) addend - offset) >> 2) & 0x0000ffff); - } - int newValueSet_CPCALL = ((oldValue | newValue) & 0xffffffff); - memory.setInt(relocationAddress, newValueSet_CPCALL); - break; - case AVR32_ElfRelocationConstants.R_AVR32_9W_CP: //WORKING! (LDDPC) - newValue = - (int) ((((symbolValue + (int) addend - (offset & 0xfffffffc)) >>> 2) << 4) & - 0x000007f0); - newValueShiftToAligntoUpper = (newValue << 16); - newValue = ((oldValue | newValueShiftToAligntoUpper) & 0xffffffff); - memory.setInt(relocationAddress, newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_ALIGN: - //System.out.print("-> type = " + type + ", symbolValue = " + symbolValue + ", addend = " + addend + ", offset = " + offset + " - "); - /*if((addend == 2) && (oldValueLong == 0)){ - try{ - Listing listing = prog.getListing(); - listing.createData(relocationAddress, StructConverter.WORD, (int)addend); - }catch(CodeUnitInsertionException cuie){ - System.out.println("Attempting to create Pointer Data: " + cuie); - } - System.out.println(" HANDLED AVR relocation: R_AVR32_ALIGN at "+relocationAddress + ", New = " + newValue); - }*/ - //System.out.println(" HANDLED AVR relocation: R_AVR32_ALIGN at "+relocationAddress + ", OldValue = " + Integer.toHexString(oldValue)); - return RelocationResult.SKIPPED; - //TODO: THE FOLLOWING: - /*case AVR32_ElfRelocationConstants.R_AVR32_16_CP: - //System.out.print("-> type = " + type + ", symbolValue = " + symbolValue + ", addend = " + addend + ", offset = " + offset + " - "); - //newValue = (int)((symbolValue + (int)addend - offset)) & 0x0000ffff; - //memory.setInt(relocationAddress, newValue); - //System.out.println("? HANDLED AVR relocation: R_AVR32_16_CP at "+relocationAddress + ", New = " + Integer.toHexString(newValue)); - break;*/ - /*case AVR32_ElfRelocationConstants.R_AVR32_RELATIVE: - newValue = (((int)elf.getImageBase() + (int)addend) & 0xffffffff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_RELATIVE at "+relocationAddress + ", New = " + newValue); - break; - */ - /*case AVR32_ElfRelocationConstants.R_AVR32_16: - newValue = ((symbolValue + (int)addend) & 0x0000ffff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_16 at "+relocationAddress + ", New = " + newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_8: - newValue = ((symbolValue + (int)addend) & 0x000000ff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_8 at "+relocationAddress + ", New = " + newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_32_PCREL: - newValue = (int)((symbolValue + (int)addend - offset) & 0xffffffff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_32_PCREL at "+relocationAddress + ", New = " + newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_16_PCREL: - newValue = (int)((symbolValue + (int)addend - offset) & 0x0000ffff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_16_PCREL at "+relocationAddress + ", New = " + newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_8_PCREL: - newValue = (int)((symbolValue + (int)addend - offset) & 0x000000ff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_8_PCREL at "+relocationAddress + ", New = " + newValue); - break;*/ - /*case AVR32_ElfRelocationConstants.R_AVR32_DIFF16: - newValue = ((symbolValue) & 0x0000ffff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_DIFF8 at "+relocationAddress + ", New = " + newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_DIFF8: - newValue = ((symbolValue) & 0x000000ff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_DIFF8 at "+relocationAddress + ", New = " + newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_21S: - newValue = ((symbolValue + (int)addend) & 0x1e10ffff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_21S at "+relocationAddress + ", New = " + newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_16U: //Use long to accommodate the Unsignedness... - long newValueLong = ((symbolValue + addend) & 0x0000ffff); - memory.setLong(relocationAddress, newValueLong); - System.out.println(" HANDLED AVR relocation: R_AVR32_16U at "+relocationAddress + ", NewLong = " + newValueLong); - break; - case AVR32_ElfRelocationConstants.R_AVR32_16S: - newValue = ((symbolValue + (int)addend) & 0x0000ffff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_16S at "+relocationAddress + ", New = " + newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_8S: - newValue = (((symbolValue + (int)addend) << 4) & 0x00000ff0); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_8S at "+relocationAddress + ", New = " + newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_8S_EXT: - newValue = ((symbolValue + (int)addend) & 0x000000ff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_8S_EXT at "+relocationAddress + ", New = " + newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_18W_PCREL: - newValue = (int)(((symbolValue + (int)addend - offset) >> 2) & 0x0000ffff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_18W_PCREL at "+relocationAddress + ", New = " + newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_16B_PCREL: - newValue = (int)((symbolValue + (int)addend - offset) & 0xffffffff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_16B_PCREL at "+relocationAddress + ", New = " + newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_16N_PCREL: - newValue = (int)((offset - symbolValue - (int)addend) & 0x0000ffff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_16N_PCREL at "+relocationAddress + ", New = " + newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_14UW_PCREL: - newValue = (int)(((symbolValue + (int)addend - offset) >>> 2) & 0x0000f0ff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_14UW_PCREL at "+relocationAddress + ", New = " + newValue); - break;*/ - /*case AVR32_ElfRelocationConstants.R_AVR32_10UW_PCREL: - newValue = (int)(((symbolValue + (int)addend - offset) >>> 2) & 0x000000ff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_10UW_PCREL at "+relocationAddress + ", New = " + newValue); - break;*/ - /*case AVR32_ElfRelocationConstants.R_AVR32_9UW_PCREL: - newValue = (int)((((symbolValue + (int)addend - offset) >>> 2) << 4) & 0x000007f0); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_9UW_PCREL at "+relocationAddress + ", New = " + newValue); - break; - - case AVR32_ElfRelocationConstants.R_AVR32_HI16: - newValue = (((symbolValue + (int)addend) >> 16) & 0x0000ffff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_HI16 at "+relocationAddress + ", New = " + newValue); - break; - case AVR32_ElfRelocationConstants.R_AVR32_LO16: - newValue = ((symbolValue + (int)addend) & 0x0000ffff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_LO16 at "+relocationAddress + ", New = " + newValue); - break; - - case AVR32_ElfRelocationConstants.R_AVR32_GOTPC: - ElfSectionHeader dotgot = elf.getGOT(); - MemoryBlock got = memory.getBlock(dotgot.getNameAsString()); - newValue = ((symbolValue + (int)addend - (int)got.getStart().getOffset()) & 0xffffffff); - memory.setInt(relocationAddress, newValue); - System.out.println(" HANDLED AVR relocation: R_AVR32_GOTPC at "+relocationAddress + ", New = " + newValue); - break;*/ - default: - markAsUnhandled(program, relocationAddress, type, symbolIndex, - elfRelocationContext.getSymbolName(symbolIndex), - elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - } + StringBuffer newSectionNameBuff = new StringBuffer(); + newSectionNameBuff.append("cpool."); + newSectionNameBuff.append(currElfSymbolName); + + StringBuffer newSectionTypeBuff = new StringBuffer(); + newSectionTypeBuff.append("Constant Pool "); + boolean isReadable = true; + boolean isWritable = true; + boolean isExecutable = true; + + if (currElfSymbolInfoType == ElfSymbol.STT_OBJECT) { + isReadable = true; + isWritable = true; + isExecutable = false; + newSectionTypeBuff.append("Global Variable Object"); + } + else { + isReadable = true; + isWritable = false; + isExecutable = true; + newSectionTypeBuff.append("Global External Function"); + } + ElfLoadHelper loadHelper = elfRelocationContext.getLoadHelper(); + MemoryBlockUtils.createInitializedBlock(program, false, + newSectionNameBuff.toString(), currNewAddress, currElfSymbolSize, + newSectionTypeBuff.toString(), "AVR32-ELF Loader", isReadable, + isWritable, isExecutable, loadHelper.getLog()); + } + } + try { + Listing listing = program.getListing(); + listing.createData(relocationAddress, StructConverter.POINTER, + relocationAddress.getPointerSize()); + } + catch (CodeUnitInsertionException cuie) { + System.out.println("Attempting to create Pointer Data: " + cuie); + } + break; + case R_AVR32_CPCALL: //WORKING! (MCALL) + int checkForPC = (oldValue & 0x000f0000); + if (checkForPC == 0xf0000) { + newValue = (int) (((symbolValue + (int) addend - (offset & 0xfffffffc)) >> 2) & + 0x0000ffff); + } + else { + newValue = (int) (((symbolValue + (int) addend - offset) >> 2) & 0x0000ffff); + } + int newValueSet_CPCALL = ((oldValue | newValue) & 0xffffffff); + memory.setInt(relocationAddress, newValueSet_CPCALL); + break; + case R_AVR32_9W_CP: //WORKING! (LDDPC) + newValue = + (int) ((((symbolValue + (int) addend - (offset & 0xfffffffc)) >>> 2) << 4) & + 0x000007f0); + newValueShiftToAligntoUpper = (newValue << 16); + newValue = ((oldValue | newValueShiftToAligntoUpper) & 0xffffffff); + memory.setInt(relocationAddress, newValue); + break; + case R_AVR32_ALIGN: + //System.out.print("-> type = " + type + ", symbolValue = " + symbolValue + ", addend = " + addend + ", offset = " + offset + " - "); + /*if((addend == 2) && (oldValueLong == 0)){ + try{ + Listing listing = prog.getListing(); + listing.createData(relocationAddress, StructConverter.WORD, (int)addend); + }catch(CodeUnitInsertionException cuie){ + System.out.println("Attempting to create Pointer Data: " + cuie); + } + System.out.println(" HANDLED AVR relocation: R_AVR32_ALIGN at "+relocationAddress + ", New = " + newValue); + }*/ + //System.out.println(" HANDLED AVR relocation: R_AVR32_ALIGN at "+relocationAddress + ", OldValue = " + Integer.toHexString(oldValue)); + return RelocationResult.SKIPPED; + + //TODO: THE FOLLOWING: + /*case R_AVR32_16_CP: + //System.out.print("-> type = " + type + ", symbolValue = " + symbolValue + ", addend = " + addend + ", offset = " + offset + " - "); + //newValue = (int)((symbolValue + (int)addend - offset)) & 0x0000ffff; + //memory.setInt(relocationAddress, newValue); + //System.out.println("? HANDLED AVR relocation: R_AVR32_16_CP at "+relocationAddress + ", New = " + Integer.toHexString(newValue)); + break;*/ + /*case R_AVR32_RELATIVE: + newValue = (((int)elf.getImageBase() + (int)addend) & 0xffffffff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_RELATIVE at "+relocationAddress + ", New = " + newValue); + break; + */ + /*case R_AVR32_16: + newValue = ((symbolValue + (int)addend) & 0x0000ffff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_16 at "+relocationAddress + ", New = " + newValue); + break; + case R_AVR32_8: + newValue = ((symbolValue + (int)addend) & 0x000000ff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_8 at "+relocationAddress + ", New = " + newValue); + break; + case R_AVR32_32_PCREL: + newValue = (int)((symbolValue + (int)addend - offset) & 0xffffffff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_32_PCREL at "+relocationAddress + ", New = " + newValue); + break; + case R_AVR32_16_PCREL: + newValue = (int)((symbolValue + (int)addend - offset) & 0x0000ffff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_16_PCREL at "+relocationAddress + ", New = " + newValue); + break; + case R_AVR32_8_PCREL: + newValue = (int)((symbolValue + (int)addend - offset) & 0x000000ff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_8_PCREL at "+relocationAddress + ", New = " + newValue); + break;*/ + /*case R_AVR32_DIFF16: + newValue = ((symbolValue) & 0x0000ffff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_DIFF8 at "+relocationAddress + ", New = " + newValue); + break; + case R_AVR32_DIFF8: + newValue = ((symbolValue) & 0x000000ff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_DIFF8 at "+relocationAddress + ", New = " + newValue); + break; + case R_AVR32_21S: + newValue = ((symbolValue + (int)addend) & 0x1e10ffff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_21S at "+relocationAddress + ", New = " + newValue); + break; + case R_AVR32_16U: //Use long to accommodate the Unsignedness... + long newValueLong = ((symbolValue + addend) & 0x0000ffff); + memory.setLong(relocationAddress, newValueLong); + System.out.println(" HANDLED AVR relocation: R_AVR32_16U at "+relocationAddress + ", NewLong = " + newValueLong); + break; + case R_AVR32_16S: + newValue = ((symbolValue + (int)addend) & 0x0000ffff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_16S at "+relocationAddress + ", New = " + newValue); + break; + case R_AVR32_8S: + newValue = (((symbolValue + (int)addend) << 4) & 0x00000ff0); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_8S at "+relocationAddress + ", New = " + newValue); + break; + case R_AVR32_8S_EXT: + newValue = ((symbolValue + (int)addend) & 0x000000ff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_8S_EXT at "+relocationAddress + ", New = " + newValue); + break; + case R_AVR32_18W_PCREL: + newValue = (int)(((symbolValue + (int)addend - offset) >> 2) & 0x0000ffff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_18W_PCREL at "+relocationAddress + ", New = " + newValue); + break; + case R_AVR32_16B_PCREL: + newValue = (int)((symbolValue + (int)addend - offset) & 0xffffffff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_16B_PCREL at "+relocationAddress + ", New = " + newValue); + break; + case R_AVR32_16N_PCREL: + newValue = (int)((offset - symbolValue - (int)addend) & 0x0000ffff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_16N_PCREL at "+relocationAddress + ", New = " + newValue); + break; + case R_AVR32_14UW_PCREL: + newValue = (int)(((symbolValue + (int)addend - offset) >>> 2) & 0x0000f0ff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_14UW_PCREL at "+relocationAddress + ", New = " + newValue); + break;*/ + /*case R_AVR32_10UW_PCREL: + newValue = (int)(((symbolValue + (int)addend - offset) >>> 2) & 0x000000ff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_10UW_PCREL at "+relocationAddress + ", New = " + newValue); + break;*/ + /*case R_AVR32_9UW_PCREL: + newValue = (int)((((symbolValue + (int)addend - offset) >>> 2) << 4) & 0x000007f0); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_9UW_PCREL at "+relocationAddress + ", New = " + newValue); + break; + + case R_AVR32_HI16: + newValue = (((symbolValue + (int)addend) >> 16) & 0x0000ffff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_HI16 at "+relocationAddress + ", New = " + newValue); + break; + case R_AVR32_LO16: + newValue = ((symbolValue + (int)addend) & 0x0000ffff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_LO16 at "+relocationAddress + ", New = " + newValue); + break; + + case R_AVR32_GOTPC: + ElfSectionHeader dotgot = elf.getGOT(); + MemoryBlock got = memory.getBlock(dotgot.getNameAsString()); + newValue = ((symbolValue + (int)addend - (int)got.getStart().getOffset()) & 0xffffffff); + memory.setInt(relocationAddress, newValue); + System.out.println(" HANDLED AVR relocation: R_AVR32_GOTPC at "+relocationAddress + ", New = " + newValue); + break;*/ + default: + markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, + elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; } return new RelocationResult(Status.APPLIED, byteLength); } diff --git a/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/AVR32_ElfRelocationConstants.java b/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR32_ElfRelocationType.java similarity index 73% rename from Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/AVR32_ElfRelocationConstants.java rename to Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR32_ElfRelocationType.java index 09758a6a68..2f52392964 100644 --- a/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/AVR32_ElfRelocationConstants.java +++ b/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR32_ElfRelocationType.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,58 +13,58 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.util.bin.format.elf; +package ghidra.app.util.bin.format.elf.relocation; -public class AVR32_ElfRelocationConstants { +public enum AVR32_ElfRelocationType implements ElfRelocationType { /* Atmel AVR32 relocations. */ // NONE (possibly a placeholder for relocations that are moved) // - public static final int R_AVR32_NONE = 0; + R_AVR32_NONE(0), /* Data Relocations */ // DATA: ((S + A) & 0xffffffff) (Normal Data) // - public static final int R_AVR32_32 = 1; + R_AVR32_32(1), // DATA: ((S + A) & 0x0000ffff) (Normal Data) // - public static final int R_AVR32_16 = 2; + R_AVR32_16(2), // DATA: ((S + A) & 0x000000ff)(Normal Data) // - public static final int R_AVR32_8 = 3; + R_AVR32_8(3), // DATA: ((S + A - P) & 0xffffffff) (PC-relative) // - public static final int R_AVR32_32_PCREL = 4; + R_AVR32_32_PCREL(4), // DATA: ((S + A - P) & 0x0000ffff) (PC-relative) // - public static final int R_AVR32_16_PCREL = 5; + R_AVR32_16_PCREL(5), // DATA: ((S + A - P) & 0x000000ff) (PC-relative) // - public static final int R_AVR32_8_PCREL = 6; + R_AVR32_8_PCREL(6), // Difference between two labels: L2 - L1. The value of L1 is encoded as S + // A, // while the initial difference after assembly is // inserted into the object file by the assembler. // DATA: (S & 0xffffffff) // - public static final int R_AVR32_DIFF32 = 7; + R_AVR32_DIFF32(7), // DATA: (S & 0x0000ffff) // - public static final int R_AVR32_DIFF16 = 8; + R_AVR32_DIFF16(8), // DATA: (S & 0x000000ff) // - public static final int R_AVR32_DIFF8 = 9; + R_AVR32_DIFF8(9), // Reference to a symbol through the Global Offset Table (GOT). The linker // will allocate an entry for symbol in the GOT and insert the offset - // of this entry as the relocation value. A = 0 + // of this entry as the relocation value. A(0 // DATA: (G & 0xffffffff) // - public static final int R_AVR32_GOT32 = 10; + R_AVR32_GOT32(10), // DATA: (G & 0x0000ffff) // - public static final int R_AVR32_GOT16 = 11; + R_AVR32_GOT16(11), // DATA: (G & 0x000000ff) // - public static final int R_AVR32_GOT8 = 12; + R_AVR32_GOT8(12), /* Normal Code Relocations */ // Normal (non-pc-relative) code relocations. Alignment and signedness // is indicated by the suffixes. S means signed, U means unsigned. @@ -73,19 +72,19 @@ public class AVR32_ElfRelocationConstants { // byte-aligned (no alignment.) // NORMAL CODE: ((S + A) & 0x1e10ffff) // - public static final int R_AVR32_21S = 13; + R_AVR32_21S(13), // NORMAL CODE: ((S + A) & 0x0000ffff) // - public static final int R_AVR32_16U = 14; + R_AVR32_16U(14), // NORMAL CODE: ((S + A) & 0x0000ffff) // - public static final int R_AVR32_16S = 15; + R_AVR32_16S(15), // NORMAL CODE: (((S + A)) << 4) & 0x00000ff0) // - public static final int R_AVR32_8S = 16; + R_AVR32_8S(16), // NORMAL CODE: ((S + A) & 0x000000ff) // - public static final int R_AVR32_8S_EXT = 17; + R_AVR32_8S_EXT(17), /* PC-Relative Code Relocations */ // PC-relative relocations are signed if neither 'U' nor 'S' is // specified. However, we explicitly tack on a 'B' to indicate no @@ -94,49 +93,49 @@ public class AVR32_ElfRelocationConstants { // This particular one resolves to P - S - A. // PC-REL CODE: (((S + A - P) >> 1) & 0x1e10ffff) // - public static final int R_AVR32_22H_PCREL = 18; + R_AVR32_22H_PCREL(18), // PC-REL CODE: (((S + A - P) >> 2) & 0x0000ffff) // - public static final int R_AVR32_18W_PCREL = 19; + R_AVR32_18W_PCREL(19), // PC-REL CODE: ((S + A - P) & 0x0000ffff) // - public static final int R_AVR32_16B_PCREL = 20; + R_AVR32_16B_PCREL(20), // PC-REL CODE: ((P - S - A) & 0x0000ffff) // - public static final int R_AVR32_16N_PCREL = 21; + R_AVR32_16N_PCREL(21), // PC-REL CODE: (((S + A - P) >>> 2) & 0x0000f0ff) // - public static final int R_AVR32_14UW_PCREL = 22; + R_AVR32_14UW_PCREL(22), // PC-REL CODE: (((S + A - P) >> 1) << 4) - // Must then: tmp1 = (newValue & 0x00000ff3); - // Must then: tmp2 = ((newValue & 0x00003000) >> 12); (to match opcode disp) - // Must then: tmp3 = ((tmp1 << 16) | (tmp2 << 16)) + // Must then: tmp1((newValue & 0x00000ff3)), + // Must then: tmp2(((newValue & 0x00003000) >> 12)), (to match opcode disp) + // Must then: tmp3(((tmp1 << 16) | (tmp2 << 16)) // Must then: (oldValue | tmp3) & 0xffffffff) // - public static final int R_AVR32_11H_PCREL = 23; + R_AVR32_11H_PCREL(23), // PC-REL CODE: (((S + A - P) >>> 2) & 0x000000ff) // - public static final int R_AVR32_10UW_PCREL = 24; + R_AVR32_10UW_PCREL(24), // PC-REL CODE: ((((S + A - P) >> 1) << 4) & 0x00000ff0) // Must then: (oldValue | newValue << 16) & 0xffffffff) // - public static final int R_AVR32_9H_PCREL = 25; + R_AVR32_9H_PCREL(25), // PC-REL CODE: ((((S + A) << 4) - P) >>> 2) & 0x000007f0) // - public static final int R_AVR32_9UW_PCREL = 26; + R_AVR32_9UW_PCREL(26), /* Special Code Relocations */ // Special CODE: (((S + A) >> 16) & 0x0000ffff) // - public static final int R_AVR32_HI16 = 27; + R_AVR32_HI16(27), // Special CODE: ((S + A) & 0x0000ffff) // - public static final int R_AVR32_LO16 = 28; + R_AVR32_LO16(28), /* PIC Relocations */ // Subtract the link-time address of the GOT from (S + A) and // insert the result. // PIC: (((S + A) - GOT) & 0xffffffff) // - public static final int R_AVR32_GOTPC = 29; + R_AVR32_GOTPC(29), // Reference to a symbol through the GOT. The linker will // allocate an entry for symbol in the GOT and insert // the offset of this entry as the relocation value. @@ -144,51 +143,51 @@ public class AVR32_ElfRelocationConstants { // word-aligned, etc. // PIC: ((G >> 2) & 0x1e10ffff) // (Call instructions) - public static final int R_AVR32_GOTCALL = 30; + R_AVR32_GOTCALL(30), // PIC: ((G >> 2) & 0x1e10ffff) // (lda.w instructions) - public static final int R_AVR32_LDA_GOT = 31; + R_AVR32_LDA_GOT(31), // PIC: (G & 0x1e10ffff) // - public static final int R_AVR32_GOT21S = 32; + R_AVR32_GOT21S(32), // PIC: ((G >> 2) & 0x0000ffff) // - public static final int R_AVR32_GOT18SW = 33; + R_AVR32_GOT18SW(33), // PIC: (G & 0x0000ffff) // - public static final int R_AVR32_GOT16S = 34; + R_AVR32_GOT16S(34), // PIC: (((G) << 4) >> 2) & 0x000001f0) // - public static final int R_AVR32_GOT7UW = 35; + R_AVR32_GOT7UW(35), /* Constant Pool Relocations */ // 32-bit constant pool entry. // CONST POOL: ((S + A) & 0xffffffff) // - public static final int R_AVR32_32_CPENT = 36; + R_AVR32_32_CPENT(36), // Constant pool references. Some of these relocations are signed, // others are unsigned. Constant pool always comes after // the code that references it. // CONST POOL: (((S + A - P) >> 2) & 0x0000ffff) // Must then: ((oldValue | newValue) & 0xffffffff) // - public static final int R_AVR32_CPCALL = 37; + R_AVR32_CPCALL(37), // CONST POOL: ((S + A - P) & 0x0000ffff) // - public static final int R_AVR32_16_CP = 38; + R_AVR32_16_CP(38), // CONST POOL: ((((S + A - P) >>> 2) << 4) & 0x000007f0) // Must then: ((oldValue | newValue << 16) & 0xffffffff) // - public static final int R_AVR32_9W_CP = 39; + R_AVR32_9W_CP(39), /* Dynamic Relocations */ // Dynamic: ((B + A) & 0xffffffff) // - public static final int R_AVR32_RELATIVE = 40; + R_AVR32_RELATIVE(40), // Dynamic: ((S + A) & 0xffffffff) // - public static final int R_AVR32_GLOB_DAT = 41; + R_AVR32_GLOB_DAT(41), // Dynamic: ((S + A) & 0xffffffff) // - public static final int R_AVR32_JMP_SLOT = 42; + R_AVR32_JMP_SLOT(42), /* Linkrelax Information */ // Symbol(S) must be the absolute symbol. The Addend(A) specifies // the alignment order, e.g. if A is 2, the linker must add @@ -196,11 +195,22 @@ public class AVR32_ElfRelocationConstants { // boundary. // Linkrelax: (P << A) // - public static final int R_AVR32_ALIGN = 43; - public static final int R_AVR32_NUM = 44; + R_AVR32_ALIGN(43), + R_AVR32_NUM(44), /* Total Size in Bytes of the Global Offset Table */ - public static final int DT_AVR32_GOTSZ = 0x70000001; + DT_AVR32_GOTSZ(0x70000001), /* CPU-Specific flags for the ELF header e_flags field */ - public static final int EF_AVR32_LINKRELAX = 0x01; - public static final int EF_AVR32_PIC = 0x02; + EF_AVR32_LINKRELAX(0x01), + EF_AVR32_PIC(0x02); + + public final int typeId; + + private AVR32_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } } diff --git a/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR8_ElfRelocationHandler.java b/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR8_ElfRelocationHandler.java index 3d9379975b..8a054fbf01 100644 --- a/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR8_ElfRelocationHandler.java +++ b/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR8_ElfRelocationHandler.java @@ -20,11 +20,18 @@ import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryAccessException; -import ghidra.program.model.reloc.RelocationResult; import ghidra.program.model.reloc.Relocation.Status; -import ghidra.util.exception.NotFoundException; +import ghidra.program.model.reloc.RelocationResult; -public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { +public class AVR8_ElfRelocationHandler + extends AbstractElfRelocationHandler> { + + /** + * Constructor + */ + public AVR8_ElfRelocationHandler() { + super(AVR8_ElfRelocationType.class); + } @Override public boolean canRelocate(ElfHeader elf) { @@ -32,126 +39,114 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, - Address relocationAddress) throws MemoryAccessException, NotFoundException { + protected RelocationResult relocate(ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, AVR8_ElfRelocationType type, Address relocationAddress, + ElfSymbol elfSymbol, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { + + // WARNING: symbolValue is not in bytes. + // It is an addressable word offset within the symbols address space Program program = elfRelocationContext.getProgram(); - Memory memory = program.getMemory(); - int type = relocation.getType(); - int symbolIndex = relocation.getSymbolIndex(); - long addend = relocation.getAddend(); // will be 0 for REL case - ElfHeader elf = elfRelocationContext.getElfHeader(); - - // WARNING: offset is in bytes - // be careful, word address potentially with byte indexes + // WARNING: offset is in bytes be careful, word address potentially with byte indexes long offset = relocationAddress.getOffset(); - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null - // WARNING: symbolValue here is not in bytes. - // it is an addressable word offset for the symbols address space - long symbolValue = elfRelocationContext.getSymbolValue(sym); - String symbolName = elfRelocationContext.getSymbolName(symbolIndex); - + int symbolIndex = relocation.getSymbolIndex(); int oldValue = memory.getShort(relocationAddress); - if (elf.e_machine() != ElfConstants.EM_AVR) { - return RelocationResult.FAILURE; - } - int newValue = 0; int byteLength = 2; // most relocations affect 2-bytes (change if different) switch (type) { - case AVR8_ElfRelocationConstants.R_AVR_NONE: + case R_AVR_NONE: return RelocationResult.SKIPPED; - case AVR8_ElfRelocationConstants.R_AVR_32: + case R_AVR_32: newValue = (((int) symbolValue + (int) addend) & 0xffffffff); memory.setInt(relocationAddress, newValue); break; - case AVR8_ElfRelocationConstants.R_AVR_7_PCREL: + case R_AVR_7_PCREL: newValue = (int) ((symbolValue * 2 + (int) addend - offset)); newValue -= 2; // branch PC is offset+2 if ((newValue & 1) == 1) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); return RelocationResult.FAILURE; } if (newValue > ((1 << 7) - 1) || (newValue < -(1 << 7))) { - markAsError(program, relocationAddress, type, symbolName, "relocation overflow", - elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation overflow", elfRelocationContext.getLog()); return RelocationResult.FAILURE; } newValue = (oldValue & 0xfc07) | (((newValue >> 1) << 3) & 0x3f8); memory.setShort(relocationAddress, (short) newValue); break; - case AVR8_ElfRelocationConstants.R_AVR_13_PCREL: + case R_AVR_13_PCREL: newValue = (int) ((symbolValue * 2 + (int) addend - offset)); newValue -= 2; // branch PC is offset+2 if ((newValue & 1) == 1) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); return RelocationResult.FAILURE; } newValue >>= 1; if (newValue < -2048 || newValue > 2047) { - markAsWarning(program, relocationAddress, symbolName, symbolName, symbolIndex, - "possible relocation error", elfRelocationContext.getLog()); + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, + "Possible relocation error", elfRelocationContext.getLog()); } newValue = (oldValue & 0xf000) | (newValue & 0xfff); memory.setShort(relocationAddress, (short) newValue); break; - case AVR8_ElfRelocationConstants.R_AVR_16: + case R_AVR_16: newValue = ((int) symbolValue + (int) addend); memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_16_PM: + case R_AVR_16_PM: newValue = (((int) symbolValue * 2 + (int) addend)); newValue >>= 1; memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_LO8_LDI: + case R_AVR_LO8_LDI: newValue = (((int) symbolValue + (int) addend)); newValue = (oldValue & 0xf0f0) | (newValue & 0xf) | ((newValue << 4) & 0xf00); memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_HI8_LDI: + case R_AVR_HI8_LDI: newValue = (((int) symbolValue + (int) addend)); newValue = (newValue >> 8) & 0xff; newValue = (oldValue & 0xf0f0) | (newValue & 0xf) | ((newValue << 4) & 0xf00); memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_HH8_LDI: + case R_AVR_HH8_LDI: newValue = (((int) symbolValue + (int) addend)); newValue = (newValue >> 16) & 0xff; newValue = (oldValue & 0xf0f0) | (newValue & 0xf) | ((newValue << 4) & 0xf00); memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_LO8_LDI_NEG: + case R_AVR_LO8_LDI_NEG: newValue = (((int) symbolValue + (int) addend)); newValue = -newValue; newValue = (oldValue & 0xf0f0) | (newValue & 0xf) | ((newValue << 4) & 0xf00); memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_HI8_LDI_NEG: + case R_AVR_HI8_LDI_NEG: newValue = (((int) symbolValue + (int) addend)); newValue = -newValue; newValue = (newValue >> 8) & 0xff; @@ -159,7 +154,7 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_HH8_LDI_NEG: + case R_AVR_HH8_LDI_NEG: newValue = (((int) symbolValue + (int) addend)); newValue = -newValue; newValue = (newValue >> 16) & 0xff; @@ -167,11 +162,11 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_LO8_LDI_PM: + case R_AVR_LO8_LDI_PM: newValue = (((int) symbolValue * 2 + (int) addend)); if ((newValue & 1) == 1) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); return RelocationResult.FAILURE; } newValue >>= 1; @@ -179,11 +174,11 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_HI8_LDI_PM: + case R_AVR_HI8_LDI_PM: newValue = (((int) symbolValue * 2 + (int) addend)); if ((newValue & 1) == 1) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); return RelocationResult.FAILURE; } newValue >>= 1; @@ -192,11 +187,11 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_HH8_LDI_PM: + case R_AVR_HH8_LDI_PM: newValue = (((int) symbolValue * 2 + (int) addend)); if ((newValue & 1) == 1) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); return RelocationResult.FAILURE; } newValue >>= 1; @@ -205,12 +200,12 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_LO8_LDI_PM_NEG: + case R_AVR_LO8_LDI_PM_NEG: newValue = (((int) symbolValue * 2 + (int) addend)); newValue = -newValue; if ((newValue & 1) == 1) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); return RelocationResult.FAILURE; } newValue >>= 1; @@ -218,12 +213,12 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_HI8_LDI_PM_NEG: + case R_AVR_HI8_LDI_PM_NEG: newValue = (((int) symbolValue * 2 + (int) addend)); newValue = -newValue; if ((newValue & 1) == 1) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); return RelocationResult.FAILURE; } newValue >>= 1; @@ -232,12 +227,12 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_HH8_LDI_PM_NEG: + case R_AVR_HH8_LDI_PM_NEG: newValue = (((int) symbolValue * 2 + (int) addend)); newValue = -newValue; if ((newValue & 1) == 1) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); return RelocationResult.FAILURE; } newValue >>= 1; @@ -246,12 +241,12 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_CALL: + case R_AVR_CALL: newValue = (int) symbolValue * 2 + (int) addend; if ((newValue & 1) == 1) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); return RelocationResult.FAILURE; } newValue >>= 1; @@ -263,12 +258,12 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 4; break; - case AVR8_ElfRelocationConstants.R_AVR_LDI: /* data/eeprom */ + case R_AVR_LDI: /* data/eeprom */ newValue = (((int) symbolValue + (int) addend)); if ((newValue & 0xffff) > 255) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); // continue to apply } @@ -277,12 +272,12 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_6: /* data/eeprom **/ + case R_AVR_6: /* data/eeprom **/ newValue = (((int) symbolValue + (int) addend)); if (((newValue & 0xffff) > 63) || (newValue < 0)) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); // continue to apply } @@ -291,12 +286,12 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_6_ADIW: + case R_AVR_6_ADIW: newValue = (((int) symbolValue + (int) addend)); if (((newValue & 0xffff) > 63) || (newValue < 0)) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); // continue to apply } @@ -305,18 +300,18 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_DIFF8: - case AVR8_ElfRelocationConstants.R_AVR_DIFF16: - case AVR8_ElfRelocationConstants.R_AVR_DIFF32: + case R_AVR_DIFF8: + case R_AVR_DIFF16: + case R_AVR_DIFF32: // nothing to do break; - case AVR8_ElfRelocationConstants.R_AVR_LDS_STS_16: + case R_AVR_LDS_STS_16: newValue = (((int) symbolValue + (int) addend)); if (((newValue & 0xffff) < 0x40) || (newValue & 0xFFFF) > 0xbf) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); // continue to apply } @@ -325,12 +320,12 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_PORT6: + case R_AVR_PORT6: newValue = (((int) symbolValue + (int) addend)); if ((newValue & 0xffff) > 0x3f) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); // continue to apply } @@ -338,12 +333,12 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_PORT5: + case R_AVR_PORT5: newValue = (((int) symbolValue + (int) addend)); if ((newValue & 0xffff) > 0x1f) { - markAsError(program, relocationAddress, type, symbolName, - "relocation out of range", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Relocation out of range", elfRelocationContext.getLog()); // continue to apply } @@ -351,14 +346,14 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case AVR8_ElfRelocationConstants.R_AVR_MS8_LDI: - case AVR8_ElfRelocationConstants.R_AVR_MS8_LDI_NEG: - case AVR8_ElfRelocationConstants.R_AVR_LO8_LDI_GS: - case AVR8_ElfRelocationConstants.R_AVR_HI8_LDI_GS: - case AVR8_ElfRelocationConstants.R_AVR_8: - case AVR8_ElfRelocationConstants.R_AVR_8_LO8: - case AVR8_ElfRelocationConstants.R_AVR_8_HI8: - case AVR8_ElfRelocationConstants.R_AVR_8_HLO8: + case R_AVR_MS8_LDI: + case R_AVR_MS8_LDI_NEG: + case R_AVR_LO8_LDI_GS: + case R_AVR_HI8_LDI_GS: + case R_AVR_8: + case R_AVR_8_LO8: + case R_AVR_8_HI8: + case R_AVR_8_HLO8: default: markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, elfRelocationContext.getLog()); diff --git a/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR8_ElfRelocationType.java b/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR8_ElfRelocationType.java new file mode 100644 index 0000000000..f682cb1625 --- /dev/null +++ b/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR8_ElfRelocationType.java @@ -0,0 +1,68 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum AVR8_ElfRelocationType implements ElfRelocationType { + + R_AVR_NONE(0), + R_AVR_32(1), + R_AVR_7_PCREL(2), + R_AVR_13_PCREL(3), + R_AVR_16(4), + R_AVR_16_PM(5), + R_AVR_LO8_LDI(6), + R_AVR_HI8_LDI(7), + R_AVR_HH8_LDI(8), + R_AVR_LO8_LDI_NEG(9), + R_AVR_HI8_LDI_NEG(10), + R_AVR_HH8_LDI_NEG(11), + R_AVR_LO8_LDI_PM(12), + R_AVR_HI8_LDI_PM(13), + R_AVR_HH8_LDI_PM(14), + R_AVR_LO8_LDI_PM_NEG(15), + R_AVR_HI8_LDI_PM_NEG(16), + R_AVR_HH8_LDI_PM_NEG(17), + R_AVR_CALL(18), + R_AVR_LDI(19), + R_AVR_6(20), + R_AVR_6_ADIW(21), + R_AVR_MS8_LDI(22), + R_AVR_MS8_LDI_NEG(23), + R_AVR_LO8_LDI_GS(24), + R_AVR_HI8_LDI_GS(25), + R_AVR_8(26), + R_AVR_8_LO8(27), + R_AVR_8_HI8(28), + R_AVR_8_HLO8(29), + R_AVR_DIFF8(30), + R_AVR_DIFF16(31), + R_AVR_DIFF32(32), + R_AVR_LDS_STS_16(33), + R_AVR_PORT6(34), + R_AVR_PORT5(35); + + public final int typeId; + + private AVR8_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } + +} diff --git a/Ghidra/Processors/Loongarch/src/main/java/ghidra/app/util/bin/format/elf/relocation/Loongarch_ElfRelocationConstants.java b/Ghidra/Processors/Loongarch/src/main/java/ghidra/app/util/bin/format/elf/relocation/Loongarch_ElfRelocationConstants.java deleted file mode 100644 index 26d9673962..0000000000 --- a/Ghidra/Processors/Loongarch/src/main/java/ghidra/app/util/bin/format/elf/relocation/Loongarch_ElfRelocationConstants.java +++ /dev/null @@ -1,156 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.util.bin.format.elf.relocation; - -public class Loongarch_ElfRelocationConstants { - - public static final int R_LARCH_NONE = 0; - - /* Runtime address resolving */ - public static final int R_LARCH_32 = 1; // *(int32_t *) PC = RtAddr + A - public static final int R_LARCH_64 = 2; // *(int64_t *) PC = RtAddr + A - - public static final int R_LARCH_RELATIVE = 3; // Runtime fixup for load-address *(void **) PC = B + A - public static final int R_LARCH_COPY = 4; // Runtime memory copy in executable memcpy (PC, RtAddr, sizeof (sym)) - public static final int R_LARCH_JUMP_SLOT = 5; // Runtime PLT supporting (implementation defined) - - /* Runtime relocations for TLS-GD */ - public static final int R_LARCH_TLS_DTPMOD32 = 6; // *(int32_t *) PC = ID of module defining sym - public static final int R_LARCH_TLS_DTPMOD64 = 7; // *(int64_t *) PC = ID of module defining sym - public static final int R_LARCH_TLS_DTPREL32 = 8; // *(int32_t *) PC = DTV-relative offset for sym - public static final int R_LARCH_TLS_DTPREL64 = 9; // *(int64_t *) PC = DTV-relative offset for sym - - /* Runtime relocations for TLE-IE */ - public static final int R_LARCH_TLS_TPREL32 = 10; // *(int32_t *) PC = T - public static final int R_LARCH_TLS_TPREL64 = 11; // *(int64_t *) PC = T - - public static final int R_LARCH_IRELATIVE = 12; /* Runtime local indirect function resolving - *(void **) PC = (((void *)(*)()) (B + A)) () */ - - /* Relocations 13..19 reserved for dynamic linker */ - - public static final int R_LARCH_MARK_LA = 20; // Mark la.abs Load absolute address for static link. - public static final int R_LARCH_MARK_PCREL = 21; // Mark external label branch Access PC relative address for static link. - public static final int R_LARCH_SOP_PUSH_PCREL = 22; // Push PC-relative offset push (S - PC + A) - public static final int R_LARCH_SOP_PUSH_ABSOLUTE = 23; // Push constant or absolute address push (S + A) - public static final int R_LARCH_SOP_PUSH_DUP = 24; // Duplicate stack top opr1 = pop (), push (opr1), push (opr1) - public static final int R_LARCH_SOP_PUSH_GPREL = 25; // Push for access GOT entry push (G) - public static final int R_LARCH_SOP_PUSH_TLS_TPREL = 26; // Push for TLS-LE push (T) - public static final int R_LARCH_SOP_PUSH_TLS_GOT = 27; // Push for TLS-IE push (IE) - public static final int R_LARCH_SOP_PUSH_TLS_GD = 28; // Push for TLS-GD push (GD) - public static final int R_LARCH_SOP_PUSH_PLT_PCREL = 29; // Push for external function calling push (PLT - PC) - public static final int R_LARCH_SOP_ASSERT = 30; // Assert stack top assert (pop ()) - - /* Stack top operations */ - public static final int R_LARCH_SOP_NOT = 31; - public static final int R_LARCH_SOP_SUB = 32; - public static final int R_LARCH_SOP_SL = 33; - public static final int R_LARCH_SOP_SR = 34; - public static final int R_LARCH_SOP_ADD = 35; - public static final int R_LARCH_SOP_AND = 36; - public static final int R_LARCH_SOP_IF_ELSE = 37; - - /* Instruction imm-field relocation */ - public static final int R_LARCH_SOP_POP_32_S_10_5 = 38; - public static final int R_LARCH_SOP_POP_32_U_10_12 = 39; - public static final int R_LARCH_SOP_POP_32_S_10_12 = 40; - public static final int R_LARCH_SOP_POP_32_S_10_16 = 41; - public static final int R_LARCH_SOP_POP_32_S_10_16_S2 = 42; - public static final int R_LARCH_SOP_POP_32_S_5_20 = 43; - public static final int R_LARCH_SOP_POP_32_S_0_5_10_16_S2 = 44; - public static final int R_LARCH_SOP_POP_32_S_0_10_10_16_S2 = 45; - - /* Instruction fixup */ - public static final int R_LARCH_SOP_POP_32_U = 46; - - /* n-bit in-place additions */ - public static final int R_LARCH_ADD8 = 47; - public static final int R_LARCH_ADD16 = 48; - public static final int R_LARCH_ADD24 = 49; - public static final int R_LARCH_ADD32 = 50; - public static final int R_LARCH_ADD64 = 51; - - /* n-bit in-place subtractions */ - public static final int R_LARCH_SUB8 = 52; - public static final int R_LARCH_SUB16 = 53; - public static final int R_LARCH_SUB24 = 54; - public static final int R_LARCH_SUB32 = 55; - public static final int R_LARCH_SUB64 = 56; - - - public static final int R_LARCH_GNU_VTINHERIT = 57; // GNU C++ vtable hierarchy - public static final int R_LARCH_GNU_VTENTRY = 58; // GNU C++ vtable member usage - - /* 59..63 reserved */ - - /* n-bit relative jumps */ - public static final int R_LARCH_B16 = 64; - public static final int R_LARCH_B21 = 65; - public static final int R_LARCH_B26 = 66; - - public static final int R_LARCH_ABS_HI20 = 67; // [31 …​ 12] bits of 32/64-bit absolute address - public static final int R_LARCH_ABS_LO12 = 68; // [11 …​ 0] bits of 32/64-bit absolute address - public static final int R_LARCH_ABS64_LO20 = 69; // [51 …​ 32] bits of 64-bit absolute address - public static final int R_LARCH_ABS64_HI12 = 70; // [63 …​ 52] bits of 64-bit absolute address - public static final int R_LARCH_PCALA_HI20 = 71; // [31 …​ 12] bits of 32/64-bit PC-relative offset - public static final int R_LARCH_PCALA_LO12 = 72; // [11 …​ 0] bits of 32/64-bit address - public static final int R_LARCH_PCALA64_LO20 = 73; // [51 …​ 32] bits of 64-bit PC-relative offset - public static final int R_LARCH_PCALA64_HI12 = 74; // [63 …​ 52] bits of 64-bit PC-relative offset - - public static final int R_LARCH_GOT_PC_HI20 = 75; // [31 …​ 12] bits of 32/64-bit PC-relative offset to GOT entry - public static final int R_LARCH_GOT_PC_LO12 = 76; // [11 …​ 0] bits of 32/64-bit GOT entry address - public static final int R_LARCH_GOT64_PC_LO20 = 77; // [51 …​ 32] bits of 64-bit PC-relative offset to GOT entry - public static final int R_LARCH_GOT64_PC_HI12 = 78; // [63 …​ 52] bits of 64-bit PC-relative offset to GOT entry - public static final int R_LARCH_GOT_HI20 = 79; // [31 …​ 12] bits of 32/64-bit GOT entry absolute address - public static final int R_LARCH_GOT_LO12 = 80; // [11 …​ 0] bits of 32/64-bit GOT entry absolute address - public static final int R_LARCH_GOT64_LO20 = 81; // [51 …​ 32] bits of 64-bit GOT entry absolute address - public static final int R_LARCH_GOT64_HI12 = 82; // [63 …​ 52] bits of 64-bit GOT entry absolute address - - public static final int R_LARCH_TLS_LE_HI20 = 83; // [31 …​ 12] bits of TLS LE 32/64-bit offset from TP register - public static final int R_LARCH_TLS_LE_LO12 = 84; // [11 …​ 0] bits of TLS LE 32/64-bit offset from TP register - public static final int R_LARCH_TLS_LE64_LO20 = 85; // [51 …​ 32] bits of TLS LE 64-bit offset from TP register - public static final int R_LARCH_TLS_LE64_HI12 = 86; // [63 …​ 52] bits of TLS LE 64-bit offset from TP register - public static final int R_LARCH_TLS_IE_PC_HI20 = 87; // [31 …​ 12] bits of 32/64-bit PC-relative offset to TLS IE GOT entry - public static final int R_LARCH_TLS_IE_PC_LO12 = 88; // [11 …​ 0] bits of 32/64-bit TLS IE GOT entry address - public static final int R_LARCH_TLS_IE64_PC_LO20 = 89; // [51 …​ 32] bits of 64-bit PC-relative offset to TLS IE GOT entry - public static final int R_LARCH_TLS_IE64_PC_HI12 = 90; // [63 …​ 52] bits of 64-bit PC-relative offset to TLS IE GOT entry - public static final int R_LARCH_TLS_IE_HI20 = 91; // [31 …​ 12] bits of 32/64-bit TLS IE GOT entry absolute address - public static final int R_LARCH_TLS_IE_LO12 = 92; // [11 …​ 0] bits of 32/64-bit TLS IE GOT entry absolute address - public static final int R_LARCH_TLS_IE64_LO20 = 93; // [51 …​ 32] bits of 64-bit TLS IE GOT entry absolute address - public static final int R_LARCH_TLS_IE64_HI12 = 94; // [63 …​ 52] bits of 64-bit TLS IE GOT entry absolute address - public static final int R_LARCH_TLS_LD_PC_HI20 = 95; // [31 …​ 12] bits of 32/64-bit PC-relative offset to TLS LD GOT entry - public static final int R_LARCH_TLS_LD_HI20 = 96; // [31 …​ 12] bits of 32/64-bit TLS LD GOT entry absolute address - public static final int R_LARCH_TLS_GD_PC_HI20 = 97; // [31 …​ 12] bits of 32/64-bit PC-relative offset to TLS GD GOT entry - public static final int R_LARCH_TLS_GD_HI20 = 98; // [31 …​ 12] bits of 32/64-bit TLS GD GOT entry absolute address - - public static final int R_LARCH_32_PCREL = 99; // 32-bit PC relative - public static final int R_LARCH_RELAX = 100; // Instruction can be relaxed, paired with a normal relocation at the same address - - // The following are from binutils and not found in the official Loongarch documentation - public static final int R_LARCH_DELETE = 101; // relax delete - public static final int R_LARCH_ALIGN = 102; // relax delete - public static final int R_LARCH_PCREL20_S2 = 103; // pcaddi - public static final int R_LARCH_CFA = 104; // relax delete - public static final int R_LARCH_ADD6 = 105; // relax delete - public static final int R_LARCH_SUB6 = 106; // pcaddi - public static final int R_LARCH_ADD_ULEB128 = 107; // relax delete - public static final int R_LARCH_SUB_ULEB128 = 108; // relax delete - public static final int R_LARCH_64_PCREL = 109; // pcaddi - - private Loongarch_ElfRelocationConstants() { - // no construct - } -} diff --git a/Ghidra/Processors/Loongarch/src/main/java/ghidra/app/util/bin/format/elf/relocation/Loongarch_ElfRelocationHandler.java b/Ghidra/Processors/Loongarch/src/main/java/ghidra/app/util/bin/format/elf/relocation/Loongarch_ElfRelocationHandler.java index 8589f5dbaa..c94cedb630 100644 --- a/Ghidra/Processors/Loongarch/src/main/java/ghidra/app/util/bin/format/elf/relocation/Loongarch_ElfRelocationHandler.java +++ b/Ghidra/Processors/Loongarch/src/main/java/ghidra/app/util/bin/format/elf/relocation/Loongarch_ElfRelocationHandler.java @@ -22,10 +22,16 @@ import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.reloc.RelocationResult; -import ghidra.util.exception.NotFoundException; +public class Loongarch_ElfRelocationHandler + extends AbstractElfRelocationHandler> { -public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { + /** + * Constructor + */ + public Loongarch_ElfRelocationHandler() { + super(Loongarch_ElfRelocationType.class); + } @Override public boolean canRelocate(ElfHeader elf) { @@ -33,72 +39,61 @@ public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, - Address relocationAddress) throws MemoryAccessException, NotFoundException { - ElfHeader elf = elfRelocationContext.getElfHeader(); - if (!canRelocate(elf)) { - return RelocationResult.FAILURE; - } + protected RelocationResult relocate(ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, Loongarch_ElfRelocationType type, Address relocationAddress, + ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); - boolean is32 = elf.is32Bit(); - int type = relocation.getType(); - if (Loongarch_ElfRelocationConstants.R_LARCH_NONE == type) { - return RelocationResult.SKIPPED; - } + ElfHeader elf = elfRelocationContext.getElfHeader(); + + long addend = relocation.hasAddend() ? relocation.getAddend() + : elf.is32Bit() ? memory.getInt(relocationAddress) + : memory.getLong(relocationAddress); - long addend = relocation.hasAddend() ? relocation.getAddend() : is32 ? memory.getInt(relocationAddress) : memory.getLong(relocationAddress); - long offset = relocationAddress.getOffset(); long base = elfRelocationContext.getImageBaseWordAdjustmentOffset(); - int symbolIndex = relocation.getSymbolIndex(); - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); - Address symbolAddr = elfRelocationContext.getSymbolAddress(sym); - long symbolValue = elfRelocationContext.getSymbolValue(sym); - String symbolName = elfRelocationContext.getSymbolName(symbolIndex); - long value64 = 0; int value32 = 0; short value16 = 0; byte value8 = 0; byte[] bytes24 = new byte[3]; - + int byteLength = 4; // most relocations affect 4-bytes (change if different) switch (type) { - case Loongarch_ElfRelocationConstants.R_LARCH_32: + case R_LARCH_32: // Runtime address resolving *(int32_t *) PC = RtAddr + A value32 = (int) (symbolValue + addend); memory.setInt(relocationAddress, value32); if (symbolIndex != 0 && addend != 0 && !sym.isSection()) { - warnExternalOffsetRelocation(program, relocationAddress, - symbolAddr, symbolName, addend, elfRelocationContext.getLog()); + warnExternalOffsetRelocation(program, relocationAddress, symbolAddr, symbolName, + addend, elfRelocationContext.getLog()); if (elf.is32Bit()) { applyComponentOffsetPointer(program, relocationAddress, addend); } } break; - case Loongarch_ElfRelocationConstants.R_LARCH_64: + case R_LARCH_64: // Runtime address resolving *(int64_t *) PC = RtAddr + A value64 = symbolValue + addend; memory.setLong(relocationAddress, value64); byteLength = 8; if (symbolIndex != 0 && addend != 0 && !sym.isSection()) { - warnExternalOffsetRelocation(program, relocationAddress, - symbolAddr, symbolName, addend, elfRelocationContext.getLog()); + warnExternalOffsetRelocation(program, relocationAddress, symbolAddr, symbolName, + addend, elfRelocationContext.getLog()); if (elf.is64Bit()) { applyComponentOffsetPointer(program, relocationAddress, addend); } } break; - case Loongarch_ElfRelocationConstants.R_LARCH_RELATIVE: + case R_LARCH_RELATIVE: // Runtime fixup for load-address *(void **) PC = B + A - if (is32) { + if (elf.is32Bit()) { value32 = (int) (base + addend); memory.setInt(relocationAddress, value32); } @@ -109,15 +104,15 @@ public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { } break; - case Loongarch_ElfRelocationConstants.R_LARCH_COPY: + case R_LARCH_COPY: // Runtime memory copy in executable memcpy (PC, RtAddr, sizeof (sym)) - markAsWarning(program, relocationAddress, "R_LARCH_COPY", symbolName, symbolIndex, + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, "Runtime copy not supported", elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; - case Loongarch_ElfRelocationConstants.R_LARCH_JUMP_SLOT: + case R_LARCH_JUMP_SLOT: // Runtime PLT supporting (implementation-defined) - if (is32) { + if (elf.is32Bit()) { value32 = (int) (symbolValue); memory.setInt(relocationAddress, value32); } @@ -128,47 +123,20 @@ public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { } break; - case Loongarch_ElfRelocationConstants.R_LARCH_TLS_DTPMOD32: - // TLS relocation word32 = S->TLSINDEX - markAsWarning(program, relocationAddress, "R_LARCH_TLS_DTPMOD32", symbolName, - symbolIndex, "Thread Local Symbol relocation not supported", - elfRelocationContext.getLog()); + case R_LARCH_TLS_DTPMOD32: // TLS relocation word32 = S->TLSINDEX + case R_LARCH_TLS_DTPMOD64: // TLS relocation word64 = S->TLSINDEX + case R_LARCH_TLS_DTPREL32: + case R_LARCH_TLS_DTPREL64: + case R_LARCH_TLS_TPREL32: + case R_LARCH_TLS_TPREL64: + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, + "Thread Local Symbol relocation not supported", elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; - case Loongarch_ElfRelocationConstants.R_LARCH_TLS_DTPMOD64: - // TLS relocation word64 = S->TLSINDEX - markAsWarning(program, relocationAddress, "R_LARCH_TLS_DTPMOD64", symbolName, - symbolIndex, "Thread Local Symbol relocation not supported", - elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case Loongarch_ElfRelocationConstants.R_LARCH_TLS_DTPREL32: - markAsWarning(program, relocationAddress, "R_LARCH_TLS_DTPREL32", symbolName, - symbolIndex, "Thread Local Symbol relocation not supported", - elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case Loongarch_ElfRelocationConstants.R_LARCH_TLS_DTPREL64: - markAsWarning(program, relocationAddress, "R_LARCH_TLS_DTPREL64", symbolName, - symbolIndex, "Thread Local Symbol relocation not supported", - elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case Loongarch_ElfRelocationConstants.R_LARCH_TLS_TPREL32: - markAsWarning(program, relocationAddress, "R_LARCH_TLS_DTREL32", symbolName, - symbolIndex, "Thread Local Symbol relocation not supported", - elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case Loongarch_ElfRelocationConstants.R_LARCH_TLS_TPREL64: - markAsWarning(program, relocationAddress, "R_LARCH_TLS_TPREL64", symbolName, - symbolIndex, "Thread Local Symbol relocation not supported", - elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case Loongarch_ElfRelocationConstants.R_LARCH_IRELATIVE: - if (is32) { - value32 = (int) ( addend + elfRelocationContext.getImageBaseWordAdjustmentOffset()); + case R_LARCH_IRELATIVE: + if (elf.is32Bit()) { + value32 = + (int) (addend + elfRelocationContext.getImageBaseWordAdjustmentOffset()); memory.setInt(relocationAddress, value32); } else { @@ -178,75 +146,66 @@ public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { } break; -// case Loongarch_ElfRelocationConstants.R_LARCH_MARK_LA: +// case R_LARCH_MARK_LA: +// case R_LARCH_MARK_PCREL: +// case R_LARCH_SOP_PUSH_PCREL: -// case Loongarch_ElfRelocationConstants.R_LARCH_MARK_PCREL: +// case R_LARCH_SOP_PUSH_ABSOLUTE: + // PC-relative GOT reference MACRO la -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_PUSH_PCREL: +// case R_LARCH_SOP_PUSH_DUP: + // PC-relative TLS IE GOT offset MACRO la.tls.ie -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_PUSH_ABSOLUTE: - // PC-relative GOT reference MACRO la +// case R_LARCH_SOP_PUSH_GPREL: + // PC-relative TLS GD reference MACRO la.tls.gd -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_PUSH_DUP: - // PC-relative TLS IE GOT offset MACRO la.tls.ie +// case R_LARCH_SOP_PUSH_TLS_TPREL: +// case R_LARCH_SOP_PUSH_TLS_GOT: +// case R_LARCH_SOP_PUSH_TLS_GD: +// case R_LARCH_SOP_PUSH_PLT_PCREL: +// case R_LARCH_SOP_ASSERT: -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_PUSH_GPREL: - // PC-relative TLS GD reference MACRO la.tls.gd +// case R_LARCH_SOP_NOT: + // Absolute address %lo(symbol) (S-Type) +// case R_LARCH_SOP_SUB: +// case R_LARCH_SOP_SL: +// case R_LARCH_SOP_SR: -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_PUSH_TLS_TPREL: +// case R_LARCH_SOP_ADD: + // TLS LE thread usage %tprel_add(symbol) -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_PUSH_TLS_GOT: +// case R_LARCH_SOP_AND: + // TLS LE thread usage %tprel_add(symbol) -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_PUSH_TLS_GD: +// case R_LARCH_SOP_IF_ELSE: + // TLS LE thread usage %tprel_add(symbol) -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_PUSH_PLT_PCREL: +// case R_LARCH_SOP_POP_32_S_10_5: -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_ASSERT: +// case R_LARCH_SOP_POP_32_U_10_12: -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_NOT: - // Absolute address %lo(symbol) (S-Type) +// case R_LARCH_SOP_POP_32_S_10_12: + // TLS LE thread usage %tprel_add(symbol) -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_SUB: +// case R_LARCH_SOP_POP_32_S_10_16: + // TLS LE thread usage %tprel_add(symbol) -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_SL: +// case R_LARCH_SOP_POP_32_S_10_16_S2: + // TLS LE thread usage %tprel_add(symbol) -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_SR: +// case R_LARCH_SOP_POP_32_S_5_20: -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_ADD: - // TLS LE thread usage %tprel_add(symbol) +// case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: + // TLS LE thread usage %tprel_add(symbol) -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_AND: - // TLS LE thread usage %tprel_add(symbol) +// case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: + // TLS LE thread usage %tprel_add(symbol) -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_IF_ELSE: - // TLS LE thread usage %tprel_add(symbol) +// case R_LARCH_SOP_POP_32_U: + // TLS LE thread usage %tprel_add(symbol) -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_POP_32_S_10_5: - -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_POP_32_U_10_12: - -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_POP_32_S_10_12: - // TLS LE thread usage %tprel_add(symbol) - -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_POP_32_S_10_16: - // TLS LE thread usage %tprel_add(symbol) - -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_POP_32_S_10_16_S2: - // TLS LE thread usage %tprel_add(symbol) - -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_POP_32_S_5_20: - -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_POP_32_S_0_5_10_16_S2: - // TLS LE thread usage %tprel_add(symbol) - -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_POP_32_S_0_10_10_16_S2: - // TLS LE thread usage %tprel_add(symbol) - -// case Loongarch_ElfRelocationConstants.R_LARCH_SOP_POP_32_U: - // TLS LE thread usage %tprel_add(symbol) - - case Loongarch_ElfRelocationConstants.R_LARCH_ADD8: + case R_LARCH_ADD8: // 8-bit in-place addition *(int8_t *) PC += S + A value8 = memory.getByte(relocationAddress); value8 += (byte) symbolValue; @@ -255,7 +214,7 @@ public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 1; break; - case Loongarch_ElfRelocationConstants.R_LARCH_ADD16: + case R_LARCH_ADD16: // 16-bit in-place addition *(int16_t *) PC += S + A value16 = memory.getShort(relocationAddress); value16 += (short) symbolValue; @@ -264,10 +223,10 @@ public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 2; break; - case Loongarch_ElfRelocationConstants.R_LARCH_ADD24: + case R_LARCH_ADD24: // 24-bit in-place addition (int24_t *) PC += S + A memory.getBytes(relocationAddress, bytes24); - value32 = ((bytes24[2] << 8) + bytes24[1] ) << 8 + bytes24[0]; + value32 = ((bytes24[2] << 8) + bytes24[1]) << 8 + bytes24[0]; value32 += (int) symbolValue; value32 += (int) addend; bytes24[0] = (byte) value32; @@ -276,8 +235,8 @@ public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { memory.setBytes(relocationAddress, bytes24); byteLength = 3; break; - - case Loongarch_ElfRelocationConstants.R_LARCH_ADD32: + + case R_LARCH_ADD32: // 32-bit in-place addition *(int32_t *) PC += S + A value32 = memory.getInt(relocationAddress); @@ -286,7 +245,7 @@ public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, value32); break; - case Loongarch_ElfRelocationConstants.R_LARCH_ADD64: + case R_LARCH_ADD64: // 64-bit in-place addition *(int64_t *) PC += S + A value64 = memory.getLong(relocationAddress); @@ -296,7 +255,7 @@ public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 8; break; - case Loongarch_ElfRelocationConstants.R_LARCH_SUB8: + case R_LARCH_SUB8: // 8-bit in-place subtraction *(int8_t *) PC -= S + A value8 = memory.getByte(relocationAddress); value8 -= (byte) symbolValue; @@ -305,7 +264,7 @@ public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 1; break; - case Loongarch_ElfRelocationConstants.R_LARCH_SUB16: + case R_LARCH_SUB16: // 16-bit in-place subtraction *(int16_t *) PC -= S + A value16 = memory.getShort(relocationAddress); value16 -= (short) symbolValue; @@ -314,10 +273,10 @@ public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 2; break; - case Loongarch_ElfRelocationConstants.R_LARCH_SUB24: + case R_LARCH_SUB24: // 24-bit in-place subtraction *(int324_t *) PC -= S + A memory.getBytes(relocationAddress, bytes24); - value32 = ((bytes24[2] << 8) + bytes24[1] ) << 8 + bytes24[0]; + value32 = ((bytes24[2] << 8) + bytes24[1]) << 8 + bytes24[0]; value32 -= (int) symbolValue; value32 -= (int) addend; bytes24[0] = (byte) value32; @@ -327,7 +286,7 @@ public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 3; break; - case Loongarch_ElfRelocationConstants.R_LARCH_SUB32: + case R_LARCH_SUB32: // 32-bit in-place subtraction *(int32_t *) PC -= S + A value32 = memory.getInt(relocationAddress); value32 -= (int) symbolValue; @@ -335,7 +294,7 @@ public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, value32); break; - case Loongarch_ElfRelocationConstants.R_LARCH_SUB64: + case R_LARCH_SUB64: // 64-bit in-place subtraction *(int64_t *) PC -= S + A value64 = memory.getLong(relocationAddress); value64 -= symbolValue; @@ -344,113 +303,87 @@ public class Loongarch_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 8; break; -// case Loongarch_ElfRelocationConstants.R_LARCH_GNU_VTINHERIT: - // GNU C++ vtable hierarchy +// case R_LARCH_GNU_VTINHERIT: + // GNU C++ vtable hierarchy -// case Loongarch_ElfRelocationConstants.R_LARCH_GNU_VTENTRY: - // GNU C++ vtable member usage +// case R_LARCH_GNU_VTENTRY: + // GNU C++ vtable member usage -// case Loongarch_ElfRelocationConstants.R_LARCH_B16: +// case R_LARCH_B16: +// case R_LARCH_B21: +// case R_LARCH_B26: +// case R_LARCH_ABS_HI20: +// case R_LARCH_ABS_LO12: +// case R_LARCH_ABS64_LO20: +// case R_LARCH_ABS64_HI12: +// case R_LARCH_PCALA_HI20: +// case R_LARCH_PCALA_LO12: +// case R_LARCH_PCALA64_LO20: +// case R_LARCH_PCALA64_HI12: +// case R_LARCH_GOT_PC_HI20: +// case R_LARCH_GOT_PC_LO12: +// case R_LARCH_GOT64_PC_LO20: +// case R_LARCH_GOT64_HI12: +// case R_LARCH_TLS_LE_HI20: +// case R_LARCH_TLS_LE_LO12: +// case R_LARCH_TLS_LE64_LO20: -// case Loongarch_ElfRelocationConstants.R_LARCH_B21: +// case R_LARCH_TLS_LE64_HI12: + // Instruction pair can be relaxed -// case Loongarch_ElfRelocationConstants.R_LARCH_B26: +// case R_LARCH_TLS_IE_PC_HI20: + // Local label subtraction -// case Loongarch_ElfRelocationConstants.R_LARCH_ABS_HI20: +// case R_LARCH_TLS_IE_PC_LO12: -// case Loongarch_ElfRelocationConstants.R_LARCH_ABS_LO12: +// case R_LARCH_TLS_IE64_PC_LO20: + // Local label subtraction -// case Loongarch_ElfRelocationConstants.R_LARCH_ABS64_LO20: +// case R_LARCH_TLS_IE64_PC_HI12: + // Local label subtraction -// case Loongarch_ElfRelocationConstants.R_LARCH_ABS64_HI12: +// case R_LARCH_TLS_IE_HI20: + // Local label subtraction -// case Loongarch_ElfRelocationConstants.R_LARCH_PCALA_HI20: +// case R_LARCH_TLS_IE_LO12: -// case Loongarch_ElfRelocationConstants.R_LARCH_PCALA_LO12: +// case R_LARCH_TLS_IE64_LO20: + // Instruction pair can be relaxed -// case Loongarch_ElfRelocationConstants.R_LARCH_PCALA64_LO20: +// case R_LARCH_TLS_IE64_HI12: + // Local label subtraction -// case Loongarch_ElfRelocationConstants.R_LARCH_PCALA64_HI12: +// case R_LARCH_TLS_LD_PC_HI20: -// case Loongarch_ElfRelocationConstants.R_LARCH_GOT_PC_HI20: +// case R_LARCH_TLS_LD_HI20: + // Local label subtraction -// case Loongarch_ElfRelocationConstants.R_LARCH_GOT_PC_LO12: +// case R_LARCH_TLS_GD_PC_HI20: + // Local label subtraction -// case Loongarch_ElfRelocationConstants.R_LARCH_GOT64_PC_LO20: +// case R_LARCH_TLS_GD_HI20: + // Local label subtraction -// case Loongarch_ElfRelocationConstants.R_LARCH_GOT64_HI12: +// case R_LARCH_32_PCREL: + // 32-bit PC relative -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_LE_HI20: - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_LE_LO12: - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_LE64_LO20: - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_LE64_HI12: - // Instruction pair can be relaxed - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_IE_PC_HI20: - // Local label subtraction - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_IE_PC_LO12: - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_IE64_PC_LO20: - // Local label subtraction - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_IE64_PC_HI12: - // Local label subtraction - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_IE_HI20: - // Local label subtraction - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_IE_LO12: - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_IE64_LO20: - // Instruction pair can be relaxed - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_IE64_HI12: - // Local label subtraction - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_LD_PC_HI20: - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_LD_HI20: - // Local label subtraction - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_GD_PC_HI20: - // Local label subtraction - -// case Loongarch_ElfRelocationConstants.R_LARCH_TLS_GD_HI20: - // Local label subtraction - -// case Loongarch_ElfRelocationConstants.R_LARCH_32_PCREL: - // 32-bit PC relative - -// case Loongarch_ElfRelocationConstants.R_LARCH_RELAX: - -// case Loongarch_ElfRelocationConstants.R_LARCH_DELETE: - -// case Loongarch_ElfRelocationConstants.R_LARCH_ALIGN: - -// case Loongarch_ElfRelocationConstants.R_LARCH_PCREL20_S2: - -// case Loongarch_ElfRelocationConstants.R_LARCH_CFA: - -// case Loongarch_ElfRelocationConstants.R_LARCH_ADD6: - -// case Loongarch_ElfRelocationConstants.R_LARCH_SUB6: - -// case Loongarch_ElfRelocationConstants.R_LARCH_ADD_ULEB128: - -// case Loongarch_ElfRelocationConstants.R_LARCH_SUB_ULEB128: - -// case Loongarch_ElfRelocationConstants.R_LARCH_64_PCREL: +// case R_LARCH_RELAX: +// case R_LARCH_DELETE: +// case R_LARCH_ALIGN: +// case R_LARCH_PCREL20_S2: +// case R_LARCH_CFA: +// case R_LARCH_ADD6: +// case R_LARCH_SUB6: +// case R_LARCH_ADD_ULEB128: +// case R_LARCH_SUB_ULEB128: +// case R_LARCH_64_PCREL: default: markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; } - + return new RelocationResult(Status.APPLIED, byteLength); } } diff --git a/Ghidra/Processors/Loongarch/src/main/java/ghidra/app/util/bin/format/elf/relocation/Loongarch_ElfRelocationType.java b/Ghidra/Processors/Loongarch/src/main/java/ghidra/app/util/bin/format/elf/relocation/Loongarch_ElfRelocationType.java new file mode 100644 index 0000000000..78c7371602 --- /dev/null +++ b/Ghidra/Processors/Loongarch/src/main/java/ghidra/app/util/bin/format/elf/relocation/Loongarch_ElfRelocationType.java @@ -0,0 +1,163 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum Loongarch_ElfRelocationType implements ElfRelocationType { + + R_LARCH_NONE(0), + + /* Runtime address resolving */ + R_LARCH_32(1), // *(int32_t *) PC(RtAddr + A + R_LARCH_64(2), // *(int64_t *) PC(RtAddr + A + + R_LARCH_RELATIVE(3), // Runtime fixup for load-address *(void **) PC(B + A + R_LARCH_COPY(4), // Runtime memory copy in executable memcpy (PC, RtAddr, sizeof (sym)) + R_LARCH_JUMP_SLOT(5), // Runtime PLT supporting (implementation defined) + + /* Runtime relocations for TLS-GD */ + R_LARCH_TLS_DTPMOD32(6), // *(int32_t *) PC(ID of module defining sym + R_LARCH_TLS_DTPMOD64(7), // *(int64_t *) PC(ID of module defining sym + R_LARCH_TLS_DTPREL32(8), // *(int32_t *) PC(DTV-relative offset for sym + R_LARCH_TLS_DTPREL64(9), // *(int64_t *) PC(DTV-relative offset for sym + + /* Runtime relocations for TLE-IE */ + R_LARCH_TLS_TPREL32(10), // *(int32_t *) PC(T + R_LARCH_TLS_TPREL64(11), // *(int64_t *) PC(T + + R_LARCH_IRELATIVE(12), /* Runtime local indirect function resolving + * *(void **) PC((((void *)(*)()) (B + A)) () + */ + + /* Relocations 13..19 reserved for dynamic linker */ + + R_LARCH_MARK_LA(20), // Mark la.abs Load absolute address for static link. + R_LARCH_MARK_PCREL(21), // Mark external label branch Access PC relative address for static link. + R_LARCH_SOP_PUSH_PCREL(22), // Push PC-relative offset push (S - PC + A) + R_LARCH_SOP_PUSH_ABSOLUTE(23), // Push constant or absolute address push (S + A) + R_LARCH_SOP_PUSH_DUP(24), // Duplicate stack top opr1(pop (), push (opr1), push (opr1) + R_LARCH_SOP_PUSH_GPREL(25), // Push for access GOT entry push (G) + R_LARCH_SOP_PUSH_TLS_TPREL(26), // Push for TLS-LE push (T) + R_LARCH_SOP_PUSH_TLS_GOT(27), // Push for TLS-IE push (IE) + R_LARCH_SOP_PUSH_TLS_GD(28), // Push for TLS-GD push (GD) + R_LARCH_SOP_PUSH_PLT_PCREL(29), // Push for external function calling push (PLT - PC) + R_LARCH_SOP_ASSERT(30), // Assert stack top assert (pop ()) + + /* Stack top operations */ + R_LARCH_SOP_NOT(31), + R_LARCH_SOP_SUB(32), + R_LARCH_SOP_SL(33), + R_LARCH_SOP_SR(34), + R_LARCH_SOP_ADD(35), + R_LARCH_SOP_AND(36), + R_LARCH_SOP_IF_ELSE(37), + + /* Instruction imm-field relocation */ + R_LARCH_SOP_POP_32_S_10_5(38), + R_LARCH_SOP_POP_32_U_10_12(39), + R_LARCH_SOP_POP_32_S_10_12(40), + R_LARCH_SOP_POP_32_S_10_16(41), + R_LARCH_SOP_POP_32_S_10_16_S2(42), + R_LARCH_SOP_POP_32_S_5_20(43), + R_LARCH_SOP_POP_32_S_0_5_10_16_S2(44), + R_LARCH_SOP_POP_32_S_0_10_10_16_S2(45), + + /* Instruction fixup */ + R_LARCH_SOP_POP_32_U(46), + + /* n-bit in-place additions */ + R_LARCH_ADD8(47), + R_LARCH_ADD16(48), + R_LARCH_ADD24(49), + R_LARCH_ADD32(50), + R_LARCH_ADD64(51), + + /* n-bit in-place subtractions */ + R_LARCH_SUB8(52), + R_LARCH_SUB16(53), + R_LARCH_SUB24(54), + R_LARCH_SUB32(55), + R_LARCH_SUB64(56), + + R_LARCH_GNU_VTINHERIT(57), // GNU C++ vtable hierarchy + R_LARCH_GNU_VTENTRY(58), // GNU C++ vtable member usage + + /* 59..63 reserved */ + + /* n-bit relative jumps */ + R_LARCH_B16(64), + R_LARCH_B21(65), + R_LARCH_B26(66), + + R_LARCH_ABS_HI20(67), // [31 …​ 12] bits of 32/64-bit absolute address + R_LARCH_ABS_LO12(68), // [11 …​ 0] bits of 32/64-bit absolute address + R_LARCH_ABS64_LO20(69), // [51 …​ 32] bits of 64-bit absolute address + R_LARCH_ABS64_HI12(70), // [63 …​ 52] bits of 64-bit absolute address + R_LARCH_PCALA_HI20(71), // [31 …​ 12] bits of 32/64-bit PC-relative offset + R_LARCH_PCALA_LO12(72), // [11 …​ 0] bits of 32/64-bit address + R_LARCH_PCALA64_LO20(73), // [51 …​ 32] bits of 64-bit PC-relative offset + R_LARCH_PCALA64_HI12(74), // [63 …​ 52] bits of 64-bit PC-relative offset + + R_LARCH_GOT_PC_HI20(75), // [31 …​ 12] bits of 32/64-bit PC-relative offset to GOT entry + R_LARCH_GOT_PC_LO12(76), // [11 …​ 0] bits of 32/64-bit GOT entry address + R_LARCH_GOT64_PC_LO20(77), // [51 …​ 32] bits of 64-bit PC-relative offset to GOT entry + R_LARCH_GOT64_PC_HI12(78), // [63 …​ 52] bits of 64-bit PC-relative offset to GOT entry + R_LARCH_GOT_HI20(79), // [31 …​ 12] bits of 32/64-bit GOT entry absolute address + R_LARCH_GOT_LO12(80), // [11 …​ 0] bits of 32/64-bit GOT entry absolute address + R_LARCH_GOT64_LO20(81), // [51 …​ 32] bits of 64-bit GOT entry absolute address + R_LARCH_GOT64_HI12(82), // [63 …​ 52] bits of 64-bit GOT entry absolute address + + R_LARCH_TLS_LE_HI20(83), // [31 …​ 12] bits of TLS LE 32/64-bit offset from TP register + R_LARCH_TLS_LE_LO12(84), // [11 …​ 0] bits of TLS LE 32/64-bit offset from TP register + R_LARCH_TLS_LE64_LO20(85), // [51 …​ 32] bits of TLS LE 64-bit offset from TP register + R_LARCH_TLS_LE64_HI12(86), // [63 …​ 52] bits of TLS LE 64-bit offset from TP register + R_LARCH_TLS_IE_PC_HI20(87), // [31 …​ 12] bits of 32/64-bit PC-relative offset to TLS IE GOT entry + R_LARCH_TLS_IE_PC_LO12(88), // [11 …​ 0] bits of 32/64-bit TLS IE GOT entry address + R_LARCH_TLS_IE64_PC_LO20(89), // [51 …​ 32] bits of 64-bit PC-relative offset to TLS IE GOT entry + R_LARCH_TLS_IE64_PC_HI12(90), // [63 …​ 52] bits of 64-bit PC-relative offset to TLS IE GOT entry + R_LARCH_TLS_IE_HI20(91), // [31 …​ 12] bits of 32/64-bit TLS IE GOT entry absolute address + R_LARCH_TLS_IE_LO12(92), // [11 …​ 0] bits of 32/64-bit TLS IE GOT entry absolute address + R_LARCH_TLS_IE64_LO20(93), // [51 …​ 32] bits of 64-bit TLS IE GOT entry absolute address + R_LARCH_TLS_IE64_HI12(94), // [63 …​ 52] bits of 64-bit TLS IE GOT entry absolute address + R_LARCH_TLS_LD_PC_HI20(95), // [31 …​ 12] bits of 32/64-bit PC-relative offset to TLS LD GOT entry + R_LARCH_TLS_LD_HI20(96), // [31 …​ 12] bits of 32/64-bit TLS LD GOT entry absolute address + R_LARCH_TLS_GD_PC_HI20(97), // [31 …​ 12] bits of 32/64-bit PC-relative offset to TLS GD GOT entry + R_LARCH_TLS_GD_HI20(98), // [31 …​ 12] bits of 32/64-bit TLS GD GOT entry absolute address + + R_LARCH_32_PCREL(99), // 32-bit PC relative + R_LARCH_RELAX(100), // Instruction can be relaxed, paired with a normal relocation at the same address + + // The following are from binutils and not found in the official Loongarch documentation + R_LARCH_DELETE(101), // relax delete + R_LARCH_ALIGN(102), // relax delete + R_LARCH_PCREL20_S2(103), // pcaddi + R_LARCH_CFA(104), // relax delete + R_LARCH_ADD6(105), // relax delete + R_LARCH_SUB6(106), // pcaddi + R_LARCH_ADD_ULEB128(107), // relax delete + R_LARCH_SUB_ULEB128(108), // relax delete + R_LARCH_64_PCREL(109); // pcaddi + + public final int typeId; + + private Loongarch_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } +} diff --git a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationConstants.java b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationConstants.java deleted file mode 100644 index 8187e885cb..0000000000 --- a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationConstants.java +++ /dev/null @@ -1,160 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.util.bin.format.elf.relocation; - -public class MIPS_ElfRelocationConstants { - - public static final int R_MIPS_NONE = 0; - public static final int R_MIPS_16 = 1; - public static final int R_MIPS_32 = 2; /* In Elf 64: alias R_MIPS_ADD */ - public static final int R_MIPS_REL32 = 3; /* In Elf 64: alias R_MIPS_REL */ - public static final int R_MIPS_26 = 4; - public static final int R_MIPS_HI16 = 5; - public static final int R_MIPS_LO16 = 6; - public static final int R_MIPS_GPREL16 = 7; /* In Elf 64: alias R_MIPS_GPREL */ - public static final int R_MIPS_LITERAL = 8; - public static final int R_MIPS_GOT16 = 9; /* In Elf 64: alias R_MIPS_GOT */ - public static final int R_MIPS_PC16 = 10; - public static final int R_MIPS_CALL16 = 11; /* In Elf 64: alias R_MIPS_CALL */ - public static final int R_MIPS_GPREL32 = 12; - - /* The remaining relocs are defined on Irix = although they are not - in the MIPS ELF ABI. */ - public static final int R_MIPS_UNUSED1 = 13; - public static final int R_MIPS_UNUSED2 = 14; - public static final int R_MIPS_UNUSED3 = 15; - public static final int R_MIPS_SHIFT5 = 16; - public static final int R_MIPS_SHIFT6 = 17; - public static final int R_MIPS_64 = 18; - public static final int R_MIPS_GOT_DISP = 19; - public static final int R_MIPS_GOT_PAGE = 20; - public static final int R_MIPS_GOT_OFST = 21; - public static final int R_MIPS_GOT_HI16 = 22; - public static final int R_MIPS_GOT_LO16 = 23; - public static final int R_MIPS_SUB = 24; - public static final int R_MIPS_INSERT_A = 25; - public static final int R_MIPS_INSERT_B = 26; - public static final int R_MIPS_DELETE = 27; - public static final int R_MIPS_HIGHER = 28; - public static final int R_MIPS_HIGHEST = 29; - public static final int R_MIPS_CALL_HI16 = 30; - public static final int R_MIPS_CALL_LO16 = 31; - public static final int R_MIPS_SCN_DISP = 32; - public static final int R_MIPS_REL16 = 33; - public static final int R_MIPS_ADD_IMMEDIATE = 34; - public static final int R_MIPS_PJUMP = 35; - public static final int R_MIPS_RELGOT = 36; - public static final int R_MIPS_JALR = 37; - - /* TLS relocations. */ - public static final int R_MIPS_TLS_DTPMOD32 = 38; - public static final int R_MIPS_TLS_DTPREL32 = 39; - public static final int R_MIPS_TLS_DTPMOD64 = 40; - public static final int R_MIPS_TLS_DTPREL64 = 41; - public static final int R_MIPS_TLS_GD = 42; - public static final int R_MIPS_TLS_LDM = 43; - public static final int R_MIPS_TLS_DTPREL_HI16 = 44; - public static final int R_MIPS_TLS_DTPREL_LO16 = 45; - public static final int R_MIPS_TLS_GOTTPREL = 46; - public static final int R_MIPS_TLS_TPREL32 = 47; - public static final int R_MIPS_TLS_TPREL64 = 48; - public static final int R_MIPS_TLS_TPREL_HI16 = 49; - public static final int R_MIPS_TLS_TPREL_LO16 = 50; - public static final int R_MIPS_GLOB_DAT = 51; - - /* MIPSr6 relocations */ - public static final int R_MIPS_PC21_S2 = 60; - public static final int R_MIPS_PC26_S2 = 61; - public static final int R_MIPS_PC18_S3 = 62; - public static final int R_MIPS_PC19_S2 = 63; - public static final int R_MIPS_PCHI16 = 64; - public static final int R_MIPS_PCLO16 = 65; - - /* These relocs are used for the mips16. */ - public static final int R_MIPS16_26 = 100; - public static final int R_MIPS16_GPREL = 101; - public static final int R_MIPS16_GOT16 = 102; - public static final int R_MIPS16_CALL16 = 103; - public static final int R_MIPS16_HI16 = 104; - public static final int R_MIPS16_LO16 = 105; - public static final int R_MIPS16_TLS_GD = 106; - public static final int R_MIPS16_TLS_LDM = 107; - public static final int R_MIPS16_TLS_DTPREL_HI16 = 108; - public static final int R_MIPS16_TLS_DTPREL_LO16 = 109; - public static final int R_MIPS16_TLS_GOTTPREL = 110; - public static final int R_MIPS16_TLS_TPREL_HI16 = 111; - public static final int R_MIPS16_TLS_TPREL_LO16 = 112; - - public static final int R_MIPS16_LO = 100; // First MIPS16 reloc type - public static final int R_MIPS16_HI = 112; // Last MIPS16 reloc type - - /* These relocations are specific to VxWorks. */ - public static final int R_MIPS_COPY = 126; - public static final int R_MIPS_JUMP_SLOT = 127; - - /* These relocations are specific to the MicroMIPS */ - public static final int R_MICROMIPS_26_S1 = 133; - public static final int R_MICROMIPS_HI16 = 134; - public static final int R_MICROMIPS_LO16 = 135; - public static final int R_MICROMIPS_GPREL16 = 136; - public static final int R_MICROMIPS_LITERAL = 137; - public static final int R_MICROMIPS_GOT16 = 138; - public static final int R_MICROMIPS_PC7_S1 = 139; // no shuffle required - public static final int R_MICROMIPS_PC10_S1 = 140; // no shuffle required - public static final int R_MICROMIPS_PC16_S1 = 141; - public static final int R_MICROMIPS_CALL16 = 142; - - public static final int R_MICROMIPS_GOT_DISP = 145; - public static final int R_MICROMIPS_GOT_PAGE = 146; - public static final int R_MICROMIPS_GOT_OFST = 147; - public static final int R_MICROMIPS_GOT_HI16 = 148; - public static final int R_MICROMIPS_GOT_LO16 = 149; - public static final int R_MICROMIPS_SUB = 150; - public static final int R_MICROMIPS_HIGHER = 151; - public static final int R_MICROMIPS_HIGHEST = 152; - public static final int R_MICROMIPS_CALL_HI16 = 153; - public static final int R_MICROMIPS_CALL_LO16 = 154; - public static final int R_MICROMIPS_SCN_DISP = 155; - public static final int R_MICROMIPS_JALR = 156; - public static final int R_MICROMIPS_HI0_LO16 = 157; - - /* TLS MicroMIPS related relocations */ - public static final int R_MICROMIPS_TLS_GD = 162; - public static final int R_MICROMIPS_TLS_LDM = 163; - public static final int R_MICROMIPS_TLS_DTPREL_HI16 = 164; - public static final int R_MICROMIPS_TLS_DTPREL_LO16 = 165; - public static final int R_MICROMIPS_TLS_GOTTPREL = 166; - - public static final int R_MICROMIPS_TLS_TPREL_HI16 = 169; - - public static final int R_MICROMIPS_TLS_TPREL_LO16 = 170; - - public static final int R_MICROMIPS_GPREL7_S2 = 172; - public static final int R_MICROMIPS_PC23_S2 = 173; - - public static final int R_MICROMIPS_LO = 133; // First MicroMIPS reloc type - public static final int R_MICROMIPS_HI = 173; // Last MicroMIPS reloc type - - public static final int R_MIPS_PC32 = 248; - - // Masks for manipulating MIPS relocation targets - public static final int MIPS_LOW26 = 0x03FFFFFF; - public static final int MIPS_LOW21 = 0x001FFFFF; - - private MIPS_ElfRelocationConstants() { - // no construct - } -} diff --git a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationContext.java b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationContext.java index c71d3a3eac..ac88f85aa0 100644 --- a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationContext.java +++ b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationContext.java @@ -23,19 +23,23 @@ import ghidra.app.util.bin.format.elf.extend.MIPS_ElfExtension; import ghidra.app.util.bin.format.elf.relocation.MIPS_ElfRelocationHandler.MIPS_DeferredRelocation; import ghidra.program.model.address.*; import ghidra.program.model.data.PointerDataType; +import ghidra.program.model.listing.BookmarkType; import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.mem.MemoryBlock; +import ghidra.program.model.reloc.RelocationResult; +import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.symbol.Symbol; import ghidra.program.model.symbol.SymbolUtilities; import ghidra.util.*; import ghidra.util.exception.AssertException; +import ghidra.util.exception.NotFoundException; /** * {@link MIPS_ElfRelocationContext} provides extended relocation context with the ability * to retain deferred relocation lists. In addition, the ability to generate a section GOT * table is provided to facilitate relocations encountered within object modules. */ -class MIPS_ElfRelocationContext extends ElfRelocationContext { +class MIPS_ElfRelocationContext extends ElfRelocationContext { private LinkedList hi16list = new LinkedList<>(); private LinkedList got16list = new LinkedList<>(); @@ -47,6 +51,7 @@ class MIPS_ElfRelocationContext extends ElfRelocationContext { private Map gotMap; + boolean saveValueForNextReloc; boolean useSavedAddend = false; boolean savedAddendHasError = false; long savedAddend; @@ -59,6 +64,81 @@ class MIPS_ElfRelocationContext extends ElfRelocationContext { super(handler, loadHelper, symbolMap); } + @Override + protected RelocationResult processRelocation(ElfRelocation relocation, ElfSymbol elfSymbol, + Address relocationAddress) throws MemoryAccessException { + + lastSymbolAddr = null; + lastElfSymbol = null; + + int typeId = relocation.getType(); + int symbolIndex = relocation.getSymbolIndex(); + + saveValueForNextReloc = nextRelocationHasSameOffset(relocation); + + RelocationResult lastResult = RelocationResult.FAILURE; + if (getElfHeader().is64Bit()) { + + MIPS_Elf64Relocation mips64Relocation = (MIPS_Elf64Relocation) relocation; + + // Each relocation can pack upto 3 relocations for 64-bit + for (int n = 0; n < 3; n++) { + + if (n == 1) { + symbolIndex = mips64Relocation.getSpecialSymbolIndex(); + } + else { + symbolIndex = 0; + } + + int relocType = typeId & 0xff; + typeId >>= 8; + int nextRelocType = (n < 2) ? (typeId & 0xff) : 0; + if (nextRelocType == MIPS_ElfRelocationType.R_MIPS_NONE.typeId) { + saveValueForNextReloc = false; + } + + RelocationResult result = + doRelocate(mips64Relocation, relocationAddress, relocType, symbolIndex); + + if (result.status() == Status.FAILURE || result.status() == Status.UNSUPPORTED) { + return result; + } + lastResult = result; + + if (nextRelocType == MIPS_ElfRelocationType.R_MIPS_NONE.typeId) { + break; + } + } + return lastResult; + } + + return doRelocate(relocation, relocationAddress, typeId, symbolIndex); + } + + private RelocationResult doRelocate(ElfRelocation relocation, Address relocationAddress, + int relocType, int symbolIndex) throws MemoryAccessException { + + if (relocType == 0) { + return RelocationResult.SKIPPED; + } + + ElfSymbol elfSymbol = getSymbol(symbolIndex); + Address symbolAddr = getSymbolAddress(elfSymbol); + long symbolValue = getSymbolValue(elfSymbol); + String symbolName = elfSymbol != null ? elfSymbol.getNameAsString() : null; + + MIPS_ElfRelocationType relocationType = handler.getRelocationType(relocType); + if (relocationType == null) { + handler.markAsUndefined(program, relocationAddress, relocType, symbolName, symbolIndex, + getLog()); + return RelocationResult.UNSUPPORTED; + } + + return handler.relocate(this, relocation, relocationType, relocationAddress, + getSymbol(symbolIndex), symbolAddr, symbolValue, symbolName); + } + @Override public void endRelocationTableProcessing() { @@ -185,7 +265,7 @@ class MIPS_ElfRelocationContext extends ElfRelocationContext { return false; } return relocations[relocIndex].getOffset() == relocations[relocIndex + 1].getOffset() && - relocations[relocIndex + 1].getType() != MIPS_ElfRelocationConstants.R_MIPS_NONE; + relocations[relocIndex + 1].getType() != MIPS_ElfRelocationType.R_MIPS_NONE.typeId; } /** @@ -226,8 +306,8 @@ class MIPS_ElfRelocationContext extends ElfRelocationContext { int size = (int) lastSectionGotEntryAddress.subtract(sectionGotAddress) + 1; String blockName = getSectionGotName(); try { - MemoryBlock block = MemoryBlockUtils.createInitializedBlock(program, false, - blockName, sectionGotAddress, size, + MemoryBlock block = MemoryBlockUtils.createInitializedBlock(program, false, blockName, + sectionGotAddress, size, "NOTE: This block is artificial and allows ELF Relocations to work correctly", "Elf Loader", true, false, false, loadHelper.getLog()); DataConverter converter = @@ -260,7 +340,7 @@ class MIPS_ElfRelocationContext extends ElfRelocationContext { // TODO: this is a simplified use of GP and could be incorrect when multiple GPs exist Symbol symbol = SymbolUtilities.getLabelOrFunctionSymbol(program, - MIPS_ElfExtension.MIPS_GP_VALUE_SYMBOL, err -> getLog().error("MIPS_ELF", err)); + MIPS_ElfExtension.MIPS_GP_VALUE_SYMBOL, err -> getLog().appendMsg("MIPS_ELF", err)); if (symbol == null) { return -1; } @@ -269,12 +349,11 @@ class MIPS_ElfRelocationContext extends ElfRelocationContext { /** * Get the GP0 value (from .reginfo and generated symbol) - * @param mipsRelocationContext * @return adjusted GP0 value or -1 if _mips_gp0_value symbol not defined. */ long getGP0Value() { Symbol symbol = SymbolUtilities.getLabelOrFunctionSymbol(program, - MIPS_ElfExtension.MIPS_GP0_VALUE_SYMBOL, err -> getLog().error("MIPS_ELF", err)); + MIPS_ElfExtension.MIPS_GP0_VALUE_SYMBOL, err -> getLog().appendMsg("MIPS_ELF", err)); if (symbol == null) { return -1; } @@ -316,8 +395,8 @@ class MIPS_ElfRelocationContext extends ElfRelocationContext { } /** - * Add HI16 relocation for deferred processing - * @param hi16reloc HI16 relocation + * Add GOT16 relocation for deferred processing + * @param got16reloc GOT16 relocation */ void addGOT16Relocation(MIPS_DeferredRelocation got16reloc) { got16list.add(got16reloc); diff --git a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationHandler.java b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationHandler.java index 2a5e3008ef..a019967156 100644 --- a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationHandler.java +++ b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationHandler.java @@ -22,18 +22,29 @@ import ghidra.app.util.bin.format.elf.*; import ghidra.app.util.bin.format.elf.extend.MIPS_ElfExtension; import ghidra.app.util.importer.MessageLog; import ghidra.program.model.address.Address; -import ghidra.program.model.address.AddressOutOfBoundsException; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.*; import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.reloc.RelocationResult; import ghidra.util.exception.AssertException; -public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { +public class MIPS_ElfRelocationHandler + extends AbstractElfRelocationHandler { // private static final int TP_OFFSET = 0x7000; // private static final int DTP_OFFSET = 0x8000; + // Masks for manipulating MIPS relocation targets + private static final int MIPS_LOW26 = 0x03FFFFFF; + private static final int MIPS_LOW21 = 0x001FFFFF; + + /** + * Constructor + */ + public MIPS_ElfRelocationHandler() { + super(MIPS_ElfRelocationType.class); + } + @Override public boolean canRelocate(ElfHeader elf) { return elf.e_machine() == ElfConstants.EM_MIPS; @@ -46,122 +57,40 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, Address relocationAddress) + protected RelocationResult relocate(MIPS_ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, MIPS_ElfRelocationType type, Address relocationAddress, + ElfSymbol elfSymbol, Address symbolAddr, long symbolValue, String symbolName) throws MemoryAccessException { - ElfHeader elf = elfRelocationContext.getElfHeader(); + // Determine if result value should be saved as addend for next relocation + final boolean saveValue = elfRelocationContext.saveValueForNextReloc; - if (elf.e_machine() != ElfConstants.EM_MIPS) { - return RelocationResult.FAILURE; - } - - MIPS_ElfRelocationContext mipsRelocationContext = - (MIPS_ElfRelocationContext) elfRelocationContext; - mipsRelocationContext.lastSymbolAddr = null; - mipsRelocationContext.lastElfSymbol = null; - - int type = relocation.getType(); - int symbolIndex = relocation.getSymbolIndex(); - - boolean saveValueForNextReloc = - mipsRelocationContext.nextRelocationHasSameOffset(relocation); - - RelocationResult lastResult = RelocationResult.FAILURE; - if (elf.is64Bit()) { - - MIPS_Elf64Relocation mips64Relocation = (MIPS_Elf64Relocation) relocation; - - // Each relocation can pack upto 3 relocations for 64-bit - for (int n = 0; n < 3; n++) { - - if (n == 0) { - symbolIndex = mips64Relocation.getSymbolIndex(); - } - else if (n == 1) { - symbolIndex = mips64Relocation.getSpecialSymbolIndex(); - } - else { - symbolIndex = 0; - } - - int relocType = type & 0xff; - type >>= 8; - int nextRelocType = - (n < 2) ? (type & 0xff) : MIPS_ElfRelocationConstants.R_MIPS_NONE; - - RelocationResult result = doRelocate(mipsRelocationContext, relocType, symbolIndex, - mips64Relocation, relocationAddress, - nextRelocType != MIPS_ElfRelocationConstants.R_MIPS_NONE || - saveValueForNextReloc); - if (result.status() == Status.FAILURE || result.status() == Status.UNSUPPORTED) { - return result; - } - lastResult = result; - - symbolIndex = 0; // set to STN_UNDEF(0) once symbol used by first relocation - - if (nextRelocType == MIPS_ElfRelocationConstants.R_MIPS_NONE) { - break; - } - } - return lastResult; - } - - return doRelocate(mipsRelocationContext, type, symbolIndex, relocation, relocationAddress, - saveValueForNextReloc); - } - - /** - * Perform MIPS ELF relocation - * @param mipsRelocationContext MIPS ELF relocation context - * @param relocType relocation type (unpacked from relocation r_info) - * @param relocation relocation record to be processed (may be compound for 64-bit) - * @param relocationAddress address at which relocation is applied (i.e., relocation offset) - * @param saveValue true if result value should be stored in mipsRelocationContext.savedAddend - * and mipsRelocationContext.useSavedAddend set true. If false, result value should be written - * to relocationAddress per relocation type. - * @return applied relocation result - * @throws MemoryAccessException memory access error occured - */ - private RelocationResult doRelocate(MIPS_ElfRelocationContext mipsRelocationContext, - int relocType, int symbolIndex, ElfRelocation relocation, Address relocationAddress, - boolean saveValue) throws MemoryAccessException, AddressOutOfBoundsException { - - if (relocType == MIPS_ElfRelocationConstants.R_MIPS_NONE) { - return RelocationResult.SKIPPED; - } - - Program program = mipsRelocationContext.getProgram(); + Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); - MessageLog log = mipsRelocationContext.getLog(); + MessageLog log = elfRelocationContext.getLog(); - ElfHeader elf = mipsRelocationContext.getElfHeader(); + ElfHeader elf = elfRelocationContext.getElfHeader(); long offset = (int) relocationAddress.getOffset(); // Although elfSymbol may be null we assume it will not be when it is required by a reloc - ElfSymbol elfSymbol = mipsRelocationContext.getSymbol(symbolIndex); - - Address symbolAddr = mipsRelocationContext.getSymbolAddress(elfSymbol); - long symbolValue = mipsRelocationContext.getSymbolValue(elfSymbol); - String symbolName = mipsRelocationContext.getSymbolName(symbolIndex); + int symbolIndex = elfSymbol != null ? elfSymbol.getSymbolTableIndex() : 0; if (symbolIndex != 0) { - mipsRelocationContext.lastSymbolAddr = symbolAddr; - mipsRelocationContext.lastElfSymbol = elfSymbol; + elfRelocationContext.lastSymbolAddr = symbolAddr; + elfRelocationContext.lastElfSymbol = elfSymbol; } long addend = 0; - if (mipsRelocationContext.useSavedAddend) { - if (mipsRelocationContext.savedAddendHasError) { - markAsError(program, relocationAddress, Integer.toString(relocType), symbolName, + if (elfRelocationContext.useSavedAddend) { + if (elfRelocationContext.savedAddendHasError) { + markAsError(program, relocationAddress, type, symbolName, symbolIndex, "Stacked relocation failure", log); - mipsRelocationContext.useSavedAddend = saveValue; - mipsRelocationContext.savedAddend = 0; + elfRelocationContext.useSavedAddend = saveValue; + elfRelocationContext.savedAddend = 0; return RelocationResult.FAILURE; } - addend = mipsRelocationContext.savedAddend; + addend = elfRelocationContext.savedAddend; } else if (relocation.hasAddend()) { addend = relocation.getAddend(); @@ -169,18 +98,18 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { // Treat global GOT_PAGE relocations as GOT_DISP if (!elfSymbol.isLocal()) { - if (relocType == MIPS_ElfRelocationConstants.R_MIPS_GOT_PAGE) { - relocType = MIPS_ElfRelocationConstants.R_MIPS_GOT_DISP; + if (type == MIPS_ElfRelocationType.R_MIPS_GOT_PAGE) { + type = MIPS_ElfRelocationType.R_MIPS_GOT_DISP; addend = 0; // addend handled by GOT_OFST } - else if (relocType == MIPS_ElfRelocationConstants.R_MICROMIPS_GOT_PAGE) { - relocType = MIPS_ElfRelocationConstants.R_MICROMIPS_GOT_DISP; + else if (type == MIPS_ElfRelocationType.R_MICROMIPS_GOT_PAGE) { + type = MIPS_ElfRelocationType.R_MICROMIPS_GOT_DISP; addend = 0; // addend handled by GOT_OFST } } - mipsRelocationContext.savedAddendHasError = false; - mipsRelocationContext.savedAddend = 0; + elfRelocationContext.savedAddendHasError = false; + elfRelocationContext.savedAddend = 0; boolean isGpDisp = false; if (MIPS_ElfExtension.MIPS_GP_DISP_SYMBOL_NAME.equals(symbolName)) { @@ -188,17 +117,17 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { } else if (MIPS_ElfExtension.MIPS_GP_GNU_LOCAL_SYMBOL_NAME.equals(symbolName)) { // TODO: GP based relocation not yet supported - need to evaluate an example - markAsError(program, relocationAddress, Integer.toString(relocType), symbolName, + markAsError(program, relocationAddress, type, symbolName, symbolIndex, MIPS_ElfExtension.MIPS_GP_GNU_LOCAL_SYMBOL_NAME + " relocation not yet supported", log); if (saveValue) { - mipsRelocationContext.savedAddendHasError = true; + elfRelocationContext.savedAddendHasError = true; } return RelocationResult.FAILURE; } long oldValue = Integer.toUnsignedLong( - unshuffle(memory.getInt(relocationAddress), relocType, mipsRelocationContext)); + unshuffle(memory.getInt(relocationAddress), type, elfRelocationContext)); // Intermediate results are retained as long values so they may be used with 64-bit // compound relocation processing @@ -210,11 +139,11 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { Status status = Status.PARTIAL; int byteLength = 4; // most relocations affect 4-bytes (change if different) - switch (relocType) { + switch (type) { - case MIPS_ElfRelocationConstants.R_MIPS_GOT_OFST: - case MIPS_ElfRelocationConstants.R_MICROMIPS_GOT_OFST: - if (mipsRelocationContext.extractAddend()) { + case R_MIPS_GOT_OFST: + case R_MICROMIPS_GOT_OFST: + if (elfRelocationContext.extractAddend()) { addend = oldValue & 0xffff; } @@ -225,35 +154,31 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MIPS_GOT_PAGE: - case MIPS_ElfRelocationConstants.R_MICROMIPS_GOT_PAGE: + case R_MIPS_GOT_PAGE: + case R_MICROMIPS_GOT_PAGE: - if (mipsRelocationContext.extractAddend()) { + if (elfRelocationContext.extractAddend()) { addend = oldValue & 0xffff; } pageOffset = ((symbolValue + addend + 0x8000) & ~0xffff); // Get section GOT entry for local symbol - Address gotAddr = mipsRelocationContext.getSectionGotAddress(pageOffset); + Address gotAddr = elfRelocationContext.getSectionGotAddress(pageOffset); if (gotAddr == null) { // failed to allocate section GOT entry for symbol - markAsError(mipsRelocationContext.getProgram(), relocationAddress, - Integer.toString(relocType), symbolName, - "Relocation Failed, unable to allocate GOT entry for relocation symbol: " + - symbolName, - mipsRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Unable to allocate GOT entry", log); return RelocationResult.FAILURE; } - value = getGpOffset(mipsRelocationContext, gotAddr.getOffset()); + value = getGpOffset(elfRelocationContext, gotAddr.getOffset()); if (value == -1) { // Unhandled GOT/GP case - markAsError(mipsRelocationContext.getProgram(), relocationAddress, - Integer.toString(relocType), symbolName, - "Failed to perform GP-based relocation", mipsRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to perform GP-based relocation", log); if (saveValue) { - mipsRelocationContext.savedAddendHasError = true; + elfRelocationContext.savedAddendHasError = true; } return RelocationResult.FAILURE; } @@ -262,38 +187,34 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MIPS_GOT_DISP: - case MIPS_ElfRelocationConstants.R_MICROMIPS_GOT_DISP: - case MIPS_ElfRelocationConstants.R_MIPS_GOT_HI16: - case MIPS_ElfRelocationConstants.R_MICROMIPS_GOT_HI16: + case R_MIPS_GOT_DISP: + case R_MICROMIPS_GOT_DISP: + case R_MIPS_GOT_HI16: + case R_MICROMIPS_GOT_HI16: // Get section GOT entry for local symbol - gotAddr = mipsRelocationContext.getSectionGotAddress(symbolValue); + gotAddr = elfRelocationContext.getSectionGotAddress(symbolValue); if (gotAddr == null) { // failed to allocate section GOT entry for symbol - markAsError(mipsRelocationContext.getProgram(), relocationAddress, - Integer.toString(relocType), symbolName, - "Relocation Failed, unable to allocate GOT entry for relocation symbol: " + - symbolName, - mipsRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Unable to allocate GOT entry", log); return RelocationResult.FAILURE; } // use address offset within section GOT as symbol value - value = getGpOffset(mipsRelocationContext, gotAddr.getOffset()); + value = getGpOffset(elfRelocationContext, gotAddr.getOffset()); if (value == -1) { // Unhandled GOT/GP case - markAsError(mipsRelocationContext.getProgram(), relocationAddress, - Integer.toString(relocType), symbolName, - "Failed to perform GP-based relocation", mipsRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to perform GP-based relocation", log); if (saveValue) { - mipsRelocationContext.savedAddendHasError = true; + elfRelocationContext.savedAddendHasError = true; } return RelocationResult.FAILURE; } long appliedValue; - if (relocType == MIPS_ElfRelocationConstants.R_MIPS_GOT_DISP) { + if (type == MIPS_ElfRelocationType.R_MIPS_GOT_DISP) { appliedValue = value & 0xffff; } else { @@ -304,44 +225,40 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MIPS_GOT16: - case MIPS_ElfRelocationConstants.R_MIPS16_GOT16: - case MIPS_ElfRelocationConstants.R_MICROMIPS_GOT16: + case R_MIPS_GOT16: + case R_MIPS16_GOT16: + case R_MICROMIPS_GOT16: if (elfSymbol.isLocal()) { // Defer processing of local GOT16 relocations until suitable LO16 relocation is processed - MIPS_DeferredRelocation got16reloc = new MIPS_DeferredRelocation(relocType, + MIPS_DeferredRelocation got16reloc = new MIPS_DeferredRelocation(type, elfSymbol, relocationAddress, oldValue, addend, isGpDisp); - mipsRelocationContext.addGOT16Relocation(got16reloc); + elfRelocationContext.addGOT16Relocation(got16reloc); break; // report as 4-byte applied even though it is deferred (could still fail) } // fall-through - case MIPS_ElfRelocationConstants.R_MIPS_CALL16: - case MIPS_ElfRelocationConstants.R_MIPS16_CALL16: - case MIPS_ElfRelocationConstants.R_MICROMIPS_CALL16: + case R_MIPS_CALL16: + case R_MIPS16_CALL16: + case R_MICROMIPS_CALL16: // Get section GOT entry for local symbol - gotAddr = mipsRelocationContext.getSectionGotAddress(symbolValue + addend); + gotAddr = elfRelocationContext.getSectionGotAddress(symbolValue + addend); if (gotAddr == null) { // failed to allocate section GOT entry for symbol - markAsError(mipsRelocationContext.getProgram(), relocationAddress, - Integer.toString(relocType), symbolName, - "Relocation Failed, unable to allocate GOT entry for relocation symbol: " + - symbolName, - mipsRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Unable to allocate GOT entry", log); return RelocationResult.FAILURE; } - value = getGpOffset(mipsRelocationContext, gotAddr.getOffset()); + value = getGpOffset(elfRelocationContext, gotAddr.getOffset()); if (value == -1) { // Unhandled GOT/GP case - markAsError(mipsRelocationContext.getProgram(), relocationAddress, - Integer.toString(relocType), symbolName, - "Failed to perform GP-based relocation", mipsRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to perform GP-based relocation", log); if (saveValue) { - mipsRelocationContext.savedAddendHasError = true; + elfRelocationContext.savedAddendHasError = true; } return RelocationResult.FAILURE; } @@ -350,29 +267,25 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MIPS_CALL_HI16: - case MIPS_ElfRelocationConstants.R_MICROMIPS_CALL_HI16: + case R_MIPS_CALL_HI16: + case R_MICROMIPS_CALL_HI16: // Get section GOT entry for local symbol - gotAddr = mipsRelocationContext.getSectionGotAddress(symbolValue + addend); + gotAddr = elfRelocationContext.getSectionGotAddress(symbolValue + addend); if (gotAddr == null) { // failed to allocate section GOT entry for symbol - markAsError(mipsRelocationContext.getProgram(), relocationAddress, - Integer.toString(relocType), symbolName, - "Relocation Failed, unable to allocate GOT entry for relocation symbol: " + - symbolName, - mipsRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Unable to allocate GOT entry", log); return RelocationResult.FAILURE; } - value = getGpOffset(mipsRelocationContext, gotAddr.getOffset()); + value = getGpOffset(elfRelocationContext, gotAddr.getOffset()); if (value == -1) { // Unhandled GOT/GP case - markAsError(mipsRelocationContext.getProgram(), relocationAddress, - Integer.toString(relocType), symbolName, - "Failed to perform GP-based relocation", mipsRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to perform GP-based relocation", log); if (saveValue) { - mipsRelocationContext.savedAddendHasError = true; + elfRelocationContext.savedAddendHasError = true; } return RelocationResult.FAILURE; } @@ -381,48 +294,46 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MIPS_HI16: - case MIPS_ElfRelocationConstants.R_MIPS16_HI16: - case MIPS_ElfRelocationConstants.R_MICROMIPS_HI16: + case R_MIPS_HI16: + case R_MIPS16_HI16: + case R_MICROMIPS_HI16: // Verify the we have GP - if (mipsRelocationContext.getGPValue() == -1) { - markAsError(mipsRelocationContext.getProgram(), relocationAddress, - Integer.toString(relocType), elfSymbol.getNameAsString(), - "Failed to perform GP-based relocation", mipsRelocationContext.getLog()); + if (elfRelocationContext.getGPValue() == -1) { + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to perform GP-based relocation", log); return RelocationResult.FAILURE; } // Defer processing of HI16 relocations until suitable LO16 relocation is processed - MIPS_DeferredRelocation hi16reloc = new MIPS_DeferredRelocation(relocType, - elfSymbol, relocationAddress, oldValue, (int) addend, isGpDisp); - mipsRelocationContext.addHI16Relocation(hi16reloc); + MIPS_DeferredRelocation hi16reloc = new MIPS_DeferredRelocation(type, elfSymbol, + relocationAddress, oldValue, (int) addend, isGpDisp); + elfRelocationContext.addHI16Relocation(hi16reloc); break; // report as 4-byte applied even though it is deferred - case MIPS_ElfRelocationConstants.R_MIPS_LO16: - case MIPS_ElfRelocationConstants.R_MIPS16_LO16: - case MIPS_ElfRelocationConstants.R_MICROMIPS_LO16: - case MIPS_ElfRelocationConstants.R_MICROMIPS_HI0_LO16: + case R_MIPS_LO16: + case R_MIPS16_LO16: + case R_MICROMIPS_LO16: + case R_MICROMIPS_HI0_LO16: - if (mipsRelocationContext.extractAddend()) { + if (elfRelocationContext.extractAddend()) { addend = (short) (oldValue & 0xffff); // 16-bit sign extended } - processHI16Relocations(mipsRelocationContext, relocType, elfSymbol, (int) addend); + processHI16Relocations(elfRelocationContext, type, elfSymbol, (int) addend); - processGOT16Relocations(mipsRelocationContext, relocType, elfSymbol, (int) addend); + processGOT16Relocations(elfRelocationContext, type, elfSymbol, (int) addend); if (isGpDisp) { - value = mipsRelocationContext.getGPValue(); + value = elfRelocationContext.getGPValue(); if (value == -1) { - markAsError(program, relocationAddress, Integer.toString(relocType), - symbolName, "Failed to perform GP-based relocation", - mipsRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to perform GP-based relocation", log); if (saveValue) { - mipsRelocationContext.savedAddendHasError = true; + elfRelocationContext.savedAddendHasError = true; } return RelocationResult.FAILURE; } - if (relocType == MIPS_ElfRelocationConstants.R_MIPS16_LO16) { + if (type == MIPS_ElfRelocationType.R_MIPS16_LO16) { value -= (offset & ~0x3); } else { @@ -438,12 +349,12 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MIPS_REL32: + case R_MIPS_REL32: if (symbolIndex == 0) { - symbolValue = mipsRelocationContext.getImageBaseWordAdjustmentOffset(); + symbolValue = elfRelocationContext.getImageBaseWordAdjustmentOffset(); } value = symbolValue; - if (mipsRelocationContext.extractAddend()) { + if (elfRelocationContext.extractAddend()) { // extract addend based upon pointer size addend = elf.is64Bit() ? (int) memory.getLong(relocationAddress) : memory.getInt(relocationAddress); @@ -452,7 +363,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { newValue = value + addend; if (saveValue) { - mipsRelocationContext.savedAddend = newValue; + elfRelocationContext.savedAddend = newValue; } else { memory.setInt(relocationAddress, (int) newValue); @@ -461,23 +372,23 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { // Handle possible offset-pointer use if (symbolIndex != 0 && addend != 0 && !elfSymbol.isSection()) { // create offset-pointer and resulting offset-reference - warnExternalOffsetRelocation(program, relocationAddress, - symbolAddr, symbolName, addend, mipsRelocationContext.getLog()); + warnExternalOffsetRelocation(program, relocationAddress, symbolAddr, + symbolName, addend, log); applyComponentOffsetPointer(program, relocationAddress, addend); } } break; - case MIPS_ElfRelocationConstants.R_MIPS_32: /* In Elf 64: alias R_MIPS_ADD */ + case R_MIPS_32: /* In Elf 64: alias R_MIPS_ADD */ value = symbolValue; - if (mipsRelocationContext.extractAddend()) { + if (elfRelocationContext.extractAddend()) { addend = memory.getInt(relocationAddress); } newValue = value + addend; if (saveValue) { - mipsRelocationContext.savedAddend = newValue; + elfRelocationContext.savedAddend = newValue; } else { memory.setInt(relocationAddress, (int) newValue); @@ -485,51 +396,48 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { } break; - case MIPS_ElfRelocationConstants.R_MIPS_26: - case MIPS_ElfRelocationConstants.R_MIPS16_26: - case MIPS_ElfRelocationConstants.R_MICROMIPS_26_S1: - int shift = (relocType == MIPS_ElfRelocationConstants.R_MICROMIPS_26_S1) ? 1 : 2; - if (mipsRelocationContext.extractAddend()) { - addend = (oldValue & MIPS_ElfRelocationConstants.MIPS_LOW26) << shift; + case R_MIPS_26: + case R_MIPS16_26: + case R_MICROMIPS_26_S1: + int shift = (type == MIPS_ElfRelocationType.R_MICROMIPS_26_S1) ? 1 : 2; + if (elfRelocationContext.extractAddend()) { + addend = (oldValue & MIPS_LOW26) << shift; } if (!elfSymbol.isLocal() && !elfSymbol.isSection()) { addend = signExtend((int) addend, 26 + shift); } // TODO: cross-mode jump detection/handling is unsupported value = (addend + symbolValue) >> shift; - newValue = (oldValue & ~MIPS_ElfRelocationConstants.MIPS_LOW26) | - (value & MIPS_ElfRelocationConstants.MIPS_LOW26); + newValue = (oldValue & ~MIPS_LOW26) | (value & MIPS_LOW26); writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MIPS_PC21_S2: - if (mipsRelocationContext.extractAddend()) { - addend = (oldValue & MIPS_ElfRelocationConstants.MIPS_LOW21) << 2; + case R_MIPS_PC21_S2: + if (elfRelocationContext.extractAddend()) { + addend = (oldValue & MIPS_LOW21) << 2; } if (!elfSymbol.isLocal() && !elfSymbol.isSection()) { addend = signExtend((int) addend, 21 + 2); } value = (addend + symbolValue - offset) >> 2; - newValue = (oldValue & ~MIPS_ElfRelocationConstants.MIPS_LOW21) | - (value & MIPS_ElfRelocationConstants.MIPS_LOW21); + newValue = (oldValue & ~MIPS_LOW21) | (value & MIPS_LOW21); writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MIPS_PC26_S2: - if (mipsRelocationContext.extractAddend()) { - addend = (oldValue & MIPS_ElfRelocationConstants.MIPS_LOW26) << 2; + case R_MIPS_PC26_S2: + if (elfRelocationContext.extractAddend()) { + addend = (oldValue & MIPS_LOW26) << 2; } if (!elfSymbol.isLocal() && !elfSymbol.isSection()) { addend = signExtend((int) addend, 26 + 2); } value = (addend + symbolValue - offset) >> 2; - newValue = (oldValue & ~MIPS_ElfRelocationConstants.MIPS_LOW26) | - (value & MIPS_ElfRelocationConstants.MIPS_LOW26); + newValue = (oldValue & ~MIPS_LOW26) | (value & MIPS_LOW26); writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MIPS_PC16: - if (mipsRelocationContext.extractAddend()) { + case R_MIPS_PC16: + if (elfRelocationContext.extractAddend()) { addend = (oldValue & 0xffff) << 2; } value = symbolValue - offset + signExtend((int) addend, 18); @@ -537,13 +445,13 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MIPS_64: - if (mipsRelocationContext.extractAddend()) { + case R_MIPS_64: + if (elfRelocationContext.extractAddend()) { addend = memory.getLong(relocationAddress); } newValue = symbolValue + addend; if (saveValue) { - mipsRelocationContext.savedAddend = newValue; + elfRelocationContext.savedAddend = newValue; } else { memory.setLong(relocationAddress, newValue); @@ -553,11 +461,11 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { // Handle possible offset-pointer use boolean isSectionBased = elfSymbol.isSection(); Address addr = symbolAddr; - if (symbolIndex == 0 && mipsRelocationContext.lastSymbolAddr != null) { + if (symbolIndex == 0 && elfRelocationContext.lastSymbolAddr != null) { // handle compound mips64 relocation - addr = mipsRelocationContext.lastSymbolAddr; - symbolName = mipsRelocationContext.lastElfSymbol.getNameAsString(); - isSectionBased = mipsRelocationContext.lastElfSymbol.isSection(); + addr = elfRelocationContext.lastSymbolAddr; + symbolName = elfRelocationContext.lastElfSymbol.getNameAsString(); + isSectionBased = elfRelocationContext.lastElfSymbol.isSection(); } if (addr != null && !isSectionBased) { if (symbolIndex == 0) { @@ -566,8 +474,8 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { } if (addend != 0) { // create offset-pointer and resulting offset-reference - warnExternalOffsetRelocation(program, relocationAddress, - addr, symbolName, addend, mipsRelocationContext.getLog()); + warnExternalOffsetRelocation(program, relocationAddress, addr, + symbolName, addend, log); if (elf.is64Bit()) { applyComponentOffsetPointer(program, relocationAddress, addend); } @@ -576,9 +484,9 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { } break; - case MIPS_ElfRelocationConstants.R_MIPS_HIGHER: - case MIPS_ElfRelocationConstants.R_MICROMIPS_HIGHER: - if (mipsRelocationContext.extractAddend()) { + case R_MIPS_HIGHER: + case R_MICROMIPS_HIGHER: + if (elfRelocationContext.extractAddend()) { addend = oldValue; } addend &= 0xffff; @@ -588,9 +496,9 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MIPS_HIGHEST: - case MIPS_ElfRelocationConstants.R_MICROMIPS_HIGHEST: - if (mipsRelocationContext.extractAddend()) { + case R_MIPS_HIGHEST: + case R_MICROMIPS_HIGHEST: + if (elfRelocationContext.extractAddend()) { addend = oldValue; } addend &= 0xffff; @@ -600,8 +508,8 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MICROMIPS_PC7_S1: - if (mipsRelocationContext.extractAddend()) { + case R_MICROMIPS_PC7_S1: + if (elfRelocationContext.extractAddend()) { addend = (oldValue & 0x7f0000) >> 15; } value = (((symbolValue + addend) - offset) >> 1) & 0x7f; @@ -609,8 +517,8 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MICROMIPS_PC10_S1: - if (mipsRelocationContext.extractAddend()) { + case R_MICROMIPS_PC10_S1: + if (elfRelocationContext.extractAddend()) { addend = (oldValue & 0x3ff0000) >> 15; } value = (((symbolValue + addend) - offset) >> 1) & 0x3ff; @@ -618,8 +526,8 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MICROMIPS_PC16_S1: - if (mipsRelocationContext.extractAddend()) { + case R_MICROMIPS_PC16_S1: + if (elfRelocationContext.extractAddend()) { addend = (oldValue & 0xffff) << 1; } value = (((symbolValue + addend) - offset) >> 1) & 0xffff; @@ -627,20 +535,20 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MIPS_GPREL16: - case MIPS_ElfRelocationConstants.R_MIPS_GPREL32: - case MIPS_ElfRelocationConstants.R_MIPS16_GPREL: - case MIPS_ElfRelocationConstants.R_MICROMIPS_GPREL16: - case MIPS_ElfRelocationConstants.R_MICROMIPS_GPREL7_S2: - case MIPS_ElfRelocationConstants.R_MIPS_LITERAL: - case MIPS_ElfRelocationConstants.R_MICROMIPS_LITERAL: - if (mipsRelocationContext.extractAddend()) { - if (relocType == MIPS_ElfRelocationConstants.R_MIPS_GPREL32) { + case R_MIPS_GPREL16: + case R_MIPS_GPREL32: + case R_MIPS16_GPREL: + case R_MICROMIPS_GPREL16: + case R_MICROMIPS_GPREL7_S2: + case R_MIPS_LITERAL: + case R_MICROMIPS_LITERAL: + if (elfRelocationContext.extractAddend()) { + if (type == MIPS_ElfRelocationType.R_MIPS_GPREL32) { addend = oldValue; } else { addend = oldValue & 0xffff; - if (relocType == MIPS_ElfRelocationConstants.R_MICROMIPS_GPREL7_S2) { + if (type == MIPS_ElfRelocationType.R_MICROMIPS_GPREL7_S2) { addend <<= 2; } addend = signExtend((int) addend, 16); @@ -648,53 +556,48 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { } long gp0 = 0; - if (elfSymbol.isLocal() && - (relocType == MIPS_ElfRelocationConstants.R_MIPS_GPREL16 || - relocType == MIPS_ElfRelocationConstants.R_MIPS_GPREL32)) { - gp0 = mipsRelocationContext.getGP0Value(); + if (elfSymbol.isLocal() && (type == MIPS_ElfRelocationType.R_MIPS_GPREL16 || + type == MIPS_ElfRelocationType.R_MIPS_GPREL32)) { + gp0 = elfRelocationContext.getGP0Value(); if (gp0 == -1) { - markAsError(mipsRelocationContext.getProgram(), relocationAddress, - Integer.toString(relocType), symbolName, - "Failed to perform local GP0-based relocation (requires .reginfo data)", - mipsRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to perform GP0-based relocation (requires .reginfo data)", log); if (saveValue) { - mipsRelocationContext.savedAddendHasError = true; + elfRelocationContext.savedAddendHasError = true; } return RelocationResult.FAILURE; } if (gp0 == 0) { - gp0 = mipsRelocationContext.getImageBaseWordAdjustmentOffset(); + gp0 = elfRelocationContext.getImageBaseWordAdjustmentOffset(); } } - long gp = mipsRelocationContext.getGPValue(); + long gp = elfRelocationContext.getGPValue(); if (gp == -1) { - markAsError(mipsRelocationContext.getProgram(), relocationAddress, - Integer.toString(relocType), symbolName, - "Failed to perform GP-based relocation", mipsRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to perform GP-based relocation", log); if (saveValue) { - mipsRelocationContext.savedAddendHasError = true; + elfRelocationContext.savedAddendHasError = true; } return RelocationResult.FAILURE; } value = (symbolValue + addend - gp + gp0); - long mask = - relocType == MIPS_ElfRelocationConstants.R_MIPS_GPREL32 ? 0xffffffffL : 0xffff; + long mask = type == MIPS_ElfRelocationType.R_MIPS_GPREL32 ? 0xffffffffL : 0xffff; newValue = (oldValue & ~mask) | (value & mask); writeNewValue = true; break; - case MIPS_ElfRelocationConstants.R_MIPS_SUB: - case MIPS_ElfRelocationConstants.R_MICROMIPS_SUB: - if (mipsRelocationContext.extractAddend()) { + case R_MIPS_SUB: + case R_MICROMIPS_SUB: + if (elfRelocationContext.extractAddend()) { addend = oldValue; } newValue = symbolValue - addend; if (saveValue) { - mipsRelocationContext.savedAddend = newValue; + elfRelocationContext.savedAddend = newValue; } else { memory.setLong(relocationAddress, newValue); @@ -703,20 +606,20 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { } break; - case MIPS_ElfRelocationConstants.R_MIPS_COPY: + case R_MIPS_COPY: // TODO: Requires symbol lookup into dynamic library - not sure what we can do here - markAsWarning(program, relocationAddress, "R_MIPS_COPY", symbolName, symbolIndex, + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, "Runtime copy not supported", log); if (saveValue) { - mipsRelocationContext.savedAddendHasError = true; + elfRelocationContext.savedAddendHasError = true; } return RelocationResult.UNSUPPORTED; - case MIPS_ElfRelocationConstants.R_MIPS_JUMP_SLOT: + case R_MIPS_JUMP_SLOT: if (saveValue) { - mipsRelocationContext.savedAddend = symbolValue; + elfRelocationContext.savedAddend = symbolValue; } - else if (mipsRelocationContext.getElfHeader().is64Bit()) { + else if (elfRelocationContext.getElfHeader().is64Bit()) { memory.setLong(relocationAddress, symbolValue); byteLength = 8; } @@ -726,23 +629,23 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { status = Status.APPLIED; break; - case MIPS_ElfRelocationConstants.R_MIPS_JALR: - case MIPS_ElfRelocationConstants.R_MICROMIPS_JALR: + case R_MIPS_JALR: + case R_MICROMIPS_JALR: boolean success = false; - Address symAddr = mipsRelocationContext.getSymbolAddress(elfSymbol); + Address symAddr = elfRelocationContext.getSymbolAddress(elfSymbol); if (symAddr != null) { MemoryBlock block = memory.getBlock(symAddr); if (block != null) { if (MemoryBlock.EXTERNAL_BLOCK_NAME.equals(block.getName())) { - success = mipsRelocationContext.getLoadHelper() + success = elfRelocationContext.getLoadHelper() .createExternalFunctionLinkage(symbolName, symAddr, null) != null; if (success) { // Inject appropriate JAL instruction - if (relocType == MIPS_ElfRelocationConstants.R_MICROMIPS_JALR) { + if (type == MIPS_ElfRelocationType.R_MICROMIPS_JALR) { int offsetBits = (int) (symAddr.getOffset() >> 1) & 0x3ffffff; // TODO: upper bits should really come from delay slot int microJalrBits = 0xf4000000 | offsetBits; @@ -767,19 +670,16 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { } } if (!success) { - markAsError(program, relocationAddress, - relocType == MIPS_ElfRelocationConstants.R_MIPS_JALR ? "R_MIPS_JALR" - : "R_MICROMIPS_JALR", - symbolName, "Failed to establish external linkage", log); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to establish external linkage", log); return RelocationResult.FAILURE; } break; default: - markAsUnhandled(program, relocationAddress, relocType, symbolIndex, - symbolName, log); + markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, log); if (saveValue) { - mipsRelocationContext.savedAddendHasError = true; + elfRelocationContext.savedAddendHasError = true; } return RelocationResult.UNSUPPORTED; } @@ -787,44 +687,48 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { if (writeNewValue) { if (saveValue) { // Save "value" as addend for next relocation - mipsRelocationContext.savedAddend = value; + elfRelocationContext.savedAddend = value; } else { // Write 32-bit memory location at relocationAddress using "newValue". // Each relocation which sets writeNewValue must establish a 32-bit newValue // to be written to relocationAddress. memory.setInt(relocationAddress, - shuffle((int) newValue, relocType, mipsRelocationContext)); + shuffle((int) newValue, type, elfRelocationContext)); status = Status.APPLIED; } } - mipsRelocationContext.useSavedAddend = saveValue; + elfRelocationContext.useSavedAddend = saveValue; return new RelocationResult(status, byteLength); } - private boolean isMIPS16Reloc(int type) { - return type >= MIPS_ElfRelocationConstants.R_MIPS16_LO && - type <= MIPS_ElfRelocationConstants.R_MIPS16_HI; + private boolean isMIPS16Reloc(MIPS_ElfRelocationType type) { + int typeId = type.typeId; + return typeId >= MIPS_ElfRelocationType.R_MIPS16_LO.typeId && + typeId <= MIPS_ElfRelocationType.R_MIPS16_HI.typeId; } - private boolean isMicroMIPSReloc(int type) { - return type >= MIPS_ElfRelocationConstants.R_MICROMIPS_LO && - type <= MIPS_ElfRelocationConstants.R_MICROMIPS_HI; + private boolean isMicroMIPSReloc(MIPS_ElfRelocationType type) { + int typeId = type.typeId; + return typeId >= MIPS_ElfRelocationType.R_MICROMIPS_LO.typeId && + typeId <= MIPS_ElfRelocationType.R_MICROMIPS_HI.typeId; } - private boolean shuffleRequired(int type) { + private boolean shuffleRequired(MIPS_ElfRelocationType type) { return isMIPS16Reloc(type) || - (isMicroMIPSReloc(type) && type != MIPS_ElfRelocationConstants.R_MICROMIPS_PC7_S1 && - type != MIPS_ElfRelocationConstants.R_MICROMIPS_PC10_S1); + (isMicroMIPSReloc(type) && type != MIPS_ElfRelocationType.R_MICROMIPS_PC7_S1 && + type != MIPS_ElfRelocationType.R_MICROMIPS_PC10_S1); } - private boolean isMIPS16_26_JAL_Reloc(int type, ElfRelocationContext elfRelocationContext) { - return (type == MIPS_ElfRelocationConstants.R_MIPS16_26 && + private boolean isMIPS16_26_JAL_Reloc(MIPS_ElfRelocationType type, + MIPS_ElfRelocationContext elfRelocationContext) { + return (type == MIPS_ElfRelocationType.R_MIPS16_26 && elfRelocationContext.getElfHeader().isRelocatable()); } - private int unshuffle(int value, int type, ElfRelocationContext elfRelocationContext) { + private int unshuffle(int value, MIPS_ElfRelocationType type, + MIPS_ElfRelocationContext elfRelocationContext) { if (!shuffleRequired(type)) { return value; } @@ -844,7 +748,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { value = (((first & 0xf800) << 16) | ((second & 0xffe0) << 11) | ((first & 0x1f) << 11) | (first & 0x7e0) | (second & 0x1f)); } - else if (isMicroMIPSReloc(type) || type == MIPS_ElfRelocationConstants.R_MIPS16_26) { + else if (isMicroMIPSReloc(type) || type == MIPS_ElfRelocationType.R_MIPS16_26) { value = first << 16 | second; } else { @@ -854,7 +758,8 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { return value; } - private int shuffle(int value, int type, ElfRelocationContext elfRelocationContext) { + private int shuffle(int value, MIPS_ElfRelocationType type, + MIPS_ElfRelocationContext elfRelocationContext) { if (!shuffleRequired(type)) { return value; } @@ -865,7 +770,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { first = (short) (((value >> 16) & 0xf800) | ((value >> 11) & 0x1f) | (value & 0x7e0)); second = (short) (((value >> 11) & 0xffe0) | (value & 0x1f)); } - else if (isMicroMIPSReloc(type) || type == MIPS_ElfRelocationConstants.R_MIPS16_26) { + else if (isMicroMIPSReloc(type) || type == MIPS_ElfRelocationType.R_MIPS16_26) { first = (short) (value >> 16); second = (short) value; } @@ -885,19 +790,21 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { return value; } - private boolean matchingHiLo16Types(int hi16Type, int lo16Type) { + private boolean matchingHiLo16Types(MIPS_ElfRelocationType hi16Type, + MIPS_ElfRelocationType lo16Type) { switch (hi16Type) { - case MIPS_ElfRelocationConstants.R_MIPS_HI16: - case MIPS_ElfRelocationConstants.R_MIPS_GOT16: - return lo16Type == MIPS_ElfRelocationConstants.R_MIPS_LO16; - case MIPS_ElfRelocationConstants.R_MIPS16_HI16: - case MIPS_ElfRelocationConstants.R_MIPS16_GOT16: - return lo16Type == MIPS_ElfRelocationConstants.R_MIPS16_LO16; - case MIPS_ElfRelocationConstants.R_MICROMIPS_HI16: - case MIPS_ElfRelocationConstants.R_MICROMIPS_GOT16: - return lo16Type == MIPS_ElfRelocationConstants.R_MICROMIPS_LO16; + case R_MIPS_HI16: + case R_MIPS_GOT16: + return lo16Type == MIPS_ElfRelocationType.R_MIPS_LO16; + case R_MIPS16_HI16: + case R_MIPS16_GOT16: + return lo16Type == MIPS_ElfRelocationType.R_MIPS16_LO16; + case R_MICROMIPS_HI16: + case R_MICROMIPS_GOT16: + return lo16Type == MIPS_ElfRelocationType.R_MICROMIPS_LO16; + default: + return false; } - return false; } private int signExtend(int val, int bits) { @@ -907,20 +814,20 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { /** * Processes all pending HI16 relocations which match with the specified LO16 relocation - * @param mipsRelocationContext + * @param elfRelocationContext * @param lo16RelocType * @param lo16ElfSymbol * @param lo16Addend */ - private void processHI16Relocations(MIPS_ElfRelocationContext mipsRelocationContext, - int lo16RelocType, ElfSymbol lo16ElfSymbol, int lo16Addend) { + private void processHI16Relocations(MIPS_ElfRelocationContext elfRelocationContext, + MIPS_ElfRelocationType lo16RelocType, ElfSymbol lo16ElfSymbol, int lo16Addend) { - Iterator iterateHi16 = mipsRelocationContext.iterateHi16(); + Iterator iterateHi16 = elfRelocationContext.iterateHi16(); while (iterateHi16.hasNext()) { MIPS_DeferredRelocation hi16reloc = iterateHi16.next(); if (matchingHiLo16Types(hi16reloc.relocType, lo16RelocType) && hi16reloc.elfSymbol == lo16ElfSymbol) { - processHI16Relocation(mipsRelocationContext, hi16reloc, lo16Addend); + processHI16Relocation(elfRelocationContext, hi16reloc, lo16Addend); iterateHi16.remove(); // remove queued HI16 relocation if processed } } @@ -929,25 +836,26 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { /** * Complete HI16 relocation (R_MIPS_HI16, R_MIPS16_HI16, R_MICROMIPS_HI16) using * specified LO16 relocation data - * @param mipsRelocationContext + * @param elfRelocationContext * @param hi16reloc * @param lo16Addend * @return true if successful or false if unsupported */ - private void processHI16Relocation(MIPS_ElfRelocationContext mipsRelocationContext, + private void processHI16Relocation(MIPS_ElfRelocationContext elfRelocationContext, MIPS_DeferredRelocation hi16reloc, long lo16Addend) { long newValue; if (hi16reloc.isGpDisp) { - newValue = (int) mipsRelocationContext.getGPValue(); + newValue = (int) elfRelocationContext.getGPValue(); if (newValue == -1) { - markAsError(mipsRelocationContext.getProgram(), hi16reloc.relocAddr, - Integer.toString(hi16reloc.relocType), hi16reloc.elfSymbol.getNameAsString(), - "Failed to perform GP-based relocation", mipsRelocationContext.getLog()); + markAsError(elfRelocationContext.getProgram(), hi16reloc.relocAddr, + hi16reloc.relocType, hi16reloc.elfSymbol.getNameAsString(), + hi16reloc.elfSymbol.getSymbolTableIndex(), + "Failed to perform GP-based relocation", elfRelocationContext.getLog()); return; } - if (hi16reloc.relocType == MIPS_ElfRelocationConstants.R_MIPS16_HI16) { + if (hi16reloc.relocType == MIPS_ElfRelocationType.R_MIPS16_HI16) { newValue -= (hi16reloc.relocAddr.getOffset() + 4) & ~0x3; } else { @@ -955,11 +863,11 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { } } else { - newValue = (int) mipsRelocationContext.getSymbolValue(hi16reloc.elfSymbol); + newValue = (int) elfRelocationContext.getSymbolValue(hi16reloc.elfSymbol); } // FIXME: should always use hi16reloc.addend - figure out at time of deferral long addend; - if (mipsRelocationContext.extractAddend()) { + if (elfRelocationContext.extractAddend()) { addend = ((hi16reloc.oldValueL & 0xffff) << 16) + lo16Addend; } else { @@ -968,10 +876,10 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { newValue = (newValue + addend + 0x8000) >> 16; newValue = (hi16reloc.oldValueL & ~0xffff) | (newValue & 0xffff); - Memory memory = mipsRelocationContext.getProgram().getMemory(); + Memory memory = elfRelocationContext.getProgram().getMemory(); try { memory.setInt(hi16reloc.relocAddr, - shuffle((int) newValue, hi16reloc.relocType, mipsRelocationContext)); + shuffle((int) newValue, hi16reloc.relocType, elfRelocationContext)); } catch (MemoryAccessException e) { // Unexpected since we did a previous getInt without failure @@ -981,20 +889,20 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { /** * Processes all pending GOT16 relocations which match with the specified LO16 relocation - * @param mipsRelocationContext + * @param elfRelocationContext * @param lo16RelocType * @param lo16SymIndex * @param lo16Addend */ - private void processGOT16Relocations(MIPS_ElfRelocationContext mipsRelocationContext, - int lo16RelocType, ElfSymbol lo16ElfSymbol, int lo16Addend) { + private void processGOT16Relocations(MIPS_ElfRelocationContext elfRelocationContext, + MIPS_ElfRelocationType lo16RelocType, ElfSymbol lo16ElfSymbol, int lo16Addend) { - Iterator iterateGot16 = mipsRelocationContext.iterateGot16(); + Iterator iterateGot16 = elfRelocationContext.iterateGot16(); while (iterateGot16.hasNext()) { MIPS_DeferredRelocation hi16reloc = iterateGot16.next(); if (matchingHiLo16Types(hi16reloc.relocType, lo16RelocType) && hi16reloc.elfSymbol == lo16ElfSymbol) { - processGOT16Relocation(mipsRelocationContext, hi16reloc, lo16Addend); + processGOT16Relocation(elfRelocationContext, hi16reloc, lo16Addend); iterateGot16.remove(); // remove queued GOT16 relocation if processed } } @@ -1003,54 +911,53 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { /** * Complete Local GOT16 relocation (R_MIPS_GOT16, R_MIPS16_GOT16, R_MICROMIPS_GOT16) using * specified LO16 relocation data. Section GOT entry will be utilized. - * @param mipsRelocationContext + * @param elfRelocationContext * @param got16reloc * @param lo16Addend * @return true if successful or false if unsupported */ - private void processGOT16Relocation(MIPS_ElfRelocationContext mipsRelocationContext, + private void processGOT16Relocation(MIPS_ElfRelocationContext elfRelocationContext, MIPS_DeferredRelocation got16reloc, long lo16Addend) { long addend; - if (mipsRelocationContext.extractAddend()) { + if (elfRelocationContext.extractAddend()) { addend = ((got16reloc.oldValueL & 0xffff) << 16) + lo16Addend; } else { addend = got16reloc.addendL; } - long symbolValue = (int) mipsRelocationContext.getSymbolValue(got16reloc.elfSymbol); + long symbolValue = (int) elfRelocationContext.getSymbolValue(got16reloc.elfSymbol); String symbolName = got16reloc.elfSymbol.getNameAsString(); long value = (symbolValue + addend + 0x8000) & ~0xffff; // generate page offset // Get section GOT entry for local symbol - Address gotAddr = mipsRelocationContext.getSectionGotAddress(value); + Address gotAddr = elfRelocationContext.getSectionGotAddress(value); if (gotAddr == null) { // failed to allocate section GOT entry for symbol - markAsError(mipsRelocationContext.getProgram(), got16reloc.relocAddr, - Integer.toString(got16reloc.relocType), symbolName, - "Relocation Failed, unable to allocate GOT entry for relocation symbol", - mipsRelocationContext.getLog()); + markAsError(elfRelocationContext.getProgram(), got16reloc.relocAddr, + got16reloc.relocType, symbolName, got16reloc.elfSymbol.getSymbolTableIndex(), + "Unable to allocate GOT entry", elfRelocationContext.getLog()); return; } // use address offset within section GOT as value - value = getGpOffset(mipsRelocationContext, gotAddr.getOffset()); + value = getGpOffset(elfRelocationContext, gotAddr.getOffset()); if (value == -1) { // Unhandled GOT/GP case - markAsError(mipsRelocationContext.getProgram(), got16reloc.relocAddr, - Integer.toString(got16reloc.relocType), symbolName, - "Failed to perform GP-based relocation", mipsRelocationContext.getLog()); + markAsError(elfRelocationContext.getProgram(), got16reloc.relocAddr, + got16reloc.relocType, symbolName, got16reloc.elfSymbol.getSymbolTableIndex(), + "Failed to perform GP-based relocation", elfRelocationContext.getLog()); return; } long newValue = (got16reloc.oldValueL & ~0xffff) | ((int) value & 0xffff); - Memory memory = mipsRelocationContext.getProgram().getMemory(); + Memory memory = elfRelocationContext.getProgram().getMemory(); try { memory.setInt(got16reloc.relocAddr, - shuffle((int) newValue, got16reloc.relocType, mipsRelocationContext)); + shuffle((int) newValue, got16reloc.relocType, elfRelocationContext)); } catch (MemoryAccessException e) { // Unexpected since we did a previous getInt without failure @@ -1058,9 +965,9 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { } } - private long getGpOffset(MIPS_ElfRelocationContext mipsRelocationContext, long value) { + private long getGpOffset(MIPS_ElfRelocationContext elfRelocationContext, long value) { // TODO: this is a simplified use of GP and could be incorrect when multiple GPs exist - long gp = mipsRelocationContext.getGPValue(); + long gp = elfRelocationContext.getGPValue(); if (gp == -1) { return -1; } @@ -1072,17 +979,17 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { * MIPS_DeferredRelocation is used to capture a relocation whose processing * must be deferred. */ - static class MIPS_DeferredRelocation { + class MIPS_DeferredRelocation { - final int relocType; + final MIPS_ElfRelocationType relocType; final ElfSymbol elfSymbol; final Address relocAddr; final long oldValueL; final long addendL; final boolean isGpDisp; - MIPS_DeferredRelocation(int relocType, ElfSymbol elfSymbol, Address relocAddr, - long oldValue, long addend, boolean isGpDisp) { + MIPS_DeferredRelocation(MIPS_ElfRelocationType relocType, ElfSymbol elfSymbol, + Address relocAddr, long oldValue, long addend, boolean isGpDisp) { this.relocType = relocType; this.elfSymbol = elfSymbol; this.relocAddr = relocAddr; @@ -1091,11 +998,12 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler { this.isGpDisp = isGpDisp; } - void markUnprocessed(MIPS_ElfRelocationContext mipsRelocationContext, + void markUnprocessed(MIPS_ElfRelocationContext elfRelocationContext, String missingDependencyName) { - markAsError(mipsRelocationContext.getProgram(), relocAddr, Integer.toString(relocType), - elfSymbol.getNameAsString(), "Relocation missing required " + missingDependencyName, - mipsRelocationContext.getLog()); + markAsError(elfRelocationContext.getProgram(), relocAddr, relocType, + elfSymbol.getNameAsString(), elfSymbol.getSymbolTableIndex(), + "Relocation missing required " + missingDependencyName, + elfRelocationContext.getLog()); } } } diff --git a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationType.java b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationType.java new file mode 100644 index 0000000000..3ab727b0a5 --- /dev/null +++ b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationType.java @@ -0,0 +1,162 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum MIPS_ElfRelocationType implements ElfRelocationType { + + R_MIPS_NONE(0), + R_MIPS_16(1), + R_MIPS_32(2), // In Elf 64: alias R_MIPS_ADD + R_MIPS_REL32(3), // In Elf 64: alias R_MIPS_REL + R_MIPS_26(4), + R_MIPS_HI16(5), + R_MIPS_LO16(6), + R_MIPS_GPREL16(7), // In Elf 64: alias R_MIPS_GPREL + R_MIPS_LITERAL(8), + R_MIPS_GOT16(9), // In Elf 64: alias R_MIPS_GOT + R_MIPS_PC16(10), + R_MIPS_CALL16(11), // In Elf 64: alias R_MIPS_CALL + R_MIPS_GPREL32(12), + + /* The remaining relocs are defined on Irix(although they are not in the MIPS ELF ABI. */ + R_MIPS_UNUSED1(13), + R_MIPS_UNUSED2(14), + R_MIPS_UNUSED3(15), + R_MIPS_SHIFT5(16), + R_MIPS_SHIFT6(17), + R_MIPS_64(18), + R_MIPS_GOT_DISP(19), + R_MIPS_GOT_PAGE(20), + R_MIPS_GOT_OFST(21), + R_MIPS_GOT_HI16(22), + R_MIPS_GOT_LO16(23), + R_MIPS_SUB(24), + R_MIPS_INSERT_A(25), + R_MIPS_INSERT_B(26), + R_MIPS_DELETE(27), + R_MIPS_HIGHER(28), + R_MIPS_HIGHEST(29), + R_MIPS_CALL_HI16(30), + R_MIPS_CALL_LO16(31), + R_MIPS_SCN_DISP(32), + R_MIPS_REL16(33), + R_MIPS_ADD_IMMEDIATE(34), + R_MIPS_PJUMP(35), + R_MIPS_RELGOT(36), + R_MIPS_JALR(37), + + /* TLS relocations. */ + R_MIPS_TLS_DTPMOD32(38), + R_MIPS_TLS_DTPREL32(39), + R_MIPS_TLS_DTPMOD64(40), + R_MIPS_TLS_DTPREL64(41), + R_MIPS_TLS_GD(42), + R_MIPS_TLS_LDM(43), + R_MIPS_TLS_DTPREL_HI16(44), + R_MIPS_TLS_DTPREL_LO16(45), + R_MIPS_TLS_GOTTPREL(46), + R_MIPS_TLS_TPREL32(47), + R_MIPS_TLS_TPREL64(48), + R_MIPS_TLS_TPREL_HI16(49), + R_MIPS_TLS_TPREL_LO16(50), + R_MIPS_GLOB_DAT(51), + + /* MIPSr6 relocations */ + R_MIPS_PC21_S2(60), + R_MIPS_PC26_S2(61), + R_MIPS_PC18_S3(62), + R_MIPS_PC19_S2(63), + R_MIPS_PCHI16(64), + R_MIPS_PCLO16(65), + + /* These relocs are used for the mips16. */ + R_MIPS16_26(100), + R_MIPS16_GPREL(101), + R_MIPS16_GOT16(102), + R_MIPS16_CALL16(103), + R_MIPS16_HI16(104), + R_MIPS16_LO16(105), + R_MIPS16_TLS_GD(106), + R_MIPS16_TLS_LDM(107), + R_MIPS16_TLS_DTPREL_HI16(108), + R_MIPS16_TLS_DTPREL_LO16(109), + R_MIPS16_TLS_GOTTPREL(110), + R_MIPS16_TLS_TPREL_HI16(111), + R_MIPS16_TLS_TPREL_LO16(112), + + R_MIPS16_LO(100), // First MIPS16 reloc type + R_MIPS16_HI(112), // Last MIPS16 reloc type + + /* These relocations are specific to VxWorks. */ + R_MIPS_COPY(126), + R_MIPS_JUMP_SLOT(127), + + /* These relocations are specific to the MicroMIPS */ + R_MICROMIPS_26_S1(133), + R_MICROMIPS_HI16(134), + R_MICROMIPS_LO16(135), + R_MICROMIPS_GPREL16(136), + R_MICROMIPS_LITERAL(137), + R_MICROMIPS_GOT16(138), + R_MICROMIPS_PC7_S1(139), // no shuffle required + R_MICROMIPS_PC10_S1(140), // no shuffle required + R_MICROMIPS_PC16_S1(141), + R_MICROMIPS_CALL16(142), + + R_MICROMIPS_GOT_DISP(145), + R_MICROMIPS_GOT_PAGE(146), + R_MICROMIPS_GOT_OFST(147), + R_MICROMIPS_GOT_HI16(148), + R_MICROMIPS_GOT_LO16(149), + R_MICROMIPS_SUB(150), + R_MICROMIPS_HIGHER(151), + R_MICROMIPS_HIGHEST(152), + R_MICROMIPS_CALL_HI16(153), + R_MICROMIPS_CALL_LO16(154), + R_MICROMIPS_SCN_DISP(155), + R_MICROMIPS_JALR(156), + R_MICROMIPS_HI0_LO16(157), + + /* TLS MicroMIPS related relocations */ + R_MICROMIPS_TLS_GD(162), + R_MICROMIPS_TLS_LDM(163), + R_MICROMIPS_TLS_DTPREL_HI16(164), + R_MICROMIPS_TLS_DTPREL_LO16(165), + R_MICROMIPS_TLS_GOTTPREL(166), + + R_MICROMIPS_TLS_TPREL_HI16(169), + + R_MICROMIPS_TLS_TPREL_LO16(170), + + R_MICROMIPS_GPREL7_S2(172), + R_MICROMIPS_PC23_S2(173), + + R_MICROMIPS_LO(133), // First MicroMIPS reloc type + R_MICROMIPS_HI(173), // Last MicroMIPS reloc type + + R_MIPS_PC32(248); + + public final int typeId; + + private MIPS_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } +} diff --git a/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationContext.java b/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationContext.java index e6dacb9f3a..d87f5a926b 100644 --- a/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationContext.java +++ b/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationContext.java @@ -22,13 +22,13 @@ import ghidra.app.util.bin.format.elf.ElfSymbol; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSpace; -class PIC30_ElfRelocationContext extends ElfRelocationContext { - - protected PIC30_ElfRelocationContext(ElfRelocationHandler handler, ElfLoadHelper loadHelper, - Map symbolMap) { +class PIC30_ElfRelocationContext extends ElfRelocationContext { + + protected PIC30_ElfRelocationContext(PIC30_ElfRelocationHandler handler, + ElfLoadHelper loadHelper, Map symbolMap) { super(handler, loadHelper, symbolMap); } - + private boolean isDebugSection(AddressSpace overlaySpace) { String name = overlaySpace.getName(); return name.startsWith(".debug_") || ".comment".equals(name); diff --git a/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationHandler.java b/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationHandler.java index 212facf1cf..abf3320fbf 100644 --- a/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationHandler.java +++ b/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationHandler.java @@ -23,81 +23,18 @@ import ghidra.program.model.lang.Register; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryAccessException; -import ghidra.program.model.reloc.RelocationResult; import ghidra.program.model.reloc.Relocation.Status; -import ghidra.util.exception.NotFoundException; +import ghidra.program.model.reloc.RelocationResult; -public class PIC30_ElfRelocationHandler extends ElfRelocationHandler { +public class PIC30_ElfRelocationHandler + extends AbstractElfRelocationHandler { - /* PIC30 Relocation Types */ - - // Numbers found in ./include/elf/pic30.h: - public static final int R_PIC30_NONE = 0; - public static final int R_PIC30_8 = 1; - public static final int R_PIC30_16 = 2; - public static final int R_PIC30_32 = 3; - public static final int R_PIC30_FILE_REG_BYTE = 4; - public static final int R_PIC30_FILE_REG = 5; - public static final int R_PIC30_FILE_REG_WORD = 6; - public static final int R_PIC30_FILE_REG_WORD_WITH_DST = 7; - public static final int R_PIC30_WORD = 8; - public static final int R_PIC30_PBYTE = 9; - public static final int R_PIC30_PWORD = 10; - public static final int R_PIC30_HANDLE = 11; - public static final int R_PIC30_PADDR = 12; - public static final int R_PIC30_P_PADDR = 13; - public static final int R_PIC30_PSVOFFSET = 14; - public static final int R_PIC30_TBLOFFSET = 15; - public static final int R_PIC30_WORD_HANDLE = 16; - public static final int R_PIC30_WORD_PSVOFFSET = 17; - public static final int R_PIC30_PSVPAGE = 18; - public static final int R_PIC30_P_PSVPAGE = 19; - public static final int R_PIC30_WORD_PSVPAGE = 20; - public static final int R_PIC30_WORD_TBLOFFSET = 21; - public static final int R_PIC30_TBLPAGE = 22; - public static final int R_PIC30_P_TBLPAGE = 23; - public static final int R_PIC30_WORD_TBLPAGE = 24; - public static final int R_PIC30_P_HANDLE = 25; - public static final int R_PIC30_P_PSVOFFSET = 26; - public static final int R_PIC30_P_TBLOFFSET = 27; - public static final int R_PIC30_PCREL_BRANCH = 28; - public static final int R_PIC30_BRANCH_ABSOLUTE = 29; - public static final int R_PIC30_PCREL_DO = 30; - public static final int R_PIC30_DO_ABSOLUTE = 31; - public static final int R_PIC30_PGM_ADDR_LSB = 32; - public static final int R_PIC30_PGM_ADDR_MSB = 33; - public static final int R_PIC30_UNSIGNED_4 = 34; - public static final int R_PIC30_UNSIGNED_5 = 35; - public static final int R_PIC30_BIT_SELECT_3 = 36; - public static final int R_PIC30_BIT_SELECT_4_BYTE = 37; - public static final int R_PIC30_BIT_SELECT_4 = 38; - public static final int R_PIC30_DSP_6 = 39; - public static final int R_PIC30_DSP_PRESHIFT = 40; - public static final int R_PIC30_SIGNED_10_BYTE = 41; - public static final int R_PIC30_UNSIGNED_10 = 42; - public static final int R_PIC30_UNSIGNED_14 = 43; - public static final int R_PIC30_FRAME_SIZE = 44; - public static final int R_PIC30_PWRSAV_MODE = 45; - public static final int R_PIC30_DMAOFFSET = 46; - public static final int R_PIC30_P_DMAOFFSET = 47; - public static final int R_PIC30_WORD_DMAOFFSET = 48; - public static final int R_PIC30_PSVPTR = 49; - public static final int R_PIC30_P_PSVPTR = 50; - public static final int R_PIC30_L_PSVPTR = 51; - public static final int R_PIC30_WORD_PSVPTR = 52; - public static final int R_PIC30_CALL_ACCESS = 53; - public static final int R_PIC30_PCREL_ACCESS = 54; - public static final int R_PIC30_ACCESS = 55; - public static final int R_PIC30_P_ACCESS = 56; - public static final int R_PIC30_L_ACCESS = 57; - public static final int R_PIC30_WORD_ACCESS = 58; - public static final int R_PIC30_EDSPAGE = 59; - public static final int R_PIC30_P_EDSPAGE = 60; - public static final int R_PIC30_WORD_EDSPAGE = 61; - public static final int R_PIC30_EDSOFFSET = 62; - public static final int R_PIC30_P_EDSOFFSET = 63; - public static final int R_PIC30_WORD_EDSOFFSET = 64; - public static final int R_PIC30_UNSIGNED_8 = 65; + /** + * Constructor + */ + public PIC30_ElfRelocationHandler() { + super(PIC30_ElfRelocationType.class); + } // cached state assumes new instance created for each import use private Boolean isEDSVariant = null; @@ -112,8 +49,8 @@ public class PIC30_ElfRelocationHandler extends ElfRelocationHandler { Map symbolMap) { return new PIC30_ElfRelocationContext(this, loadHelper, symbolMap); } - - private boolean isEDSVariant(ElfRelocationContext elfRelocationContext) { + + private boolean isEDSVariant(PIC30_ElfRelocationContext elfRelocationContext) { if (isEDSVariant == null) { // NOTE: non-EDS variants may improperly define DSRPAG // in register space which should be corrected @@ -124,50 +61,37 @@ public class PIC30_ElfRelocationHandler extends ElfRelocationHandler { } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, Address relocationAddress) - throws MemoryAccessException, NotFoundException { - - int type = relocation.getType(); - if (type == R_PIC30_NONE) { - return RelocationResult.SKIPPED; - } + protected RelocationResult relocate(PIC30_ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, PIC30_ElfRelocationType type, Address relocationAddress, + ElfSymbol elfSymbol, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); - int symbolIndex = relocation.getSymbolIndex(); - int addend = (int) relocation.getAddend(); long relocWordOffset = (int) relocationAddress.getAddressableWordOffset(); - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null - int symbolValue = (int) elfRelocationContext.getSymbolValue(sym); // word offset - int oldValue = memory.getInt(relocationAddress); short oldShortValue = memory.getShort(relocationAddress); - int newValue; int byteLength = 2; // most relocations affect 2-bytes (change if different) - - ElfHeader elf = elfRelocationContext.getElfHeader(); - if (elf.e_machine() == ElfConstants.EM_DSPIC30F) { - switch (type) { + switch (type) { case R_PIC30_16: // 2 case R_PIC30_FILE_REG_WORD: // 6 - newValue = (symbolValue + addend + oldShortValue); + newValue = ((int) symbolValue + addend + oldShortValue); memory.setShort(relocationAddress, (short) newValue); break; case R_PIC30_32: // 3 - newValue = symbolValue + addend + oldValue; + newValue = (int) symbolValue + addend + oldValue; memory.setInt(relocationAddress, newValue); byteLength = 4; break; case R_PIC30_FILE_REG_BYTE: // 4 short case R_PIC30_FILE_REG: // 5 short - int reloc = symbolValue; + int reloc = (int) symbolValue; reloc += addend; reloc += oldShortValue; reloc &= 0x1fff; @@ -175,7 +99,7 @@ public class PIC30_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) newValue); break; case R_PIC30_FILE_REG_WORD_WITH_DST: // 7 - reloc = symbolValue >> 1; + reloc = (int) symbolValue >> 1; reloc += addend; reloc += oldValue >> 4; reloc &= 0x7fff; @@ -185,7 +109,7 @@ public class PIC30_ElfRelocationHandler extends ElfRelocationHandler { break; case R_PIC30_WORD: // 8 case R_PIC30_WORD_TBLOFFSET: // 0x15 - reloc = symbolValue; + reloc = (int) symbolValue; reloc += addend; reloc += oldValue >> 4; reloc &= 0xffff; @@ -194,7 +118,7 @@ public class PIC30_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 4; break; case R_PIC30_WORD_TBLPAGE: // 0x18 - reloc = symbolValue >> 16; + reloc = (int) symbolValue >> 16; reloc += addend; reloc += oldValue >> 4; reloc &= 0xffff; @@ -211,11 +135,9 @@ public class PIC30_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; default: - String symbolName = elfRelocationContext.getSymbolName(symbolIndex); - markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, - elfRelocationContext.getLog()); + markAsUnhandled(program, relocationAddress, type, relocation.getSymbolIndex(), + symbolName, elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; - } } return new RelocationResult(Status.APPLIED, byteLength); } diff --git a/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationType.java b/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationType.java new file mode 100644 index 0000000000..32df48ae2d --- /dev/null +++ b/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationType.java @@ -0,0 +1,97 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum PIC30_ElfRelocationType implements ElfRelocationType { + + R_PIC30_NONE(0), + R_PIC30_8(1), + R_PIC30_16(2), + R_PIC30_32(3), + R_PIC30_FILE_REG_BYTE(4), + R_PIC30_FILE_REG(5), + R_PIC30_FILE_REG_WORD(6), + R_PIC30_FILE_REG_WORD_WITH_DST(7), + R_PIC30_WORD(8), + R_PIC30_PBYTE(9), + R_PIC30_PWORD(10), + R_PIC30_HANDLE(11), + R_PIC30_PADDR(12), + R_PIC30_P_PADDR(13), + R_PIC30_PSVOFFSET(14), + R_PIC30_TBLOFFSET(15), + R_PIC30_WORD_HANDLE(16), + R_PIC30_WORD_PSVOFFSET(17), + R_PIC30_PSVPAGE(18), + R_PIC30_P_PSVPAGE(19), + R_PIC30_WORD_PSVPAGE(20), + R_PIC30_WORD_TBLOFFSET(21), + R_PIC30_TBLPAGE(22), + R_PIC30_P_TBLPAGE(23), + R_PIC30_WORD_TBLPAGE(24), + R_PIC30_P_HANDLE(25), + R_PIC30_P_PSVOFFSET(26), + R_PIC30_P_TBLOFFSET(27), + R_PIC30_PCREL_BRANCH(28), + R_PIC30_BRANCH_ABSOLUTE(29), + R_PIC30_PCREL_DO(30), + R_PIC30_DO_ABSOLUTE(31), + R_PIC30_PGM_ADDR_LSB(32), + R_PIC30_PGM_ADDR_MSB(33), + R_PIC30_UNSIGNED_4(34), + R_PIC30_UNSIGNED_5(35), + R_PIC30_BIT_SELECT_3(36), + R_PIC30_BIT_SELECT_4_BYTE(37), + R_PIC30_BIT_SELECT_4(38), + R_PIC30_DSP_6(39), + R_PIC30_DSP_PRESHIFT(40), + R_PIC30_SIGNED_10_BYTE(41), + R_PIC30_UNSIGNED_10(42), + R_PIC30_UNSIGNED_14(43), + R_PIC30_FRAME_SIZE(44), + R_PIC30_PWRSAV_MODE(45), + R_PIC30_DMAOFFSET(46), + R_PIC30_P_DMAOFFSET(47), + R_PIC30_WORD_DMAOFFSET(48), + R_PIC30_PSVPTR(49), + R_PIC30_P_PSVPTR(50), + R_PIC30_L_PSVPTR(51), + R_PIC30_WORD_PSVPTR(52), + R_PIC30_CALL_ACCESS(53), + R_PIC30_PCREL_ACCESS(54), + R_PIC30_ACCESS(55), + R_PIC30_P_ACCESS(56), + R_PIC30_L_ACCESS(57), + R_PIC30_WORD_ACCESS(58), + R_PIC30_EDSPAGE(59), + R_PIC30_P_EDSPAGE(60), + R_PIC30_WORD_EDSPAGE(61), + R_PIC30_EDSOFFSET(62), + R_PIC30_P_EDSOFFSET(63), + R_PIC30_WORD_EDSOFFSET(64), + R_PIC30_UNSIGNED_8(65); + + public final int typeId; + + private PIC30_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } +} diff --git a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/extend/PowerPC64_ElfExtension.java b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/extend/PowerPC64_ElfExtension.java index 72cad20a24..52d64343eb 100644 --- a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/extend/PowerPC64_ElfExtension.java +++ b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/extend/PowerPC64_ElfExtension.java @@ -22,7 +22,7 @@ import org.apache.commons.lang3.StringUtils; import ghidra.app.util.bin.format.elf.*; import ghidra.app.util.bin.format.elf.ElfDynamicType.ElfDynamicValueType; -import ghidra.app.util.bin.format.elf.relocation.PowerPC64_ElfRelocationConstants; +import ghidra.app.util.bin.format.elf.relocation.PowerPC64_ElfRelocationType; import ghidra.app.util.opinion.ElfLoader; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressOverflowException; @@ -155,7 +155,7 @@ public class PowerPC64_ElfExtension extends ElfExtension { // paint TOC_BASE value as r2 across executable blocks since r2 // is needed to resolve call stubs Symbol tocSymbol = SymbolUtilities.getLabelOrFunctionSymbol(elfLoadHelper.getProgram(), - TOC_BASE, err -> elfLoadHelper.getLog().error("PowerPC64_ELF", err)); + TOC_BASE, err -> elfLoadHelper.getLog().appendMsg("PowerPC64_ELF", err)); if (tocSymbol != null) { paintTocAsR2value(tocSymbol.getAddress().getOffset(), elfLoadHelper, monitor); } @@ -180,8 +180,9 @@ public class PowerPC64_ElfExtension extends ElfExtension { return; } - int relEntrySize = (dynamicTable.getDynamicValue( - ElfDynamicType.DT_PLTREL) == ElfDynamicType.DT_RELA.value) ? 24 : 16; + int relEntrySize = (dynamicTable + .getDynamicValue(ElfDynamicType.DT_PLTREL) == ElfDynamicType.DT_RELA.value) ? 24 + : 16; long pltEntryCount = dynamicTable.getDynamicValue(ElfDynamicType.DT_PLTRELSZ) / relEntrySize; @@ -392,8 +393,8 @@ public class PowerPC64_ElfExtension extends ElfExtension { if (function == null) { // Check for potential pointer table (unsure a non-function would be referenced by OPD section) List relocations = program.getRelocationTable().getRelocations(refAddr); - if (!relocations.isEmpty() && - relocations.get(0).getType() == PowerPC64_ElfRelocationConstants.R_PPC64_RELATIVE) { + if (!relocations.isEmpty() && relocations.get(0) + .getType() == PowerPC64_ElfRelocationType.R_PPC64_RELATIVE.typeId) { return program.getSymbolTable().getPrimarySymbol(refAddr); } @@ -455,7 +456,7 @@ public class PowerPC64_ElfExtension extends ElfExtension { // ensure that r12 context has been set on global entry function Symbol entrySymbol = SymbolUtilities.getLabelOrFunctionSymbol( elfLoadHelper.getProgram(), ElfLoader.ELF_ENTRY_FUNCTION_NAME, - err -> elfLoadHelper.getLog().error("PowerPC64_ELF", err)); + err -> elfLoadHelper.getLog().appendMsg("PowerPC64_ELF", err)); if (entrySymbol != null && entrySymbol.getSymbolType() == SymbolType.FUNCTION) { setPPC64v2GlobalFunctionR12Context(program, entrySymbol.getAddress()); } @@ -508,8 +509,9 @@ public class PowerPC64_ElfExtension extends ElfExtension { // TODO: global function should be a thunk to the local function - need analyzer to do this String cmt = "local function entry for global function " + name + " at {@address " + address + "}"; - elfLoadHelper.getProgram().getListing().setComment(localFunctionAddr, - CodeUnit.PRE_COMMENT, cmt); + elfLoadHelper.getProgram() + .getListing() + .setComment(localFunctionAddr, CodeUnit.PRE_COMMENT, cmt); } catch (Exception e) { elfLoadHelper.log("Failed to generate local function symbol " + localName + " at " + diff --git a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC64_ElfRelocationConstants.java b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC64_ElfRelocationConstants.java deleted file mode 100644 index a0c691b6b1..0000000000 --- a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC64_ElfRelocationConstants.java +++ /dev/null @@ -1,173 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.util.bin.format.elf.relocation; - -public class PowerPC64_ElfRelocationConstants { - - public static final int R_PPC64_NONE = 0; - public static final int R_PPC64_ADDR32 = 1; // word32* S + A - public static final int R_PPC64_ADDR24 = 2; // low24* (S + A) >> 2 - public static final int R_PPC64_ADDR16 = 3; // half16* S + A - public static final int R_PPC64_ADDR16_LO = 4; // half16 #lo(S + A) - public static final int R_PPC64_ADDR16_HI = 5; // half16 #hi(S + A) - public static final int R_PPC64_ADDR16_HA = 6; // half16 #ha(S + A) - public static final int R_PPC64_ADDR14 = 7; // low14* (S + A) >> 2 - public static final int R_PPC64_ADDR14_BRTAKEN = 8; // low14* (S + A) >> 2 - public static final int R_PPC64_ADDR14_BRNTAKEN = 9; // low14* (S + A) >> 2 - public static final int R_PPC64_REL24 = 10; // low24* (S + A - P) >> 2 - public static final int R_PPC64_REL14 = 11; // low14* (S + A - P) >> 2 - public static final int R_PPC64_REL14_BRTAKEN = 12; // low14* (S + A - P) >> 2 - public static final int R_PPC64_REL14_BRNTAKEN = 13; // low14* (S + A - P) >> 2 - public static final int R_PPC64_GOT16 = 14; // half16* G - public static final int R_PPC64_GOT16_LO = 15; // half16 #lo(G) - public static final int R_PPC64_GOT16_HI = 16; // half16 #hi(G) - public static final int R_PPC64_GOT16_HA = 17; // half16 #ha(G) - public static final int R_PPC64_COPY = 19; - public static final int R_PPC64_GLOB_DAT = 20; // doubleword64 S + A - public static final int R_PPC64_JMP_SLOT = 21; // none see below - public static final int R_PPC64_RELATIVE = 22; // doubleword64 B + A - public static final int R_PPC64_UADDR32 = 24; // word32* S + A - public static final int R_PPC64_UADDR16 = 25; // half16* S + A - public static final int R_PPC64_REL32 = 26; // word32* S + A - P - public static final int R_PPC64_PLT32 = 27; // word32* L - public static final int R_PPC64_PLTREL32 = 28; // word32* L - P - public static final int R_PPC64_PLT16_LO = 29; // half16 #lo(L) - public static final int R_PPC64_PLT16_HI = 30; // half16 #hi(L) - public static final int R_PPC64_PLT16_HA = 31; // half16 #ha(L) - public static final int R_PPC64_SECTOFF = 33; // half16* R + A - public static final int R_PPC64_SECTOFF_LO = 34; // half16 #lo(R + A) - public static final int R_PPC64_SECTOFF_HI = 35; // half16 #hi(R + A) - public static final int R_PPC64_SECTOFF_HA = 36; // half16 #ha(R + A) - public static final int R_PPC64_ADDR30 = 37; // word30 (S + A - P) >> 2 - public static final int R_PPC64_ADDR64 = 38; // doubleword64 S + A - public static final int R_PPC64_ADDR16_HIGHER = 39; // half16 #higher(S + A) - public static final int R_PPC64_ADDR16_HIGHERA = 40; // half16 #highera(S + A) - public static final int R_PPC64_ADDR16_HIGHEST = 41; // half16 #highest(S + A) - public static final int R_PPC64_ADDR16_HIGHESTA = 42; // half16 #highesta(S + A) - public static final int R_PPC64_UADDR64 = 43; // doubleword64 S + A - public static final int R_PPC64_REL64 = 44; // doubleword64 S + A - P - public static final int R_PPC64_PLT64 = 45; // doubleword64 L - public static final int R_PPC64_PLTREL64 = 46; // doubleword64 L - P - public static final int R_PPC64_TOC16 = 47; // half16* S + A - .TOC. - public static final int R_PPC64_TOC16_LO = 48; // half16 #lo(S + A - .TOC.) - public static final int R_PPC64_TOC16_HI = 49; // half16 #hi(S + A - .TOC.) - public static final int R_PPC64_TOC16_HA = 50; // half16 #ha(S + A - .TOC.) - public static final int R_PPC64_TOC = 51; // doubleword64 .TOC. - public static final int R_PPC64_PLTGOT16 = 52; // half16* M - public static final int R_PPC64_PLTGOT16_LO = 53; // half16 #lo(M) - public static final int R_PPC64_PLTGOT16_HI = 54; // half16 #hi(M) - public static final int R_PPC64_PLTGOT16_HA = 55; // half16 #ha(M) - public static final int R_PPC64_ADDR16_DS = 56; // half16ds* (S + A) >> 2 - public static final int R_PPC64_ADDR16_LO_DS = 57; // half16ds #lo(S + A) >> 2 - public static final int R_PPC64_GOT16_DS = 58; // half16ds* G >> 2 - public static final int R_PPC64_GOT16_LO_DS = 59; // half16ds #lo(G) >> 2 - public static final int R_PPC64_PLT16_LO_DS = 60; // half16ds #lo(L) >> 2 - public static final int R_PPC64_SECTOFF_DS = 61; // half16ds* (R + A) >> 2 - public static final int R_PPC64_SECTOFF_LO_DS = 62; // half16ds #lo(R + A) >> 2 - public static final int R_PPC64_TOC16_DS = 63; // half16ds* (S + A - .TOC.) >> 2 - public static final int R_PPC64_TOC16_LO_DS = 64; // half16ds #lo(S + A - .TOC.) >> 2 - public static final int R_PPC64_PLTGOT16_DS = 65; // half16ds* M >> 2 - public static final int R_PPC64_PLTGOT16_LO_DS = 66; // half16ds #lo(M) >> 2 - public static final int R_PPC64_TLS = 67; - public static final int R_PPC64_DTPMOD64 = 68; // doubleword64 @dtpmod - public static final int R_PPC64_TPREL16 = 69; // half16* @tprel - public static final int R_PPC64_TPREL16_LO = 60; // half16 #lo(@tprel) - public static final int R_PPC64_TPREL16_HI = 71; // half16 #hi(@tprel) - public static final int R_PPC64_TPREL16_HA = 72; // half16 #ha(@tprel) - public static final int R_PPC64_TPREL64 = 73; // doubleword64 @tprel - public static final int R_PPC64_DTPREL16 = 74; // half16* @dtprel - public static final int R_PPC64_DTPREL16_LO = 75; // half16 #lo(@dtprel) - public static final int R_PPC64_DTPREL16_HI = 76; // half16 #hi(@dtprel) - public static final int R_PPC64_DTPREL16_HA = 77; // half16 #ha(@dtprel) - public static final int R_PPC64_DTPREL64 = 78; // doubleword64 @dtprel - public static final int R_PPC64_GOT_TLSGD16 = 79; // half16* @got@tlsgd - public static final int R_PPC64_GOT_TLSGD16_LO = 80; // half16 #lo(@got@tlsgd) - public static final int R_PPC64_GOT_TLSGD16_HI = 81; // half16 #hi(@got@tlsgd) - public static final int R_PPC64_GOT_TLSGD16_HA = 82; // half16 #ha(@got@tlsgd) - public static final int R_PPC64_GOT_TLSLD16 = 83; // half16* @got@tlsld - public static final int R_PPC64_GOT_TLSLD16_LO = 84; // half16 #lo(@got@tlsld) - public static final int R_PPC64_GOT_TLSLD16_HI = 85; // half16 #hi(@got@tlsld) - public static final int R_PPC64_GOT_TLSLD16_HA = 86; // half16 #ha(@got@tlsld) - public static final int R_PPC64_GOT_TPREL16_DS = 87; // half16ds* @got@tprel - public static final int R_PPC64_GOT_TPREL16_LO_DS = 88; // half16ds #lo(@got@tprel) - public static final int R_PPC64_GOT_TPREL16_HI = 89; // half16 #hi(@got@tprel) - public static final int R_PPC64_GOT_TPREL16_HA = 90; // half16 #ha(@got@tprel) - public static final int R_PPC64_GOT_DTPREL16_DS = 91; // half16ds* @got@dtprel - public static final int R_PPC64_GOT_DTPREL16_LO_DS = 92;// half16ds #lo(@got@dtprel) - public static final int R_PPC64_GOT_DTPREL16_HI = 93; // half16 #hi(@got@dtprel) - public static final int R_PPC64_GOT_DTPREL16_HA = 94; // half16 #ha(@got@dtprel) - public static final int R_PPC64_TPREL16_DS = 95; // half16ds* @tprel - public static final int R_PPC64_TPREL16_LO_DS = 96; // half16ds #lo(@tprel) - public static final int R_PPC64_TPREL16_HIGHER = 97; // half16 #higher(@tprel) - public static final int R_PPC64_TPREL16_HIGHERA = 98; // half16 #highera(@tprel) - public static final int R_PPC64_TPREL16_HIGHEST = 99; // half16 #highest(@tprel) - public static final int R_PPC64_TPREL16_HIGHESTA = 100; // half16 #highesta(@tprel) - public static final int R_PPC64_DTPREL16_DS = 101; // half16ds* @dtprel - public static final int R_PPC64_DTPREL16_LO_DS = 102; // half16ds #lo(@dtprel) - public static final int R_PPC64_DTPREL16_HIGHER = 103; // half16 #higher(@dtprel) - public static final int R_PPC64_DTPREL16_HIGHERA = 104; // half16 #highera(@dtprel) - public static final int R_PPC64_DTPREL16_HIGHEST = 105; // half16 #highest(@dtprel) - public static final int R_PPC64_DTPREL16_HIGHESTA = 106; // half16 #highesta(@dtprel) - - public static final int R_PPC64_PLTSEQ_NOTOC = 121; - public static final int R_PPC64_PLTCALL_NOTOC = 122; - public static final int R_PPC64_PCREL_OPT = 123; - - public static final int R_PPC64_D34 = 128; - public static final int R_PPC64_D34_LO = 129; - public static final int R_PPC64_D34_HI30 = 130; - public static final int R_PPC64_D34_HA30 = 131; - public static final int R_PPC64_PCREL34 = 132; - public static final int R_PPC64_GOT_PCREL34 = 133; - public static final int R_PPC64_PLT_PCREL34 = 134; - public static final int R_PPC64_PLT_PCREL34_NOTOC = 135; - public static final int R_PPC64_ADDR16_HIGHER34 = 136; - public static final int R_PPC64_ADDR16_HIGHERA34 = 137; - public static final int R_PPC64_ADDR16_HIGHEST34 = 138; - public static final int R_PPC64_ADDR16_HIGHESTA34 = 139; - public static final int R_PPC64_REL16_HIGHER34 = 140; - public static final int R_PPC64_REL16_HIGHERA34 = 141; - public static final int R_PPC64_REL16_HIGHEST34 = 142; - public static final int R_PPC64_REL16_HIGHESTA34 = 143; - public static final int R_PPC64_D28 = 144; - public static final int R_PPC64_PCREL28 = 145; - public static final int R_PPC64_TPREL34 = 146; - public static final int R_PPC64_DTPREL34 = 147; - public static final int R_PPC64_GOT_TLSGD_PCREL34 = 148; - public static final int R_PPC64_GOT_TLSLD_PCREL34 = 149; - public static final int R_PPC64_GOT_TPREL_PCREL34 = 150; - public static final int R_PPC64_GOT_DTPREL_PCREL34 = 151; - - public static final int R_PPC64_REL16_HIGH = 240; - public static final int R_PPC64_REL16_HIGHA = 241; - public static final int R_PPC64_REL16_HIGHER = 242; - public static final int R_PPC64_REL16_HIGHERA = 243; - public static final int R_PPC64_REL16_HIGHEST = 244; - public static final int R_PPC64_REL16_HIGHESTA = 245; - - public static final int R_PPC64_JMP_IREL = 247; - - // Masks for manipulating Power PC relocation targets - public static final int PPC64_WORD32 = 0xFFFFFFFF; - public static final int PPC64_WORD30 = 0xFFFFFFFC; - public static final int PPC64_LOW24 = 0x03FFFFFC; - public static final int PPC64_LOW14 = 0x0020FFFC; - public static final int PPC64_HALF16 = 0xFFFF; - - private PowerPC64_ElfRelocationConstants() { - // no construct - } -} diff --git a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC64_ElfRelocationHandler.java b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC64_ElfRelocationHandler.java index 97ada5bc4e..8e6ef55707 100644 --- a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC64_ElfRelocationHandler.java +++ b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC64_ElfRelocationHandler.java @@ -19,7 +19,6 @@ import ghidra.app.util.bin.format.elf.*; import ghidra.app.util.bin.format.elf.extend.PowerPC64_ElfExtension; import ghidra.app.util.importer.MessageLog; import ghidra.program.model.address.Address; -import ghidra.program.model.lang.Language; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.*; import ghidra.program.model.reloc.Relocation.Status; @@ -27,9 +26,23 @@ import ghidra.program.model.reloc.RelocationResult; import ghidra.program.model.symbol.Symbol; import ghidra.program.model.symbol.SymbolUtilities; import ghidra.util.*; -import ghidra.util.exception.NotFoundException; -public class PowerPC64_ElfRelocationHandler extends ElfRelocationHandler { +public class PowerPC64_ElfRelocationHandler + extends AbstractElfRelocationHandler> { + + // Masks for manipulating Power PC relocation targets + private static final int PPC64_WORD32 = 0xFFFFFFFF; + private static final int PPC64_WORD30 = 0xFFFFFFFC; + private static final int PPC64_LOW24 = 0x03FFFFFC; + private static final int PPC64_LOW14 = 0x0020FFFC; + private static final int PPC64_HALF16 = 0xFFFF; + + /** + * Constructor + */ + public PowerPC64_ElfRelocationHandler() { + super(PowerPC64_ElfRelocationType.class); + } @Override public boolean canRelocate(ElfHeader elf) { @@ -37,42 +50,19 @@ public class PowerPC64_ElfRelocationHandler extends ElfRelocationHandler { } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, - Address relocationAddress) throws MemoryAccessException, NotFoundException { - - ElfHeader elf = elfRelocationContext.getElfHeader(); - if (elf.e_machine() != ElfConstants.EM_PPC64 || !elf.is64Bit()) { - return RelocationResult.FAILURE; - } + protected RelocationResult relocate(ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, PowerPC64_ElfRelocationType type, Address relocationAddress, + ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); - int type = relocation.getType(); - if (type == PowerPC64_ElfRelocationConstants.R_PPC64_NONE) { - return RelocationResult.SKIPPED; - } - int symbolIndex = relocation.getSymbolIndex(); - - Language language = elfRelocationContext.getProgram().getLanguage(); - if (!"PowerPC".equals(language.getProcessor().toString()) || - language.getLanguageDescription().getSize() != 64) { - markAsError(program, relocationAddress, Long.toString(type), null, - "Unsupported language for 64-bit PowerPC relocation", - elfRelocationContext.getLog()); - } - // NOTE: Based upon glibc source it appears that PowerPC only uses RELA relocations long addend = relocation.getAddend(); long offset = relocationAddress.getOffset(); - - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null - String symbolName = elfRelocationContext.getSymbolName(symbolIndex); - Address symbolAddr = elfRelocationContext.getSymbolAddress(sym); - long symbolValue = elfRelocationContext.getSymbolValue(sym); - + int symbolIndex = relocation.getSymbolIndex(); int oldValue = memory.getInt(relocationAddress); int newValue = 0; int byteLength = 4; // most relocations affect 4-bytes (change if different) @@ -89,17 +79,17 @@ public class PowerPC64_ElfRelocationHandler extends ElfRelocationHandler { // Obtain TOC base used by certain relocations long toc = 0; switch (type) { - case PowerPC64_ElfRelocationConstants.R_PPC64_TOC16_LO: - case PowerPC64_ElfRelocationConstants.R_PPC64_TOC16_HI: - case PowerPC64_ElfRelocationConstants.R_PPC64_TOC16_HA: - case PowerPC64_ElfRelocationConstants.R_PPC64_TOC16_LO_DS: - case PowerPC64_ElfRelocationConstants.R_PPC64_TOC: + case R_PPC64_TOC16_LO: + case R_PPC64_TOC16_HI: + case R_PPC64_TOC16_HA: + case R_PPC64_TOC16_LO_DS: + case R_PPC64_TOC: MessageLog log = elfRelocationContext.getLog(); Symbol tocBaseSym = SymbolUtilities.getLabelOrFunctionSymbol(program, PowerPC64_ElfExtension.TOC_BASE, err -> log.appendMsg(err)); if (tocBaseSym == null) { - markAsError(program, relocationAddress, type, symbolName, + markAsError(program, relocationAddress, type, symbolName, symbolIndex, "TOC_BASE unknown", log); return RelocationResult.FAILURE; } @@ -109,101 +99,98 @@ public class PowerPC64_ElfRelocationHandler extends ElfRelocationHandler { } switch (type) { - case PowerPC64_ElfRelocationConstants.R_PPC64_COPY: - markAsWarning(program, relocationAddress, "R_PPC64_COPY", symbolName, - symbolIndex, "Runtime copy not supported", elfRelocationContext.getLog()); + case R_PPC64_COPY: + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, + "Runtime copy not supported", elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; - case PowerPC64_ElfRelocationConstants.R_PPC64_ADDR32: + case R_PPC64_ADDR32: newValue = (int) (symbolValue + addend); memory.setInt(relocationAddress, newValue); break; - case PowerPC64_ElfRelocationConstants.R_PPC64_ADDR24: + case R_PPC64_ADDR24: newValue = (int) ((symbolValue + addend) >> 2); - newValue = - (oldValue & ~PowerPC64_ElfRelocationConstants.PPC64_LOW24) | (newValue << 2); + newValue = (oldValue & ~PPC64_LOW24) | (newValue << 2); memory.setInt(relocationAddress, newValue); break; - case PowerPC64_ElfRelocationConstants.R_PPC64_ADDR16: + case R_PPC64_ADDR16: newValue = (int) (symbolValue + addend); memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; - case PowerPC64_ElfRelocationConstants.R_PPC64_ADDR16_LO: + case R_PPC64_ADDR16_LO: newValue = (int) (symbolValue + addend); memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; - case PowerPC64_ElfRelocationConstants.R_PPC64_TOC16_LO: + case R_PPC64_TOC16_LO: newValue = (int) (symbolValue + addend - toc); memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; - case PowerPC64_ElfRelocationConstants.R_PPC64_TOC16_LO_DS: + case R_PPC64_TOC16_LO_DS: newValue = (int) ((symbolValue + addend - toc) >> 2); newValue = ((oldValue >>> 16) & 0x3) | (newValue << 2); memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; - case PowerPC64_ElfRelocationConstants.R_PPC64_ADDR16_HI: + case R_PPC64_ADDR16_HI: newValue = (int) (symbolValue + addend); newValue = ((newValue >> 16) & 0xFFFF); memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; - case PowerPC64_ElfRelocationConstants.R_PPC64_TOC16_HI: + case R_PPC64_TOC16_HI: newValue = (int) (symbolValue + addend - toc); newValue = ((newValue >> 16) & 0xFFFF); memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; - case PowerPC64_ElfRelocationConstants.R_PPC64_ADDR16_HA: + case R_PPC64_ADDR16_HA: newValue = (int) (symbolValue + addend); newValue = ((newValue >> 16) + (((newValue & 0x8000) != 0) ? 1 : 0)); memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; - case PowerPC64_ElfRelocationConstants.R_PPC64_TOC16_HA: + case R_PPC64_TOC16_HA: newValue = (int) (symbolValue + addend - toc); newValue = ((newValue >> 16) + (((newValue & 0x8000) != 0) ? 1 : 0)); memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; - case PowerPC64_ElfRelocationConstants.R_PPC64_ADDR14: - case PowerPC64_ElfRelocationConstants.R_PPC64_ADDR14_BRTAKEN: - case PowerPC64_ElfRelocationConstants.R_PPC64_ADDR14_BRNTAKEN: + case R_PPC64_ADDR14: + case R_PPC64_ADDR14_BRTAKEN: + case R_PPC64_ADDR14_BRNTAKEN: newValue = (int) ((symbolValue + addend) >> 2); - newValue = (oldValue & ~PowerPC64_ElfRelocationConstants.PPC64_LOW14) | - ((newValue << 2) & PowerPC64_ElfRelocationConstants.PPC64_LOW24); + newValue = (oldValue & ~PPC64_LOW14) | ((newValue << 2) & PPC64_LOW24); memory.setInt(relocationAddress, newValue); break; - case PowerPC64_ElfRelocationConstants.R_PPC64_REL24: + case R_PPC64_REL24: // attempt to handle Object module case where referenced symbol resides within .opd symbolValue = fixupOPDSymbolValue(elfRelocationContext, sym); newValue = (int) ((symbolValue + addend - offset) >> 2); - newValue = ((newValue << 2) & PowerPC64_ElfRelocationConstants.PPC64_LOW24); - newValue = (oldValue & ~PowerPC64_ElfRelocationConstants.PPC64_LOW24) | newValue; + newValue = ((newValue << 2) & PPC64_LOW24); + newValue = (oldValue & ~PPC64_LOW24) | newValue; memory.setInt(relocationAddress, newValue); break; - case PowerPC64_ElfRelocationConstants.R_PPC64_RELATIVE: + case R_PPC64_RELATIVE: long value64 = elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend; memory.setLong(relocationAddress, value64); byteLength = 8; break; - case PowerPC64_ElfRelocationConstants.R_PPC64_REL32: + case R_PPC64_REL32: newValue = (int) (symbolValue + addend - offset); memory.setInt(relocationAddress, newValue); break; - case PowerPC64_ElfRelocationConstants.R_PPC64_REL14: - case PowerPC64_ElfRelocationConstants.R_PPC64_REL14_BRTAKEN: - case PowerPC64_ElfRelocationConstants.R_PPC64_REL14_BRNTAKEN: + case R_PPC64_REL14: + case R_PPC64_REL14_BRTAKEN: + case R_PPC64_REL14_BRNTAKEN: newValue = (int) (symbolValue + addend - offset) >> 2; - newValue = (oldValue & ~PowerPC64_ElfRelocationConstants.PPC64_LOW14) | - ((newValue << 2) & PowerPC64_ElfRelocationConstants.PPC64_LOW14); + newValue = (oldValue & ~PPC64_LOW14) | ((newValue << 2) & PPC64_LOW14); memory.setInt(relocationAddress, newValue); break; - case PowerPC64_ElfRelocationConstants.R_PPC64_JMP_SLOT: + case R_PPC64_JMP_SLOT: // TODO: do we need option to allow function descriptor // use - or not? The EF_PPC64_ABI in e_flags is not reliable. Address functionDescriptorAddr = relocationAddress.getNewAddress(symbolValue); @@ -226,28 +213,28 @@ public class PowerPC64_ElfRelocationHandler extends ElfRelocationHandler { byteLength = bytes.length; } break; - case PowerPC64_ElfRelocationConstants.R_PPC64_UADDR32: + case R_PPC64_UADDR32: newValue = (int) (symbolValue + addend); memory.setInt(relocationAddress, newValue); break; - case PowerPC64_ElfRelocationConstants.R_PPC64_UADDR16: + case R_PPC64_UADDR16: newValue = (int) (symbolValue + addend); memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; - case PowerPC64_ElfRelocationConstants.R_PPC64_UADDR64: - case PowerPC64_ElfRelocationConstants.R_PPC64_ADDR64: - case PowerPC64_ElfRelocationConstants.R_PPC64_GLOB_DAT: + case R_PPC64_UADDR64: + case R_PPC64_ADDR64: + case R_PPC64_GLOB_DAT: value64 = symbolValue + addend; memory.setLong(relocationAddress, value64); byteLength = 8; if (symbolIndex != 0 && addend != 0 && !sym.isSection()) { - warnExternalOffsetRelocation(program, relocationAddress, - symbolAddr, symbolName, addend, elfRelocationContext.getLog()); + warnExternalOffsetRelocation(program, relocationAddress, symbolAddr, symbolName, + addend, elfRelocationContext.getLog()); applyComponentOffsetPointer(program, relocationAddress, addend); } break; - case PowerPC64_ElfRelocationConstants.R_PPC64_TOC: + case R_PPC64_TOC: memory.setLong(relocationAddress, toc); byteLength = 8; break; @@ -266,12 +253,12 @@ public class PowerPC64_ElfRelocationHandler extends ElfRelocationHandler { * applied to call stubs. It is also important that relocations have already * been applied to the .opd section since we will be using its data for * locating the real function. - * @param elfRelocationContext - * @param sym + * @param elfRelocationContext ELF relocation context + * @param sym ELF relocation symbol * @return symbol value - * @throws MemoryAccessException + * @throws MemoryAccessException if memory access error occurs */ - private long fixupOPDSymbolValue(ElfRelocationContext elfRelocationContext, ElfSymbol sym) + private long fixupOPDSymbolValue(ElfRelocationContext elfRelocationContext, ElfSymbol sym) throws MemoryAccessException { Address addr = elfRelocationContext.getSymbolAddress(sym); if (addr == null) { diff --git a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC64_ElfRelocationType.java b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC64_ElfRelocationType.java new file mode 100644 index 0000000000..f6c09a2709 --- /dev/null +++ b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC64_ElfRelocationType.java @@ -0,0 +1,174 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum PowerPC64_ElfRelocationType implements ElfRelocationType { + + R_PPC64_NONE(0), + R_PPC64_ADDR32(1), // word32* S + A + R_PPC64_ADDR24(2), // low24* (S + A) >> 2 + R_PPC64_ADDR16(3), // half16* S + A + R_PPC64_ADDR16_LO(4), // half16 #lo(S + A) + R_PPC64_ADDR16_HI(5), // half16 #hi(S + A) + R_PPC64_ADDR16_HA(6), // half16 #ha(S + A) + R_PPC64_ADDR14(7), // low14* (S + A) >> 2 + R_PPC64_ADDR14_BRTAKEN(8), // low14* (S + A) >> 2 + R_PPC64_ADDR14_BRNTAKEN(9), // low14* (S + A) >> 2 + R_PPC64_REL24(10), // low24* (S + A - P) >> 2 + R_PPC64_REL14(11), // low14* (S + A - P) >> 2 + R_PPC64_REL14_BRTAKEN(12), // low14* (S + A - P) >> 2 + R_PPC64_REL14_BRNTAKEN(13), // low14* (S + A - P) >> 2 + R_PPC64_GOT16(14), // half16* G + R_PPC64_GOT16_LO(15), // half16 #lo(G) + R_PPC64_GOT16_HI(16), // half16 #hi(G) + R_PPC64_GOT16_HA(17), // half16 #ha(G) + R_PPC64_COPY(19), + R_PPC64_GLOB_DAT(20), // doubleword64 S + A + R_PPC64_JMP_SLOT(21), // none see below + R_PPC64_RELATIVE(22), // doubleword64 B + A + R_PPC64_UADDR32(24), // word32* S + A + R_PPC64_UADDR16(25), // half16* S + A + R_PPC64_REL32(26), // word32* S + A - P + R_PPC64_PLT32(27), // word32* L + R_PPC64_PLTREL32(28), // word32* L - P + R_PPC64_PLT16_LO(29), // half16 #lo(L) + R_PPC64_PLT16_HI(30), // half16 #hi(L) + R_PPC64_PLT16_HA(31), // half16 #ha(L) + R_PPC64_SECTOFF(33), // half16* R + A + R_PPC64_SECTOFF_LO(34), // half16 #lo(R + A) + R_PPC64_SECTOFF_HI(35), // half16 #hi(R + A) + R_PPC64_SECTOFF_HA(36), // half16 #ha(R + A) + R_PPC64_ADDR30(37), // word30 (S + A - P) >> 2 + R_PPC64_ADDR64(38), // doubleword64 S + A + R_PPC64_ADDR16_HIGHER(39), // half16 #higher(S + A) + R_PPC64_ADDR16_HIGHERA(40), // half16 #highera(S + A) + R_PPC64_ADDR16_HIGHEST(41), // half16 #highest(S + A) + R_PPC64_ADDR16_HIGHESTA(42), // half16 #highesta(S + A) + R_PPC64_UADDR64(43), // doubleword64 S + A + R_PPC64_REL64(44), // doubleword64 S + A - P + R_PPC64_PLT64(45), // doubleword64 L + R_PPC64_PLTREL64(46), // doubleword64 L - P + R_PPC64_TOC16(47), // half16* S + A - .TOC. + R_PPC64_TOC16_LO(48), // half16 #lo(S + A - .TOC.) + R_PPC64_TOC16_HI(49), // half16 #hi(S + A - .TOC.) + R_PPC64_TOC16_HA(50), // half16 #ha(S + A - .TOC.) + R_PPC64_TOC(51), // doubleword64 .TOC. + R_PPC64_PLTGOT16(52), // half16* M + R_PPC64_PLTGOT16_LO(53), // half16 #lo(M) + R_PPC64_PLTGOT16_HI(54), // half16 #hi(M) + R_PPC64_PLTGOT16_HA(55), // half16 #ha(M) + R_PPC64_ADDR16_DS(56), // half16ds* (S + A) >> 2 + R_PPC64_ADDR16_LO_DS(57), // half16ds #lo(S + A) >> 2 + R_PPC64_GOT16_DS(58), // half16ds* G >> 2 + R_PPC64_GOT16_LO_DS(59), // half16ds #lo(G) >> 2 + R_PPC64_PLT16_LO_DS(60), // half16ds #lo(L) >> 2 + R_PPC64_SECTOFF_DS(61), // half16ds* (R + A) >> 2 + R_PPC64_SECTOFF_LO_DS(62), // half16ds #lo(R + A) >> 2 + R_PPC64_TOC16_DS(63), // half16ds* (S + A - .TOC.) >> 2 + R_PPC64_TOC16_LO_DS(64), // half16ds #lo(S + A - .TOC.) >> 2 + R_PPC64_PLTGOT16_DS(65), // half16ds* M >> 2 + R_PPC64_PLTGOT16_LO_DS(66), // half16ds #lo(M) >> 2 + R_PPC64_TLS(67), + R_PPC64_DTPMOD64(68), // doubleword64 @dtpmod + R_PPC64_TPREL16(69), // half16* @tprel + R_PPC64_TPREL16_LO(60), // half16 #lo(@tprel) + R_PPC64_TPREL16_HI(71), // half16 #hi(@tprel) + R_PPC64_TPREL16_HA(72), // half16 #ha(@tprel) + R_PPC64_TPREL64(73), // doubleword64 @tprel + R_PPC64_DTPREL16(74), // half16* @dtprel + R_PPC64_DTPREL16_LO(75), // half16 #lo(@dtprel) + R_PPC64_DTPREL16_HI(76), // half16 #hi(@dtprel) + R_PPC64_DTPREL16_HA(77), // half16 #ha(@dtprel) + R_PPC64_DTPREL64(78), // doubleword64 @dtprel + R_PPC64_GOT_TLSGD16(79), // half16* @got@tlsgd + R_PPC64_GOT_TLSGD16_LO(80), // half16 #lo(@got@tlsgd) + R_PPC64_GOT_TLSGD16_HI(81), // half16 #hi(@got@tlsgd) + R_PPC64_GOT_TLSGD16_HA(82), // half16 #ha(@got@tlsgd) + R_PPC64_GOT_TLSLD16(83), // half16* @got@tlsld + R_PPC64_GOT_TLSLD16_LO(84), // half16 #lo(@got@tlsld) + R_PPC64_GOT_TLSLD16_HI(85), // half16 #hi(@got@tlsld) + R_PPC64_GOT_TLSLD16_HA(86), // half16 #ha(@got@tlsld) + R_PPC64_GOT_TPREL16_DS(87), // half16ds* @got@tprel + R_PPC64_GOT_TPREL16_LO_DS(88), // half16ds #lo(@got@tprel) + R_PPC64_GOT_TPREL16_HI(89), // half16 #hi(@got@tprel) + R_PPC64_GOT_TPREL16_HA(90), // half16 #ha(@got@tprel) + R_PPC64_GOT_DTPREL16_DS(91), // half16ds* @got@dtprel + R_PPC64_GOT_DTPREL16_LO_DS(92),// half16ds #lo(@got@dtprel) + R_PPC64_GOT_DTPREL16_HI(93), // half16 #hi(@got@dtprel) + R_PPC64_GOT_DTPREL16_HA(94), // half16 #ha(@got@dtprel) + R_PPC64_TPREL16_DS(95), // half16ds* @tprel + R_PPC64_TPREL16_LO_DS(96), // half16ds #lo(@tprel) + R_PPC64_TPREL16_HIGHER(97), // half16 #higher(@tprel) + R_PPC64_TPREL16_HIGHERA(98), // half16 #highera(@tprel) + R_PPC64_TPREL16_HIGHEST(99), // half16 #highest(@tprel) + R_PPC64_TPREL16_HIGHESTA(100), // half16 #highesta(@tprel) + R_PPC64_DTPREL16_DS(101), // half16ds* @dtprel + R_PPC64_DTPREL16_LO_DS(102), // half16ds #lo(@dtprel) + R_PPC64_DTPREL16_HIGHER(103), // half16 #higher(@dtprel) + R_PPC64_DTPREL16_HIGHERA(104), // half16 #highera(@dtprel) + R_PPC64_DTPREL16_HIGHEST(105), // half16 #highest(@dtprel) + R_PPC64_DTPREL16_HIGHESTA(106), // half16 #highesta(@dtprel) + + R_PPC64_PLTSEQ_NOTOC(121), + R_PPC64_PLTCALL_NOTOC(122), + R_PPC64_PCREL_OPT(123), + + R_PPC64_D34(128), + R_PPC64_D34_LO(129), + R_PPC64_D34_HI30(130), + R_PPC64_D34_HA30(131), + R_PPC64_PCREL34(132), + R_PPC64_GOT_PCREL34(133), + R_PPC64_PLT_PCREL34(134), + R_PPC64_PLT_PCREL34_NOTOC(135), + R_PPC64_ADDR16_HIGHER34(136), + R_PPC64_ADDR16_HIGHERA34(137), + R_PPC64_ADDR16_HIGHEST34(138), + R_PPC64_ADDR16_HIGHESTA34(139), + R_PPC64_REL16_HIGHER34(140), + R_PPC64_REL16_HIGHERA34(141), + R_PPC64_REL16_HIGHEST34(142), + R_PPC64_REL16_HIGHESTA34(143), + R_PPC64_D28(144), + R_PPC64_PCREL28(145), + R_PPC64_TPREL34(146), + R_PPC64_DTPREL34(147), + R_PPC64_GOT_TLSGD_PCREL34(148), + R_PPC64_GOT_TLSLD_PCREL34(149), + R_PPC64_GOT_TPREL_PCREL34(150), + R_PPC64_GOT_DTPREL_PCREL34(151), + + R_PPC64_REL16_HIGH(240), + R_PPC64_REL16_HIGHA(241), + R_PPC64_REL16_HIGHER(242), + R_PPC64_REL16_HIGHERA(243), + R_PPC64_REL16_HIGHEST(244), + R_PPC64_REL16_HIGHESTA(245), + + R_PPC64_JMP_IREL(247); + + public final int typeId; + + private PowerPC64_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } + +} diff --git a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationConstants.java b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationConstants.java deleted file mode 100644 index 6c3554eae4..0000000000 --- a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationConstants.java +++ /dev/null @@ -1,150 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.util.bin.format.elf.relocation; - -public class PowerPC_ElfRelocationConstants { - - public static final int R_PPC_NONE = 0; - public static final int R_PPC_ADDR32 = 1; // word32 S + A - public static final int R_PPC_ADDR24 = 2; // low24 (S + A) >> 2 - public static final int R_PPC_ADDR16 = 3; // half16 S + A - public static final int R_PPC_ADDR16_LO = 4; // half16 #lo(S + A) - public static final int R_PPC_ADDR16_HI = 5; // half16 #hi(S + A) - public static final int R_PPC_ADDR16_HA = 6; // half16 #ha(S + A) - public static final int R_PPC_ADDR14 = 7; // low14 (S + A) >> 2 - public static final int R_PPC_ADDR14_BRTAKEN = 8; // low14 (S + A) >> 2 - public static final int R_PPC_ADDR14_BRNTAKEN = 9; // low14 (S + A) >> 2 - public static final int R_PPC_REL24 = 10; // low24 (S + A - P) >> 2 - public static final int R_PPC_REL14 = 11; // low14 (S + A - P) >> 2 - public static final int R_PPC_REL14_BRTAKEN = 12; // low14 (S + A - P) >> - // 2 - public static final int R_PPC_REL14_BRNTAKEN = 13; // low14 (S + A - P) >> - // 2 - public static final int R_PPC_GOT16 = 14; // half16 G + A - public static final int R_PPC_GOT16_LO = 15; // half16 #lo(G + A) - public static final int R_PPC_GOT16_HI = 16; // half16 #hi(G + A) - public static final int R_PPC_GOT16_HA = 17; // half16 #ha(G + A) - public static final int R_PPC_PLTREL24 = 18; // low24 (L + A + P) >> 2 - public static final int R_PPC_COPY = 19; // none none - public static final int R_PPC_GLOB_DAT = 20; // word32 S + A - public static final int R_PPC_JMP_SLOT = 21; // Old ABI: word32 S + A, New ABI: generate branch instruction - public static final int R_PPC_RELATIVE = 22; // word32 S + A - public static final int R_PPC_LOCAL24PC = 23; // none - public static final int R_PPC_UADDR32 = 24; // low24 - public static final int R_PPC_UADDR16 = 25; // half16 S + A - public static final int R_PPC_REL32 = 26; // word32 S + A - P - public static final int R_PPC_PLT32 = 27; // word32 L + A - public static final int R_PPC_PLTREL32 = 28; // word32 L + A - P - public static final int R_PPC_PLT16_LO = 29; // half16 #lo(L + A) - public static final int R_PPC_PLT16_HI = 30; // half16 #hi(L + A) - public static final int R_PPC_PLT16_HA = 31; // half16 #ha(L + A) - public static final int R_PPC_SDAREL16 = 32; // half16 S + A - _SDA_BASE_ - public static final int R_PPC_SECTOFF = 33; // half16 R + A - public static final int R_PPC_SECTOFF_LO = 34; // half16 #lo(R + A) - public static final int R_PPC_SECTOFF_HI = 35; // half16 #hi(R + A) - public static final int R_PPC_SECTOFF_HA = 36; // half16 #ha(R + A) - public static final int R_PPC_ADDR30 = 37; // word30 (S + A - P) >> 2 - - public static final int R_POWERPC_TLS = 67; - public static final int R_POWERPC_DTPMOD = 68; - public static final int R_POWERPC_TPREL16 = 69; - public static final int R_POWERPC_TPREL16_LO = 70; - public static final int R_POWERPC_TPREL16_HI = 71; - public static final int R_POWERPC_TPREL16_HA = 72; - public static final int R_POWERPC_TPREL = 73; - public static final int R_POWERPC_DTPREL16 = 74; - public static final int R_POWERPC_DTPREL16_LO = 75; - public static final int R_POWERPC_DTPREL16_HI = 76; - public static final int R_POWERPC_DTPREL16_HA = 77; - public static final int R_POWERPC_DTPREL = 78; - public static final int R_POWERPC_GOT_TLSGD16 = 79; - public static final int R_POWERPC_GOT_TLSGD16_LO = 80; - public static final int R_POWERPC_GOT_TLSGD16_HI = 81; - public static final int R_POWERPC_GOT_TLSGD16_HA = 82; - public static final int R_POWERPC_GOT_TLSLD16 = 83; - public static final int R_POWERPC_GOT_TLSLD16_LO = 84; - public static final int R_POWERPC_GOT_TLSLD16_HI = 85; - public static final int R_POWERPC_GOT_TLSLD16_HA = 86; - public static final int R_POWERPC_GOT_TPREL16 = 87; - public static final int R_POWERPC_GOT_TPREL16_LO = 88; - public static final int R_POWERPC_GOT_TPREL16_HI = 89; - public static final int R_POWERPC_GOT_TPREL16_HA = 90; - public static final int R_POWERPC_GOT_DTPREL16 = 91; - public static final int R_POWERPC_GOT_DTPREL16_LO = 92; - public static final int R_POWERPC_GOT_DTPREL16_HI = 93; - public static final int R_POWERPC_GOT_DTPREL16_HA = 94; - public static final int R_PPC_TLSGD = 95; - public static final int R_PPC_TLSLD = 96; - - public static final int R_PPC_EMB_NADDR32 = 101; // uword32 (A - S) - public static final int R_PPC_EMB_NADDR16 = 102; // uhalf16 (A - S) - public static final int R_PPC_EMB_NADDR16_LO = 103; // uhalf16 #lo(A - S) - public static final int R_PPC_EMB_NADDR16_HI = 104; // uhalf16 #hi(A - S) - public static final int R_PPC_EMB_NADDR16_HA = 105; // uhalf16 #ha(A - S) - public static final int R_PPC_EMB_SDAI16 = 106; // uhalf16 T - public static final int R_PPC_EMB_SDA2I16 = 107; // uhalf16 U - public static final int R_PPC_EMB_SDA2REL = 108; // uhalf16 S + A - _SDA2_BASE_ - public static final int R_PPC_EMB_SDA21 = 109; // ulow21 - public static final int R_PPC_EMB_MRKREF = 110; // none - public static final int R_PPC_EMB_RELSEC16 = 111; // uhalf16 V + A - public static final int R_PPC_EMB_RELST_LO = 112; // uhalf16 #lo(W + A) - public static final int R_PPC_EMB_RELST_HI = 113; // uhalf16 #hi(W + A) - public static final int R_PPC_EMB_RELST_HA = 114; // uhalf16 #ha(W + A) - public static final int R_PPC_EMB_BIT_FLD = 115; // uword32 - public static final int R_PPC_EMB_RELSDA = 116; // uhalf16 - - public static final int R_POWERPC_PLTSEQ = 119; - public static final int R_POWERPC_PLTCALL = 120; - - public static final int R_PPC_VLE_REL8 = 216; - public static final int R_PPC_VLE_REL15 = 217; - public static final int R_PPC_VLE_REL24 = 218; - public static final int R_PPC_VLE_LO16A = 219; - public static final int R_PPC_VLE_LO16D = 220; - public static final int R_PPC_VLE_HI16A = 221; - public static final int R_PPC_VLE_HI16D = 222; - public static final int R_PPC_VLE_HA16A = 223; - public static final int R_PPC_VLE_HA16D = 224; - public static final int R_PPC_VLE_SDA21 = 225; - public static final int R_PPC_VLE_SDA21_LO = 226; - public static final int R_PPC_VLE_SDAREL_LO16A = 227; - public static final int R_PPC_VLE_SDAREL_LO16D = 228; - public static final int R_PPC_VLE_SDAREL_HI16A = 229; - public static final int R_PPC_VLE_SDAREL_HI16D = 230; - public static final int R_PPC_VLE_SDAREL_HA16A = 231; - public static final int R_PPC_VLE_SDAREL_HA16D = 232; - - public static final int R_POWERPC_REL16DX_HA = 246; - public static final int R_POWERPC_IRELATIVE = 248; - public static final int R_POWERPC_REL16 = 249; - public static final int R_POWERPC_REL16_LO = 250; - public static final int R_POWERPC_REL16_HI = 251; - public static final int R_POWERPC_REL16_HA = 252; - public static final int R_POWERPC_GNU_VTINHERIT = 253; - public static final int R_POWERPC_GNU_VTENTRY = 254; - public static final int R_PPC_TOC16 = 255; - - // Masks for manipulating Power PC relocation targets - public static final int PPC_WORD32 = 0xFFFFFFFF; - public static final int PPC_WORD30 = 0xFFFFFFFC; - public static final int PPC_LOW24 = 0x03FFFFFC; - public static final int PPC_LOW14 = 0x0020FFFC; - public static final int PPC_HALF16 = 0xFFFF; - - private PowerPC_ElfRelocationConstants() { - // no construct - } -} diff --git a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationContext.java b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationContext.java new file mode 100644 index 0000000000..e5bc8a0767 --- /dev/null +++ b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationContext.java @@ -0,0 +1,165 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +import java.math.BigInteger; +import java.util.Map; + +import ghidra.app.util.bin.format.elf.ElfLoadHelper; +import ghidra.app.util.bin.format.elf.ElfSymbol; +import ghidra.app.util.importer.MessageLog; +import ghidra.program.model.address.*; +import ghidra.program.model.lang.Register; +import ghidra.program.model.listing.ContextChangeException; +import ghidra.program.model.mem.Memory; +import ghidra.program.model.mem.MemoryBlock; +import ghidra.program.model.symbol.*; +import ghidra.util.exception.AssertException; +import ghidra.util.exception.InvalidInputException; + +public class PowerPC_ElfRelocationContext + extends ElfRelocationContext { + + private Integer sdaBase; + private Integer sda2Base; + + protected PowerPC_ElfRelocationContext(PowerPC_ElfRelocationHandler handler, + ElfLoadHelper loadHelper, Map symbolMap) { + super(handler, loadHelper, symbolMap); + } + + /** + * Get or establish _SDA_BASE_ value and apply as r13 context value to all memory blocks + * with execute permission. + * @return _SDA_BASE_ offset or null if unable to determine or establish + */ + Integer getSDABase() { + if (sdaBase != null) { + if (sdaBase == -1) { + return null; + } + return sdaBase; + } + sdaBase = getBaseOffset("_SDA_BASE_", ".sdata", ".sbss"); + if (sdaBase == -1) { + getLog().appendMsg("ERROR: failed to establish _SDA_BASE_"); + return null; + } + setRegisterContext("r13", BigInteger.valueOf(sdaBase)); + return sdaBase; + } + + /** + * Get or establish _SDA2_BASE_ value and apply as r2 context value to all memory blocks + * with execute permission. + * @return _SDA2_BASE_ offset or null if unable to determine or establish + */ + Integer getSDA2Base() { + if (sda2Base != null) { + if (sda2Base == -1) { + return null; + } + return sda2Base; + } + sda2Base = getBaseOffset("_SDA2_BASE_", ".sdata2", ".sbss2"); + if (sda2Base == -1) { + getLog().appendMsg("ERROR: failed to establish _SDA2_BASE_"); + return null; + } + setRegisterContext("r2", BigInteger.valueOf(sda2Base)); + return sda2Base; + } + + /** + * Apply register context to all memory blocks which satisfy blockPredicate check. + * @param regName register name + * @param value context value + */ + private void setRegisterContext(String regName, BigInteger value) { + Register reg = program.getRegister(regName); + for (MemoryBlock block : program.getMemory().getBlocks()) { + if (block.isExecute()) { + try { + program.getProgramContext() + .setValue(reg, block.getStart(), block.getEnd(), value); + } + catch (ContextChangeException e) { + throw new AssertException(e); // no instructions should exist yet + } + } + } + } + + /** + * Establish base offset from symbol or range of specified memory blocks. + * @param symbolName base symbol name + * @param blockNames block names which may be used to establish base range + * @return base offset or -1 on failure + */ + private Integer getBaseOffset(String symbolName, String... blockNames) { + + MessageLog log = getLog(); + + Symbol baseSymbol = SymbolUtilities.getLabelOrFunctionSymbol(program, symbolName, + msg -> log.appendMsg(msg)); + if (baseSymbol != null) { + int baseOffset = (int) baseSymbol.getAddress().getOffset(); + String absString = ""; + if (baseSymbol.isPinned()) { + absString = "absolute "; + } + log.appendMsg( + "Using " + absString + symbolName + " of 0x" + Integer.toHexString(baseOffset)); + return baseOffset; + } + + Memory mem = program.getMemory(); + AddressSpace defaultSpace = program.getAddressFactory().getDefaultAddressSpace(); + AddressSet blockSet = new AddressSet(); + for (String blockName : blockNames) { + MemoryBlock block = mem.getBlock(blockName); + if (block != null) { + if (!block.getStart().getAddressSpace().equals(defaultSpace)) { + log.appendMsg("ERROR: " + blockName + " not in default space"); + return -1; + } + blockSet.add(block.getStart(), block.getEnd()); + } + } + if (blockSet.isEmpty()) { + return -1; + } + + Address baseAddr = blockSet.getMinAddress(); + long range = blockSet.getMaxAddress().subtract(baseAddr) + 1; + if (range > Short.MAX_VALUE) { + // use aligned midpoint of range + baseAddr = baseAddr.add((range / 2) & ~0x0f); + } + + try { + program.getSymbolTable().createLabel(baseAddr, symbolName, SourceType.ANALYSIS); + } + catch (InvalidInputException e) { + throw new AssertException(e); + } + + int baseOffset = (int) baseAddr.getOffset(); + log.appendMsg("Defined " + symbolName + " of 0x" + Integer.toHexString(baseOffset)); + return baseOffset; + } + +} diff --git a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationHandler.java b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationHandler.java index 5fa207189d..3680866b10 100644 --- a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationHandler.java +++ b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationHandler.java @@ -15,26 +15,32 @@ */ package ghidra.app.util.bin.format.elf.relocation; -import java.math.BigInteger; import java.util.Map; -import com.google.common.base.Predicate; - import ghidra.app.util.bin.format.elf.*; import ghidra.app.util.bin.format.elf.extend.PowerPC_ElfExtension; -import ghidra.app.util.importer.MessageLog; -import ghidra.program.model.address.*; -import ghidra.program.model.lang.Language; -import ghidra.program.model.lang.Register; -import ghidra.program.model.listing.ContextChangeException; +import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.*; import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.reloc.RelocationResult; -import ghidra.program.model.symbol.*; -import ghidra.util.exception.*; -public class PowerPC_ElfRelocationHandler extends ElfRelocationHandler { +public class PowerPC_ElfRelocationHandler extends + AbstractElfRelocationHandler { + + // Masks for manipulating Power PC relocation targets + private static final int PPC_WORD32 = 0xFFFFFFFF; + private static final int PPC_WORD30 = 0xFFFFFFFC; + private static final int PPC_LOW24 = 0x03FFFFFC; + private static final int PPC_LOW14 = 0x0020FFFC; + private static final int PPC_HALF16 = 0xFFFF; + + /** + * Constructor + */ + public PowerPC_ElfRelocationHandler() { + super(PowerPC_ElfRelocationType.class); + } @Override public boolean canRelocate(ElfHeader elf) { @@ -48,43 +54,19 @@ public class PowerPC_ElfRelocationHandler extends ElfRelocationHandler { } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, - Address relocationAddress) throws MemoryAccessException, NotFoundException { + protected RelocationResult relocate(PowerPC_ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, PowerPC_ElfRelocationType type, Address relocationAddress, + ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { - PowerPC_ElfRelocationContext ppcRelocationContext = - (PowerPC_ElfRelocationContext) elfRelocationContext; - - ElfHeader elf = ppcRelocationContext.getElfHeader(); - if (elf.e_machine() != ElfConstants.EM_PPC || !elf.is32Bit()) { - return RelocationResult.FAILURE; - } - - Program program = ppcRelocationContext.getProgram(); + Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); - int type = relocation.getType(); - if (type == PowerPC_ElfRelocationConstants.R_PPC_NONE) { - return RelocationResult.SKIPPED; - } int symbolIndex = relocation.getSymbolIndex(); - Language language = ppcRelocationContext.getProgram().getLanguage(); - if (!"PowerPC".equals(language.getProcessor().toString()) || - language.getLanguageDescription().getSize() != 32) { - markAsError(program, relocationAddress, Long.toString(type), null, - "Unsupported language for 32-bit PowerPC relocation", - ppcRelocationContext.getLog()); - // TODO: should we return failure status? - } - // NOTE: Based upon glibc source it appears that PowerPC only uses RELA relocations int addend = (int) relocation.getAddend(); - int offset = (int) relocationAddress.getOffset(); - - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null - // if (sym.isLocal() && sym.getSectionHeaderIndex() != ElfSectionHeaderConstants.SHN_UNDEF) { // // // see glibc - sysdeps/powerpc/powerpc32/dl-machine.h elf_machine_rela @@ -93,49 +75,44 @@ public class PowerPC_ElfRelocationHandler extends ElfRelocationHandler { // // // Relocation addend already includes original symbol value but needs to account // // for any image base adjustment -// symbolValue = (int) ppcRelocationContext.getImageBaseWordAdjustmentOffset(); +// symbolValue = elfRelocationContext.getImageBaseWordAdjustmentOffset(); // } -// else { - Address symbolAddr = (elfRelocationContext.getSymbolAddress(sym)); - int symbolValue = (int) elfRelocationContext.getSymbolValue(sym); -// } - String symbolName = elfRelocationContext.getSymbolName(symbolIndex); + int offset = (int) relocationAddress.getOffset(); int oldValue = memory.getInt(relocationAddress); int newValue = 0; - int byteLength = 4; // most relocations affect 4-bytes (change if different) switch (type) { - case PowerPC_ElfRelocationConstants.R_PPC_COPY: - markAsWarning(program, relocationAddress, "R_PPC_COPY", symbolName, - symbolIndex, "Runtime copy not supported", elfRelocationContext.getLog()); + case R_PPC_COPY: + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, + "Runtime copy not supported", elfRelocationContext.getLog()); return RelocationResult.SKIPPED; - case PowerPC_ElfRelocationConstants.R_PPC_ADDR32: - case PowerPC_ElfRelocationConstants.R_PPC_UADDR32: - case PowerPC_ElfRelocationConstants.R_PPC_GLOB_DAT: - newValue = symbolValue + addend; + case R_PPC_ADDR32: + case R_PPC_UADDR32: + case R_PPC_GLOB_DAT: + newValue = (int) symbolValue + addend; memory.setInt(relocationAddress, newValue); if (symbolIndex != 0 && addend != 0 && !sym.isSection()) { - warnExternalOffsetRelocation(program, relocationAddress, - symbolAddr, symbolName, addend, elfRelocationContext.getLog()); + warnExternalOffsetRelocation(program, relocationAddress, symbolAddr, symbolName, + addend, elfRelocationContext.getLog()); applyComponentOffsetPointer(program, relocationAddress, addend); } break; - case PowerPC_ElfRelocationConstants.R_PPC_ADDR24: - newValue = (symbolValue + addend) >> 2; - newValue = (oldValue & ~PowerPC_ElfRelocationConstants.PPC_LOW24) | (newValue << 2); + case R_PPC_ADDR24: + newValue = ((int) symbolValue + addend) >> 2; + newValue = (oldValue & ~PPC_LOW24) | (newValue << 2); memory.setInt(relocationAddress, newValue); break; - case PowerPC_ElfRelocationConstants.R_PPC_ADDR16: - case PowerPC_ElfRelocationConstants.R_PPC_UADDR16: - case PowerPC_ElfRelocationConstants.R_PPC_ADDR16_LO: - newValue = symbolValue + addend; + case R_PPC_ADDR16: + case R_PPC_UADDR16: + case R_PPC_ADDR16_LO: + newValue = (int) symbolValue + addend; memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; - case PowerPC_ElfRelocationConstants.R_PPC_ADDR16_HI: - newValue = (symbolValue + addend) >> 16; + case R_PPC_ADDR16_HI: + newValue = ((int) symbolValue + addend) >> 16; memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; @@ -168,44 +145,43 @@ public class PowerPC_ElfRelocationHandler extends ElfRelocationHandler { */ - case PowerPC_ElfRelocationConstants.R_PPC_ADDR16_HA: - newValue = (symbolValue + addend + 0x8000) >> 16; + case R_PPC_ADDR16_HA: + newValue = ((int) symbolValue + addend + 0x8000) >> 16; memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; - case PowerPC_ElfRelocationConstants.R_PPC_ADDR14: - case PowerPC_ElfRelocationConstants.R_PPC_ADDR14_BRTAKEN: - case PowerPC_ElfRelocationConstants.R_PPC_ADDR14_BRNTAKEN: - newValue = (symbolValue + addend) >> 2; - newValue = (oldValue & ~PowerPC_ElfRelocationConstants.PPC_LOW14) | - ((newValue << 2) & PowerPC_ElfRelocationConstants.PPC_LOW24); + case R_PPC_ADDR14: + case R_PPC_ADDR14_BRTAKEN: + case R_PPC_ADDR14_BRNTAKEN: + newValue = ((int) symbolValue + addend) >> 2; + newValue = (oldValue & ~PPC_LOW14) | ((newValue << 2) & PPC_LOW24); memory.setInt(relocationAddress, newValue); break; - case PowerPC_ElfRelocationConstants.R_PPC_REL24: - newValue = (symbolValue + addend - offset) >> 2; - newValue = ((newValue << 2) & PowerPC_ElfRelocationConstants.PPC_LOW24); - newValue = (oldValue & ~PowerPC_ElfRelocationConstants.PPC_LOW24) | newValue; + case R_PPC_REL24: + newValue = ((int) symbolValue + addend - offset) >> 2; + newValue = ((newValue << 2) & PPC_LOW24); + newValue = (oldValue & ~PPC_LOW24) | newValue; memory.setInt(relocationAddress, newValue); break; - case PowerPC_ElfRelocationConstants.R_PPC_RELATIVE: - newValue = (int) ppcRelocationContext.getImageBaseWordAdjustmentOffset() + addend; + case R_PPC_RELATIVE: + newValue = (int) elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend; memory.setInt(relocationAddress, newValue); break; - case PowerPC_ElfRelocationConstants.R_PPC_REL32: - newValue = (symbolValue + addend - offset); + case R_PPC_REL32: + newValue = ((int) symbolValue + addend - offset); memory.setInt(relocationAddress, newValue); break; - case PowerPC_ElfRelocationConstants.R_PPC_REL14: - case PowerPC_ElfRelocationConstants.R_PPC_REL14_BRTAKEN: - case PowerPC_ElfRelocationConstants.R_PPC_REL14_BRNTAKEN: - newValue = (symbolValue + addend - offset) >> 2; - newValue = (oldValue & ~PowerPC_ElfRelocationConstants.PPC_LOW14) | - ((newValue << 2) & PowerPC_ElfRelocationConstants.PPC_LOW14); + case R_PPC_REL14: + case R_PPC_REL14_BRTAKEN: + case R_PPC_REL14_BRNTAKEN: + newValue = ((int) symbolValue + addend - offset) >> 2; + newValue = (oldValue & ~PPC_LOW14) | ((newValue << 2) & PPC_LOW14); memory.setInt(relocationAddress, newValue); break; - case PowerPC_ElfRelocationConstants.R_PPC_JMP_SLOT: - int value = symbolValue + addend; - ElfDynamicTable dynamicTable = elf.getDynamicTable(); + case R_PPC_JMP_SLOT: + int value = (int) symbolValue + addend; + ElfDynamicTable dynamicTable = + elfRelocationContext.getElfHeader().getDynamicTable(); if (dynamicTable != null && dynamicTable.containsDynamicValue(PowerPC_ElfExtension.DT_PPC_GOT)) { // Old ABI - presence of dynamic entry DT_PPC_GOT used as indicator @@ -228,11 +204,11 @@ public class PowerPC_ElfRelocationHandler extends ElfRelocationHandler { // not too far away since a fabricated GOT would be in the same block // and we may only have room in the plt for two instructions. markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, - ppcRelocationContext.getLog()); + elfRelocationContext.getLog()); return RelocationResult.FAILURE; } break; - case PowerPC_ElfRelocationConstants.R_PPC_EMB_SDA21: + case R_PPC_EMB_SDA21: // NOTE: PPC EABI V1.0 specifies this relocation on a 24-bit field address while // GNU assumes a 32-bit field address. We cope with this difference by // forcing a 32-bit alignment of the relocation address. @@ -241,7 +217,7 @@ public class PowerPC_ElfRelocationHandler extends ElfRelocationHandler { oldValue = memory.getInt(relocationAddress); - Address symAddr = ppcRelocationContext.getSymbolAddress(sym); + Address symAddr = elfRelocationContext.getSymbolAddress(sym); MemoryBlock block = memory.getBlock(symAddr); Integer sdaBase = null; Integer gprID = null; @@ -249,11 +225,11 @@ public class PowerPC_ElfRelocationHandler extends ElfRelocationHandler { if (block != null) { String blockName = block.getName(); if (".sdata".equals(blockName) || ".sbss".equals(blockName)) { - sdaBase = ppcRelocationContext.getSDABase(); + sdaBase = elfRelocationContext.getSDABase(); gprID = 13; } else if (".sdata2".equals(blockName) || ".sbss2".equals(blockName)) { - sdaBase = ppcRelocationContext.getSDA2Base(); + sdaBase = elfRelocationContext.getSDA2Base(); gprID = 2; } else if (".PPC.EMB.sdata0".equals(blockName) || @@ -262,19 +238,19 @@ public class PowerPC_ElfRelocationHandler extends ElfRelocationHandler { gprID = 0; } else if (MemoryBlock.EXTERNAL_BLOCK_NAME.equals(blockName)) { - markAsError(program, relocationAddress, type, symbolName, + markAsError(program, relocationAddress, type, symbolName, symbolIndex, "Unsupported relocation for external symbol", - ppcRelocationContext.getLog()); + elfRelocationContext.getLog()); return RelocationResult.FAILURE; } } if (gprID == null || sdaBase == null) { - markAsError(program, relocationAddress, type, symbolName, - "Failed to identfy appropriate data block", ppcRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to identfy appropriate data block", elfRelocationContext.getLog()); return RelocationResult.FAILURE; } - newValue = (symbolValue - sdaBase + addend) & 0xffff; + newValue = ((int) symbolValue - sdaBase + addend) & 0xffff; newValue |= gprID << 16; newValue |= oldValue & 0xffe00000; memory.setInt(relocationAddress, newValue); @@ -282,147 +258,10 @@ public class PowerPC_ElfRelocationHandler extends ElfRelocationHandler { default: markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, - ppcRelocationContext.getLog()); + elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; } return new RelocationResult(Status.APPLIED, byteLength); } - /** - * PowerPC_ElfRelocationContext provides extended relocation context.. - */ - private static class PowerPC_ElfRelocationContext extends ElfRelocationContext { - - private Integer sdaBase; - private Integer sda2Base; - - protected PowerPC_ElfRelocationContext(ElfRelocationHandler handler, - ElfLoadHelper loadHelper, Map symbolMap) { - super(handler, loadHelper, symbolMap); - } - - /** - * Get or establish _SDA_BASE_ value and apply as r13 context value to all memory blocks - * with execute permission. - * @return _SDA_BASE_ offset or null if unable to determine or establish - */ - Integer getSDABase() { - if (sdaBase != null) { - if (sdaBase == -1) { - return null; - } - return sdaBase; - } - sdaBase = getBaseOffset("_SDA_BASE_", ".sdata", ".sbss"); - if (sdaBase == -1) { - getLog().appendMsg("ERROR: failed to establish _SDA_BASE_"); - return null; - } - setRegisterContext("r13", BigInteger.valueOf(sdaBase), b -> b.isExecute()); - return sdaBase; - } - - /** - * Get or establish _SDA2_BASE_ value and apply as r2 context value to all memory blocks - * with execute permission. - * @return _SDA2_BASE_ offset or null if unable to determine or establish - */ - Integer getSDA2Base() { - if (sda2Base != null) { - if (sda2Base == -1) { - return null; - } - return sda2Base; - } - sda2Base = getBaseOffset("_SDA2_BASE_", ".sdata2", ".sbss2"); - if (sda2Base == -1) { - getLog().appendMsg("ERROR: failed to establish _SDA2_BASE_"); - return null; - } - setRegisterContext("r2", BigInteger.valueOf(sda2Base), b -> b.isExecute()); - return sda2Base; - } - - /** - * Apply register context to all memory blocks which satisfy blockPredicate check. - * @param regName register name - * @param value context value - * @param blockPredicate determine which memory blocks get context applied - */ - private void setRegisterContext(String regName, BigInteger value, - Predicate blockPredicate) { - Register reg = program.getRegister(regName); - for (MemoryBlock block : program.getMemory().getBlocks()) { - if (block.isExecute()) { - try { - program.getProgramContext().setValue(reg, block.getStart(), block.getEnd(), - value); - } - catch (ContextChangeException e) { - throw new AssertException(e); // no instructions should exist yet - } - } - } - } - - /** - * Establish base offset from symbol or range of specified memory blocks. - * @param symbolName base symbol name - * @param blockNames block names which may be used to establish base range - * @return base offset or -1 on failure - */ - private Integer getBaseOffset(String symbolName, String... blockNames) { - - MessageLog log = getLog(); - - Symbol baseSymbol = SymbolUtilities.getLabelOrFunctionSymbol(program, symbolName, - msg -> log.appendMsg(msg)); - if (baseSymbol != null) { - int baseOffset = (int) baseSymbol.getAddress().getOffset(); - String absString = ""; - if (baseSymbol.isPinned()) { - absString = "absolute "; - } - log.appendMsg( - "Using " + absString + symbolName + " of 0x" + Integer.toHexString(baseOffset)); - return baseOffset; - } - - Memory mem = program.getMemory(); - AddressSpace defaultSpace = program.getAddressFactory().getDefaultAddressSpace(); - AddressSet blockSet = new AddressSet(); - for (String blockName : blockNames) { - MemoryBlock block = mem.getBlock(blockName); - if (block != null) { - if (!block.getStart().getAddressSpace().equals(defaultSpace)) { - log.appendMsg("ERROR: " + blockName + " not in default space"); - return -1; - } - blockSet.add(block.getStart(), block.getEnd()); - } - } - if (blockSet.isEmpty()) { - return -1; - } - - Address baseAddr = blockSet.getMinAddress(); - long range = blockSet.getMaxAddress().subtract(baseAddr) + 1; - if (range > Short.MAX_VALUE) { - // use aligned midpoint of range - baseAddr = baseAddr.add((range / 2) & ~0x0f); - } - - try { - program.getSymbolTable().createLabel(baseAddr, symbolName, SourceType.ANALYSIS); - } - catch (InvalidInputException e) { - throw new AssertException(e); - } - - int baseOffset = (int) baseAddr.getOffset(); - log.appendMsg("Defined " + symbolName + " of 0x" + Integer.toHexString(baseOffset)); - return baseOffset; - } - - } } diff --git a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationType.java b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationType.java new file mode 100644 index 0000000000..d69b695596 --- /dev/null +++ b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationType.java @@ -0,0 +1,149 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum PowerPC_ElfRelocationType implements ElfRelocationType { + + R_PPC_NONE(0), + R_PPC_ADDR32(1), // word32 S + A + R_PPC_ADDR24(2), // low24 (S + A) >> 2 + R_PPC_ADDR16(3), // half16 S + A + R_PPC_ADDR16_LO(4), // half16 #lo(S + A) + R_PPC_ADDR16_HI(5), // half16 #hi(S + A) + R_PPC_ADDR16_HA(6), // half16 #ha(S + A) + R_PPC_ADDR14(7), // low14 (S + A) >> 2 + R_PPC_ADDR14_BRTAKEN(8), // low14 (S + A) >> 2 + R_PPC_ADDR14_BRNTAKEN(9), // low14 (S + A) >> 2 + R_PPC_REL24(10), // low24 (S + A - P) >> 2 + R_PPC_REL14(11), // low14 (S + A - P) >> 2 + R_PPC_REL14_BRTAKEN(12), // low14 (S + A - P) >> 2 + R_PPC_REL14_BRNTAKEN(13), // low14 (S + A - P) >> 2 + R_PPC_GOT16(14), // half16 G + A + R_PPC_GOT16_LO(15), // half16 #lo(G + A) + R_PPC_GOT16_HI(16), // half16 #hi(G + A) + R_PPC_GOT16_HA(17), // half16 #ha(G + A) + R_PPC_PLTREL24(18), // low24 (L + A + P) >> 2 + R_PPC_COPY(19), // none none + R_PPC_GLOB_DAT(20), // word32 S + A + R_PPC_JMP_SLOT(21), // Old ABI: word32 S + A, New ABI: generate branch instruction + R_PPC_RELATIVE(22), // word32 S + A + R_PPC_LOCAL24PC(23), // none + R_PPC_UADDR32(24), // low24 + R_PPC_UADDR16(25), // half16 S + A + R_PPC_REL32(26), // word32 S + A - P + R_PPC_PLT32(27), // word32 L + A + R_PPC_PLTREL32(28), // word32 L + A - P + R_PPC_PLT16_LO(29), // half16 #lo(L + A) + R_PPC_PLT16_HI(30), // half16 #hi(L + A) + R_PPC_PLT16_HA(31), // half16 #ha(L + A) + R_PPC_SDAREL16(32), // half16 S + A - _SDA_BASE_ + R_PPC_SECTOFF(33), // half16 R + A + R_PPC_SECTOFF_LO(34), // half16 #lo(R + A) + R_PPC_SECTOFF_HI(35), // half16 #hi(R + A) + R_PPC_SECTOFF_HA(36), // half16 #ha(R + A) + R_PPC_ADDR30(37), // word30 (S + A - P) >> 2 + + R_POWERPC_TLS(67), + R_POWERPC_DTPMOD(68), + R_POWERPC_TPREL16(69), + R_POWERPC_TPREL16_LO(70), + R_POWERPC_TPREL16_HI(71), + R_POWERPC_TPREL16_HA(72), + R_POWERPC_TPREL(73), + R_POWERPC_DTPREL16(74), + R_POWERPC_DTPREL16_LO(75), + R_POWERPC_DTPREL16_HI(76), + R_POWERPC_DTPREL16_HA(77), + R_POWERPC_DTPREL(78), + R_POWERPC_GOT_TLSGD16(79), + R_POWERPC_GOT_TLSGD16_LO(80), + R_POWERPC_GOT_TLSGD16_HI(81), + R_POWERPC_GOT_TLSGD16_HA(82), + R_POWERPC_GOT_TLSLD16(83), + R_POWERPC_GOT_TLSLD16_LO(84), + R_POWERPC_GOT_TLSLD16_HI(85), + R_POWERPC_GOT_TLSLD16_HA(86), + R_POWERPC_GOT_TPREL16(87), + R_POWERPC_GOT_TPREL16_LO(88), + R_POWERPC_GOT_TPREL16_HI(89), + R_POWERPC_GOT_TPREL16_HA(90), + R_POWERPC_GOT_DTPREL16(91), + R_POWERPC_GOT_DTPREL16_LO(92), + R_POWERPC_GOT_DTPREL16_HI(93), + R_POWERPC_GOT_DTPREL16_HA(94), + R_PPC_TLSGD(95), + R_PPC_TLSLD(96), + + R_PPC_EMB_NADDR32(101), // uword32 (A - S) + R_PPC_EMB_NADDR16(102), // uhalf16 (A - S) + R_PPC_EMB_NADDR16_LO(103), // uhalf16 #lo(A - S) + R_PPC_EMB_NADDR16_HI(104), // uhalf16 #hi(A - S) + R_PPC_EMB_NADDR16_HA(105), // uhalf16 #ha(A - S) + R_PPC_EMB_SDAI16(106), // uhalf16 T + R_PPC_EMB_SDA2I16(107), // uhalf16 U + R_PPC_EMB_SDA2REL(108), // uhalf16 S + A - _SDA2_BASE_ + R_PPC_EMB_SDA21(109), // ulow21 + R_PPC_EMB_MRKREF(110), // none + R_PPC_EMB_RELSEC16(111), // uhalf16 V + A + R_PPC_EMB_RELST_LO(112), // uhalf16 #lo(W + A) + R_PPC_EMB_RELST_HI(113), // uhalf16 #hi(W + A) + R_PPC_EMB_RELST_HA(114), // uhalf16 #ha(W + A) + R_PPC_EMB_BIT_FLD(115), // uword32 + R_PPC_EMB_RELSDA(116), // uhalf16 + + R_POWERPC_PLTSEQ(119), + R_POWERPC_PLTCALL(120), + + R_PPC_VLE_REL8(216), + R_PPC_VLE_REL15(217), + R_PPC_VLE_REL24(218), + R_PPC_VLE_LO16A(219), + R_PPC_VLE_LO16D(220), + R_PPC_VLE_HI16A(221), + R_PPC_VLE_HI16D(222), + R_PPC_VLE_HA16A(223), + R_PPC_VLE_HA16D(224), + R_PPC_VLE_SDA21(225), + R_PPC_VLE_SDA21_LO(226), + R_PPC_VLE_SDAREL_LO16A(227), + R_PPC_VLE_SDAREL_LO16D(228), + R_PPC_VLE_SDAREL_HI16A(229), + R_PPC_VLE_SDAREL_HI16D(230), + R_PPC_VLE_SDAREL_HA16A(231), + R_PPC_VLE_SDAREL_HA16D(232), + + R_POWERPC_REL16DX_HA(246), + R_POWERPC_IRELATIVE(248), + R_POWERPC_REL16(249), + R_POWERPC_REL16_LO(250), + R_POWERPC_REL16_HI(251), + R_POWERPC_REL16_HA(252), + R_POWERPC_GNU_VTINHERIT(253), + R_POWERPC_GNU_VTENTRY(254), + R_PPC_TOC16(255); + + public final int typeId; + + private PowerPC_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } + +} diff --git a/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationConstants.java b/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationConstants.java deleted file mode 100644 index 2d39f5d500..0000000000 --- a/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationConstants.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ghidra.app.util.bin.format.elf.relocation; - -public class RISCV_ElfRelocationConstants { - - /* - * A Addend field in the relocation entry associated with the symbol - * B Base address of a shared object loaded into memory - * G Offset of the symbol into the GOT (Global Offset Table) - * S Value of the symbol in the symbol table - * GP Global Pointer register (x3) - */ - public static final int R_RISCV_NONE = 0; // None - public static final int R_RISCV_32 = 1; // Runtime relocation word32 = S + A - public static final int R_RISCV_64 = 2; // Runtime relocation word64 = S + A - public static final int R_RISCV_RELATIVE = 3; // Runtime relocation word32,64 = B + A - public static final int R_RISCV_COPY = 4; // Runtime relocation must be in executable. not allowed in shared library - public static final int R_RISCV_JUMP_SLOT = 5; // Runtime relocation word32,64 = S ;handled by PLT unless LD_BIND_NOW - public static final int R_RISCV_TLS_DTPMOD32 = 6; // TLS relocation word32 = S->TLSINDEX - public static final int R_RISCV_TLS_DTPMOD64 = 7; // TLS relocation word64 = S->TLSINDEX - public static final int R_RISCV_TLS_DTPREL32 = 8; // TLS relocation word32 = TLS + S + A - TLS_TP_OFFSET - public static final int R_RISCV_TLS_DTPREL64 = 9; // TLS relocation word64 = TLS + S + A - TLS_TP_OFFSET - public static final int R_RISCV_TLS_TPREL32 = 10; // TLS relocation word32 = TLS + S + A + S_TLS_OFFSET - TLS_DTV_OFFSET - public static final int R_RISCV_TLS_TPREL64 = 11; // TLS relocation word64 = TLS + S + A + S_TLS_OFFSET - TLS_DTV_OFFSET - public static final int R_RISCV_BRANCH = 16; // PC-relative branch (SB-Type) - public static final int R_RISCV_JAL = 17; // PC-relative jump (UJ-Type) - public static final int R_RISCV_CALL = 18; // PC-relative call MACRO call,tail (auipc+jalr pair) - public static final int R_RISCV_CALL_PLT = 19; // PC-relative call (PLT) MACRO call,tail (auipc+jalr pair) PIC - public static final int R_RISCV_GOT_HI20 = 20; // PC-relative GOT reference MACRO la - public static final int R_RISCV_TLS_GOT_HI20 = 21; // PC-relative TLS IE GOT offset MACRO la.tls.ie - public static final int R_RISCV_TLS_GD_HI20 = 22; // PC-relative TLS GD reference MACRO la.tls.gd - public static final int R_RISCV_PCREL_HI20 = 23; // PC-relative reference %pcrel_hi(symbol) (U-Type) - public static final int R_RISCV_PCREL_LO12_I = 24; // PC-relative reference %pcrel_lo(symbol) (I-Type) - public static final int R_RISCV_PCREL_LO12_S = 25; // PC-relative reference %pcrel_lo(symbol) (S-Type) - public static final int R_RISCV_HI20 = 26; // Absolute address %hi(symbol) (U-Type) - public static final int R_RISCV_LO12_I = 27; // Absolute address %lo(symbol) (I-Type) - public static final int R_RISCV_LO12_S = 28; // Absolute address %lo(symbol) (S-Type) - public static final int R_RISCV_TPREL_HI20 = 29; // TLS LE thread offset %tprel_hi(symbol) (U-Type) - public static final int R_RISCV_TPREL_LO12_I = 30; // TLS LE thread offset %tprel_lo(symbol) (I-Type) - public static final int R_RISCV_TPREL_LO12_S = 31; // TLS LE thread offset %tprel_lo(symbol) (S-Type) - public static final int R_RISCV_TPREL_ADD = 32; // TLS LE thread usage %tprel_add(symbol) - public static final int R_RISCV_ADD8 = 33; // 8-bit label addition word8 = old + S + A - public static final int R_RISCV_ADD16 = 34; // 16-bit label addition word16 = old + S + A - public static final int R_RISCV_ADD32 = 35; // 32-bit label addition word32 = old + S + A - public static final int R_RISCV_ADD64 = 36; // 64-bit label addition word64 = old + S + A - public static final int R_RISCV_SUB8 = 37; // 8-bit label subtraction word8 = old - S - A - public static final int R_RISCV_SUB16 = 38; // 16-bit label subtraction word16 = old - S - A - public static final int R_RISCV_SUB32 = 39; // 32-bit label subtraction word32 = old - S - A - public static final int R_RISCV_SUB64 = 40; // 64-bit label subtraction word64 = old - S - A - public static final int R_RISCV_GNU_VTINHERIT = 41; // GNU C++ vtable hierarchy - public static final int R_RISCV_GNU_VTENTRY = 42; // GNU C++ vtable member usage - public static final int R_RISCV_ALIGN = 43; // Alignment statement - public static final int R_RISCV_RVC_BRANCH = 44; // PC-relative branch offset (CB-Type) - public static final int R_RISCV_RVC_JUMP = 45; // PC-relative jump offset (CJ-Type) - public static final int R_RISCV_RVC_LUI = 46; // Absolute address (CI-Type) - public static final int R_RISCV_GPREL_I = 47; // GP-relative reference (I-Type) - public static final int R_RISCV_GPREL_S = 48; // GP-relative reference (S-Type) - public static final int R_RISCV_TPREL_I = 49; // TP-relative TLS LE load (I-Type) - public static final int R_RISCV_TPREL_S = 50; // TP-relative TLS LE store (S-Type) - public static final int R_RISCV_RELAX = 51; // Instruction pair can be relaxed - public static final int R_RISCV_SUB6 = 52; // Local label subtraction - public static final int R_RISCV_SET6 = 53; // Local label subtraction - public static final int R_RISCV_SET8 = 54; // Local label subtraction - public static final int R_RISCV_SET16 = 55; // Local label subtraction - public static final int R_RISCV_SET32 = 56; // Local label subtraction - public static final int R_RISCV_32_PCREL = 57; // 32-bit PC relative - // 58-191 Reserved Reserved for future standard use - // 192-255 Reserved Reserved for nonstandard ABI extensions -} diff --git a/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationContext.java b/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationContext.java index c423f4ed6a..090ceab974 100644 --- a/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationContext.java +++ b/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationContext.java @@ -20,10 +20,10 @@ import java.util.*; import ghidra.app.util.bin.format.elf.*; import ghidra.program.model.address.Address; -class RISCV_ElfRelocationContext extends ElfRelocationContext { +class RISCV_ElfRelocationContext extends ElfRelocationContext { - protected RISCV_ElfRelocationContext(ElfRelocationHandler handler, ElfLoadHelper loadHelper, - Map symbolMap) { + protected RISCV_ElfRelocationContext(RISCV_ElfRelocationHandler handler, + ElfLoadHelper loadHelper, Map symbolMap) { super(handler, loadHelper, symbolMap); } @@ -72,9 +72,9 @@ class RISCV_ElfRelocationContext extends ElfRelocationContext { } // look for hi20 relocation while (relIndex < relocations.length && relocations[relIndex].getOffset() == symValue) { - int type = relocations[relIndex].getType(); - if ((type == RISCV_ElfRelocationConstants.R_RISCV_PCREL_HI20) || - (type == RISCV_ElfRelocationConstants.R_RISCV_GOT_HI20)) { + int typeId = relocations[relIndex].getType(); + if ((typeId == RISCV_ElfRelocationType.R_RISCV_PCREL_HI20.typeId) || + (typeId == RISCV_ElfRelocationType.R_RISCV_GOT_HI20.typeId)) { return relocations[relIndex]; } ++relIndex; diff --git a/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationHandler.java b/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationHandler.java index a09e402637..36193deaa3 100644 --- a/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationHandler.java +++ b/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationHandler.java @@ -24,14 +24,16 @@ import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.reloc.RelocationResult; -import ghidra.util.exception.NotFoundException; /** - * See https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc for information on the different riscv elf - * relocation types. Different relocation types are found in different contexts - not all of which are currently handled here. + * See https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc for + * information on the different RISCV ELF relocation types. Different relocation types are found + * in different contexts - not all of which are currently handled here. + * * The contexts we *attempt* to handle include: * - * 1. fully linked Elf executables like the Linux `cp` utility which rely on dynamic linking to libraries like libc.so.6 + * 1. fully linked Elf executables like the Linux `cp` utility which rely on dynamic linking to + * libraries like libc.so.6 * 2. object files compiled with or without Position Independent code (`-fpic`) support * 3. Sharable object libraries like `libc.so.6` * 3. kernel load modules compiled with position independent code (`-fpic`) support @@ -39,13 +41,24 @@ import ghidra.util.exception.NotFoundException; * Keep in mind: * * 1. You may find multiple relocations at any single address. - * 2. Many relocations and relocation variants are there to support linker/loader optimizations unneeded by Ghidra. - * 3. Some relocations can only name their target indirectly. R_RISCV_PCREL_LO12_I references a R_RISCV_PCREL_HI20 relocation, - * but needs the symbol referenced by that R_RISCV_PCREL_HI20 in order to compute a PC relative offset. - * 4. Many discrete symbols can share the same symbol name, e.g. `.L0`. These symbol names can include non-printing characters like `".L0^B2"` + * 2. Many relocations and relocation variants are there to support linker/loader optimizations + * unneeded by Ghidra. + * 3. Some relocations can only name their target indirectly. R_RISCV_PCREL_LO12_I references + * a R_RISCV_PCREL_HI20 relocation, but needs the symbol referenced by that R_RISCV_PCREL_HI20 + * in order to compute a PC relative offset. + * 4. Many discrete symbols can share the same symbol name, e.g. `.L0`. These symbol names can + * include non-printing characters like `".L0^B2"` * */ -public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { +public class RISCV_ElfRelocationHandler + extends AbstractElfRelocationHandler { + + /** + * Constructor + */ + public RISCV_ElfRelocationHandler() { + super(RISCV_ElfRelocationType.class); + } @Override public boolean canRelocate(ElfHeader elf) { @@ -94,11 +107,10 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { * actual address offet within the target program. * @return the 32-bit HI20 relative offset value or 0 if HI20 relocation not found */ - private static int getSymbolValueIndirect(ElfRelocationContext elfRelocationContext, + private static int getSymbolValueIndirect(RISCV_ElfRelocationContext elfRelocationContext, ElfSymbol hi20Symbol, long relocAddrOffsetAdj) { - RISCV_ElfRelocationContext relocContext = (RISCV_ElfRelocationContext) elfRelocationContext; - ElfRelocation hi20Reloc = relocContext.getHi20Relocation(hi20Symbol); + ElfRelocation hi20Reloc = elfRelocationContext.getHi20Relocation(hi20Symbol); if (hi20Reloc == null) { return 0; } @@ -118,36 +130,25 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, Address relocationAddress) - throws MemoryAccessException, NotFoundException { - ElfHeader elf = elfRelocationContext.getElfHeader(); - if (!canRelocate(elf)) { - return RelocationResult.FAILURE; - } + protected RelocationResult relocate(RISCV_ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, RISCV_ElfRelocationType type, Address relocationAddress, + ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { if (!relocation.hasAddend()) { // Implementation only supports Elf_Rela relocations for RISCV return RelocationResult.UNSUPPORTED; } + ElfHeader elf = elfRelocationContext.getElfHeader(); Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); - boolean is32 = elf.is32Bit(); - int type = relocation.getType(); - if (RISCV_ElfRelocationConstants.R_RISCV_NONE == type) { - return RelocationResult.SKIPPED; - } long addend = relocation.getAddend(); long offset = relocationAddress.getOffset(); long base = elfRelocationContext.getImageBaseWordAdjustmentOffset(); int symbolIndex = relocation.getSymbolIndex(); - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); - Address symbolAddr = elfRelocationContext.getSymbolAddress(sym); - long symbolValue = elfRelocationContext.getSymbolValue(sym); - String symbolName = elfRelocationContext.getSymbolName(symbolIndex); long value64 = 0; int value32 = 0; @@ -158,7 +159,7 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { int byteLength = 4; // most relocations affect 4-bytes (change if different) switch (type) { - case RISCV_ElfRelocationConstants.R_RISCV_32: + case R_RISCV_32: // Runtime relocation word32 = S + A value32 = (int) (symbolValue + addend); memory.setInt(relocationAddress, value32); @@ -171,7 +172,7 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { } break; - case RISCV_ElfRelocationConstants.R_RISCV_64: + case R_RISCV_64: // Runtime relocation word64 = S + A value64 = symbolValue + addend; memory.setLong(relocationAddress, value64); @@ -185,9 +186,9 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { } break; - case RISCV_ElfRelocationConstants.R_RISCV_RELATIVE: + case R_RISCV_RELATIVE: // Runtime relocation word32,64 = B + A - if (is32) { + if (elf.is32Bit()) { value32 = (int) (base + addend); memory.setInt(relocationAddress, value32); } @@ -198,15 +199,15 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { } break; - case RISCV_ElfRelocationConstants.R_RISCV_COPY: + case R_RISCV_COPY: // Runtime relocation must be in executable. not allowed in shared library - markAsWarning(program, relocationAddress, "R_RISCV_COPY", symbolName, symbolIndex, - "TODO, needs support ", elfRelocationContext.getLog()); + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, + "Runtime copy not supported", elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; - case RISCV_ElfRelocationConstants.R_RISCV_JUMP_SLOT: + case R_RISCV_JUMP_SLOT: // Runtime relocation word32,64 = S ;handled by PLT unless LD_BIND_NOW - if (is32) { + if (elf.is32Bit()) { value32 = (int) (symbolValue); memory.setInt(relocationAddress, value32); } @@ -217,43 +218,19 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { } break; - case RISCV_ElfRelocationConstants.R_RISCV_TLS_DTPMOD32: - // TLS relocation word32 = S->TLSINDEX - markAsWarning(program, relocationAddress, "R_RISCV_TLS_DTPMOD32", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; +// case R_RISCV_TLS_DTPMOD32: // TLS relocation word32 = S->TLSINDEX +// +// case R_RISCV_TLS_DTPMOD64: // TLS relocation word64 = S->TLSINDEX +// +// case R_RISCV_TLS_DTPREL32: // TLS relocation word32 = TLS + S + A - TLS_TP_OFFSET +// +// case R_RISCV_TLS_DTPREL64: // TLS relocation word64 = TLS + S + A - TLS_TP_OFFSET +// +// case R_RISCV_TLS_TPREL32: // TLS relocation word32 = TLS + S + A + S_TLS_OFFSET - TLS_DTV_OFFSET +// +// case R_RISCV_TLS_TPREL64: // TLS relocation word64 = TLS + S + A + S_TLS_OFFSET - TLS_DTV_OFFSET - case RISCV_ElfRelocationConstants.R_RISCV_TLS_DTPMOD64: - // TLS relocation word64 = S->TLSINDEX - markAsWarning(program, relocationAddress, "R_RISCV_TLS_DTPMOD64", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_TLS_DTPREL32: - // TLS relocation word32 = TLS + S + A - TLS_TP_OFFSET - markAsWarning(program, relocationAddress, "R_RISCV_TLS_DTPREL32", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_TLS_DTPREL64: - // TLS relocation word64 = TLS + S + A - TLS_TP_OFFSET - markAsWarning(program, relocationAddress, "R_RISCV_TLS_DTPREL64", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_TLS_TPREL32: - // TLS relocation word32 = TLS + S + A + S_TLS_OFFSET - TLS_DTV_OFFSET - markAsWarning(program, relocationAddress, "R_RISCV_TLS_TPREL32", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_TLS_TPREL64: - // TLS relocation word64 = TLS + S + A + S_TLS_OFFSET - TLS_DTV_OFFSET - markAsWarning(program, relocationAddress, "R_RISCV_TLS_TPREL64", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_BRANCH: + case R_RISCV_BRANCH: // PC-relative branch (SB-Type) target = (int) (addend + symbolValue - offset); value32 = encodeSBTypeImm(target) | @@ -261,7 +238,7 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, value32); break; - case RISCV_ElfRelocationConstants.R_RISCV_JAL: + case R_RISCV_JAL: // PC-relative jump (UJ-Type) target = (int) (addend + symbolValue - offset); value32 = encodeUJTypeImm(target) | @@ -269,11 +246,11 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, value32); break; - case RISCV_ElfRelocationConstants.R_RISCV_CALL: + case R_RISCV_CALL: // PC-relative call (PLT) MACRO call,tail (auipc+jalr pair) PIC // Identical processing in Ghidra as the following - case RISCV_ElfRelocationConstants.R_RISCV_CALL_PLT: + case R_RISCV_CALL_PLT: // PC-relative call MACRO call,tail (auipc+jalr pair) target = (int) (addend + symbolValue - offset); memory.setInt(relocationAddress, @@ -283,35 +260,26 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 8; break; - case RISCV_ElfRelocationConstants.R_RISCV_TLS_GOT_HI20: - // PC-relative TLS IE GOT offset MACRO la.tls.ie - markAsWarning(program, relocationAddress, "R_RISCV_TLS_GOT_HI20", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; +// case R_RISCV_TLS_GOT_HI20: // PC-relative TLS IE GOT offset MACRO la.tls.ie +// +// case R_RISCV_TLS_GD_HI20: // PC-relative TLS GD reference MACRO la.tls.gd - case RISCV_ElfRelocationConstants.R_RISCV_TLS_GD_HI20: - // PC-relative TLS GD reference MACRO la.tls.gd - markAsWarning(program, relocationAddress, "R_RISCV_TLS_GD_HI20", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_GOT_HI20: + case R_RISCV_GOT_HI20: // PC-relative GOT reference MACRO la - case RISCV_ElfRelocationConstants.R_RISCV_PCREL_HI20: + case R_RISCV_PCREL_HI20: // PC-relative, not tested on 32 bit objects target = (int) (addend + symbolValue - offset); memory.setInt(relocationAddress, getHi20(target) | (memory.getInt(relocationAddress) & 0xfff)); break; - case RISCV_ElfRelocationConstants.R_RISCV_PCREL_LO12_I: + case R_RISCV_PCREL_LO12_I: // PC-relative reference %pcrel_lo(symbol) (I-Type), relative to the cited pc_rel_hi20 target = getSymbolValueIndirect(elfRelocationContext, sym, relocationAddress.getOffset() - relocation.getOffset()); if (target == 0) { - markAsError(program, relocationAddress, type, symbolName, - "Failed to locate HI20 relocation for R_RISCV_PCREL_LO12_I", - elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to locate HI20 relocation", elfRelocationContext.getLog()); return RelocationResult.FAILURE; } value32 = @@ -319,16 +287,15 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, value32); break; - case RISCV_ElfRelocationConstants.R_RISCV_PCREL_LO12_S: + case R_RISCV_PCREL_LO12_S: // PC-relative reference %pcrel_lo(symbol) (S-Type) // S-type immediates split the 12 bit value into separate 7 bit and 5 bit fields. // Warning: untested! target = getSymbolValueIndirect(elfRelocationContext, sym, relocationAddress.getOffset() - relocation.getOffset()); if (target == 0) { - markAsError(program, relocationAddress, type, symbolName, - "Failed to locate HI20 relocation for R_RISCV_PCREL_LO12_S", - elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to locate HI20 relocation", elfRelocationContext.getLog()); return RelocationResult.FAILURE; } value32 = ((target & 0x000007f) << 25) | (target & 0x00000f80) | @@ -336,21 +303,21 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, value32); break; - case RISCV_ElfRelocationConstants.R_RISCV_HI20: + case R_RISCV_HI20: // Absolute address %hi(symbol) (U-Type) value32 = (int) ((symbolValue + 0x800) & 0xfffff000) | (memory.getInt(relocationAddress) & 0xfff); memory.setInt(relocationAddress, value32); break; - case RISCV_ElfRelocationConstants.R_RISCV_LO12_I: + case R_RISCV_LO12_I: // Absolute address %lo(symbol) (I-Type) value32 = ((int) (symbolValue & 0x00000fff) << 20) | (memory.getInt(relocationAddress) & 0xfffff); memory.setInt(relocationAddress, value32); break; - case RISCV_ElfRelocationConstants.R_RISCV_LO12_S: + case R_RISCV_LO12_S: // Absolute address %lo(symbol) (S-Type) value32 = (int) (symbolValue & 0x00000fff); value32 = ((value32 & 0x1f) << 7) | ((value32 & 0xfe0) << 20) | @@ -358,31 +325,15 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, value32); break; - case RISCV_ElfRelocationConstants.R_RISCV_TPREL_HI20: - // TLS LE thread offset %tprel_hi(symbol) (U-Type) - markAsWarning(program, relocationAddress, "R_RISCV_TPREL_HI20", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; +// case R_RISCV_TPREL_HI20: // TLS LE thread offset %tprel_hi(symbol) (U-Type) +// +// case R_RISCV_TPREL_LO12_I: // TLS LE thread offset %tprel_lo(symbol) (I-Type) +// +// case R_RISCV_TPREL_LO12_S: // TLS LE thread offset %tprel_lo(symbol) (S-Type) +// +// case R_RISCV_TPREL_ADD: // TLS LE thread usage %tprel_add(symbol) - case RISCV_ElfRelocationConstants.R_RISCV_TPREL_LO12_I: - // TLS LE thread offset %tprel_lo(symbol) (I-Type) - markAsWarning(program, relocationAddress, "R_RISCV_TPREL_LO12_I", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_TPREL_LO12_S: - // TLS LE thread offset %tprel_lo(symbol) (S-Type) - markAsWarning(program, relocationAddress, "R_RISCV_TPREL_LO12_S", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_TPREL_ADD: - // TLS LE thread usage %tprel_add(symbol) - markAsWarning(program, relocationAddress, "R_RISCV_TPREL_ADD", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_ADD8: + case R_RISCV_ADD8: // 8-bit label addition word8 = old + S + A value8 = memory.getByte(relocationAddress); value8 += (byte) (symbolValue + addend); @@ -390,7 +341,7 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 1; break; - case RISCV_ElfRelocationConstants.R_RISCV_ADD16: + case R_RISCV_ADD16: // 16-bit label addition word16 = old + S + A value16 = memory.getShort(relocationAddress); value16 += (short) (symbolValue + addend); @@ -398,14 +349,14 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 2; break; - case RISCV_ElfRelocationConstants.R_RISCV_ADD32: + case R_RISCV_ADD32: // 32-bit label addition word32 = old + S + A value32 = memory.getInt(relocationAddress); value32 += (int) (symbolValue + addend); memory.setInt(relocationAddress, value32); break; - case RISCV_ElfRelocationConstants.R_RISCV_ADD64: + case R_RISCV_ADD64: // 64-bit label addition word64 = old + S + A value64 = memory.getLong(relocationAddress); value64 += (symbolValue + addend); @@ -413,7 +364,7 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 8; break; - case RISCV_ElfRelocationConstants.R_RISCV_SUB8: + case R_RISCV_SUB8: // 8-bit label subtraction word8 = old - S - A value8 = memory.getByte(relocationAddress); value8 -= (byte) (symbolValue + addend); @@ -421,7 +372,7 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 1; break; - case RISCV_ElfRelocationConstants.R_RISCV_SUB16: + case R_RISCV_SUB16: // 16-bit label subtraction word16 = old - S - A value16 = memory.getShort(relocationAddress); value16 -= (short) (symbolValue + addend); @@ -429,14 +380,14 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 2; break; - case RISCV_ElfRelocationConstants.R_RISCV_SUB32: + case R_RISCV_SUB32: // 32-bit label subtraction word32 = old - S - A value32 = memory.getInt(relocationAddress); value32 -= (int) (symbolValue + addend); memory.setInt(relocationAddress, value32); break; - case RISCV_ElfRelocationConstants.R_RISCV_SUB64: + case R_RISCV_SUB64: // 64-bit label subtraction word64 = old - S - A value64 = memory.getLong(relocationAddress); value64 -= (symbolValue + addend); @@ -444,25 +395,13 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 8; break; - case RISCV_ElfRelocationConstants.R_RISCV_GNU_VTINHERIT: - // GNU C++ vtable hierarchy - markAsWarning(program, relocationAddress, "R_RISCV_GNU_VTINHERIT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; +// case R_RISCV_GNU_VTINHERIT: // GNU C++ vtable hierarchy +// +// case R_RISCV_GNU_VTENTRY: // GNU C++ vtable member usage +// +// case R_RISCV_ALIGN: // Alignment statement - case RISCV_ElfRelocationConstants.R_RISCV_GNU_VTENTRY: - // GNU C++ vtable member usage - markAsWarning(program, relocationAddress, "R_RISCV_GNU_VTENTRY", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_ALIGN: - // Alignment statement - markAsWarning(program, relocationAddress, "R_RISCV_ALIGN", symbolName, symbolIndex, - "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_RVC_BRANCH: { + case R_RISCV_RVC_BRANCH: { // PC-relative branch offset (CB-Type) short target_s = (short) (addend + symbolValue - offset); value16 = (short) (encodeCBTypeImm(target_s) | @@ -472,7 +411,7 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { break; } - case RISCV_ElfRelocationConstants.R_RISCV_RVC_JUMP: { + case R_RISCV_RVC_JUMP: { // PC-relative jump offset (CJ-Type) short target_s = (short) (addend + symbolValue - offset); value16 = (short) (encodeCJTypeImm(target_s) | @@ -482,41 +421,21 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { break; } - case RISCV_ElfRelocationConstants.R_RISCV_RVC_LUI: - // Absolute address (CI-Type) - markAsWarning(program, relocationAddress, "R_RISCV_RVC_LUI", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; +// case R_RISCV_RVC_LUI: // Absolute address (CI-Type) +// +// case R_RISCV_GPREL_I: // GP-relative reference (I-Type) +// +// case R_RISCV_GPREL_S: // GP-relative reference (S-Type) +// +// case R_RISCV_TPREL_I: // TP-relative TLS LE load (I-Type) +// +// case R_RISCV_TPREL_S: // TP-relative TLS LE store (S-Type) - case RISCV_ElfRelocationConstants.R_RISCV_GPREL_I: - // GP-relative reference (I-Type) - markAsWarning(program, relocationAddress, "R_RISCV_GPREL_I", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_GPREL_S: - // GP-relative reference (S-Type) - markAsWarning(program, relocationAddress, "R_RISCV_GPREL_S", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_TPREL_I: - // TP-relative TLS LE load (I-Type) - markAsWarning(program, relocationAddress, "R_RISCV_TPREL_I", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_TPREL_S: - // TP-relative TLS LE store (S-Type) - markAsWarning(program, relocationAddress, "R_RISCV_TPREL_S", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case RISCV_ElfRelocationConstants.R_RISCV_RELAX: + case R_RISCV_RELAX: // Instruction pair can be relaxed by the linker/loader- ignore return RelocationResult.SKIPPED; - case RISCV_ElfRelocationConstants.R_RISCV_SUB6: + case R_RISCV_SUB6: int loc8 = memory.getByte(relocationAddress); value8 = (byte) (symbolValue + addend); value8 = (byte) ((loc8 & 0xc0) | (((loc8 & 0x3f) - value8) & 0x3f)); @@ -524,7 +443,7 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 1; break; - case RISCV_ElfRelocationConstants.R_RISCV_SET6: + case R_RISCV_SET6: loc8 = memory.getByte(relocationAddress); value8 = (byte) (symbolValue + addend); value8 = (byte) ((loc8 & 0xc0) | (value8 & 0x3f)); @@ -532,20 +451,20 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 1; break; - case RISCV_ElfRelocationConstants.R_RISCV_SET8: + case R_RISCV_SET8: value8 = (byte) (symbolValue + addend); memory.setByte(relocationAddress, value8); byteLength = 1; break; - case RISCV_ElfRelocationConstants.R_RISCV_SET16: + case R_RISCV_SET16: value16 = (short) (symbolValue + addend); memory.setShort(relocationAddress, value8); byteLength = 2; break; - case RISCV_ElfRelocationConstants.R_RISCV_32_PCREL: - case RISCV_ElfRelocationConstants.R_RISCV_SET32: + case R_RISCV_32_PCREL: + case R_RISCV_SET32: value32 = (int) (symbolValue + addend); memory.setInt(relocationAddress, value8); break; diff --git a/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationType.java b/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationType.java new file mode 100644 index 0000000000..88d693ad7c --- /dev/null +++ b/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationType.java @@ -0,0 +1,94 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum RISCV_ElfRelocationType implements ElfRelocationType { + + /* + * A Addend field in the relocation entry associated with the symbol + * B Base address of a shared object loaded into memory + * G Offset of the symbol into the GOT (Global Offset Table) + * S Value of the symbol in the symbol table + * GP Global Pointer register (x3) + */ + R_RISCV_NONE(0), // None + R_RISCV_32(1), // Runtime relocation word32(S + A + R_RISCV_64(2), // Runtime relocation word64(S + A + R_RISCV_RELATIVE(3), // Runtime relocation word32,64(B + A + R_RISCV_COPY(4), // Runtime relocation must be in executable. not allowed in shared library + R_RISCV_JUMP_SLOT(5), // Runtime relocation word32,64(S ),handled by PLT unless LD_BIND_NOW + R_RISCV_TLS_DTPMOD32(6), // TLS relocation word32(S->TLSINDEX + R_RISCV_TLS_DTPMOD64(7), // TLS relocation word64(S->TLSINDEX + R_RISCV_TLS_DTPREL32(8), // TLS relocation word32(TLS + S + A - TLS_TP_OFFSET + R_RISCV_TLS_DTPREL64(9), // TLS relocation word64(TLS + S + A - TLS_TP_OFFSET + R_RISCV_TLS_TPREL32(10), // TLS relocation word32(TLS + S + A + S_TLS_OFFSET - TLS_DTV_OFFSET + R_RISCV_TLS_TPREL64(11), // TLS relocation word64(TLS + S + A + S_TLS_OFFSET - TLS_DTV_OFFSET + R_RISCV_BRANCH(16), // PC-relative branch (SB-Type) + R_RISCV_JAL(17), // PC-relative jump (UJ-Type) + R_RISCV_CALL(18), // PC-relative call MACRO call,tail (auipc+jalr pair) + R_RISCV_CALL_PLT(19), // PC-relative call (PLT) MACRO call,tail (auipc+jalr pair) PIC + R_RISCV_GOT_HI20(20), // PC-relative GOT reference MACRO la + R_RISCV_TLS_GOT_HI20(21), // PC-relative TLS IE GOT offset MACRO la.tls.ie + R_RISCV_TLS_GD_HI20(22), // PC-relative TLS GD reference MACRO la.tls.gd + R_RISCV_PCREL_HI20(23), // PC-relative reference %pcrel_hi(symbol) (U-Type) + R_RISCV_PCREL_LO12_I(24), // PC-relative reference %pcrel_lo(symbol) (I-Type) + R_RISCV_PCREL_LO12_S(25), // PC-relative reference %pcrel_lo(symbol) (S-Type) + R_RISCV_HI20(26), // Absolute address %hi(symbol) (U-Type) + R_RISCV_LO12_I(27), // Absolute address %lo(symbol) (I-Type) + R_RISCV_LO12_S(28), // Absolute address %lo(symbol) (S-Type) + R_RISCV_TPREL_HI20(29), // TLS LE thread offset %tprel_hi(symbol) (U-Type) + R_RISCV_TPREL_LO12_I(30), // TLS LE thread offset %tprel_lo(symbol) (I-Type) + R_RISCV_TPREL_LO12_S(31), // TLS LE thread offset %tprel_lo(symbol) (S-Type) + R_RISCV_TPREL_ADD(32), // TLS LE thread usage %tprel_add(symbol) + R_RISCV_ADD8(33), // 8-bit label addition word8(old + S + A + R_RISCV_ADD16(34), // 16-bit label addition word16(old + S + A + R_RISCV_ADD32(35), // 32-bit label addition word32(old + S + A + R_RISCV_ADD64(36), // 64-bit label addition word64(old + S + A + R_RISCV_SUB8(37), // 8-bit label subtraction word8(old - S - A + R_RISCV_SUB16(38), // 16-bit label subtraction word16(old - S - A + R_RISCV_SUB32(39), // 32-bit label subtraction word32(old - S - A + R_RISCV_SUB64(40), // 64-bit label subtraction word64(old - S - A + R_RISCV_GNU_VTINHERIT(41), // GNU C++ vtable hierarchy + R_RISCV_GNU_VTENTRY(42), // GNU C++ vtable member usage + R_RISCV_ALIGN(43), // Alignment statement + R_RISCV_RVC_BRANCH(44), // PC-relative branch offset (CB-Type) + R_RISCV_RVC_JUMP(45), // PC-relative jump offset (CJ-Type) + R_RISCV_RVC_LUI(46), // Absolute address (CI-Type) + R_RISCV_GPREL_I(47), // GP-relative reference (I-Type) + R_RISCV_GPREL_S(48), // GP-relative reference (S-Type) + R_RISCV_TPREL_I(49), // TP-relative TLS LE load (I-Type) + R_RISCV_TPREL_S(50), // TP-relative TLS LE store (S-Type) + R_RISCV_RELAX(51), // Instruction pair can be relaxed + R_RISCV_SUB6(52), // Local label subtraction + R_RISCV_SET6(53), // Local label subtraction + R_RISCV_SET8(54), // Local label subtraction + R_RISCV_SET16(55), // Local label subtraction + R_RISCV_SET32(56), // Local label subtraction + R_RISCV_32_PCREL(57); // 32-bit PC relative + // 58-191 Reserved Reserved for future standard use + // 192-255 Reserved Reserved for nonstandard ABI extensions + + public final int typeId; + + private RISCV_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } +} diff --git a/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationConstants.java b/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationConstants.java deleted file mode 100644 index ac6c789a9c..0000000000 --- a/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationConstants.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.util.bin.format.elf.relocation; - -public class SPARC_ElfRelocationConstants { - - public static final int R_SPARC_NONE = 0; // No calculation - public static final int R_SPARC_5 = 44; // S + A - public static final int R_SPARC_6 = 45; // S + A - public static final int R_SPARC_7 = 43; // S + A - public static final int R_SPARC_8 = 1; // S + A - public static final int R_SPARC_10 = 30; // S + A - public static final int R_SPARC_11 = 31; // S + A - public static final int R_SPARC_13 = 11; // S + A - public static final int R_SPARC_16 = 2; // S + A - public static final int R_SPARC_22 = 10; // S + A - public static final int R_SPARC_32 = 3; // S + A - public static final int R_SPARC_LO10 = 12; // (S + A) & 0x3FF - public static final int R_SPARC_HI22 = 9; // (S + A) >> 10 - public static final int R_SPARC_DISP8 = 4; // S + A - P - public static final int R_SPARC_DISP16 = 5; // S + A - P - public static final int R_SPARC_DISP32 = 6; // S + A - P - public static final int R_SPARC_WDISP16 = 40; // (S + A - P) >> 2 - public static final int R_SPARC_WDISP19 = 41; // (S + A - P) >> 2 - public static final int R_SPARC_WDISP22 = 8; // (S + A - P) >> 2 - public static final int R_SPARC_WDISP30 = 7; // (S + A - P) >> 2 - public static final int R_SPARC_PC10 = 16; // (S + A - P) & 0x3FF - public static final int R_SPARC_PC22 = 17; // (S + A - P) >> 10 - public static final int R_SPARC_PLT32 = 24; // L + A - public static final int R_SPARC_PCPLT10 = 29; // (L + A - P) & 0x3FF - public static final int R_SPARC_PCPLT22 = 28; // (L + A - P) >> 10 - public static final int R_SPARC_PCPLT32 = 27; // L + A - P - public static final int R_SPARC_GOT10 = 13; // G & 0x3FF - public static final int R_SPARC_GOT13 = 14; // G - public static final int R_SPARC_GOT22 = 15; // G >> 10 - public static final int R_SPARC_WPLT30 = 18; // (L + A - P) >> 2 - public static final int R_SPARC_LOPLT10 = 26; // (L + A) & 0x3FF - public static final int R_SPARC_HIPLT22 = 25; // (L + A) >> 10 - - public static final int R_SPARC_JMP_SLOT = 21; - public static final int R_SPARC_UA32 = 23; // S + A - public static final int R_SPARC_GLOB_DAT = 20; // S + A - public static final int R_SPARC_RELATIVE = 22; // B + A - public static final int R_SPARC_COPY = 19; // No calculation - - private SPARC_ElfRelocationConstants() { - // no construct - } -} diff --git a/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationHandler.java b/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationHandler.java index fd888c815e..76c414dc5e 100644 --- a/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationHandler.java +++ b/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationHandler.java @@ -20,11 +20,18 @@ import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryAccessException; -import ghidra.program.model.reloc.RelocationResult; import ghidra.program.model.reloc.Relocation.Status; -import ghidra.util.exception.NotFoundException; +import ghidra.program.model.reloc.RelocationResult; -public class SPARC_ElfRelocationHandler extends ElfRelocationHandler { +public class SPARC_ElfRelocationHandler + extends AbstractElfRelocationHandler> { + + /** + * Constructor + */ + public SPARC_ElfRelocationHandler() { + super(SPARC_ElfRelocationType.class); + } @Override public boolean canRelocate(ElfHeader elf) { @@ -34,78 +41,62 @@ public class SPARC_ElfRelocationHandler extends ElfRelocationHandler { } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, - Address relocationAddress) throws MemoryAccessException, NotFoundException { - - ElfHeader elf = elfRelocationContext.getElfHeader(); - if (elf.e_machine() != ElfConstants.EM_SPARC && - elf.e_machine() != ElfConstants.EM_SPARC32PLUS) { - return RelocationResult.FAILURE; - } + protected RelocationResult relocate(ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, SPARC_ElfRelocationType type, Address relocationAddress, + ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); - int type = relocation.getType(); - if (type == SPARC_ElfRelocationConstants.R_SPARC_NONE) { - return RelocationResult.SKIPPED; - } - - int symbolIndex = relocation.getSymbolIndex(); - long addend = relocation.getAddend(); // will be 0 for REL case + // TODO: possible sign-extension seems wrong; there are both 32-bit and 64-bit variants long offset = (int) relocationAddress.getOffset(); - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null - String symbolName = elfRelocationContext.getSymbolName(symbolIndex); - - long symbolValue = elfRelocationContext.getSymbolValue(sym); - + int symbolIndex = relocation.getSymbolIndex(); int oldValue = memory.getInt(relocationAddress); int newValue = 0; - int byteLength = 4; // most relocations affect 4-bytes (change if different) switch (type) { - case SPARC_ElfRelocationConstants.R_SPARC_DISP32: + case R_SPARC_DISP32: newValue = (int) (symbolValue + addend - offset); memory.setInt(relocationAddress, oldValue | newValue); break; - case SPARC_ElfRelocationConstants.R_SPARC_WDISP30: + case R_SPARC_WDISP30: newValue = (int) (symbolValue + addend - offset) >>> 2; memory.setInt(relocationAddress, oldValue | newValue); break; - case SPARC_ElfRelocationConstants.R_SPARC_HI22: + case R_SPARC_HI22: newValue = ((int) symbolValue + (int) addend) >>> 10; memory.setInt(relocationAddress, oldValue | newValue); break; - case SPARC_ElfRelocationConstants.R_SPARC_LO10: + case R_SPARC_LO10: newValue = ((int) symbolValue + (int) addend) & 0x3FF; memory.setInt(relocationAddress, oldValue | newValue); break; - case SPARC_ElfRelocationConstants.R_SPARC_JMP_SLOT: + case R_SPARC_JMP_SLOT: // should copy address of symbol in EXTERNAL block - case SPARC_ElfRelocationConstants.R_SPARC_32: + case R_SPARC_32: newValue = (int) symbolValue + (int) addend; memory.setInt(relocationAddress, newValue); break; // we punt on this because it's not linked yet! - case SPARC_ElfRelocationConstants.R_SPARC_GLOB_DAT: + case R_SPARC_GLOB_DAT: newValue = (int) symbolValue; memory.setInt(relocationAddress, newValue); break; - case SPARC_ElfRelocationConstants.R_SPARC_RELATIVE: - newValue = (int) elf.getImageBase() + (int) addend; + case R_SPARC_RELATIVE: + newValue = (int) elfRelocationContext.getElfHeader().getImageBase() + (int) addend; memory.setInt(relocationAddress, newValue); break; - case SPARC_ElfRelocationConstants.R_SPARC_UA32: + case R_SPARC_UA32: newValue = (int) symbolValue + (int) addend; memory.setInt(relocationAddress, newValue); break; - case SPARC_ElfRelocationConstants.R_SPARC_COPY: - markAsWarning(program, relocationAddress, "R_SPARC_COPY", symbolName, symbolIndex, + case R_SPARC_COPY: + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, "Runtime copy not supported", elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; default: diff --git a/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationType.java b/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationType.java new file mode 100644 index 0000000000..bf6298eb60 --- /dev/null +++ b/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationType.java @@ -0,0 +1,70 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum SPARC_ElfRelocationType implements ElfRelocationType { + + R_SPARC_NONE(0), // No calculation + R_SPARC_5(44), // S + A + R_SPARC_6(45), // S + A + R_SPARC_7(43), // S + A + R_SPARC_8(1), // S + A + R_SPARC_10(30), // S + A + R_SPARC_11(31), // S + A + R_SPARC_13(11), // S + A + R_SPARC_16(2), // S + A + R_SPARC_22(10), // S + A + R_SPARC_32(3), // S + A + R_SPARC_LO10(12), // (S + A) & 0x3FF + R_SPARC_HI22(9), // (S + A) >> 10 + R_SPARC_DISP8(4), // S + A - P + R_SPARC_DISP16(5), // S + A - P + R_SPARC_DISP32(6), // S + A - P + R_SPARC_WDISP16(40), // (S + A - P) >> 2 + R_SPARC_WDISP19(41), // (S + A - P) >> 2 + R_SPARC_WDISP22(8), // (S + A - P) >> 2 + R_SPARC_WDISP30(7), // (S + A - P) >> 2 + R_SPARC_PC10(16), // (S + A - P) & 0x3FF + R_SPARC_PC22(17), // (S + A - P) >> 10 + R_SPARC_PLT32(24), // L + A + R_SPARC_PCPLT10(29), // (L + A - P) & 0x3FF + R_SPARC_PCPLT22(28), // (L + A - P) >> 10 + R_SPARC_PCPLT32(27), // L + A - P + R_SPARC_GOT10(13), // G & 0x3FF + R_SPARC_GOT13(14), // G + R_SPARC_GOT22(15), // G >> 10 + R_SPARC_WPLT30(18), // (L + A - P) >> 2 + R_SPARC_LOPLT10(26), // (L + A) & 0x3FF + R_SPARC_HIPLT22(25), // (L + A) >> 10 + + R_SPARC_JMP_SLOT(21), + R_SPARC_UA32(23), // S + A + R_SPARC_GLOB_DAT(20), // S + A + R_SPARC_RELATIVE(22), // B + A + R_SPARC_COPY(19); // No calculation + + public final int typeId; + + private SPARC_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } + +} diff --git a/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfSH4RelocationFixupHandler.java b/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfSH4RelocationFixupHandler.java index 8432a6db03..b99979af4f 100644 --- a/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfSH4RelocationFixupHandler.java +++ b/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfSH4RelocationFixupHandler.java @@ -15,7 +15,7 @@ */ package ghidra.app.util.bin.format.elf.relocation; -import ghidra.app.plugin.core.reloc.RelocationFixupHandler; +import ghidra.app.plugin.core.reloc.ElfRelocationFixupHandler; import ghidra.app.util.opinion.ElfLoader; import ghidra.program.model.address.Address; import ghidra.program.model.lang.Language; @@ -23,29 +23,44 @@ import ghidra.program.model.lang.Processor; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.reloc.Relocation; +import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.util.CodeUnitInsertionException; -public class ElfSH4RelocationFixupHandler extends RelocationFixupHandler { +public class ElfSH4RelocationFixupHandler extends ElfRelocationFixupHandler { + + public ElfSH4RelocationFixupHandler() { + super(SH_ElfRelocationType.class); + } @Override public boolean processRelocation(Program program, Relocation relocation, Address oldImageBase, Address newImageBase) throws MemoryAccessException, CodeUnitInsertionException { - switch (relocation.getType()) { - case SH_ElfRelocationConstants.R_SH_DIR32: - case SH_ElfRelocationConstants.R_SH_REL32: - case SH_ElfRelocationConstants.R_SH_GLOB_DAT: - case SH_ElfRelocationConstants.R_SH_JMP_SLOT: - case SH_ElfRelocationConstants.R_SH_RELATIVE: + if (relocation.getStatus() != Status.APPLIED) { + return false; + } + + SH_ElfRelocationType type = (SH_ElfRelocationType) getRelocationType(relocation.getType()); + if (type == null) { + return false; + } + + switch (type) { + case R_SH_DIR32: + case R_SH_REL32: + case R_SH_GLOB_DAT: + case R_SH_JMP_SLOT: + case R_SH_RELATIVE: return process32BitRelocation(program, relocation, oldImageBase, newImageBase); -// case SH_ElfRelocationConstants.R_SH_DIR8WPN: -// case SH_ElfRelocationConstants.R_SH_DIR8WPZ: -// case SH_ElfRelocationConstants.R_SH_IND12W: -// case SH_ElfRelocationConstants.R_SH_DIR8WPL: +// case R_SH_DIR8WPN: +// case R_SH_DIR8WPZ: +// case R_SH_IND12W: +// case R_SH_DIR8WPL: + default: + return false; } - return false; } @Override @@ -58,7 +73,7 @@ public class ElfSH4RelocationFixupHandler extends RelocationFixupHandler { return false; } Processor processor = language.getProcessor(); - return ("SuperH4".equals(processor.toString()) || "SuperH".equals(processor.toString())); + return "SuperH4".equals(processor.toString()); } } diff --git a/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/SH_ElfRelocationConstants.java b/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/SH_ElfRelocationConstants.java deleted file mode 100644 index 27e7f89ecd..0000000000 --- a/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/SH_ElfRelocationConstants.java +++ /dev/null @@ -1,134 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.util.bin.format.elf.relocation; - -public class SH_ElfRelocationConstants { - - public static final int R_SH_NONE = 0; // No operation needed - public static final int R_SH_DIR32 = 1; // (S + A) */ - public static final int R_SH_REL32 = 2; // (S + A) - P - public static final int R_SH_DIR8WPN = 3; // 8-bit PC relative branch divided by 2 : (((S + A) - P) >> 1) & 0xff - public static final int R_SH_IND12W = 4; // 12-bit PC relative branch divided by 2 : (((S + A) - P) >> 1) & 0xfff - public static final int R_SH_DIR8WPL = 5; // 8-bit PC unsigned-relative branch divided by 4 : (((S + A) - P) >> 2) & 0xff - public static final int R_SH_DIR8WPZ = 6; // 8-bit PC unsigned-relative branch divided by 2 : (((S + A) - P) >> 1) & 0xff - public static final int R_SH_DIR8BP = 7; - public static final int R_SH_DIR8W = 8; - public static final int R_SH_DIR8L = 9; - - // Relocation numbering in this file corresponds to GNU binutils and - // values below this point may differ significantly from those specified - // for other uses (e.g., see https://android.googlesource.com/platform/external/elfutils/+/android-4.1.2_r1/libelf/elf.h ) - - public static final int R_SH_LOOP_START = 10; - public static final int R_SH_LOOP_END = 11; - - public static final int R_SH_GNU_VTINHERIT = 22; - public static final int R_SH_GNU_VTENTRY = 23; - public static final int R_SH_SWITCH8 = 24; - - public static final int R_SH_SWITCH16 = 25; - public static final int R_SH_SWITCH32 = 26; - public static final int R_SH_USES = 27; - public static final int R_SH_COUNT = 28; - public static final int R_SH_ALIGN = 29; - public static final int R_SH_CODE = 30; - public static final int R_SH_DATA = 31; - public static final int R_SH_LABEL = 32; - - public static final int R_SH_DIR16 = 33; - public static final int R_SH_DIR8 = 34; - public static final int R_SH_DIR8UL = 35; - public static final int R_SH_DIR8UW = 36; - public static final int R_SH_DIR8U = 37; - public static final int R_SH_DIR8SW = 38; - public static final int R_SH_DIR8S = 39; - public static final int R_SH_DIR4UL = 40; - public static final int R_SH_DIR4UW = 41; - public static final int R_SH_DIR4U = 42; - public static final int R_SH_PSHA = 43; - public static final int R_SH_PSHL = 44; - public static final int R_SH_DIR5U = 45; - public static final int R_SH_DIR6U = 46; - public static final int R_SH_DIR6S = 47; - public static final int R_SH_DIR10S = 48; - public static final int R_SH_DIR10SW = 49; - public static final int R_SH_DIR10SL = 50; - public static final int R_SH_DIR10SQ = 51; - - public static final int R_SH_DIR16S = 53; - - public static final int R_SH_TLS_GD_32 = 144; - public static final int R_SH_TLS_LD_32 = 145; - public static final int R_SH_TLS_LDO_32 = 146; - public static final int R_SH_TLS_IE_32 = 147; - public static final int R_SH_TLS_LE_32 = 148; - public static final int R_SH_TLS_DTPMOD32 = 149; - public static final int R_SH_TLS_DTPOFF32 = 150; - public static final int R_SH_TLS_TPOFF32 = 151; - - public static final int R_SH_GOT32 = 160; - public static final int R_SH_PLT32 = 161; - public static final int R_SH_COPY = 162; - public static final int R_SH_GLOB_DAT = 163; - public static final int R_SH_JMP_SLOT = 164; - public static final int R_SH_RELATIVE = 165; - public static final int R_SH_GOTOFF = 166; - public static final int R_SH_GOTPC = 167; - public static final int R_SH_GOTPLT32 = 168; - public static final int R_SH_GOT_LOW16 = 169; - public static final int R_SH_GOT_MEDLOW16 = 170; - public static final int R_SH_GOT_MEDHI16 = 171; - public static final int R_SH_GOT_HI16 = 172; - public static final int R_SH_GOTPLT_LOW16 = 173; - public static final int R_SH_GOTPLT_MEDLOW16 = 174; - public static final int R_SH_GOTPLT_MEDHI16 = 175; - public static final int R_SH_GOTPLT_HI16 = 176; - public static final int R_SH_PLT_LOW16 = 177; - public static final int R_SH_PLT_MEDLOW16 = 178; - public static final int R_SH_PLT_MEDHI16 = 179; - public static final int R_SH_PLT_HI16 = 180; - public static final int R_SH_GOTOFF_LOW16 = 181; - public static final int R_SH_GOTOFF_MEDLOW16 = 182; - public static final int R_SH_GOTOFF_MEDHI16 = 183; - public static final int R_SH_GOTOFF_HI16 = 184; - public static final int R_SH_GOTPC_LOW16 = 185; - public static final int R_SH_GOTPC_MEDLOW16 = 186; - public static final int R_SH_GOTPC_MEDHI16 = 187; - public static final int R_SH_GOTPC_HI16 = 188; - public static final int R_SH_GOT10BY4 = 189; - public static final int R_SH_GOTPLT10BY4 = 190; - public static final int R_SH_GOT10BY8 = 191; - public static final int R_SH_GOTPLT10BY8 = 192; - public static final int R_SH_COPY64 = 193; - public static final int R_SH_GLOB_DAT64 = 194; - public static final int R_SH_JMP_SLOT64 = 195; - public static final int R_SH_RELATIVE64 = 196; - - public static final int R_SH_SHMEDIA_CODE = 242; - public static final int R_SH_PT_16 = 243; - public static final int R_SH_IMMS16 = 244; - public static final int R_SH_IMMU16 = 245; - public static final int R_SH_IMM_LOW16 = 246; - public static final int R_SH_IMM_LOW16_PCREL = 247; - public static final int R_SH_IMM_MEDLOW16 = 248; - public static final int R_SH_IMM_MEDLOW16_PCREL = 249; - public static final int R_SH_IMM_MEDHI16 = 250; - public static final int R_SH_IMM_MEDHI16_PCREL = 251; - public static final int R_SH_IMM_HI16 = 252; - public static final int R_SH_IMM_HI16_PCREL = 253; - public static final int R_SH_64 = 254; - public static final int R_SH_64_PCREL = 255; -} diff --git a/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/SH_ElfRelocationHandler.java b/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/SH_ElfRelocationHandler.java index d8c0453917..a21927245e 100644 --- a/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/SH_ElfRelocationHandler.java +++ b/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/SH_ElfRelocationHandler.java @@ -22,9 +22,16 @@ import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.reloc.RelocationResult; -import ghidra.util.exception.NotFoundException; -public class SH_ElfRelocationHandler extends ElfRelocationHandler { +public class SH_ElfRelocationHandler + extends AbstractElfRelocationHandler> { + + /** + * Constructor + */ + public SH_ElfRelocationHandler() { + super(SH_ElfRelocationType.class); + } @Override public boolean canRelocate(ElfHeader elf) { @@ -32,84 +39,66 @@ public class SH_ElfRelocationHandler extends ElfRelocationHandler { } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, - Address relocationAddress) throws MemoryAccessException, NotFoundException { - - ElfHeader elf = elfRelocationContext.getElfHeader(); - if (elf.e_machine() != ElfConstants.EM_SH || !elf.is32Bit()) { - return RelocationResult.FAILURE; - } + protected RelocationResult relocate(ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, SH_ElfRelocationType type, Address relocationAddress, + ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { Program program = elfRelocationContext.getProgram(); - Memory memory = program.getMemory(); - - int type = relocation.getType(); - if (type == SH_ElfRelocationConstants.R_SH_NONE) { - return RelocationResult.SKIPPED; - } - int symbolIndex = relocation.getSymbolIndex(); int addend = (int) relocation.getAddend(); - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null - String symbolName = elfRelocationContext.getSymbolName(symbolIndex); - int offset = (int) relocationAddress.getOffset(); - - Address symbolAddr = elfRelocationContext.getSymbolAddress(sym); - int symbolValue = (int) elfRelocationContext.getSymbolValue(sym); - + int symbolIndex = relocation.getSymbolIndex(); int newValue = 0; int oldValue; - int byteLength = 4; // most relocations affect 4-bytes (change if different) switch (type) { - case SH_ElfRelocationConstants.R_SH_DIR32: + case R_SH_DIR32: // 32-bit absolute relocation w/ addend if (elfRelocationContext.extractAddend()) { addend = memory.getInt(relocationAddress); } - newValue = symbolValue + addend; + newValue = (int) symbolValue + addend; memory.setInt(relocationAddress, newValue); if (symbolIndex != 0 && addend != 0 && !sym.isSection()) { - warnExternalOffsetRelocation(program, relocationAddress, - symbolAddr, symbolName, addend, elfRelocationContext.getLog()); + warnExternalOffsetRelocation(program, relocationAddress, symbolAddr, symbolName, + addend, elfRelocationContext.getLog()); applyComponentOffsetPointer(program, relocationAddress, addend); } break; - case SH_ElfRelocationConstants.R_SH_GLOB_DAT: - case SH_ElfRelocationConstants.R_SH_JMP_SLOT: + case R_SH_GLOB_DAT: + case R_SH_JMP_SLOT: // 32-bit absolute relocations, no addend - memory.setInt(relocationAddress, symbolValue); + memory.setInt(relocationAddress, (int) symbolValue); break; - case SH_ElfRelocationConstants.R_SH_REL32: // 32-bit PC relative relocation + case R_SH_REL32: // 32-bit PC relative relocation if (elfRelocationContext.extractAddend()) { addend = memory.getInt(relocationAddress); } - newValue = (symbolValue + addend) - offset; + newValue = ((int) symbolValue + addend) - offset; memory.setInt(relocationAddress, newValue); break; - case SH_ElfRelocationConstants.R_SH_DIR8WPN: // 8-bit PC relative branch divided by 2 - case SH_ElfRelocationConstants.R_SH_DIR8WPZ: // 8-bit PC unsigned-relative branch divided by 2 + case R_SH_DIR8WPN: // 8-bit PC relative branch divided by 2 + case R_SH_DIR8WPZ: // 8-bit PC unsigned-relative branch divided by 2 oldValue = memory.getShort(relocationAddress); if (elfRelocationContext.extractAddend()) { addend = oldValue & 0xff; - if (type == SH_ElfRelocationConstants.R_SH_DIR8WPN && (addend & 0x80) != 0) { + if (type == SH_ElfRelocationType.R_SH_DIR8WPN && (addend & 0x80) != 0) { addend -= 0x100; // sign-extend addend for R_SH_DIR8WPN } } - newValue = ((symbolValue + addend) - offset) >> 1; + newValue = (((int) symbolValue + addend) - offset) >> 1; newValue = (oldValue & 0xff00) | (newValue & 0xff); memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; - case SH_ElfRelocationConstants.R_SH_IND12W: // 12-bit PC relative branch divided by 2 + case R_SH_IND12W: // 12-bit PC relative branch divided by 2 oldValue = memory.getShort(relocationAddress); if (elfRelocationContext.extractAddend()) { addend = oldValue & 0xfff; @@ -117,29 +106,29 @@ public class SH_ElfRelocationHandler extends ElfRelocationHandler { addend -= 0x1000; // sign-extend addend } } - newValue = ((symbolValue + addend) - offset) >> 1; + newValue = (((int) symbolValue + addend) - offset) >> 1; newValue = (oldValue & 0xf000) | (newValue & 0xfff); memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; - case SH_ElfRelocationConstants.R_SH_DIR8WPL: // 8-bit PC unsigned-relative branch divided by 4 + case R_SH_DIR8WPL: // 8-bit PC unsigned-relative branch divided by 4 oldValue = memory.getShort(relocationAddress); if (elfRelocationContext.extractAddend()) { addend = oldValue & 0xff; } - newValue = ((symbolValue + addend) - offset) >> 2; + newValue = (((int) symbolValue + addend) - offset) >> 2; newValue = (oldValue & 0xff00) | (newValue & 0xff); memory.setShort(relocationAddress, (short) newValue); byteLength = 2; break; - case SH_ElfRelocationConstants.R_SH_COPY: - markAsWarning(program, relocationAddress, "R_SH_COPY", symbolName, symbolIndex, + case R_SH_COPY: + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, "Runtime copy not supported", elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; - case SH_ElfRelocationConstants.R_SH_RELATIVE: + case R_SH_RELATIVE: if (elfRelocationContext.extractAddend()) { addend = memory.getInt(relocationAddress); } diff --git a/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/SH_ElfRelocationType.java b/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/SH_ElfRelocationType.java new file mode 100644 index 0000000000..b1d51340f6 --- /dev/null +++ b/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/SH_ElfRelocationType.java @@ -0,0 +1,145 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum SH_ElfRelocationType implements ElfRelocationType { + + R_SH_NONE(0), // No operation needed + R_SH_DIR32(1), // (S + A) */ + R_SH_REL32(2), // (S + A) - P + R_SH_DIR8WPN(3), // 8-bit PC relative branch divided by 2 : (((S + A) - P) >> 1) & 0xff + R_SH_IND12W(4), // 12-bit PC relative branch divided by 2 : (((S + A) - P) >> 1) & 0xfff + R_SH_DIR8WPL(5), // 8-bit PC unsigned-relative branch divided by 4 : (((S + A) - P) >> 2) & 0xff + R_SH_DIR8WPZ(6), // 8-bit PC unsigned-relative branch divided by 2 : (((S + A) - P) >> 1) & 0xff + R_SH_DIR8BP(7), + R_SH_DIR8W(8), + R_SH_DIR8L(9), + + // Relocation numbering in this file corresponds to GNU binutils and + // values below this point may differ significantly from those specified + // for other uses (e.g., see https://android.googlesource.com/platform/external/elfutils/+/android-4.1.2_r1/libelf/elf.h ) + + R_SH_LOOP_START(10), + R_SH_LOOP_END(11), + + R_SH_GNU_VTINHERIT(22), + R_SH_GNU_VTENTRY(23), + R_SH_SWITCH8(24), + + R_SH_SWITCH16(25), + R_SH_SWITCH32(26), + R_SH_USES(27), + R_SH_COUNT(28), + R_SH_ALIGN(29), + R_SH_CODE(30), + R_SH_DATA(31), + R_SH_LABEL(32), + + R_SH_DIR16(33), + R_SH_DIR8(34), + R_SH_DIR8UL(35), + R_SH_DIR8UW(36), + R_SH_DIR8U(37), + R_SH_DIR8SW(38), + R_SH_DIR8S(39), + R_SH_DIR4UL(40), + R_SH_DIR4UW(41), + R_SH_DIR4U(42), + R_SH_PSHA(43), + R_SH_PSHL(44), + R_SH_DIR5U(45), + R_SH_DIR6U(46), + R_SH_DIR6S(47), + R_SH_DIR10S(48), + R_SH_DIR10SW(49), + R_SH_DIR10SL(50), + R_SH_DIR10SQ(51), + + R_SH_DIR16S(53), + + R_SH_TLS_GD_32(144), + R_SH_TLS_LD_32(145), + R_SH_TLS_LDO_32(146), + R_SH_TLS_IE_32(147), + R_SH_TLS_LE_32(148), + R_SH_TLS_DTPMOD32(149), + R_SH_TLS_DTPOFF32(150), + R_SH_TLS_TPOFF32(151), + + R_SH_GOT32(160), + R_SH_PLT32(161), + R_SH_COPY(162), + R_SH_GLOB_DAT(163), + R_SH_JMP_SLOT(164), + R_SH_RELATIVE(165), + R_SH_GOTOFF(166), + R_SH_GOTPC(167), + R_SH_GOTPLT32(168), + R_SH_GOT_LOW16(169), + R_SH_GOT_MEDLOW16(170), + R_SH_GOT_MEDHI16(171), + R_SH_GOT_HI16(172), + R_SH_GOTPLT_LOW16(173), + R_SH_GOTPLT_MEDLOW16(174), + R_SH_GOTPLT_MEDHI16(175), + R_SH_GOTPLT_HI16(176), + R_SH_PLT_LOW16(177), + R_SH_PLT_MEDLOW16(178), + R_SH_PLT_MEDHI16(179), + R_SH_PLT_HI16(180), + R_SH_GOTOFF_LOW16(181), + R_SH_GOTOFF_MEDLOW16(182), + R_SH_GOTOFF_MEDHI16(183), + R_SH_GOTOFF_HI16(184), + R_SH_GOTPC_LOW16(185), + R_SH_GOTPC_MEDLOW16(186), + R_SH_GOTPC_MEDHI16(187), + R_SH_GOTPC_HI16(188), + R_SH_GOT10BY4(189), + R_SH_GOTPLT10BY4(190), + R_SH_GOT10BY8(191), + R_SH_GOTPLT10BY8(192), + R_SH_COPY64(193), + R_SH_GLOB_DAT64(194), + R_SH_JMP_SLOT64(195), + R_SH_RELATIVE64(196), + + R_SH_SHMEDIA_CODE(242), + R_SH_PT_16(243), + R_SH_IMMS16(244), + R_SH_IMMU16(245), + R_SH_IMM_LOW16(246), + R_SH_IMM_LOW16_PCREL(247), + R_SH_IMM_MEDLOW16(248), + R_SH_IMM_MEDLOW16_PCREL(249), + R_SH_IMM_MEDHI16(250), + R_SH_IMM_MEDHI16_PCREL(251), + R_SH_IMM_HI16(252), + R_SH_IMM_HI16_PCREL(253), + R_SH_64(254), + R_SH_64_PCREL(255); + + public final int typeId; + + private SH_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } +} diff --git a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430X_ElfRelocationConstants.java b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430X_ElfRelocationConstants.java deleted file mode 100644 index e9acd105b7..0000000000 --- a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430X_ElfRelocationConstants.java +++ /dev/null @@ -1,53 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.util.bin.format.elf.relocation; - -/** - * class for elf_msp430x_reloc_type (from binutils source) - */ -public class MSP430X_ElfRelocationConstants { - // Note: some of the msp430x relocation types have "msp430" (without the x) - // in their names - public static final int R_MSP430_NONE = 0; // No calculation - public static final int R_MSP430_ABS32 = 1;// S + A - public static final int R_MSP430_ABS16 = 2; // S + A - public static final int R_MSP430_ABS8 = 3; // S + A - public static final int R_MSP430_PCR16 = 4; // S + A - PC - public static final int R_MSP430X_PCR20_EXT_SRC = 5; // S + A - PC - public static final int R_MSP430X_PCR20_EXT_DST = 6; // S + A - PC - public static final int R_MSP430X_PCR20_EXT_ODST = 7; // S + A - PC - public static final int R_MSP430X_ABS20_EXT_SRC = 8; // S + A - public static final int R_MSP430X_ABS20_EXT_DST = 9; // S + A - public static final int R_MSP430X_ABS20_EXT_ODST = 10; // S + A - public static final int R_MSP430X_ABS20_ADR_SRC = 11; // S + A - public static final int R_MSP430X_ABS20_ADR_DST = 12; // S + A - public static final int R_MSP430X_PCR16 = 13; // S + A - PC - public static final int R_MSP430X_PCR20_CALL = 14; // S + A - PC - public static final int R_MSP430X_ABS16 = 15; // S + A - public static final int R_MSP430_ABS_HI16 = 16; // S + A (Rela only) - public static final int R_MSP430_PREL31 = 17; // S + A - PC - public static final int R_MSP430_EHTYPE = 18; // encodes typeinfo addresses in exception tables - public static final int R_MSP430X_10_PCREL = 19; // Red Hat invention. - public static final int R_MSP430X_2X_PCREL = 20; // Red Hat invention - public static final int R_MSP430X_SYM_DIFF = 21; // Red Hat invention*/ - public static final int R_MSP430X_SET_ULEB128 = 22; // GNU only - public static final int R_MSP430X_SUB_ULEB128 = 23; // GNU only - - private MSP430X_ElfRelocationConstants() { - //class not for instantiation - } - -} diff --git a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430X_ElfRelocationHandler.java b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430X_ElfRelocationHandler.java index 0597dfb6a1..e9f02e4e7f 100644 --- a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430X_ElfRelocationHandler.java +++ b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430X_ElfRelocationHandler.java @@ -23,9 +23,16 @@ import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.reloc.RelocationResult; -import ghidra.util.exception.NotFoundException; -public class MSP430X_ElfRelocationHandler extends ElfRelocationHandler { +public class MSP430X_ElfRelocationHandler + extends AbstractElfRelocationHandler> { + + /** + * Constructor + */ + public MSP430X_ElfRelocationHandler() { + super(MSP430X_ElfRelocationType.class); + } @Override public boolean canRelocate(ElfHeader elf) { @@ -34,48 +41,42 @@ public class MSP430X_ElfRelocationHandler extends ElfRelocationHandler { } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, Address relocationAddress) - throws MemoryAccessException, NotFoundException { - int type = relocation.getType(); - if (type == MSP430X_ElfRelocationConstants.R_MSP430_NONE) { - return RelocationResult.SKIPPED; - } + protected RelocationResult relocate(ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, MSP430X_ElfRelocationType type, Address relocationAddress, + ElfSymbol elfSymbol, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); int symbolIndex = relocation.getSymbolIndex(); long addend = relocation.getAddend(); // will be 0 for REL case long offset = relocationAddress.getOffset(); - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null - String symbolName = elfRelocationContext.getSymbolName(symbolIndex); - long symbolValue = elfRelocationContext.getSymbolValue(sym); - int byteLength = 0; + int byteLength; switch (type) { - case MSP430X_ElfRelocationConstants.R_MSP430_ABS32: + case R_MSP430_ABS32: int newIntValue = (int) (symbolValue + addend); memory.setInt(relocationAddress, newIntValue); byteLength = 4; break; - case MSP430X_ElfRelocationConstants.R_MSP430_ABS16: - case MSP430X_ElfRelocationConstants.R_MSP430X_ABS16: + case R_MSP430_ABS16: + case R_MSP430X_ABS16: short newShortValue = (short) (symbolValue + addend); memory.setShort(relocationAddress, newShortValue); byteLength = 2; break; - case MSP430X_ElfRelocationConstants.R_MSP430_ABS8: + case R_MSP430_ABS8: byte newByteValue = (byte) (symbolValue + addend); memory.setByte(relocationAddress, newByteValue); byteLength = 1; break; - case MSP430X_ElfRelocationConstants.R_MSP430_PCR16: - case MSP430X_ElfRelocationConstants.R_MSP430X_PCR16: + case R_MSP430_PCR16: + case R_MSP430X_PCR16: newShortValue = (short) (symbolValue + addend - offset); memory.setShort(relocationAddress, newShortValue); byteLength = 2; break; - case MSP430X_ElfRelocationConstants.R_MSP430X_PCR20_EXT_SRC: + case R_MSP430X_PCR20_EXT_SRC: newIntValue = (int) (symbolValue + addend - offset - 4); memory.setShort(relocationAddress.add(4), (short) (newIntValue)); newIntValue >>= 16; @@ -86,7 +87,7 @@ public class MSP430X_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, highWord); byteLength = 6; break; - case MSP430X_ElfRelocationConstants.R_MSP430X_PCR20_EXT_DST: + case R_MSP430X_PCR20_EXT_DST: newIntValue = (int) (symbolValue + addend - offset - 4); memory.setShort(relocationAddress.add(4), (short) (newIntValue)); newIntValue >>= 16; @@ -97,7 +98,7 @@ public class MSP430X_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, highWord); byteLength = 6; break; - case MSP430X_ElfRelocationConstants.R_MSP430X_PCR20_EXT_ODST: + case R_MSP430X_PCR20_EXT_ODST: newIntValue = (int) (symbolValue + addend - offset - 4); memory.setShort(relocationAddress.add(6), (short) (newIntValue)); newIntValue >>= 16; @@ -108,7 +109,7 @@ public class MSP430X_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, highWord); byteLength = 8; break; - case MSP430X_ElfRelocationConstants.R_MSP430X_ABS20_EXT_SRC: + case R_MSP430X_ABS20_EXT_SRC: newIntValue = (int) (symbolValue + addend); memory.setShort(relocationAddress.add(4), (short) (newIntValue)); newIntValue >>= 16; @@ -119,7 +120,7 @@ public class MSP430X_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, highWord); byteLength = 6; break; - case MSP430X_ElfRelocationConstants.R_MSP430X_ABS20_EXT_DST: + case R_MSP430X_ABS20_EXT_DST: newIntValue = (int) (symbolValue + addend); memory.setShort(relocationAddress.add(4), (short) (newIntValue)); newIntValue >>= 16; @@ -130,7 +131,7 @@ public class MSP430X_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, highWord); byteLength = 6; break; - case MSP430X_ElfRelocationConstants.R_MSP430X_ABS20_EXT_ODST: + case R_MSP430X_ABS20_EXT_ODST: newIntValue = (int) (symbolValue + addend); memory.setShort(relocationAddress.add(6), (short) (newIntValue)); newIntValue >>= 16; @@ -141,7 +142,7 @@ public class MSP430X_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, highWord); byteLength = 8; break; - case MSP430X_ElfRelocationConstants.R_MSP430X_ABS20_ADR_SRC: + case R_MSP430X_ABS20_ADR_SRC: newIntValue = (int) (symbolValue + addend); memory.setShort(relocationAddress.add(2), (short) (newIntValue & 0xffff)); newIntValue >>= 16; @@ -152,7 +153,7 @@ public class MSP430X_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, highWord); byteLength = 4; break; - case MSP430X_ElfRelocationConstants.R_MSP430X_ABS20_ADR_DST: + case R_MSP430X_ABS20_ADR_DST: newIntValue = (int) (symbolValue + addend); memory.setShort(relocationAddress.add(2), (short) (newIntValue & 0xffff)); newIntValue >>= 16; @@ -163,7 +164,7 @@ public class MSP430X_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, highWord); byteLength = 4; break; - case MSP430X_ElfRelocationConstants.R_MSP430X_PCR20_CALL: + case R_MSP430X_PCR20_CALL: newIntValue = (int) (symbolValue + addend - offset); memory.setShort(relocationAddress.add(2), (short) newIntValue); newIntValue >>= 16; @@ -174,7 +175,7 @@ public class MSP430X_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, highWord); byteLength = 4; break; - case MSP430X_ElfRelocationConstants.R_MSP430X_10_PCREL: + case R_MSP430X_10_PCREL: short oldShortValue = memory.getShort(relocationAddress); oldShortValue &= 0xfc00; newShortValue = (short) (symbolValue + addend - offset - 2); diff --git a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430X_ElfRelocationType.java b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430X_ElfRelocationType.java new file mode 100644 index 0000000000..5229692106 --- /dev/null +++ b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430X_ElfRelocationType.java @@ -0,0 +1,61 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +/** + * class for elf_msp430x_reloc_type (from binutils source) + */ +public enum MSP430X_ElfRelocationType implements ElfRelocationType { + + // Note: some of the msp430x relocation types have "msp430" (without the x) + // in their names + R_MSP430_NONE(0), // No calculation + R_MSP430_ABS32(1),// S + A + R_MSP430_ABS16(2), // S + A + R_MSP430_ABS8(3), // S + A + R_MSP430_PCR16(4), // S + A - PC + R_MSP430X_PCR20_EXT_SRC(5), // S + A - PC + R_MSP430X_PCR20_EXT_DST(6), // S + A - PC + R_MSP430X_PCR20_EXT_ODST(7), // S + A - PC + R_MSP430X_ABS20_EXT_SRC(8), // S + A + R_MSP430X_ABS20_EXT_DST(9), // S + A + R_MSP430X_ABS20_EXT_ODST(10), // S + A + R_MSP430X_ABS20_ADR_SRC(11), // S + A + R_MSP430X_ABS20_ADR_DST(12), // S + A + R_MSP430X_PCR16(13), // S + A - PC + R_MSP430X_PCR20_CALL(14), // S + A - PC + R_MSP430X_ABS16(15), // S + A + R_MSP430_ABS_HI16(16), // S + A (Rela only) + R_MSP430_PREL31(17), // S + A - PC + R_MSP430_EHTYPE(18), // encodes typeinfo addresses in exception tables + R_MSP430X_10_PCREL(19), // Red Hat invention. + R_MSP430X_2X_PCREL(20), // Red Hat invention + R_MSP430X_SYM_DIFF(21), // Red Hat invention*/ + R_MSP430X_SET_ULEB128(22), // GNU only + R_MSP430X_SUB_ULEB128(23); // GNU only + + public final int typeId; + + private MSP430X_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } + +} diff --git a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430_ElfRelocationHandler.java b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430_ElfRelocationHandler.java index a28090de4d..94901e87af 100644 --- a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430_ElfRelocationHandler.java +++ b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430_ElfRelocationHandler.java @@ -23,9 +23,16 @@ import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.reloc.RelocationResult; -import ghidra.util.exception.NotFoundException; -public class MSP430_ElfRelocationHandler extends ElfRelocationHandler { +public class MSP430_ElfRelocationHandler + extends AbstractElfRelocationHandler> { + + /** + * Constructor + */ + public MSP430_ElfRelocationHandler() { + super(MSP430_ElfRelocationType.class); + } @Override public boolean canRelocate(ElfHeader elf) { @@ -34,32 +41,25 @@ public class MSP430_ElfRelocationHandler extends ElfRelocationHandler { } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, Address relocationAddress) - throws MemoryAccessException, NotFoundException { - int type = relocation.getType(); - if (type == MSP430_ElfRelocationConstants.R_MSP430_NONE) { - return RelocationResult.SKIPPED; - } + protected RelocationResult relocate(ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, MSP430_ElfRelocationType type, Address relocationAddress, + ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); int symbolIndex = relocation.getSymbolIndex(); long addend = relocation.getAddend(); // will be 0 for REL case long offset = relocationAddress.getOffset(); - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null - String symbolName = elfRelocationContext.getSymbolName(symbolIndex); - long symbolValue = elfRelocationContext.getSymbolValue(sym); - - int byteLength = 0; + int byteLength; switch (type) { - case MSP430_ElfRelocationConstants.R_MSP430_32: + case R_MSP430_32: int newIntValue = (int) (symbolValue + addend); memory.setInt(relocationAddress, newIntValue); byteLength = 4; break; - case MSP430_ElfRelocationConstants.R_MSP430_10_PCREL: + case R_MSP430_10_PCREL: short oldShortValue = memory.getShort(relocationAddress); oldShortValue &= 0xfc00; short newShortValue = (short) (symbolValue + addend - offset - 2); @@ -69,32 +69,32 @@ public class MSP430_ElfRelocationHandler extends ElfRelocationHandler { memory.setShort(relocationAddress, newShortValue); byteLength = 2; break; - case MSP430_ElfRelocationConstants.R_MSP430_16: + case R_MSP430_16: newShortValue = (short) (symbolValue + addend); memory.setShort(relocationAddress, newShortValue); byteLength = 2; break; - //case TI_MSP430_ElfRelocationConstants.R_MSP430_16_PCREL: - case MSP430_ElfRelocationConstants.R_MSP430_16_BYTE: + //case TI_R_MSP430_16_PCREL: + case R_MSP430_16_BYTE: newShortValue = (short) (symbolValue + addend); memory.setShort(relocationAddress, newShortValue); byteLength = 2; break; - case MSP430_ElfRelocationConstants.R_MSP430_16_PCREL_BYTE: + case R_MSP430_16_PCREL_BYTE: newShortValue = (short) (symbolValue + addend - offset); memory.setShort(relocationAddress, newShortValue); byteLength = 2; break; - //case TI_MSP430_ElfRelocationConstants.R_MSP430_2X_PCREL: - //case TI_MSP430_ElfRelocationConstants.R_MSP430_RL_PCREL: - case MSP430_ElfRelocationConstants.R_MSP430_8: + //case TI_R_MSP430_2X_PCREL: + //case TI_R_MSP430_RL_PCREL: + case R_MSP430_8: byte newByteValue = (byte) (symbolValue + addend); memory.setByte(relocationAddress, newByteValue); byteLength = 1; break; - //case TI_MSP430_ElfRelocationConstants.R_MSP430_SYM_DIFF: - //case TI_MSP430_ElfRelocationConstants.R_MSP430_SET_ULEB128: - //case TI_MSP430_ElfRelocationConstants.R_MSP430_SUB_ULEB128: + //case TI_R_MSP430_SYM_DIFF: + //case TI_R_MSP430_SET_ULEB128: + //case TI_R_MSP430_SUB_ULEB128: default: markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, elfRelocationContext.getLog()); diff --git a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430_ElfRelocationConstants.java b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430_ElfRelocationType.java similarity index 50% rename from Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430_ElfRelocationConstants.java rename to Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430_ElfRelocationType.java index 5f506fa320..9e5f0a9257 100644 --- a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430_ElfRelocationConstants.java +++ b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430_ElfRelocationType.java @@ -18,18 +18,30 @@ package ghidra.app.util.bin.format.elf.relocation; /** * class for elf_msp430_reloc_type (from binutils source) */ -public class MSP430_ElfRelocationConstants { - public static final int R_MSP430_NONE = 0; - public static final int R_MSP430_32 = 1; - public static final int R_MSP430_10_PCREL = 2; - public static final int R_MSP430_16 = 3; - public static final int R_MSP430_16_PCREL = 4; - public static final int R_MSP430_16_BYTE = 5; - public static final int R_MSP430_16_PCREL_BYTE = 6; - public static final int R_MSP430_2X_PCREL = 7; - public static final int R_MSP430_RL_PCREL = 8; - public static final int R_MSP430_8 = 9; - public static final int R_MSP430_SYM_DIFF = 10; - public static final int R_MSP430_SET_ULEB128 = 11; // GNU only. - public static final int R_MSP430_SUB_ULEB128 = 12; // GNU only +public enum MSP430_ElfRelocationType implements ElfRelocationType { + + R_MSP430_NONE(0), + R_MSP430_32(1), + R_MSP430_10_PCREL(2), + R_MSP430_16(3), + R_MSP430_16_PCREL(4), + R_MSP430_16_BYTE(5), + R_MSP430_16_PCREL_BYTE(6), + R_MSP430_2X_PCREL(7), + R_MSP430_RL_PCREL(8), + R_MSP430_8(9), + R_MSP430_SYM_DIFF(10), + R_MSP430_SET_ULEB128(11), // GNU only. + R_MSP430_SUB_ULEB128(12); // GNU only + + public final int typeId; + + private MSP430_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } } diff --git a/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationConstants.java b/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationConstants.java deleted file mode 100644 index e5b9598490..0000000000 --- a/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationConstants.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.util.bin.format.elf.relocation; - -public class Xtensa_ElfRelocationConstants { - /* Xtensa processor ELF architecture-magic number */ - - // EM_XTENSA is already definded - public static final int EM_XTENSA_OLD = 0xABC7; - - /* Xtensa relocations defined by the ABIs */ - - public static final int R_XTENSA_NONE = 0; - public static final int R_XTENSA_32 = 1; - public static final int R_XTENSA_RTLD = 2; - public static final int R_XTENSA_GLOB_DAT = 3; - public static final int R_XTENSA_JMP_SLOT = 4; - public static final int R_XTENSA_RELATIVE = 5; - public static final int R_XTENSA_PLT = 6; - public static final int R_XTENSA_OP0 = 8; - public static final int R_XTENSA_OP1 = 9; - public static final int R_XTENSA_OP2 = 10; - public static final int R_XTENSA_ASM_EXPAND = 11; - public static final int R_XTENSA_ASM_SIMPLIFY = 12; - public static final int R_XTENSA_GNU_VTINHERIT = 15; - public static final int R_XTENSA_GNU_VTENTRY = 16; - public static final int R_XTENSA_DIFF8 = 17; - public static final int R_XTENSA_DIFF16 = 18; - public static final int R_XTENSA_DIFF32 = 19; - public static final int R_XTENSA_SLOT0_OP = 20; - public static final int R_XTENSA_SLOT1_OP = 21; - public static final int R_XTENSA_SLOT2_OP = 22; - public static final int R_XTENSA_SLOT3_OP = 23; - public static final int R_XTENSA_SLOT4_OP = 24; - public static final int R_XTENSA_SLOT5_OP = 25; - public static final int R_XTENSA_SLOT6_OP = 26; - public static final int R_XTENSA_SLOT7_OP = 27; - public static final int R_XTENSA_SLOT8_OP = 28; - public static final int R_XTENSA_SLOT9_OP = 29; - public static final int R_XTENSA_SLOT10_OP = 30; - public static final int R_XTENSA_SLOT11_OP = 31; - public static final int R_XTENSA_SLOT12_OP = 32; - public static final int R_XTENSA_SLOT13_OP = 33; - public static final int R_XTENSA_SLOT14_OP = 34; - public static final int R_XTENSA_SLOT0_ALT = 35; - public static final int R_XTENSA_SLOT1_ALT = 36; - public static final int R_XTENSA_SLOT2_ALT = 37; - public static final int R_XTENSA_SLOT3_ALT = 38; - public static final int R_XTENSA_SLOT4_ALT = 39; - public static final int R_XTENSA_SLOT5_ALT = 40; - public static final int R_XTENSA_SLOT6_ALT = 41; - public static final int R_XTENSA_SLOT7_ALT = 42; - public static final int R_XTENSA_SLOT8_ALT = 43; - public static final int R_XTENSA_SLOT9_ALT = 44; - public static final int R_XTENSA_SLOT10_ALT = 45; - public static final int R_XTENSA_SLOT11_ALT = 46; - public static final int R_XTENSA_SLOT12_ALT = 47; - public static final int R_XTENSA_SLOT13_ALT = 48; - public static final int R_XTENSA_SLOT14_ALT = 49; -} diff --git a/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java b/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java index 7aef4dd276..f0b6ac291b 100644 --- a/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java +++ b/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java @@ -18,238 +18,175 @@ package ghidra.app.util.bin.format.elf.relocation; import ghidra.app.util.bin.format.elf.*; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; +import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryAccessException; +import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.reloc.RelocationResult; -import ghidra.util.exception.NotFoundException; -public class Xtensa_ElfRelocationHandler extends ElfRelocationHandler { +public class Xtensa_ElfRelocationHandler + extends AbstractElfRelocationHandler> { + + /* Xtensa processor ELF architecture-magic number */ + // EM_XTENSA is already definded + public static final int EM_XTENSA_OLD = 0xABC7; + + /** + * Constructor + */ + public Xtensa_ElfRelocationHandler() { + super(Xtensa_ElfRelocationType.class); + } @Override public boolean canRelocate(ElfHeader elf) { - return elf.e_machine() == ElfConstants.EM_XTENSA || - elf.e_machine() == Xtensa_ElfRelocationConstants.EM_XTENSA_OLD; + return elf.e_machine() == ElfConstants.EM_XTENSA || elf.e_machine() == EM_XTENSA_OLD; } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, Address relocationAddress) - throws MemoryAccessException, NotFoundException { - ElfHeader elf = elfRelocationContext.getElfHeader(); - if (!canRelocate(elf)) { - return RelocationResult.FAILURE; - } - - int type = relocation.getType(); - if (Xtensa_ElfRelocationConstants.R_XTENSA_NONE == type) { - return RelocationResult.SKIPPED; - } + protected RelocationResult relocate(ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, Xtensa_ElfRelocationType type, Address relocationAddress, + ElfSymbol elfSymbol, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { Program program = elfRelocationContext.getProgram(); + Memory memory = program.getMemory(); - ElfSymbol sym = null; - String symbolName = null; + int addend = (int) relocation.getAddend(); - int symbolIndex = relocation.getSymbolIndex(); - if (symbolIndex != 0) { - sym = elfRelocationContext.getSymbol(symbolIndex); - } + //int offset = (int) relocationAddress.getOffset(); - if (null != sym) { - symbolName = sym.getNameAsString(); - } + int byteLength = -1; + int newValue; - //int byteLength = 4; // most relocations affect 4-bytes (change if different) + int diff_mask = 0; + boolean neg = false; switch (type) { - case Xtensa_ElfRelocationConstants.R_XTENSA_32: - markAsWarning(program, relocationAddress, "R_XTENSA_32", symbolName, symbolIndex, - "TODO, needs support ", elfRelocationContext.getLog()); + case R_XTENSA_32: + newValue = memory.getInt(relocationAddress); + newValue += (symbolValue + addend); + memory.setInt(relocationAddress, newValue); + byteLength = 4; break; - case Xtensa_ElfRelocationConstants.R_XTENSA_RTLD: - markAsWarning(program, relocationAddress, "R_XTENSA_RTLD", symbolName, symbolIndex, - "TODO, needs support ", elfRelocationContext.getLog()); + +// case R_XTENSA_RTLD: + + case R_XTENSA_RELATIVE: + newValue = ((int) elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend); + memory.setInt(relocationAddress, newValue); + byteLength = 4; break; - case Xtensa_ElfRelocationConstants.R_XTENSA_GLOB_DAT: - markAsWarning(program, relocationAddress, "R_XTENSA_GLOB_DAT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); + + case R_XTENSA_GLOB_DAT: + case R_XTENSA_JMP_SLOT: + case R_XTENSA_PLT: + newValue = ((int) symbolValue + addend); + memory.setInt(relocationAddress, newValue); + byteLength = 4; break; - case Xtensa_ElfRelocationConstants.R_XTENSA_JMP_SLOT: - markAsWarning(program, relocationAddress, "R_XTENSA_JMP_SLOT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); + +// case R_XTENSA_OP0: +// case R_XTENSA_OP1: +// case R_XTENSA_OP2: +// case R_XTENSA_ASM_EXPAND: +// case R_XTENSA_ASM_SIMPLIFY: +// case R_XTENSA_GNU_VTINHERIT: +// case R_XTENSA_GNU_VTENTRY: + + case R_XTENSA_DIFF8: + diff_mask = 0x7f; + byteLength = 1; break; - case Xtensa_ElfRelocationConstants.R_XTENSA_RELATIVE: - markAsWarning(program, relocationAddress, "R_XTENSA_RELATIVE", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); + case R_XTENSA_DIFF16: + diff_mask = 0x7fff; + byteLength = 2; break; - case Xtensa_ElfRelocationConstants.R_XTENSA_PLT: - markAsWarning(program, relocationAddress, "R_XTENSA_PLT", symbolName, symbolIndex, - "TODO, needs support ", elfRelocationContext.getLog()); + case R_XTENSA_DIFF32: + diff_mask = 0x7fffffff; + byteLength = 4; break; - case Xtensa_ElfRelocationConstants.R_XTENSA_OP0: - markAsWarning(program, relocationAddress, "R_XTENSA_OP0", symbolName, symbolIndex, - "TODO, needs support ", elfRelocationContext.getLog()); + +// case R_XTENSA_SLOT0_OP: +// case R_XTENSA_SLOT1_OP: +// case R_XTENSA_SLOT2_OP: +// case R_XTENSA_SLOT3_OP: +// case R_XTENSA_SLOT4_OP: +// case R_XTENSA_SLOT5_OP: +// case R_XTENSA_SLOT6_OP: +// case R_XTENSA_SLOT7_OP: +// case R_XTENSA_SLOT8_OP: +// case R_XTENSA_SLOT9_OP: +// case R_XTENSA_SLOT10_OP: +// case R_XTENSA_SLOT11_OP: +// case R_XTENSA_SLOT12_OP: +// case R_XTENSA_SLOT13_OP: +// case R_XTENSA_SLOT14_OP: +// case R_XTENSA_SLOT0_ALT: +// case R_XTENSA_SLOT1_ALT: +// case R_XTENSA_SLOT2_ALT: +// case R_XTENSA_SLOT3_ALT: +// case R_XTENSA_SLOT4_ALT: +// case R_XTENSA_SLOT5_ALT: +// case R_XTENSA_SLOT6_ALT: +// case R_XTENSA_SLOT7_ALT: +// case R_XTENSA_SLOT8_ALT: +// case R_XTENSA_SLOT9_ALT: +// case R_XTENSA_SLOT10_ALT: +// case R_XTENSA_SLOT11_ALT: +// case R_XTENSA_SLOT12_ALT: +// case R_XTENSA_SLOT13_ALT: +// case R_XTENSA_SLOT14_ALT: + + case R_XTENSA_TLSDESC_FN: + case R_XTENSA_TLSDESC_ARG: + case R_XTENSA_TLS_DTPOFF: + case R_XTENSA_TLS_TPOFF: + case R_XTENSA_TLS_FUNC: + case R_XTENSA_TLS_ARG: + case R_XTENSA_TLS_CALL: + markAsWarning(program, relocationAddress, type, symbolName, + relocation.getSymbolIndex(), "Thread Local Symbol relocation not supported", + elfRelocationContext.getLog()); break; - case Xtensa_ElfRelocationConstants.R_XTENSA_OP1: - markAsWarning(program, relocationAddress, "R_XTENSA_OP1", symbolName, symbolIndex, - "TODO, needs support ", elfRelocationContext.getLog()); + + case R_XTENSA_NDIFF8: + neg = true; + // fall-through + case R_XTENSA_PDIFF8: + diff_mask = 0xff; + byteLength = 1; break; - case Xtensa_ElfRelocationConstants.R_XTENSA_OP2: - markAsWarning(program, relocationAddress, "R_XTENSA_OP2", symbolName, symbolIndex, - "TODO, needs support ", elfRelocationContext.getLog()); + case R_XTENSA_NDIFF16: + neg = true; + // fall-through + case R_XTENSA_PDIFF16: + diff_mask = 0xffff; + byteLength = 2; break; - case Xtensa_ElfRelocationConstants.R_XTENSA_ASM_EXPAND: - markAsWarning(program, relocationAddress, "R_XTENSA_ASM_EXPAND", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_ASM_SIMPLIFY: - markAsWarning(program, relocationAddress, "R_XTENSA_ASM_SIMPLIFY", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_GNU_VTINHERIT: - markAsWarning(program, relocationAddress, "R_XTENSA_GNU_VTINHERIT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_GNU_VTENTRY: - markAsWarning(program, relocationAddress, "R_XTENSA_GNU_VTENTRY", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF8: - markAsWarning(program, relocationAddress, "R_XTENSA_DIFF8", symbolName, symbolIndex, - "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF16: - markAsWarning(program, relocationAddress, "R_XTENSA_DIFF16", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF32: - markAsWarning(program, relocationAddress, "R_XTENSA_DIFF32", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT0_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT0_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT1_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT1_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT2_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT2_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT3_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT3_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT4_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT4_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT5_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT5_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT6_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT6_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT7_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT7_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT8_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT8_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT9_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT9_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT10_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT10_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT11_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT11_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT12_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT12_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT13_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT13_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT14_OP: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT14_OP", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT0_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT0_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT1_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT1_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT2_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT2_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT3_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT3_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT4_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT4_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT5_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT5_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT6_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT6_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT7_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT7_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT8_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT8_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT9_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT9_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT10_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT10_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT11_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT11_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT12_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT12_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT13_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT13_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); - break; - case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT14_ALT: - markAsWarning(program, relocationAddress, "R_XTENSA_SLOT14_ALT", symbolName, - symbolIndex, "TODO, needs support ", elfRelocationContext.getLog()); + case R_XTENSA_NDIFF32: + neg = true; + // fall-through + case R_XTENSA_PDIFF32: + diff_mask = 0xffffffff; + byteLength = 4; break; default: - markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, - elfRelocationContext.getLog()); + markAsUnhandled(program, relocationAddress, type, relocation.getSymbolIndex(), + symbolName, elfRelocationContext.getLog()); } - return RelocationResult.UNSUPPORTED; + + if (diff_mask != 0) { + //TODO: Not sure if they can all be done here, handle DIFF relocations + //See values: diff_mask, neg, and byteLength + markAsUnhandled(program, relocationAddress, type, relocation.getSymbolIndex(), + symbolName, elfRelocationContext.getLog()); + byteLength = -1; // not yet implemented + } + + if (byteLength < 0) { + return RelocationResult.UNSUPPORTED; + } + return new RelocationResult(Status.APPLIED, byteLength); } } diff --git a/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationType.java b/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationType.java new file mode 100644 index 0000000000..53be181b2b --- /dev/null +++ b/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationType.java @@ -0,0 +1,94 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum Xtensa_ElfRelocationType implements ElfRelocationType { + + /* Xtensa relocations defined by the ABIs */ + R_XTENSA_NONE(0), + R_XTENSA_32(1), + R_XTENSA_RTLD(2), + R_XTENSA_GLOB_DAT(3), + R_XTENSA_JMP_SLOT(4), + R_XTENSA_RELATIVE(5), + R_XTENSA_PLT(6), + R_XTENSA_OP0(8), + R_XTENSA_OP1(9), + R_XTENSA_OP2(10), + R_XTENSA_ASM_EXPAND(11), + R_XTENSA_ASM_SIMPLIFY(12), + + R_XTENSA_32_PCREL(14), + R_XTENSA_GNU_VTINHERIT(15), + R_XTENSA_GNU_VTENTRY(16), + R_XTENSA_DIFF8(17), + R_XTENSA_DIFF16(18), + R_XTENSA_DIFF32(19), + R_XTENSA_SLOT0_OP(20), + R_XTENSA_SLOT1_OP(21), + R_XTENSA_SLOT2_OP(22), + R_XTENSA_SLOT3_OP(23), + R_XTENSA_SLOT4_OP(24), + R_XTENSA_SLOT5_OP(25), + R_XTENSA_SLOT6_OP(26), + R_XTENSA_SLOT7_OP(27), + R_XTENSA_SLOT8_OP(28), + R_XTENSA_SLOT9_OP(29), + R_XTENSA_SLOT10_OP(30), + R_XTENSA_SLOT11_OP(31), + R_XTENSA_SLOT12_OP(32), + R_XTENSA_SLOT13_OP(33), + R_XTENSA_SLOT14_OP(34), + R_XTENSA_SLOT0_ALT(35), + R_XTENSA_SLOT1_ALT(36), + R_XTENSA_SLOT2_ALT(37), + R_XTENSA_SLOT3_ALT(38), + R_XTENSA_SLOT4_ALT(39), + R_XTENSA_SLOT5_ALT(40), + R_XTENSA_SLOT6_ALT(41), + R_XTENSA_SLOT7_ALT(42), + R_XTENSA_SLOT8_ALT(43), + R_XTENSA_SLOT9_ALT(44), + R_XTENSA_SLOT10_ALT(45), + R_XTENSA_SLOT11_ALT(46), + R_XTENSA_SLOT12_ALT(47), + R_XTENSA_SLOT13_ALT(48), + R_XTENSA_SLOT14_ALT(49), + R_XTENSA_TLSDESC_FN(50), + R_XTENSA_TLSDESC_ARG(51), + R_XTENSA_TLS_DTPOFF(52), + R_XTENSA_TLS_TPOFF(53), + R_XTENSA_TLS_FUNC(54), + R_XTENSA_TLS_ARG(55), + R_XTENSA_TLS_CALL(56), + R_XTENSA_PDIFF8(57), + R_XTENSA_PDIFF16(58), + R_XTENSA_PDIFF32(59), + R_XTENSA_NDIFF8(60), + R_XTENSA_NDIFF16(61), + R_XTENSA_NDIFF32(62); + + public final int typeId; + + private Xtensa_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } +} diff --git a/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfeBPFRelocationFixupHandler.java b/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfeBPFRelocationFixupHandler.java deleted file mode 100644 index ff4e895499..0000000000 --- a/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfeBPFRelocationFixupHandler.java +++ /dev/null @@ -1,47 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.util.bin.format.elf.relocation; - -import ghidra.app.plugin.core.reloc.RelocationFixupHandler; -import ghidra.app.util.opinion.ElfLoader; -import ghidra.program.model.address.Address; -import ghidra.program.model.lang.Language; -import ghidra.program.model.lang.Processor; -import ghidra.program.model.listing.Program; -import ghidra.program.model.mem.MemoryAccessException; -import ghidra.program.model.reloc.Relocation; -import ghidra.program.model.util.CodeUnitInsertionException; - -public class ElfeBPFRelocationFixupHandler extends RelocationFixupHandler { - @Override - public boolean processRelocation(Program program, Relocation relocation, Address oldImageBase, - Address newImageBase) throws MemoryAccessException, CodeUnitInsertionException { - return process64BitRelocation(program, relocation, oldImageBase, newImageBase); - } - - @Override - public boolean handlesProgram(Program program) { - if (!ElfLoader.ELF_NAME.equals(program.getExecutableFormat())) { - return false; - } - Language language = program.getLanguage(); - if (language.getLanguageDescription().getSize() != 64) { - return false; - } - Processor processor = language.getProcessor(); - return (processor.equals(Processor.findOrPossiblyCreateProcessor("eBPF"))); - } -} diff --git a/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationHandler.java b/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationHandler.java index e187fc971b..ece40995c6 100644 --- a/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationHandler.java +++ b/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationHandler.java @@ -18,94 +18,91 @@ package ghidra.app.util.bin.format.elf.relocation; import ghidra.app.util.bin.format.elf.*; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; -import ghidra.program.model.mem.*; -import ghidra.program.model.reloc.RelocationResult; +import ghidra.program.model.mem.Memory; +import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.reloc.Relocation.Status; -import ghidra.program.model.symbol.SymbolTable; -import ghidra.util.exception.NotFoundException; +import ghidra.program.model.reloc.RelocationResult; -public class eBPF_ElfRelocationHandler extends ElfRelocationHandler { - @Override - public boolean canRelocate(ElfHeader elf) { - return elf.e_machine() == ElfConstants.EM_BPF; - } +public class eBPF_ElfRelocationHandler + extends AbstractElfRelocationHandler> { - @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, ElfRelocation relocation, - Address relocationAddress) throws MemoryAccessException, NotFoundException { + /** + * Constructor + */ + public eBPF_ElfRelocationHandler() { + super(eBPF_ElfRelocationType.class); + } - ElfHeader elf = elfRelocationContext.getElfHeader(); - if (elf.e_machine() != ElfConstants.EM_BPF) { - return RelocationResult.FAILURE; - } + @Override + public boolean canRelocate(ElfHeader elf) { + return elf.e_machine() == ElfConstants.EM_BPF; + } - Program program = elfRelocationContext.getProgram(); - Memory memory = program.getMemory(); + @Override + protected RelocationResult relocate(ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, eBPF_ElfRelocationType type, Address relocationAddress, + ElfSymbol symbol, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { - int type = relocation.getType(); - if (type == eBPF_ElfRelocationConstants.R_BPF_NONE) { - return RelocationResult.SKIPPED; - } + Program program = elfRelocationContext.getProgram(); + Memory memory = program.getMemory(); - String section_name = elfRelocationContext.relocationTable.getSectionToBeRelocated().getNameAsString(); - if (section_name.toString().contains("debug")) { - return RelocationResult.SKIPPED; - } + String section_name = + elfRelocationContext.relocationTable.getSectionToBeRelocated().getNameAsString(); + if (section_name.toString().contains("debug")) { + return RelocationResult.SKIPPED; + } - SymbolTable table = program.getSymbolTable(); - int symbolIndex = relocation.getSymbolIndex(); - ElfSymbol symbol = elfRelocationContext.getSymbol(symbolIndex); - String symbolName = symbol.getNameAsString(); - Address symbolAddr = table.getSymbols(symbolName).next().getAddress(); + int symbolIndex = relocation.getSymbolIndex(); + long new_value = 0; + int byteLength = 8; - long new_value = 0; - int byteLength = 4; // most relocations affect 4-bytes - - try { - switch (type){ - case eBPF_ElfRelocationConstants.R_BPF_64_64: { - new_value = symbolAddr.getAddressableWordOffset(); - Byte dst = memory.getByte(relocationAddress.add(0x1)); - memory.setLong(relocationAddress.add(0x4), new_value); - memory.setByte(relocationAddress.add(0x1), (byte)(dst + 0x10)); - break; - } - case eBPF_ElfRelocationConstants.R_BPF_64_32: { - - // if we have, e.g, non-static function, it will be marked in the relocation table - // and indexed in the symbol table and it's easy to calculate the pc-relative offset - long instr_next = relocationAddress.add(0x8).getAddressableWordOffset(); - if (symbol.isFunction()) { - new_value = symbolAddr.getAddressableWordOffset(); - int offset = (int)(new_value - instr_next); - memory.setInt(relocationAddress.add(0x4), offset); - } else if (symbol.isSection()) { - if (memory.getInt(relocationAddress) == 0x1085) { - ElfSectionHeader sectionHeader = elfRelocationContext.getElfHeader().getSection(symbolName); - long section_start = program.getImageBase().getOffset() + sectionHeader.getAddress(); + switch (type) { + case R_BPF_64_64: { + new_value = symbolAddr.getAddressableWordOffset(); + Byte dst = memory.getByte(relocationAddress.add(0x1)); + memory.setLong(relocationAddress.add(0x4), new_value); + memory.setByte(relocationAddress.add(0x1), (byte) (dst + 0x10)); + break; + } + case R_BPF_64_32: { - // getting call instruction offset (current imm) - int current_imm = memory.getInt(relocationAddress.add(0x4)); + // if we have, e.g, non-static function, it will be marked in the relocation table + // and indexed in the symbol table and it's easy to calculate the pc-relative offset + long instr_next = relocationAddress.add(0x8).getAddressableWordOffset(); + if (symbol.isFunction()) { + new_value = symbolAddr.getAddressableWordOffset(); + int offset = (int) (new_value - instr_next); + memory.setInt(relocationAddress.add(0x4), offset); + } + else if (symbol.isSection()) { + if (memory.getInt(relocationAddress) == 0x1085) { + ElfSectionHeader sectionHeader = + elfRelocationContext.getElfHeader().getSection(symbolName); + long section_start = + program.getImageBase().getOffset() + sectionHeader.getAddress(); - // calculate the call target section offset - // according to formula in "kernel.org" docs: https://www.kernel.org/doc/html/latest/bpf/llvm_reloc.html - int func_sec_offset = (current_imm + 1) * 8; - long func_addr = section_start + func_sec_offset; - int offset = (int)(func_addr - instr_next); - memory.setInt(relocationAddress.add(0x4), offset); - } - } - break; - } - default: { - if (symbolIndex == 0) { - markAsWarning(program, relocationAddress, - Long.toString(type), "applied relocation with symbol-index of 0", elfRelocationContext.getLog()); - } - return RelocationResult.UNSUPPORTED; - } - } - } catch (NullPointerException e) { } - return new RelocationResult(Status.APPLIED, byteLength); - } + // getting call instruction offset (current imm) + int current_imm = memory.getInt(relocationAddress.add(0x4)); + + // calculate the call target section offset + // according to formula in "kernel.org" docs: https://www.kernel.org/doc/html/latest/bpf/llvm_reloc.html + int func_sec_offset = (current_imm + 1) * 8; + long func_addr = section_start + func_sec_offset; + int offset = (int) (func_addr - instr_next); + memory.setInt(relocationAddress.add(0x4), offset); + } + } + break; + } + default: { + if (symbolIndex == 0) { + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, + "applied relocation with symbol-index of 0", elfRelocationContext.getLog()); + } + return RelocationResult.UNSUPPORTED; + } + } + return new RelocationResult(Status.APPLIED, byteLength); + } } diff --git a/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationType.java b/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationType.java new file mode 100644 index 0000000000..9de64e6b53 --- /dev/null +++ b/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationType.java @@ -0,0 +1,37 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum eBPF_ElfRelocationType implements ElfRelocationType { + + R_BPF_NONE(0), // No operation needed + R_BPF_64_64(1), // S + A + R_BPF_64_ABS64(2), // S + A + R_BPF_64_ABS32(3), // S + A + R_BPF_64_NODYLD32(4), // S + A + R_BPF_64_32(10); // (S + A) / 8 - 1 + + public final int typeId; + + private eBPF_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } +} diff --git a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/Elfx86_32bitRelocationFixupHandler.java b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/Elfx86_32bitRelocationFixupHandler.java index 048e4ee043..7b46ea6523 100644 --- a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/Elfx86_32bitRelocationFixupHandler.java +++ b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/Elfx86_32bitRelocationFixupHandler.java @@ -15,7 +15,7 @@ */ package ghidra.app.util.bin.format.elf.relocation; -import ghidra.app.plugin.core.reloc.RelocationFixupHandler; +import ghidra.app.plugin.core.reloc.ElfRelocationFixupHandler; import ghidra.app.util.opinion.ElfLoader; import ghidra.program.model.address.Address; import ghidra.program.model.lang.Language; @@ -23,51 +23,45 @@ import ghidra.program.model.lang.Processor; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.reloc.Relocation; +import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.util.CodeUnitInsertionException; -public class Elfx86_32bitRelocationFixupHandler extends RelocationFixupHandler { +public class Elfx86_32bitRelocationFixupHandler extends ElfRelocationFixupHandler { + + public Elfx86_32bitRelocationFixupHandler() { + super(X86_32_ElfRelocationType.class); + } @Override public boolean processRelocation(Program program, Relocation relocation, Address oldImageBase, Address newImageBase) throws MemoryAccessException, CodeUnitInsertionException { - switch (relocation.getType()) { - case X86_32_ElfRelocationConstants.R_386_NONE: - case X86_32_ElfRelocationConstants.R_386_32: - case X86_32_ElfRelocationConstants.R_386_PC32: - case X86_32_ElfRelocationConstants.R_386_GOT32: - case X86_32_ElfRelocationConstants.R_386_PLT32: - case X86_32_ElfRelocationConstants.R_386_COPY: - case X86_32_ElfRelocationConstants.R_386_GLOB_DAT: - case X86_32_ElfRelocationConstants.R_386_JMP_SLOT: - case X86_32_ElfRelocationConstants.R_386_RELATIVE: - case X86_32_ElfRelocationConstants.R_386_GOTOFF: - case X86_32_ElfRelocationConstants.R_386_GOTPC: - - case X86_32_ElfRelocationConstants.R_386_TLS_TPOFF: - case X86_32_ElfRelocationConstants.R_386_TLS_IE: - case X86_32_ElfRelocationConstants.R_386_TLS_GOTIE: - case X86_32_ElfRelocationConstants.R_386_TLS_LE: - case X86_32_ElfRelocationConstants.R_386_TLS_GD: - case X86_32_ElfRelocationConstants.R_386_TLS_LDM: - case X86_32_ElfRelocationConstants.R_386_TLS_GD_32: - case X86_32_ElfRelocationConstants.R_386_TLS_GD_PUSH: - case X86_32_ElfRelocationConstants.R_386_TLS_GD_CALL: - case X86_32_ElfRelocationConstants.R_386_TLS_GD_POP: - case X86_32_ElfRelocationConstants.R_386_TLS_LDM_32: - case X86_32_ElfRelocationConstants.R_386_TLS_LDM_PUSH: - case X86_32_ElfRelocationConstants.R_386_TLS_LDM_CALL: - case X86_32_ElfRelocationConstants.R_386_TLS_LDM_POP: - case X86_32_ElfRelocationConstants.R_386_TLS_LDO_32: - case X86_32_ElfRelocationConstants.R_386_TLS_IE_32: - case X86_32_ElfRelocationConstants.R_386_TLS_LE_32: - case X86_32_ElfRelocationConstants.R_386_TLS_DTPMOD32: - case X86_32_ElfRelocationConstants.R_386_TLS_DTPOFF32: - case X86_32_ElfRelocationConstants.R_386_TLS_TPOFF32: - return process32BitRelocation(program, relocation, oldImageBase, newImageBase); + if (relocation.getStatus() != Status.APPLIED) { + return false; } - return false; + X86_32_ElfRelocationType type = + (X86_32_ElfRelocationType) getRelocationType(relocation.getType()); + if (type == null) { + return false; + } + + switch (type) { + case R_386_32: + case R_386_PC32: + case R_386_GOT32: + case R_386_PLT32: + case R_386_COPY: + case R_386_GLOB_DAT: + case R_386_JMP_SLOT: + case R_386_RELATIVE: + case R_386_GOTOFF: + case R_386_GOTPC: + return process32BitRelocation(program, relocation, oldImageBase, newImageBase); + + default: + return false; + } } @Override diff --git a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/Elfx86_64bitRelocationFixupHandler.java b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/Elfx86_64bitRelocationFixupHandler.java index 0ea1773c63..70e1e9054f 100644 --- a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/Elfx86_64bitRelocationFixupHandler.java +++ b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/Elfx86_64bitRelocationFixupHandler.java @@ -15,7 +15,7 @@ */ package ghidra.app.util.bin.format.elf.relocation; -import ghidra.app.plugin.core.reloc.RelocationFixupHandler; +import ghidra.app.plugin.core.reloc.ElfRelocationFixupHandler; import ghidra.app.util.opinion.ElfLoader; import ghidra.program.model.address.Address; import ghidra.program.model.lang.Language; @@ -23,60 +23,43 @@ import ghidra.program.model.lang.Processor; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.reloc.Relocation; +import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.util.CodeUnitInsertionException; -public class Elfx86_64bitRelocationFixupHandler extends RelocationFixupHandler { +public class Elfx86_64bitRelocationFixupHandler extends ElfRelocationFixupHandler { + + public Elfx86_64bitRelocationFixupHandler() { + super(X86_64_ElfRelocationType.class); + } @Override public boolean processRelocation(Program program, Relocation relocation, Address oldImageBase, Address newImageBase) throws MemoryAccessException, CodeUnitInsertionException { - switch (relocation.getType()) { - case X86_64_ElfRelocationConstants.R_X86_64_NONE: - case X86_64_ElfRelocationConstants.R_X86_64_64: - case X86_64_ElfRelocationConstants.R_X86_64_PC32: - case X86_64_ElfRelocationConstants.R_X86_64_GOT32: - case X86_64_ElfRelocationConstants.R_X86_64_PLT32: - case X86_64_ElfRelocationConstants.R_X86_64_COPY: - case X86_64_ElfRelocationConstants.R_X86_64_GLOB_DAT: - case X86_64_ElfRelocationConstants.R_X86_64_JUMP_SLOT: - case X86_64_ElfRelocationConstants.R_X86_64_RELATIVE: - case X86_64_ElfRelocationConstants.R_X86_64_GOTPCREL: - case X86_64_ElfRelocationConstants.R_X86_64_32: - case X86_64_ElfRelocationConstants.R_X86_64_32S: - case X86_64_ElfRelocationConstants.R_X86_64_16: - case X86_64_ElfRelocationConstants.R_X86_64_PC16: - case X86_64_ElfRelocationConstants.R_X86_64_8: - case X86_64_ElfRelocationConstants.R_X86_64_PC8: - case X86_64_ElfRelocationConstants.R_X86_64_DTPMOD64: - case X86_64_ElfRelocationConstants.R_X86_64_DTPOFF64: - case X86_64_ElfRelocationConstants.R_X86_64_TPOFF64: - case X86_64_ElfRelocationConstants.R_X86_64_TLSGD: - case X86_64_ElfRelocationConstants.R_X86_64_TLSLD: - case X86_64_ElfRelocationConstants.R_X86_64_DTPOFF32: - case X86_64_ElfRelocationConstants.R_X86_64_GOTTPOFF: - case X86_64_ElfRelocationConstants.R_X86_64_TPOFF32: - case X86_64_ElfRelocationConstants.R_X86_64_PC64: - case X86_64_ElfRelocationConstants.R_X86_64_GOTOFF64: - case X86_64_ElfRelocationConstants.R_X86_64_GOTPC32: - case X86_64_ElfRelocationConstants.R_X86_64_GOT64: - case X86_64_ElfRelocationConstants.R_X86_64_GOTPCREL64: - case X86_64_ElfRelocationConstants.R_X86_64_GOTPC64: - case X86_64_ElfRelocationConstants.R_X86_64_GOTPLT64: - case X86_64_ElfRelocationConstants.R_X86_64_PLTOFF64: - case X86_64_ElfRelocationConstants.R_X86_64_SIZE32: - case X86_64_ElfRelocationConstants.R_X86_64_SIZE64: - case X86_64_ElfRelocationConstants.R_X86_64_GOTPC32_TLSDESC: - case X86_64_ElfRelocationConstants.R_X86_64_TLSDESC_CALL: - case X86_64_ElfRelocationConstants.R_X86_64_TLSDESC: - case X86_64_ElfRelocationConstants.R_X86_64_IRELATIVE: - case X86_64_ElfRelocationConstants.R_X86_64_RELATIVE64: - case X86_64_ElfRelocationConstants.R_X86_64_NUM: - case X86_64_ElfRelocationConstants.R_X86_64_GNU_VTINHERIT: - case X86_64_ElfRelocationConstants.R_X86_64_GNU_VTENTRY: - return process64BitRelocation(program, relocation, oldImageBase, newImageBase); + if (relocation.getStatus() != Status.APPLIED) { + return false; + } + + X86_64_ElfRelocationType type = + (X86_64_ElfRelocationType) getRelocationType(relocation.getType()); + if (type == null) { + return false; + } + + switch (type) { + case R_X86_64_COPY: + case R_X86_64_64: + case R_X86_64_RELATIVE: + case R_X86_64_RELATIVE64: + case R_X86_64_GLOB_DAT: + case R_X86_64_JUMP_SLOT: + case R_X86_64_GOTPCREL64: + case R_X86_64_IRELATIVE: + return process64BitRelocation(program, relocation, oldImageBase, newImageBase); + default: + // TODO: Apply bookmark where relocation fixup failed to be processed + return false; } - return false; } @Override diff --git a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_32_ElfRelocationConstants.java b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_32_ElfRelocationConstants.java deleted file mode 100644 index df5f342949..0000000000 --- a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_32_ElfRelocationConstants.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.util.bin.format.elf.relocation; - -public class X86_32_ElfRelocationConstants { - - public static final int R_386_NONE = 0; // No calculation - public static final int R_386_32 = 1; // S + A - public static final int R_386_PC32 = 2; // S + A - P - public static final int R_386_GOT32 = 3; // G + A - P - public static final int R_386_PLT32 = 4; // L + A - P - public static final int R_386_COPY = 5; // No calculation - public static final int R_386_GLOB_DAT = 6; // S - public static final int R_386_JMP_SLOT = 7; // S - public static final int R_386_RELATIVE = 8; // B + A - public static final int R_386_GOTOFF = 9; // S + A - GOT - public static final int R_386_GOTPC = 10; // GOT + A - P - public static final int R_386_32PLT = 11; - - public static final int R_386_TLS_TPOFF = 14; // negative offset in static TLS block - public static final int R_386_TLS_IE = 15; // absolute address of GOT entry for negative static TLS block offset - public static final int R_386_TLS_GOTIE = 16; // GOT entry for negative static TLS block offset - public static final int R_386_TLS_LE = 17; // negative offset relative to static TLS - public static final int R_386_TLS_GD = 18; // direct 32 bit for GNU version of GD TLS - public static final int R_386_TLS_LDM = 19; // direct 32 bit for GNU version of LD TLS in LE code - public static final int R_386_TLS_GD_32 = 24; // direct 32 bit for GD TLS - public static final int R_386_TLS_GD_PUSH = 25; // tag for pushl in GD TLS code - public static final int R_386_TLS_GD_CALL = 26; // relocation for call - public static final int R_386_TLS_GD_POP = 27; // tag for popl in GD TLS code - public static final int R_386_TLS_LDM_32 = 28; // direct 32 bit for local dynamic code - public static final int R_386_TLS_LDM_PUSH = 29; // tag for pushl in LDM TLS code - public static final int R_386_TLS_LDM_CALL = 30; // relocation for call - public static final int R_386_TLS_LDM_POP = 31; // tag for popl in LDM TLS code - public static final int R_386_TLS_LDO_32 = 32; // offset relative to TLS block - public static final int R_386_TLS_IE_32 = 33; // got entry for static TLS block - public static final int R_386_TLS_LE_32 = 34; // offset relative to static TLS block - public static final int R_386_TLS_DTPMOD32 = 35; // ID of module containing symbol - public static final int R_386_TLS_DTPOFF32 = 36; // offset in TLS block - public static final int R_386_TLS_TPOFF32 = 37; // offset in static TLS block - public static final int R_386_TLS_GOTDESC = 39; // GOT offset for TLS descriptor. */ - public static final int R_386_TLS_DESC_CALL = 40; // Marker of call through TLS descriptor for relaxation. */ - public static final int R_386_TLS_DESC = 41; // TLS descriptor containing pointer to code and to argument, returning the TLS offset for the symbol. */ - public static final int R_386_IRELATIVE = 42; // Adjust indirectly by program base */ - - private X86_32_ElfRelocationConstants() { - // no construct - } -} diff --git a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_32_ElfRelocationHandler.java b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_32_ElfRelocationHandler.java index f3cdfdbdee..f32082d802 100644 --- a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_32_ElfRelocationHandler.java +++ b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_32_ElfRelocationHandler.java @@ -24,7 +24,15 @@ import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.reloc.RelocationResult; import ghidra.util.exception.NotFoundException; -public class X86_32_ElfRelocationHandler extends ElfRelocationHandler { +public class X86_32_ElfRelocationHandler + extends AbstractElfRelocationHandler> { + + /** + * Constructor + */ + public X86_32_ElfRelocationHandler() { + super(X86_32_ElfRelocationType.class); + } @Override public boolean canRelocate(ElfHeader elf) { @@ -33,113 +41,84 @@ public class X86_32_ElfRelocationHandler extends ElfRelocationHandler { @Override public int getRelrRelocationType() { - return X86_32_ElfRelocationConstants.R_386_RELATIVE; + return X86_32_ElfRelocationType.R_386_RELATIVE.typeId; } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, - Address relocationAddress) throws MemoryAccessException, NotFoundException { - - ElfHeader elf = elfRelocationContext.getElfHeader(); - if (elf.e_machine() != ElfConstants.EM_386) { - return RelocationResult.FAILURE; - } + protected RelocationResult relocate(ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, X86_32_ElfRelocationType type, Address relocationAddress, + ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); - int type = relocation.getType(); - if (type == X86_32_ElfRelocationConstants.R_386_NONE) { - return RelocationResult.SKIPPED; - } - - int symbolIndex = relocation.getSymbolIndex(); - // addend is either pulled from the relocation or the bytes in memory long addend = relocation.hasAddend() ? relocation.getAddend() : memory.getInt(relocationAddress); - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); - Address symbolAddr = elfRelocationContext.getSymbolAddress(sym); - long symbolValue = elfRelocationContext.getSymbolValue(sym); - String symbolName = elfRelocationContext.getSymbolName(symbolIndex); - long offset = (int) relocationAddress.getOffset(); - + int symbolIndex = relocation.getSymbolIndex(); int byteLength = 4; // most relocations affect 4-bytes (change if different) int value; switch (type) { - case X86_32_ElfRelocationConstants.R_386_32: + case R_386_32: value = (int) (symbolValue + addend); memory.setInt(relocationAddress, value); if (symbolIndex != 0 && addend != 0 && !sym.isSection()) { - warnExternalOffsetRelocation(program, relocationAddress, - symbolAddr, symbolName, addend, elfRelocationContext.getLog()); + warnExternalOffsetRelocation(program, relocationAddress, symbolAddr, symbolName, + addend, elfRelocationContext.getLog()); applyComponentOffsetPointer(program, relocationAddress, addend); } break; - case X86_32_ElfRelocationConstants.R_386_PC32: + case R_386_PC32: value = (int) (symbolValue + addend - offset); memory.setInt(relocationAddress, value); break; // we punt on these because they're not linked yet! - case X86_32_ElfRelocationConstants.R_386_GOT32: + case R_386_GOT32: value = (int) (symbolValue + addend); memory.setInt(relocationAddress, value); break; - case X86_32_ElfRelocationConstants.R_386_PLT32: + case R_386_PLT32: value = (int) (symbolValue + addend - offset); memory.setInt(relocationAddress, value); break; - case X86_32_ElfRelocationConstants.R_386_GLOB_DAT: - case X86_32_ElfRelocationConstants.R_386_JMP_SLOT: + case R_386_GLOB_DAT: + case R_386_JMP_SLOT: value = (int) symbolValue; memory.setInt(relocationAddress, value); break; - case X86_32_ElfRelocationConstants.R_386_GOTOFF: + case R_386_GOTOFF: try { long dotgot = elfRelocationContext.getGOTValue(); value = (int) symbolValue + (int) addend - (int) dotgot; memory.setInt(relocationAddress, value); } catch (NotFoundException e) { - markAsError(program, relocationAddress, "R_386_GOTOFF", symbolName, + markAsError(program, relocationAddress, type, symbolName, symbolIndex, e.getMessage(), elfRelocationContext.getLog()); } break; - case X86_32_ElfRelocationConstants.R_386_COPY: - markAsWarning(program, relocationAddress, "R_386_COPY", symbolName, symbolIndex, + case R_386_COPY: + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, "Runtime copy not supported", elfRelocationContext.getLog()); break; // Thread Local Symbol relocations (unimplemented concept) - case X86_32_ElfRelocationConstants.R_386_TLS_DTPMOD32: - markAsWarning(program, relocationAddress, "R_386_TLS_DTPMOD32", symbolName, - symbolIndex, "Thread Local Symbol relocation not supported", - elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - case X86_32_ElfRelocationConstants.R_386_TLS_DTPOFF32: - markAsWarning(program, relocationAddress, "R_386_TLS_DTPOFF32", symbolName, - symbolIndex, "Thread Local Symbol relocation not supported", - elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - case X86_32_ElfRelocationConstants.R_386_TLS_TPOFF32: - markAsWarning(program, relocationAddress, "R_386_TLS_TPOFF32", symbolName, - symbolIndex, "Thread Local Symbol relocation not supported", - elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - case X86_32_ElfRelocationConstants.R_386_TLS_TPOFF: - markAsWarning(program, relocationAddress, "R_386_TLS_TPOFF", symbolName, - symbolIndex, "Thread Local Symbol relocation not supported", - elfRelocationContext.getLog()); + case R_386_TLS_DTPMOD32: + case R_386_TLS_DTPOFF32: + case R_386_TLS_TPOFF32: + case R_386_TLS_TPOFF: + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, + "Thread Local Symbol relocation not supported", elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; // cases which do not use symbol value - case X86_32_ElfRelocationConstants.R_386_RELATIVE: + case R_386_RELATIVE: long base = program.getImageBase().getOffset(); - if (elf.isPreLinked()) { + if (elfRelocationContext.getElfHeader().isPreLinked()) { // adjust prelinked value that is already in memory value = memory.getInt(relocationAddress) + (int) elfRelocationContext.getImageBaseWordAdjustmentOffset(); @@ -150,14 +129,14 @@ public class X86_32_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, value); break; - case X86_32_ElfRelocationConstants.R_386_IRELATIVE: + case R_386_IRELATIVE: // NOTE: We don't support this since the code actually uses a function to // compute the relocation value (i.e., indirect) - markAsError(program, relocationAddress, "R_386_IRELATIVE", symbolName, - "indirect computed relocation not supported", elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Indirect computed relocation not supported", elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; - case X86_32_ElfRelocationConstants.R_386_GOTPC: + case R_386_GOTPC: // similar to R_386_PC32 but uses .got address instead of symbol address try { long dotgot = elfRelocationContext.getGOTValue(); @@ -165,31 +144,31 @@ public class X86_32_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, value); } catch (NotFoundException e) { - markAsError(program, relocationAddress, "R_386_GOTPC", symbolName, + markAsError(program, relocationAddress, type, symbolName, symbolIndex, e.getMessage(), elfRelocationContext.getLog()); } break; // TODO: Cases not yet examined - // case ElfRelocationConstants.R_386_32PLT - // case ElfRelocationConstants.R_386_TLS_IE: - // case ElfRelocationConstants.R_386_TLS_GOTIE: - // case ElfRelocationConstants.R_386_TLS_LE: - // case ElfRelocationConstants.R_386_TLS_GD: - // case ElfRelocationConstants.R_386_TLS_LDM: - // case ElfRelocationConstants.R_386_TLS_GD_32: - // case ElfRelocationConstants.R_386_TLS_GD_PUSH: - // case ElfRelocationConstants.R_386_TLS_GD_CALL: - // case ElfRelocationConstants.R_386_TLS_GD_POP: - // case ElfRelocationConstants.R_386_TLS_LDM_32: - // case ElfRelocationConstants.R_386_TLS_LDM_PUSH: - // case ElfRelocationConstants.R_386_TLS_LDO_32: - // case ElfRelocationConstants.R_386_TLS_IE_32: - // case ElfRelocationConstants.R_386_TLS_LE_32: - // case ElfRelocationConstants.R_386_TLS_GOTDESC: - // case ElfRelocationConstants.R_386_TLS_GOTDESC: - // case ElfRelocationConstants.R_386_TLS_DESC_CALL: - // case ElfRelocationConstants.R_386_TLS_DESC: + // case R_386_32PLT + // case R_386_TLS_IE: + // case R_386_TLS_GOTIE: + // case R_386_TLS_LE: + // case R_386_TLS_GD: + // case R_386_TLS_LDM: + // case R_386_TLS_GD_32: + // case R_386_TLS_GD_PUSH: + // case R_386_TLS_GD_CALL: + // case R_386_TLS_GD_POP: + // case R_386_TLS_LDM_32: + // case R_386_TLS_LDM_PUSH: + // case R_386_TLS_LDO_32: + // case R_386_TLS_IE_32: + // case R_386_TLS_LE_32: + // case R_386_TLS_GOTDESC: + // case R_386_TLS_GOTDESC: + // case R_386_TLS_DESC_CALL: + // case R_386_TLS_DESC: default: markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, @@ -198,4 +177,5 @@ public class X86_32_ElfRelocationHandler extends ElfRelocationHandler { } return new RelocationResult(Status.APPLIED, byteLength); } + } diff --git a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_32_ElfRelocationType.java b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_32_ElfRelocationType.java new file mode 100644 index 0000000000..f8066692ea --- /dev/null +++ b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_32_ElfRelocationType.java @@ -0,0 +1,69 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum X86_32_ElfRelocationType implements ElfRelocationType { + + R_386_NONE(0), // No calculation + R_386_32(1), // S + A + R_386_PC32(2), // S + A - P + R_386_GOT32(3), // G + A - P + R_386_PLT32(4), // L + A - P + R_386_COPY(5), // No calculation + R_386_GLOB_DAT(6), // S + R_386_JMP_SLOT(7), // S + R_386_RELATIVE(8), // B + A + R_386_GOTOFF(9), // S + A - GOT + R_386_GOTPC(10), // GOT + A - P + R_386_32PLT(11), + + R_386_TLS_TPOFF(14), // negative offset in static TLS block + R_386_TLS_IE(15), // absolute address of GOT entry for negative static TLS block offset + R_386_TLS_GOTIE(16), // GOT entry for negative static TLS block offset + R_386_TLS_LE(17), // negative offset relative to static TLS + R_386_TLS_GD(18), // direct 32 bit for GNU version of GD TLS + R_386_TLS_LDM(19), // direct 32 bit for GNU version of LD TLS in LE code + R_386_TLS_GD_32(24), // direct 32 bit for GD TLS + R_386_TLS_GD_PUSH(25), // tag for pushl in GD TLS code + R_386_TLS_GD_CALL(26), // relocation for call + R_386_TLS_GD_POP(27), // tag for popl in GD TLS code + R_386_TLS_LDM_32(28), // direct 32 bit for local dynamic code + R_386_TLS_LDM_PUSH(29), // tag for pushl in LDM TLS code + R_386_TLS_LDM_CALL(30), // relocation for call + R_386_TLS_LDM_POP(31), // tag for popl in LDM TLS code + R_386_TLS_LDO_32(32), // offset relative to TLS block + R_386_TLS_IE_32(33), // got entry for static TLS block + R_386_TLS_LE_32(34), // offset relative to static TLS block + R_386_TLS_DTPMOD32(35), // ID of module containing symbol + R_386_TLS_DTPOFF32(36), // offset in TLS block + R_386_TLS_TPOFF32(37), // offset in static TLS block + R_386_TLS_GOTDESC(39), // GOT offset for TLS descriptor. */ + R_386_TLS_DESC_CALL(40), // Marker of call through TLS descriptor for relaxation. */ + R_386_TLS_DESC(41), // TLS descriptor containing pointer to code and to argument, returning the TLS offset for the symbol. */ + R_386_IRELATIVE(42); // Adjust indirectly by program base */ + + public final int typeId; + + private X86_32_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } + +} diff --git a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationConstants.java b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationConstants.java deleted file mode 100644 index a5e43220ed..0000000000 --- a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationConstants.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.util.bin.format.elf.relocation; - -public class X86_64_ElfRelocationConstants { - - public static final int R_X86_64_NONE = 0; /* No reloc */ - /** S + A */ - public static final int R_X86_64_64 = 1; /* Direct 64 bit */ - /** S + A - P */ - public static final int R_X86_64_PC32 = 2; /* PC relative 32 bit signed */ - /** G + P */ - public static final int R_X86_64_GOT32 = 3; /* 32 bit GOT entry */ - /** L + A - P */ - public static final int R_X86_64_PLT32 = 4; /* 32 bit PLT address */ - /** ? */ - public static final int R_X86_64_COPY = 5; /* Copy symbol at runtime */ - /** S */ - public static final int R_X86_64_GLOB_DAT = 6; /* Create GOT entry */ - /** S */ - public static final int R_X86_64_JUMP_SLOT = 7; /* Create PLT entry */ - /** B + A */ - public static final int R_X86_64_RELATIVE = 8; /* Adjust by program base */ - /** G + GOT + A - P */ - public static final int R_X86_64_GOTPCREL = 9; /* - * 32 bit signed pc relative - * offset to GOT - */ - /** S + A */ - public static final int R_X86_64_32 = 10; /* Direct 32 bit zero extended */ - /** S + A */ - public static final int R_X86_64_32S = 11; /* Direct 32 bit sign extended */ - /** S + A */ - public static final int R_X86_64_16 = 12; /* Direct 16 bit zero extended */ - /** S + A - P */ - public static final int R_X86_64_PC16 = 13; /* - * 16 bit sign extended pc - * relative - */ - /** S + A */ - public static final int R_X86_64_8 = 14; /* Direct 8 bit sign extended */ - /** S + A - P */ - public static final int R_X86_64_PC8 = 15; /* - * 8 bit sign extended pc - * relative - */ - /** - * Calculates the object identifier of the - * object containing the TLS symbol. - */ - public static final int R_X86_64_DTPMOD64 = 16; // ID of module containing symbol - /** - * Calculates the offset of the variable relative - * to the start of the TLS block that contains the - * variable. The computed value is used as an - * immediate value of an addend and is not associated - * with a specific register. - * - */ - public static final int R_X86_64_DTPOFF64 = 17; // Offset in module's TLS block - public static final int R_X86_64_TPOFF64 = 18; // offset in the initial TLS block - public static final int R_X86_64_TLSGD = 19; // 32 bit signed PC relative offset to - // two GOT entries for GD symbol - public static final int R_X86_64_TLSLD = 20; // 32 bit signed PC relative offset to - // two GOT entries for LD symbol - public static final int R_X86_64_DTPOFF32 = 21; // offset in TLS block - public static final int R_X86_64_GOTTPOFF = 22; // 32 bit signed pc relative offst to - // GOT entry for IE symbol - public static final int R_X86_64_TPOFF32 = 23; // offset in initial TLS block - - /** S + A - P */ - public static final int R_X86_64_PC64 = 24; // PC relative 64 bit - - /** S + A - GOT */ - public static final int R_X86_64_GOTOFF64 = 25; // 64 bit offset to GOT - /** GOT + A + P */ - public static final int R_X86_64_GOTPC32 = 26; // 32 bit signed pc relative offset to GOT - public static final int R_X86_64_GOT64 = 27; // 64 bit GOT entry offset - public static final int R_X86_64_GOTPCREL64 = 28; // 64 bit pc relative offset to GOT entry - public static final int R_X86_64_GOTPC64 = 29; // 64 bit pc relative offset to GOT - public static final int R_X86_64_GOTPLT64 = 30; // - public static final int R_X86_64_PLTOFF64 = 31; // 64 bit GOT relative offset to PLT entry - /** Z + A */ - public static final int R_X86_64_SIZE32 = 32; // Size of symbol plus 32 bit addend - /** Z + A */ - public static final int R_X86_64_SIZE64 = 33; // Size of symbol plus 64 bit addend - public static final int R_X86_64_GOTPC32_TLSDESC = 34; // GOT offset for TLS descriptor - public static final int R_X86_64_TLSDESC_CALL = 35; // Marker for call through TLS descriptor - public static final int R_X86_64_TLSDESC = 36; // TLS descriptor; word64 * 2 - public static final int R_X86_64_IRELATIVE = 37; // Adjust indirectly by program base - public static final int R_X86_64_RELATIVE64 = 38; // 64-bit adjust by program base - - public static final int R_X86_64_PC32_BND = 39; // deprecated - public static final int R_X86_64_PLT32_BND = 40; // deprecated - public static final int R_X86_64_GOTPCRELX = 41; // G + GOT + A - P - public static final int R_X86_64_REX_GOTPCRELX = 42; //G + GOT + A - P - - public static final int R_X86_64_NUM = 43; - - public static final int R_X86_64_GNU_VTINHERIT = 250; - public static final int R_X86_64_GNU_VTENTRY = 251; - - private X86_64_ElfRelocationConstants() { - // no construct - } -} diff --git a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationContext.java b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationContext.java index 0b84b04acb..91bd457cdc 100644 --- a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationContext.java +++ b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationContext.java @@ -31,7 +31,7 @@ import ghidra.util.exception.*; * Global Offset Table (GOT) to facilitate GOT related relocations encountered within * object modules. */ -class X86_64_ElfRelocationContext extends ElfRelocationContext { +class X86_64_ElfRelocationContext extends ElfRelocationContext { private AddressRange allocatedGotLimits; private Address allocatedGotAddress; @@ -116,16 +116,21 @@ class X86_64_ElfRelocationContext extends ElfRelocationContext { private boolean requiresGotEntry(ElfRelocation r) { - switch (r.getType()) { - case X86_64_ElfRelocationConstants.R_X86_64_GOTPCREL: -// case X86_64_ElfRelocationConstants.R_X86_64_GOTOFF64: -// case X86_64_ElfRelocationConstants.R_X86_64_GOTPC32: -// case X86_64_ElfRelocationConstants.R_X86_64_GOT64: - case X86_64_ElfRelocationConstants.R_X86_64_GOTPCREL64: -// case X86_64_ElfRelocationConstants.R_X86_64_GOTPC64: + X86_64_ElfRelocationType type = handler.getRelocationType(r.getType()); + if (type == null) { + return false; + } + + switch (type) { + case R_X86_64_GOTPCREL: +// case R_X86_64_GOTOFF64: +// case R_X86_64_GOTPC32: +// case R_X86_64_GOT64: + case R_X86_64_GOTPCREL64: +// case R_X86_64_GOTPC64: return true; - case X86_64_ElfRelocationConstants.R_X86_64_GOTPCRELX: - case X86_64_ElfRelocationConstants.R_X86_64_REX_GOTPCRELX: + case R_X86_64_GOTPCRELX: + case R_X86_64_REX_GOTPCRELX: // NOTE: Relocation may not actually require GOT entry in which case %got // may be over-allocated, but is required in some cases. return true; diff --git a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationHandler.java b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationHandler.java index c480a8ff01..71c966006b 100644 --- a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationHandler.java +++ b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationHandler.java @@ -26,7 +26,12 @@ import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.reloc.RelocationResult; import ghidra.util.exception.NotFoundException; -public class X86_64_ElfRelocationHandler extends ElfRelocationHandler { +public class X86_64_ElfRelocationHandler extends + AbstractElfRelocationHandler { + + public X86_64_ElfRelocationHandler() { + super(X86_64_ElfRelocationType.class); + } @Override public boolean canRelocate(ElfHeader elf) { @@ -35,7 +40,7 @@ public class X86_64_ElfRelocationHandler extends ElfRelocationHandler { @Override public int getRelrRelocationType() { - return X86_64_ElfRelocationConstants.R_X86_64_RELATIVE; + return X86_64_ElfRelocationType.R_X86_64_RELATIVE.typeId; } @Override @@ -45,49 +50,29 @@ public class X86_64_ElfRelocationHandler extends ElfRelocationHandler { } @Override - public RelocationResult relocate(ElfRelocationContext elfRelocationContext, - ElfRelocation relocation, Address relocationAddress) - throws MemoryAccessException, NotFoundException { - - ElfHeader elf = elfRelocationContext.getElfHeader(); - if (elf.e_machine() != ElfConstants.EM_X86_64) { - return RelocationResult.FAILURE; - } + protected RelocationResult relocate(X86_64_ElfRelocationContext elfRelocationContext, + ElfRelocation relocation, X86_64_ElfRelocationType type, Address relocationAddress, + ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) + throws MemoryAccessException { Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); - X86_64_ElfRelocationContext x86RelocationContext = - (X86_64_ElfRelocationContext) elfRelocationContext; - - int type = relocation.getType(); - if (type == X86_64_ElfRelocationConstants.R_X86_64_NONE) { - return RelocationResult.SKIPPED; - } - - int symbolIndex = relocation.getSymbolIndex(); - // addend is either pulled from the relocation or the bytes in memory long addend = relocation.hasAddend() ? relocation.getAddend() : memory.getLong(relocationAddress); - ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); - Address symbolAddr = elfRelocationContext.getSymbolAddress(sym); - long symbolValue = elfRelocationContext.getSymbolValue(sym); - String symbolName = elfRelocationContext.getSymbolName(symbolIndex); - long symbolSize = sym.getSize(); - long offset = relocationAddress.getOffset(); - + int symbolIndex = relocation.getSymbolIndex(); int byteLength = 8; // most relocations affect 8-bytes (change if different) long value; switch (type) { - case X86_64_ElfRelocationConstants.R_X86_64_COPY: - markAsWarning(program, relocationAddress, "R_X86_64_COPY", symbolName, symbolIndex, + case R_X86_64_COPY: + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, "Runtime copy not supported", elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; - case X86_64_ElfRelocationConstants.R_X86_64_64: + case R_X86_64_64: value = symbolValue + addend; memory.setLong(relocationAddress, value); if (symbolIndex != 0 && addend != 0 && !sym.isSection()) { @@ -96,105 +81,92 @@ public class X86_64_ElfRelocationHandler extends ElfRelocationHandler { applyComponentOffsetPointer(program, relocationAddress, addend); } break; - case X86_64_ElfRelocationConstants.R_X86_64_16: + case R_X86_64_16: value = symbolValue + addend; value = value & 0xffff; memory.setShort(relocationAddress, (short) value); byteLength = 2; break; - case X86_64_ElfRelocationConstants.R_X86_64_8: + case R_X86_64_8: value = symbolValue + addend; value = value & 0xff; memory.setByte(relocationAddress, (byte) value); byteLength = 1; break; - case X86_64_ElfRelocationConstants.R_X86_64_PC32: + case R_X86_64_PC32: value = symbolValue + addend - offset; value = value & 0xffffffff; memory.setInt(relocationAddress, (int) value); byteLength = 4; break; - case X86_64_ElfRelocationConstants.R_X86_64_PC16: + case R_X86_64_PC16: value = symbolValue + addend - offset; value = value & 0xffff; memory.setShort(relocationAddress, (short) value); byteLength = 2; break; - case X86_64_ElfRelocationConstants.R_X86_64_PC8: + case R_X86_64_PC8: value = symbolValue + addend - offset; value = value & 0xff; memory.setByte(relocationAddress, (byte) value); byteLength = 1; break; - case X86_64_ElfRelocationConstants.R_X86_64_GOT32: + case R_X86_64_GOT32: value = symbolValue + addend; memory.setInt(relocationAddress, (int) value); byteLength = 4; break; - case X86_64_ElfRelocationConstants.R_X86_64_PLT32: + case R_X86_64_PLT32: value = symbolValue + addend - offset; memory.setInt(relocationAddress, (int) value); byteLength = 4; break; - case X86_64_ElfRelocationConstants.R_X86_64_GLOB_DAT: - case X86_64_ElfRelocationConstants.R_X86_64_JUMP_SLOT: + case R_X86_64_GLOB_DAT: + case R_X86_64_JUMP_SLOT: value = symbolValue + addend; memory.setLong(relocationAddress, value); break; - case X86_64_ElfRelocationConstants.R_X86_64_GOTOFF64: + case R_X86_64_GOTOFF64: try { long dotgot = elfRelocationContext.getGOTValue(); value = symbolValue + addend - dotgot; memory.setLong(relocationAddress, value); } catch (NotFoundException e) { - markAsError(program, relocationAddress, "R_X86_64_GOTOFF64", symbolName, + markAsError(program, relocationAddress, type, symbolName, symbolIndex, e.getMessage(), elfRelocationContext.getLog()); } break; - case X86_64_ElfRelocationConstants.R_X86_64_32: // this one complains for unsigned overflow - case X86_64_ElfRelocationConstants.R_X86_64_32S: // this one complains for signed overflow + case R_X86_64_32: // this one complains for unsigned overflow + case R_X86_64_32S: // this one complains for signed overflow symbolValue += addend; value = (symbolValue & 0xffffffff); memory.setInt(relocationAddress, (int) value); byteLength = 4; break; - case X86_64_ElfRelocationConstants.R_X86_64_SIZE32: - value = symbolSize + addend; + case R_X86_64_SIZE32: + value = sym.getSize() + addend; value = (value & 0xffffffff); memory.setInt(relocationAddress, (int) value); byteLength = 4; break; - case X86_64_ElfRelocationConstants.R_X86_64_SIZE64: - value = symbolSize + addend; + case R_X86_64_SIZE64: + value = sym.getSize() + addend; memory.setLong(relocationAddress, value); break; // Thread Local Symbol relocations (unimplemented concept) - case X86_64_ElfRelocationConstants.R_X86_64_DTPMOD64: - markAsWarning(program, relocationAddress, "R_X86_64_DTPMOD64", symbolName, - symbolIndex, "Thread Local Symbol relocation not supported", - elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - case X86_64_ElfRelocationConstants.R_X86_64_DTPOFF64: - markAsWarning(program, relocationAddress, "R_X86_64_DTPOFF64", symbolName, - symbolIndex, "Thread Local Symbol relocation not supported", - elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - case X86_64_ElfRelocationConstants.R_X86_64_TPOFF64: - markAsWarning(program, relocationAddress, "R_X86_64_TPOFF64", symbolName, - symbolIndex, "Thread Local Symbol relocation not supported", - elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - case X86_64_ElfRelocationConstants.R_X86_64_TLSDESC: - markAsWarning(program, relocationAddress, "R_X86_64_TLSDESC", symbolName, - symbolIndex, "Thread Local Symbol relocation not supported", - elfRelocationContext.getLog()); + case R_X86_64_DTPMOD64: + case R_X86_64_DTPOFF64: + case R_X86_64_TPOFF64: + case R_X86_64_TLSDESC: + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, + "Thread Local Symbol relocation not supported", elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; // cases which do not use symbol value - case X86_64_ElfRelocationConstants.R_X86_64_GOTPC32: + case R_X86_64_GOTPC32: try { long dotgot = elfRelocationContext.getGOTValue(); value = dotgot + addend - offset; @@ -202,13 +174,13 @@ public class X86_64_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 4; } catch (NotFoundException e) { - markAsError(program, relocationAddress, "R_X86_64_GOTPC32", symbolName, + markAsError(program, relocationAddress, type, symbolName, symbolIndex, e.getMessage(), elfRelocationContext.getLog()); } break; - case X86_64_ElfRelocationConstants.R_X86_64_GOTPCRELX: - case X86_64_ElfRelocationConstants.R_X86_64_REX_GOTPCRELX: + case R_X86_64_GOTPCRELX: + case R_X86_64_REX_GOTPCRELX: // Check for supported Relax cases (assumes non-PIC) // Assumes non-PIC treatment is OK and attempts @@ -262,10 +234,10 @@ public class X86_64_ElfRelocationHandler extends ElfRelocationHandler { // If instruction not handled as relaxed instruction // Let R_X86_64_GOTPCREL case handle as simple GOTPCREL relocation. - case X86_64_ElfRelocationConstants.R_X86_64_GOTPCREL: - Address symbolGotAddress = x86RelocationContext.getGotEntryAddress(sym); + case R_X86_64_GOTPCREL: + Address symbolGotAddress = elfRelocationContext.getGotEntryAddress(sym); if (symbolGotAddress == null) { - markAsError(program, relocationAddress, type, symbolName, + markAsError(program, relocationAddress, type, symbolName, symbolIndex, "GOT allocation failure", elfRelocationContext.getLog()); break; } @@ -274,25 +246,25 @@ public class X86_64_ElfRelocationHandler extends ElfRelocationHandler { byteLength = 4; break; - case X86_64_ElfRelocationConstants.R_X86_64_GOTPCREL64: - symbolGotAddress = x86RelocationContext.getGotEntryAddress(sym); + case R_X86_64_GOTPCREL64: + symbolGotAddress = elfRelocationContext.getGotEntryAddress(sym); if (symbolGotAddress == null) { - markAsError(program, relocationAddress, "R_X86_64_GOTPCREL64", symbolName, + markAsError(program, relocationAddress, type, symbolName, symbolIndex, "GOT allocation failure", elfRelocationContext.getLog()); break; } value = symbolGotAddress.getOffset() + addend - offset; memory.setLong(relocationAddress, value); - case X86_64_ElfRelocationConstants.R_X86_64_RELATIVE: + case R_X86_64_RELATIVE: // word64 for LP64 and specifies word32 for ILP32, // we assume LP64 only. We probably need a hybrid // variant to handle the ILP32 case. - case X86_64_ElfRelocationConstants.R_X86_64_RELATIVE64: + case R_X86_64_RELATIVE64: // dl_machine.h // value = (Elf64_64Addr) map->l_addr + reloc->r_addend long imageBaseAdjustment = elfRelocationContext.getImageBaseWordAdjustmentOffset(); - if (elf.isPreLinked()) { + if (elfRelocationContext.getElfHeader().isPreLinked()) { // adjust prelinked value that is already in memory value = memory.getLong(relocationAddress) + imageBaseAdjustment; } @@ -301,7 +273,7 @@ public class X86_64_ElfRelocationHandler extends ElfRelocationHandler { } memory.setLong(relocationAddress, value); break; - case X86_64_ElfRelocationConstants.R_X86_64_IRELATIVE: + case R_X86_64_IRELATIVE: value = addend + elfRelocationContext.getImageBaseWordAdjustmentOffset(); memory.setLong(relocationAddress, value); break; diff --git a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationType.java b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationType.java new file mode 100644 index 0000000000..0c0af95b60 --- /dev/null +++ b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationType.java @@ -0,0 +1,91 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.elf.relocation; + +public enum X86_64_ElfRelocationType implements ElfRelocationType { + + R_X86_64_NONE(0), // No reloc + R_X86_64_64(1), // Direct 64 bit (S + A) + R_X86_64_PC32(2), // PC relative 32 bit signed (S + A - P) + R_X86_64_GOT32(3), // 32 bit GOT entry (G + P) + R_X86_64_PLT32(4), // 32 bit PLT address (L + A - P) + R_X86_64_COPY(5), // Copy symbol at runtime + R_X86_64_GLOB_DAT(6), // Create GOT entry (S) + R_X86_64_JUMP_SLOT(7), // Create PLT entry (S) + R_X86_64_RELATIVE(8), // Adjust by program base (B + A) + R_X86_64_GOTPCREL(9), // 32 bit signed pc relative offset to GOT (G + GOT + A - P) + R_X86_64_32(10), // Direct 32 bit zero extended (S + A) + R_X86_64_32S(11), // Direct 32 bit sign extended (S + A) + R_X86_64_16(12), // Direct 16 bit zero extended (S + A) + R_X86_64_PC16(13), // 16 bit sign extended pc relative (S + A - P) + R_X86_64_8(14), // Direct 8 bit sign extended (S + A) + R_X86_64_PC8(15), // 8 bit sign extended pc relative (S + A - P) + + /** + * Calculates the object identifier of the + * object containing the TLS symbol. + */ + R_X86_64_DTPMOD64(16), // ID of module containing symbol + + /** + * Calculates the offset of the variable relative + * to the start of the TLS block that contains the + * variable. The computed value is used as an + * immediate value of an addend and is not associated + * with a specific register. + */ + R_X86_64_DTPOFF64(17), // Offset in module's TLS block + R_X86_64_TPOFF64(18), // offset in the initial TLS block + R_X86_64_TLSGD(19), // 32 bit signed PC relative offset to two GOT entries for GD symbol + R_X86_64_TLSLD(20), // 32 bit signed PC relative offset to two GOT entries for LD symbol + R_X86_64_DTPOFF32(21), // offset in TLS block + R_X86_64_GOTTPOFF(22), // 32 bit signed pc relative offst to GOT entry for IE symbol + R_X86_64_TPOFF32(23), // offset in initial TLS block + R_X86_64_PC64(24), // PC relative 64 bit (S + A - P) + R_X86_64_GOTOFF64(25), // 64 bit offset to GOT (S + A - GOT) + R_X86_64_GOTPC32(26), // 32 bit signed pc relative offset to GOT (GOT + A + P) + R_X86_64_GOT64(27), // 64 bit GOT entry offset + R_X86_64_GOTPCREL64(28), // 64 bit pc relative offset to GOT entry + R_X86_64_GOTPC64(29), // 64 bit pc relative offset to GOT + R_X86_64_GOTPLT64(30), + R_X86_64_PLTOFF64(31), // 64 bit GOT relative offset to PLT entry + R_X86_64_SIZE32(32), // Size of symbol plus 32 bit addend (Z + A) + R_X86_64_SIZE64(33), // Size of symbol plus 64 bit addend (Z + A) + R_X86_64_GOTPC32_TLSDESC(34), // GOT offset for TLS descriptor + R_X86_64_TLSDESC_CALL(35), // Marker for call through TLS descriptor + R_X86_64_TLSDESC(36), // TLS descriptor), word64 * 2 + R_X86_64_IRELATIVE(37), // Adjust indirectly by program base + R_X86_64_RELATIVE64(38), // 64-bit adjust by program base + R_X86_64_PC32_BND(39), // deprecated + R_X86_64_PLT32_BND(40), // deprecated + R_X86_64_GOTPCRELX(41), // G + GOT + A - P + R_X86_64_REX_GOTPCRELX(42), //G + GOT + A - P + R_X86_64_NUM(43), + + R_X86_64_GNU_VTINHERIT(250), + R_X86_64_GNU_VTENTRY(251); + + public final int typeId; + + private X86_64_ElfRelocationType(int typeId) { + this.typeId = typeId; + } + + @Override + public int typeId() { + return typeId; + } +}