GP-2703 revised ELF relocation processing to handle statically linked

binaries and adjusted post-relocation read-only memory fixup.
This commit is contained in:
ghidra1 2022-10-14 17:15:47 -04:00
parent 0b17f7d095
commit 6b9bd6c220
19 changed files with 210 additions and 213 deletions

View file

@ -15,11 +15,10 @@
*/
package ghidra.app.util.bin.format.elf;
import java.util.*;
import java.util.function.Consumer;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.*;
import java.util.function.Consumer;
import ghidra.app.util.bin.*;
import ghidra.app.util.bin.format.Writeable;
@ -500,6 +499,12 @@ public class ElfHeader implements StructConverter, Writeable {
}
}
if (section.isInvalidOffset()) {
Msg.debug(this, "Skipping Elf relocation table section with invalid offset " +
section.getNameAsString());
return;
}
int link = section.getLink(); // section index of associated symbol table
int info = section.getInfo(); // section index of section to which relocations apply (relocation offset base)
@ -519,22 +524,18 @@ public class ElfHeader implements StructConverter, Writeable {
}
ElfSymbolTable symbolTable = getSymbolTable(symbolTableSection);
if (symbolTable == null) {
throw new NotFoundException("Referenced relocation symbol section not found.");
}
boolean addendTypeReloc =
(sectionHeaderType == ElfSectionHeaderConstants.SHT_RELA ||
sectionHeaderType == ElfSectionHeaderConstants.SHT_ANDROID_RELA);
Msg.debug(this,
"Elf relocation table section " + section.getNameAsString() +
" linked to symbol table section " + symbolTableSection.getNameAsString() +
" affecting " + relocaBaseName);
if (section.isInvalidOffset()) {
return;
String details = "Elf relocation table section " + section.getNameAsString();
if (symbolTableSection != null) {
details +=
" linked to symbol table section " + symbolTableSection.getNameAsString();
}
details += " affecting " + relocaBaseName;
Msg.debug(this, details);
ElfRelocationTable.TableFormat format = TableFormat.DEFAULT;
if (sectionHeaderType == ElfSectionHeaderConstants.SHT_ANDROID_REL ||
@ -618,12 +619,6 @@ public class ElfHeader implements StructConverter, Writeable {
return;
}
if (dynamicSymbolTable == null) {
errorConsumer.accept("Failed to process " + relocTableAddrType.name +
", missing dynamic symbol table");
return;
}
long relocTableOffset = relocTableLoadHeader.getOffset(relocTableAddr);
for (ElfRelocationTable relocTable : relocationTableList) {
if (relocTable.getFileOffset() == relocTableOffset) {

View file

@ -64,7 +64,7 @@ public class ElfRelocationTable implements ElfFileSection, ByteArrayConverter {
* @param length length of relocation table in bytes
* @param entrySize size of each relocation entry in bytes
* @param addendTypeReloc true if addend type relocation table
* @param symbolTable associated symbol table
* @param symbolTable associated symbol table (may be null if not applicable)
* @param sectionToBeRelocated or null for dynamic relocation table
* @param format table format
* @throws IOException if an IO or parse error occurs
@ -106,6 +106,21 @@ public class ElfRelocationTable implements ElfFileSection, ByteArrayConverter {
relocList.toArray(relocs);
}
/**
* Determine if required symbol table is missing. If so, relocations may not be processed.
* @return true if required symbol table is missing, else false
*/
public boolean isMissingRequiredSymbolTable() {
if (symbolTable == null) {
// relocTableSection is may only be null for dynamic relocation table which must
// have a symbol table. All other section-based relocation tables require a symbol
// table if link != 0. NOTE: There is the possibility that a symbol table is required
// when link==0 which may result in relocation processing errors if it is missing.
return relocTableSection == null || relocTableSection.getLink() != 0;
}
return false;
}
private List<ElfRelocation> parseStandardRelocations(BinaryReader reader)
throws IOException {
@ -290,7 +305,7 @@ public class ElfRelocationTable implements ElfFileSection, ByteArrayConverter {
* Returns the associated symbol table.
* A relocation object contains a symbol index.
* This index is into this symbol table.
* @return the associated symbol table
* @return the associated symbol table or null if not applicable to this reloc table
*/
public ElfSymbolTable getAssociatedSymbolTable() {
return symbolTable;

View file

@ -47,6 +47,7 @@ import ghidra.util.exception.NotFoundException;
* </pre>
*/
public class ElfSymbol implements ByteArrayConverter {
/**Local symbols are not visible outside the object file containing their definition.*/
public static final byte STB_LOCAL = 0;
/**Global symbols are visible to all object files being combined.*/
@ -104,8 +105,6 @@ public class ElfSymbol implements ByteArrayConverter {
/**
* Creates a new section symbol.
* Warning! the routine initSymbolName() must be called on the symbol later
* to initialize the string name. This is a performance enhancement.
* @param header the corresponding ELF header
* @param sectionAddress the start address of the section
* @param sectionHeaderIndex the index of the section in the section header table
@ -122,8 +121,6 @@ public class ElfSymbol implements ByteArrayConverter {
/**
* Creates a new global function symbol.
* Warning! the routine initSymbolName() must be called on the symbol later
* to initialize the string name. This is a performance enhancement.
* @param header the corresponding ELF header
* @param name the byte index of the name
* @param nameAsString the string name of the section
@ -138,6 +135,15 @@ public class ElfSymbol implements ByteArrayConverter {
(byte) ((STB_GLOBAL << 4) | STT_FUNC), (byte) 0, (short) 0, symbolIndex, symbolTable);
}
/**
* Creates a new special null symbol which corresponds to symbol index 0.
* @param header the corresponding ELF header
* @return the new null symbol
*/
public static ElfSymbol createNullSymbol(ElfHeader header) {
return new ElfSymbol(header, "", 0, 0, 0, (byte) 0, (byte) 0, (short) 0, 0, null);
}
private ElfSymbol(ElfHeader header, String nameAsString, int name, long value, long size,
byte info, byte other, short sectionHeaderIndex, int symbolIndex,
ElfSymbolTable symbolTable) {
@ -486,7 +492,7 @@ public class ElfSymbol implements ByteArrayConverter {
* @return extended symbol section index value
*/
public int getExtendedSectionHeaderIndex() {
return symbolTable.getExtendedSectionIndex(this);
return symbolTable != null ? symbolTable.getExtendedSectionIndex(this) : 0;
}
/**

View file

@ -188,6 +188,30 @@ public class ElfSymbolTable implements ElfFileSection, ByteArrayConverter {
return null;
}
/**
* Get the Elf symbol which corresponds to the specified index. Each relocation table
* may correspond to a specific symbol table to which the specified symbolIndex will be
* applied.
* @param symbolIndex symbol index
* @return Elf symbol which corresponds to symbol index or <B>null</B> if out of range
*/
public final ElfSymbol getSymbol(int symbolIndex) {
if (symbolIndex < 0 || symbolIndex >= symbols.length) {
return null;
}
return symbols[symbolIndex];
}
/**
* Get the ELF symbol name which corresponds to the specified index.
* @param symbolIndex symbol index
* @return symbol name which corresponds to symbol index or <B>&lt<NONE&gt;</B> if out of range
*/
public final String getSymbolName(int symbolIndex) {
ElfSymbol sym = getSymbol(symbolIndex);
return sym != null ? sym.getNameAsString() : "";
}
/**
* Returns all of the global symbols.
* @return all of the global symbols

View file

@ -35,7 +35,8 @@ public class ElfRelocationContext {
protected final ElfRelocationHandler handler;
protected final ElfLoadHelper loadHelper;
protected final ElfRelocationTable relocationTable;
protected final ElfSymbol[] symbols;
private ElfSymbolTable symbolTable; // may be null
private ElfSymbol nullSymbol; // corresponds to symbolIndex==0 when no symbolTable
protected final Map<ElfSymbol, Address> symbolMap;
protected final Program program;
@ -51,7 +52,10 @@ public class ElfRelocationContext {
this.handler = handler;
this.loadHelper = loadHelper;
this.relocationTable = relocationTable;
this.symbols = relocationTable.getAssociatedSymbolTable().getSymbols();
symbolTable = relocationTable.getAssociatedSymbolTable();
if (symbolTable == null) {
nullSymbol = ElfSymbol.createNullSymbol(loadHelper.getElfHeader());
}
this.symbolMap = symbolMap;
this.program = loadHelper.getProgram();
}
@ -59,8 +63,8 @@ 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.
* @param relocation
* @param relocationAddress
* @param relocation relocation to be processed
* @param relocationAddress relocation address where it should be applied
*/
public final void processRelocation(ElfRelocation relocation, Address relocationAddress) {
@ -69,15 +73,15 @@ public class ElfRelocationContext {
return;
}
long symbolIndex = relocation.getSymbolIndex();
if (symbolIndex < 0 || symbolIndex >= symbols.length) {
int symbolIndex = relocation.getSymbolIndex();
ElfSymbol sym = getSymbol(symbolIndex);
if (sym == null) {
ElfRelocationHandler.markAsUnhandled(program, relocationAddress, relocation.getType(),
symbolIndex, "index " + Long.toString(symbolIndex), getLog());
symbolIndex, "index " + symbolIndex, getLog());
return;
}
ElfSymbol sym = symbols[(int) symbolIndex];
if (sym.isTLS()) {
handleUnsupportedTLSRelocation(relocation, relocationAddress);
handleUnsupportedTLSRelocation(relocation, relocationAddress, sym);
return;
}
@ -100,17 +104,15 @@ public class ElfRelocationContext {
return handler != null ? handler.getRelrRelocationType() : 0;
}
private void handleUnsupportedTLSRelocation(ElfRelocation relocation,
Address relocationAddress) {
long symbolIndex = relocation.getSymbolIndex();
ElfSymbol sym = symbols[(int) symbolIndex];
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 = symbols[relocation.getSymbolIndex()].getNameAsString();
String symName = getSymbolName(relocation.getSymbolIndex());
program.getBookmarkManager().setBookmark(relocationAddress, BookmarkType.ERROR,
"Relocation", "No handler to process ELF Relocation to : " + symName);
@ -191,13 +193,26 @@ public class ElfRelocationContext {
/**
* Get the Elf symbol which corresponds to the specified index. Each relocation table
* corresponds to a specific symbol table to which the specified symbolIndex will be
* applied.
* @param symbolIndex
* @return Elf symbol which corresponds to symbol index
* may correspond to a specific symbol table to which the specified symbolIndex will be
* applied. In the absense of a corresponding symbol table index 0 will return a special
* null symbol.
* @param symbolIndex symbol index
* @return Elf symbol which corresponds to symbol index or <B>null</B> if out of range
*/
public final ElfSymbol getSymbol(int symbolIndex) {
return symbols[symbolIndex];
if (symbolTable == null) {
return symbolIndex == 0 ? nullSymbol : null;
}
return symbolTable.getSymbol(symbolIndex);
}
/**
* Get the ELF symbol name which corresponds to the specified index.
* @param symbolIndex symbol index
* @return symbol name which corresponds to symbol index or <B>&lt<NONE&gt;</B> if out of range
*/
public final String getSymbolName(int symbolIndex) {
return symbolTable != null ? symbolTable.getSymbolName(symbolIndex) : "";
}
/**
@ -206,7 +221,7 @@ public class ElfRelocationContext {
* @return program address
*/
public Address getSymbolAddress(ElfSymbol symbol) {
return symbolMap.get(symbol);
return symbol != null ? symbolMap.get(symbol) : null;
}
/**
@ -217,7 +232,7 @@ public class ElfRelocationContext {
* @return adjusted Elf symbol value or 0 if symbol mapping not found
*/
public long getSymbolValue(ElfSymbol symbol) {
Address symAddr = symbolMap.get(symbol);
Address symAddr = symbol != null ? symbolMap.get(symbol) : null;
return symAddr != null ? symAddr.getAddressableWordOffset() : 0;
}

View file

@ -78,7 +78,7 @@ abstract public class ElfRelocationHandler implements ExtensionPoint {
/**
* Apply a pointer-typedef with a specified component-offset.
* @param program
* @param program program
* @param addr address where data should be applied
* @param componentOffset component offset
*/
@ -103,7 +103,7 @@ abstract public class ElfRelocationHandler implements ExtensionPoint {
* warning bookmark.
* NOTE: This method should only be invoked when the symbol offset will be adjusted with a non-zero
* value (i.e., addend).
* @param program
* @param program program
* @param relocationAddress relocation address to be bookmarked if EXTERNAL block relocation
* @param symbolAddr symbol address correspondng to relocation (may be null)
* @param symbolName symbol name (may not be null if symbolAddr is not null)
@ -126,7 +126,7 @@ abstract public class ElfRelocationHandler implements ExtensionPoint {
}
String adjStr = sign + "0x" + Long.toHexString(adjustment);
symbolName = symbolName == null ? "<no name>" : symbolName;
symbolName = StringUtils.isEmpty(symbolName) ? "<no name>" : symbolName;
Msg.warn(ElfRelocationHandler.class,
"EXTERNAL Data Elf Relocation with offset: at " + relocationAddress +
" (External Location = " + symbolName + adjStr + ")");
@ -139,7 +139,7 @@ abstract public class ElfRelocationHandler implements ExtensionPoint {
/**
* Generate error log entry and bookmark at relocationAddress indicating
* an unhandled relocation.
* @param program
* @param program program
* @param relocationAddress relocation address to be bookmarked
* @param type relocation type
* @param symbolIndex associated symbol index within symbol table
@ -162,7 +162,7 @@ abstract public class ElfRelocationHandler implements ExtensionPoint {
/**
* Generate error log entry and bookmark at relocationAddress indicating
* an unsupported RELR relocation.
* @param program
* @param program program
* @param relocationAddress relocation address to be bookmarked
*/
public static void markAsUnsupportedRelr(Program program, Address relocationAddress) {
@ -174,7 +174,7 @@ abstract public class ElfRelocationHandler implements ExtensionPoint {
/**
* Generate error log entry and bookmark at relocationAddress where
* import failed to transition block to initialized while processing relocation.
* @param program
* @param program program
* @param relocationAddress relocation address to be bookmarked
* @param type relocation type
* @param symbolIndex associated symbol index within symbol table
@ -184,7 +184,7 @@ abstract public class ElfRelocationHandler implements ExtensionPoint {
public static void markAsUninitializedMemory(Program program, Address relocationAddress,
long type, long symbolIndex, String symbolName, MessageLog log) {
symbolName = symbolName == null ? "<no name>" : symbolName;
symbolName = StringUtils.isEmpty(symbolName) ? "<no name>" : symbolName;
log.appendMsg("Unable to perform relocation: Type = " + type + " (0x" +
Long.toHexString(type) + ") at " + relocationAddress + " (Symbol = " + symbolName +
") - uninitialized memory");
@ -199,10 +199,11 @@ abstract public class ElfRelocationHandler implements ExtensionPoint {
/**
* Generate error log entry and bookmark at relocationAddress where
* import failed to be applied.
* @param program
* @param program program
* @param relocationAddress relocation address to be bookmarked
* @param type relocation type
* @param symbolName associated symbol name
* @param msg error messge
* @param log import log
*/
public static void markAsError(Program program, Address relocationAddress, long type,
@ -214,7 +215,7 @@ abstract public class ElfRelocationHandler implements ExtensionPoint {
/**
* Generate error log entry and bookmark at relocationAddress where
* import failed to be applied.
* @param program
* @param program program
* @param relocationAddress relocation address to be bookmarked
* @param type relocation type
* @param symbolName associated symbol name
@ -224,7 +225,7 @@ abstract public class ElfRelocationHandler implements ExtensionPoint {
public static void markAsError(Program program, Address relocationAddress, String type,
String symbolName, String msg, MessageLog log) {
symbolName = symbolName == null ? "<no name>" : symbolName;
symbolName = StringUtils.isEmpty(symbolName) ? "<no name>" : symbolName;
log.appendMsg("Elf Relocation Error: Type = " + type + " at " + relocationAddress +
", Symbol = " + symbolName + ": " + msg);
BookmarkManager bookmarkManager = program.getBookmarkManager();
@ -235,7 +236,7 @@ abstract public class ElfRelocationHandler implements ExtensionPoint {
/**
* Generate warning log entry and bookmark at relocationAddress where
* import issue occurred.
* @param program
* @param program program
* @param relocationAddress relocation address to be bookmarked
* @param type relocation type
* @param msg message associated with warning
@ -250,7 +251,7 @@ abstract public class ElfRelocationHandler implements ExtensionPoint {
/**
* Generate warning log entry and bookmark at relocationAddress where
* import issue occurred.
* @param program
* @param program program
* @param relocationAddress relocation address to be bookmarked
* @param type relocation type
* @param symbolName symbol name
@ -261,7 +262,7 @@ abstract public class ElfRelocationHandler implements ExtensionPoint {
public static void markAsWarning(Program program, Address relocationAddress, String type,
String symbolName, long symbolIndex, String msg, MessageLog log) {
symbolName = symbolName == null ? "<no name>" : symbolName;
symbolName = StringUtils.isEmpty(symbolName) ? "<no name>" : symbolName;
log.appendMsg("Elf Relocation Warning: Type = " + type + " at " + relocationAddress +
", Symbol = " + symbolName + ": " + msg);
BookmarkManager bookmarkManager = program.getBookmarkManager();

View file

@ -15,12 +15,11 @@
*/
package ghidra.app.util.opinion;
import java.util.*;
import java.io.*;
import java.math.BigInteger;
import java.nio.file.AccessMode;
import java.text.NumberFormat;
import java.util.*;
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
import org.apache.commons.lang3.StringUtils;
@ -566,29 +565,39 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
}
/**
* Adjust GNU read-only segments following relocations (PT_GNU_RELRO).
* Adjust read-only sections/segments following relocations (PT_GNU_RELRO, .data.rel.ro, ...).
*/
private void processGNU_readOnly(TaskMonitor monitor) {
// Set read-only segments
if (elf.e_shentsize() != 0) {
return;
}
monitor.setMessage("Processing RO Definitions");
setReadOnlyMemory(elf.getSection(".data.rel.ro"), null);
monitor.setMessage("Processing GNU Definitions");
for (ElfProgramHeader roSegment : elf
.getProgramHeaders(ElfProgramHeaderConstants.PT_GNU_RELRO)) {
ElfProgramHeader loadedSegment =
elf.getProgramLoadHeaderContaining(roSegment.getVirtualAddress());
if (loadedSegment != null) {
for (AddressRange blockRange : getResolvedLoadAddresses(loadedSegment)) {
MemoryBlock block = memory.getBlock(blockRange.getMinAddress());
if (block != null) {
log("Setting block " + block.getName() +
" to read-only based upon PT_GNU_RELRO data");
block.setWrite(false);
}
}
// TODO: Identify read-only region which should be transformed
setReadOnlyMemory(elf.getProgramLoadHeaderContaining(roSegment.getVirtualAddress()),
null);
}
}
/**
* Transition load segment to read-only
* @param loadedSegment loaded segment
* @param region constrained read-only region or null for entire load segment
*/
private void setReadOnlyMemory(MemoryLoadable loadedSegment, AddressRange region) {
if (loadedSegment == null) {
return;
}
for (AddressRange blockRange : getResolvedLoadAddresses(loadedSegment)) {
MemoryBlock block = memory.getBlock(blockRange.getMinAddress());
if (block != null) {
// TODO: If sections have been stripped the block should be split-up
// based upon the size of the RO region indicated by the roSegment data
log("Setting block " + block.getName() +
" to read-only based upon PT_GNU_RELRO data");
block.setWrite(false);
}
}
}
@ -861,9 +870,21 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
ElfRelocationContext context, AddressSpace relocationSpace, long baseWordOffset,
TaskMonitor monitor) throws CancelledException {
ElfSymbol[] symbols = relocationTable.getAssociatedSymbolTable().getSymbols();
ElfSymbolTable symbolTable = relocationTable.getAssociatedSymbolTable();
ElfRelocation[] relocs = relocationTable.getRelocations();
boolean unableToApplyRelocs = relocationTable.isMissingRequiredSymbolTable();
if (unableToApplyRelocs) {
ElfSectionHeader tableSectionHeader = relocationTable.getTableSectionHeader();
String relocTableName =
tableSectionHeader != null ? tableSectionHeader.getNameAsString() : "dynamic";
ElfSectionHeader sectionToBeRelocated = relocationTable.getSectionToBeRelocated();
String relocaBaseName =
sectionToBeRelocated != null ? sectionToBeRelocated.getNameAsString() : "PT_LOAD";
log("Unable to apply " + relocTableName + " relocations affecting " + relocaBaseName +
" due to missing symbol table");
}
boolean relrTypeUnknown = false;
long relrRelocationType = 0;
if (relocationTable.isRelrTable() && context != null) {
@ -885,10 +906,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
}
int symbolIndex = reloc.getSymbolIndex();
String symbolName = null;
if (symbolIndex >= 0 && symbolIndex < symbols.length) {
symbolName = symbols[symbolIndex].getNameAsString();
}
String symbolName = symbolTable != null ? symbolTable.getSymbolName(symbolIndex) : "";
Address baseAddress = relocationSpace.getTruncatedAddress(baseWordOffset, true);
@ -905,6 +923,12 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
}
try {
if (unableToApplyRelocs) {
ElfRelocationHandler.markAsError(program, relocAddr, type, symbolName,
"missing symbol table", log);
continue;
}
MemoryBlock relocBlock = memory.getBlock(relocAddr);
if (relocBlock == null) {
throw new MemoryAccessException("Block is non-existent");

View file

@ -68,8 +68,8 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
long addend = relocation.getAddend(); // will be 0 for REL case
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex);
String symbolName = sym.getNameAsString();
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null
String symbolName = elfRelocationContext.getSymbolName(symbolIndex);
boolean isThumb = isThumb(sym);
@ -701,7 +701,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
}
private boolean isThumb(ElfSymbol symbol) {
if (symbol.isFunction() && (symbol.getValue() % 1) == 1) {
if (symbol != null && symbol.isFunction() && (symbol.getValue() % 1) == 1) {
return true;
}
return false;

View file

@ -49,16 +49,10 @@ public class AVR32_ElfRelocationHandler extends ElfRelocationHandler {
long addend = relocation.getAddend(); // will be 0 for REL case
ElfHeader elf = elfRelocationContext.getElfHeader();
if ((symbolIndex == 0) && (elf.e_machine() == ElfConstants.EM_AVR32)) {
//System.out.println("ZERO_SYMBOL_TYPE = " + type + ", Offset = " + offset + ", Addend = " + addend);
}
else if (symbolIndex == 0) {//TODO
return;
}
long offset = (int) relocationAddress.getOffset();
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex);
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null
long symbolValue = elfRelocationContext.getSymbolValue(sym);
int oldValue = memory.getInt(relocationAddress);
@ -108,7 +102,7 @@ public class AVR32_ElfRelocationHandler extends ElfRelocationHandler {
Address currNewAddress = space.getAddress(newValue);
if (!memory.contains(currNewAddress)) {
if (!memory.contains(currNewAddress) && sym != null) {
int currElfSymbolInfoBind = sym.getBind();
int currElfSymbolInfoType = sym.getType();
@ -319,8 +313,8 @@ public class AVR32_ElfRelocationHandler extends ElfRelocationHandler {
System.out.println(" HANDLED AVR relocation: R_AVR32_GOTPC at "+relocationAddress + ", New = " + newValue);
break;*/
default:
String symbolName = sym.getNameAsString();
markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName,
markAsUnhandled(program, relocationAddress, type, symbolIndex,
elfRelocationContext.getSymbolName(symbolIndex),
elfRelocationContext.getLog());
break;
}

View file

@ -15,11 +15,7 @@
*/
package ghidra.app.util.bin.format.elf.relocation;
import ghidra.app.util.bin.format.elf.AVR8_ElfRelocationConstants;
import ghidra.app.util.bin.format.elf.ElfConstants;
import ghidra.app.util.bin.format.elf.ElfHeader;
import ghidra.app.util.bin.format.elf.ElfRelocation;
import ghidra.app.util.bin.format.elf.ElfSymbol;
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;
@ -47,23 +43,16 @@ public class AVR8_ElfRelocationHandler extends ElfRelocationHandler {
long addend = relocation.getAddend(); // will be 0 for REL case
ElfHeader elf = elfRelocationContext.getElfHeader();
if ((symbolIndex == 0) && (elf.e_machine() == ElfConstants.EM_AVR)) {
// System.out.println("ZERO_SYMBOL_TYPE = " + type + ", Offset = " + offset + ",
// Addend = " + addend);
}
else if (symbolIndex == 0) {
return;
}
// WARNING: offset is in bytes
// be careful, word address potentially with byte indexes
long offset = relocationAddress.getOffset();
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex);
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 = sym.getNameAsString();
String symbolName = elfRelocationContext.getSymbolName(symbolIndex);
int oldValue = memory.getShort(relocationAddress);

View file

@ -122,11 +122,12 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
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 = elfSymbol.getNameAsString();
String symbolName = mipsRelocationContext.getSymbolName(symbolIndex);
if (symbolIndex != 0) {
mipsRelocationContext.lastSymbolAddr = symbolAddr;
@ -212,9 +213,9 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
if (gotAddr == null) {
// failed to allocate section GOT entry for symbol
markAsError(mipsRelocationContext.getProgram(), relocationAddress,
Integer.toString(relocType), elfSymbol.getNameAsString(),
Integer.toString(relocType), symbolName,
"Relocation Failed, unable to allocate GOT entry for relocation symbol: " +
elfSymbol.getNameAsString(),
symbolName,
mipsRelocationContext.getLog());
return;
}
@ -245,9 +246,9 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
if (gotAddr == null) {
// failed to allocate section GOT entry for symbol
markAsError(mipsRelocationContext.getProgram(), relocationAddress,
Integer.toString(relocType), elfSymbol.getNameAsString(),
Integer.toString(relocType), symbolName,
"Relocation Failed, unable to allocate GOT entry for relocation symbol: " +
elfSymbol.getNameAsString(),
symbolName,
mipsRelocationContext.getLog());
return;
}
@ -300,9 +301,9 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
if (gotAddr == null) {
// failed to allocate section GOT entry for symbol
markAsError(mipsRelocationContext.getProgram(), relocationAddress,
Integer.toString(relocType), elfSymbol.getNameAsString(),
Integer.toString(relocType), symbolName,
"Relocation Failed, unable to allocate GOT entry for relocation symbol: " +
elfSymbol.getNameAsString(),
symbolName,
mipsRelocationContext.getLog());
return;
}
@ -331,9 +332,9 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
if (gotAddr == null) {
// failed to allocate section GOT entry for symbol
markAsError(mipsRelocationContext.getProgram(), relocationAddress,
Integer.toString(relocType), elfSymbol.getNameAsString(),
Integer.toString(relocType), symbolName,
"Relocation Failed, unable to allocate GOT entry for relocation symbol: " +
elfSymbol.getNameAsString(),
symbolName,
mipsRelocationContext.getLog());
return;
}
@ -734,7 +735,7 @@ public class MIPS_ElfRelocationHandler extends ElfRelocationHandler {
default:
markAsUnhandled(program, relocationAddress, relocType, symbolIndex,
elfSymbol.getNameAsString(), log);
symbolName, log);
if (saveValue) {
mipsRelocationContext.savedAddendHasError = true;
}

View file

@ -137,13 +137,9 @@ public class PIC30_ElfRelocationHandler extends ElfRelocationHandler {
int addend = (int) relocation.getAddend();
if (symbolIndex == 0) {// TODO
return;
}
long relocWordOffset = (int) relocationAddress.getAddressableWordOffset();
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex);
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null
int symbolValue = (int) elfRelocationContext.getSymbolValue(sym); // word offset
int oldValue = memory.getInt(relocationAddress);
@ -206,7 +202,7 @@ public class PIC30_ElfRelocationHandler extends ElfRelocationHandler {
memory.setShort(relocationAddress, (short) (newValue & 0xffff));
break;
default:
String symbolName = sym.getNameAsString();
String symbolName = elfRelocationContext.getSymbolName(symbolIndex);
markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName,
elfRelocationContext.getLog());
break;

View file

@ -65,8 +65,8 @@ public class PowerPC64_ElfRelocationHandler extends ElfRelocationHandler {
long offset = relocationAddress.getOffset();
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex);
String symbolName = sym.getNameAsString();
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null
String symbolName = elfRelocationContext.getSymbolName(symbolIndex);
Address symbolAddr = elfRelocationContext.getSymbolAddress(sym);
long symbolValue = elfRelocationContext.getSymbolValue(sym);

View file

@ -79,7 +79,7 @@ public class PowerPC_ElfRelocationHandler extends ElfRelocationHandler {
int offset = (int) relocationAddress.getOffset();
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex);
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null
// if (sym.isLocal() && sym.getSectionHeaderIndex() != ElfSectionHeaderConstants.SHN_UNDEF) {
//
@ -95,7 +95,7 @@ public class PowerPC_ElfRelocationHandler extends ElfRelocationHandler {
Address symbolAddr = (elfRelocationContext.getSymbolAddress(sym));
int symbolValue = (int) elfRelocationContext.getSymbolValue(sym);
// }
String symbolName = sym.getNameAsString();
String symbolName = elfRelocationContext.getSymbolName(symbolIndex);
int oldValue = memory.getInt(relocationAddress);
int newValue = 0;
@ -252,14 +252,14 @@ public class PowerPC_ElfRelocationHandler extends ElfRelocationHandler {
gprID = 0;
}
else if (MemoryBlock.EXTERNAL_BLOCK_NAME.equals(blockName)) {
markAsError(program, relocationAddress, type, sym.getNameAsString(),
markAsError(program, relocationAddress, type, symbolName,
"Unsupported relocation for external symbol",
ppcRelocationContext.getLog());
break;
}
}
if (gprID == null || sdaBase == null) {
markAsError(program, relocationAddress, type, sym.getNameAsString(),
markAsError(program, relocationAddress, type, symbolName,
"Failed to identfy appropriate data block", ppcRelocationContext.getLog());
break;
}

View file

@ -49,21 +49,12 @@ public class RISCV_ElfRelocationHandler extends ElfRelocationHandler {
long addend = relocation.hasAddend() ? relocation.getAddend() : is32 ? memory.getInt(relocationAddress) : memory.getLong(relocationAddress);
long offset = relocationAddress.getOffset();
long base = elfRelocationContext.getImageBaseWordAdjustmentOffset();
ElfSymbol sym = null;
long symbolValue = 0;
Address symbolAddr = null;
String symbolName = null;
int symbolIndex = relocation.getSymbolIndex();
if (symbolIndex != 0) {
sym = elfRelocationContext.getSymbol(symbolIndex);
}
if (null != sym) {
symbolAddr = elfRelocationContext.getSymbolAddress(sym);
symbolValue = elfRelocationContext.getSymbolValue(sym);
symbolName = sym.getNameAsString();
}
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex);
Address symbolAddr = elfRelocationContext.getSymbolAddress(sym);
long symbolValue = elfRelocationContext.getSymbolValue(sym);
String symbolName = elfRelocationContext.getSymbolName(symbolIndex);
//TODO remove debug
switch(type) {

View file

@ -55,8 +55,8 @@ public class SPARC_ElfRelocationHandler extends ElfRelocationHandler {
long offset = (int) relocationAddress.getOffset();
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex);
String symbolName = sym != null ? sym.getNameAsString() : null;
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null
String symbolName = elfRelocationContext.getSymbolName(symbolIndex);
long symbolValue = elfRelocationContext.getSymbolValue(sym);

View file

@ -50,8 +50,8 @@ public class SH_ElfRelocationHandler extends ElfRelocationHandler {
int addend = (int) relocation.getAddend();
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex);
String symbolName = sym.getNameAsString();
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null
String symbolName = elfRelocationContext.getSymbolName(symbolIndex);
int offset = (int) relocationAddress.getOffset();

View file

@ -57,29 +57,15 @@ public class X86_32_ElfRelocationHandler extends ElfRelocationHandler {
long addend =
relocation.hasAddend() ? relocation.getAddend() : memory.getInt(relocationAddress);
ElfSymbol sym = null;
long symbolValue = 0;
Address symbolAddr = null;
String symbolName = null;
if (symbolIndex != 0) {
sym = elfRelocationContext.getSymbol(symbolIndex);
}
if (sym != null) {
symbolAddr = elfRelocationContext.getSymbolAddress(sym);
symbolValue = elfRelocationContext.getSymbolValue(sym);
symbolName = sym.getNameAsString();
}
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();
symbolName = symbolName == null ? "<no name>" : symbolName;
int value;
boolean appliedSymbol = true;
switch (type) {
case X86_32_ElfRelocationConstants.R_386_32:
value = (int) (symbolValue + addend);
@ -114,31 +100,26 @@ public class X86_32_ElfRelocationHandler extends ElfRelocationHandler {
memory.setInt(relocationAddress, value);
break;
case X86_32_ElfRelocationConstants.R_386_COPY:
appliedSymbol = false;
markAsWarning(program, relocationAddress, "R_386_COPY", symbolName, symbolIndex,
"Runtime copy not supported", elfRelocationContext.getLog());
break;
// Thread Local Symbol relocations (unimplemented concept)
case X86_32_ElfRelocationConstants.R_386_TLS_DTPMOD32:
appliedSymbol = false;
markAsWarning(program, relocationAddress, "R_386_TLS_DTPMOD32", symbolName,
symbolIndex, "Thread Local Symbol relocation not support",
elfRelocationContext.getLog());
break;
case X86_32_ElfRelocationConstants.R_386_TLS_DTPOFF32:
appliedSymbol = false;
markAsWarning(program, relocationAddress, "R_386_TLS_DTPOFF32", symbolName,
symbolIndex, "Thread Local Symbol relocation not support",
elfRelocationContext.getLog());
break;
case X86_32_ElfRelocationConstants.R_386_TLS_TPOFF32:
appliedSymbol = false;
markAsWarning(program, relocationAddress, "R_386_TLS_TPOFF32", symbolName,
symbolIndex, "Thread Local Symbol relocation not support",
elfRelocationContext.getLog());
break;
case X86_32_ElfRelocationConstants.R_386_TLS_TPOFF:
appliedSymbol = false;
markAsWarning(program, relocationAddress, "R_386_TLS_TPOFF", symbolName,
symbolIndex, "Thread Local Symbol relocation not support",
elfRelocationContext.getLog());
@ -147,7 +128,6 @@ public class X86_32_ElfRelocationHandler extends ElfRelocationHandler {
// cases which do not use symbol value
case X86_32_ElfRelocationConstants.R_386_RELATIVE:
appliedSymbol = false; // symbol not used, symbolIndex of 0 expected
long base = program.getImageBase().getOffset();
if (elf.isPreLinked()) {
// adjust prelinked value that is already in memory
@ -163,13 +143,11 @@ public class X86_32_ElfRelocationHandler extends ElfRelocationHandler {
case X86_32_ElfRelocationConstants.R_386_IRELATIVE:
// NOTE: We don't support this since the code actually uses a function to
// compute the relocation value (i.e., indirect)
appliedSymbol = false;
markAsError(program, relocationAddress, "R_386_IRELATIVE", symbolName,
"indirect computed relocation not supported", elfRelocationContext.getLog());
break;
case X86_32_ElfRelocationConstants.R_386_GOTPC:
appliedSymbol = false; // symbolIndex of 0 expected
// similar to R_386_PC32 but uses .got address instead of symbol address
dotgot = elfRelocationContext.getGOTValue();
value = (int) (dotgot + addend - offset);
@ -198,16 +176,10 @@ public class X86_32_ElfRelocationHandler extends ElfRelocationHandler {
// case ElfRelocationConstants.R_386_TLS_DESC:
default:
appliedSymbol = false;
markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName,
elfRelocationContext.getLog());
break;
}
if (appliedSymbol && symbolIndex == 0) {
markAsWarning(program, relocationAddress, Long.toString(type),
"applied relocation with symbol-index of 0", elfRelocationContext.getLog());
}
}
}

View file

@ -57,32 +57,18 @@ public class X86_64_ElfRelocationHandler extends ElfRelocationHandler {
long addend =
relocation.hasAddend() ? relocation.getAddend() : memory.getLong(relocationAddress);
ElfSymbol sym = null;
long symbolValue = 0;
Address symbolAddr = null;
String symbolName = null;
long symbolSize = 0;
if (symbolIndex != 0) {
sym = elfRelocationContext.getSymbol(symbolIndex);
}
if (sym != null) {
symbolAddr = elfRelocationContext.getSymbolAddress(sym);
symbolValue = elfRelocationContext.getSymbolValue(sym);
symbolName = sym.getNameAsString();
symbolSize = sym.getSize();
}
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();
long value;
boolean appliedSymbol = true;
switch (type) {
case X86_64_ElfRelocationConstants.R_X86_64_COPY:
appliedSymbol = false;
markAsWarning(program, relocationAddress, "R_X86_64_COPY", symbolName, symbolIndex,
"Runtime copy not supported", elfRelocationContext.getLog());
break;
@ -156,25 +142,21 @@ public class X86_64_ElfRelocationHandler extends ElfRelocationHandler {
// Thread Local Symbol relocations (unimplemented concept)
case X86_64_ElfRelocationConstants.R_X86_64_DTPMOD64:
appliedSymbol = false;
markAsWarning(program, relocationAddress, "R_X86_64_DTPMOD64", symbolName,
symbolIndex, "Thread Local Symbol relocation not support",
elfRelocationContext.getLog());
break;
case X86_64_ElfRelocationConstants.R_X86_64_DTPOFF64:
appliedSymbol = false;
markAsWarning(program, relocationAddress, "R_X86_64_DTPOFF64", symbolName,
symbolIndex, "Thread Local Symbol relocation not support",
elfRelocationContext.getLog());
break;
case X86_64_ElfRelocationConstants.R_X86_64_TPOFF64:
appliedSymbol = false;
markAsWarning(program, relocationAddress, "R_X86_64_TPOFF64", symbolName,
symbolIndex, "Thread Local Symbol relocation not support",
elfRelocationContext.getLog());
break;
case X86_64_ElfRelocationConstants.R_X86_64_TLSDESC:
appliedSymbol = false;
markAsWarning(program, relocationAddress, "R_X86_64_TLSDESC", symbolName,
symbolIndex, "Thread Local Symbol relocation not support",
elfRelocationContext.getLog());
@ -183,7 +165,6 @@ public class X86_64_ElfRelocationHandler extends ElfRelocationHandler {
// cases which do not use symbol value
case X86_64_ElfRelocationConstants.R_X86_64_GOTPC32:
appliedSymbol = false; // symbol not used, symbolIndex of 0 expected
dotgot = elfRelocationContext.getGOTValue();
value = dotgot + addend - offset;
memory.setInt(relocationAddress, (int) value);
@ -201,7 +182,6 @@ public class X86_64_ElfRelocationHandler extends ElfRelocationHandler {
case X86_64_ElfRelocationConstants.R_X86_64_RELATIVE64:
// dl_machine.h
// value = (Elf64_64Addr) map->l_addr + reloc->r_addend
appliedSymbol = false; // symbol not used, symbolIndex of 0 expected
long imageBaseAdjustment = elfRelocationContext.getImageBaseWordAdjustmentOffset();
if (elf.isPreLinked()) {
// adjust prelinked value that is already in memory
@ -226,16 +206,10 @@ public class X86_64_ElfRelocationHandler extends ElfRelocationHandler {
// case ElfRelocationConstants.R_X86_64_TLSDESC_CALL:
default:
appliedSymbol = false;
markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName,
elfRelocationContext.getLog());
break;
}
if (appliedSymbol && symbolIndex == 0) {
markAsWarning(program, relocationAddress, Long.toString(type),
"applied relocation with symbol-index of 0", elfRelocationContext.getLog());
}
}
}