mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-4239 Transitioned to new AbstractElfRelocationHandler implementation which uses ElfRelocationType enums specific to each handler.
This commit is contained in:
parent
f01a7172c7
commit
3ead54f0ac
71 changed files with 4921 additions and 4934 deletions
|
@ -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;
|
||||
|
||||
}
|
|
@ -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<AVR32_ElfRelocationType, ElfRelocationContext<?>> {
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
// <align:0 bitpos:0 bitsize:0 complain:dont>
|
||||
public static final int R_AVR32_NONE = 0;
|
||||
R_AVR32_NONE(0),
|
||||
/* Data Relocations */
|
||||
// DATA: ((S + A) & 0xffffffff) (Normal Data)
|
||||
// <align:0 bitpos:0 bitsize:32 complain:dont>
|
||||
public static final int R_AVR32_32 = 1;
|
||||
R_AVR32_32(1),
|
||||
// DATA: ((S + A) & 0x0000ffff) (Normal Data)
|
||||
// <align:0 bitpos:0 bitsize:16 complain:bitfield>
|
||||
public static final int R_AVR32_16 = 2;
|
||||
R_AVR32_16(2),
|
||||
// DATA: ((S + A) & 0x000000ff)(Normal Data)
|
||||
// <align:0 bitpos:0 bitsize:8 complain:bitfield>
|
||||
public static final int R_AVR32_8 = 3;
|
||||
R_AVR32_8(3),
|
||||
// DATA: ((S + A - P) & 0xffffffff) (PC-relative)
|
||||
// <align:0 bitpos:0 bitsize:32 complain:signed>
|
||||
public static final int R_AVR32_32_PCREL = 4;
|
||||
R_AVR32_32_PCREL(4),
|
||||
// DATA: ((S + A - P) & 0x0000ffff) (PC-relative)
|
||||
// <align:0 bitpos:0 bitsize:16 complain:signed>
|
||||
public static final int R_AVR32_16_PCREL = 5;
|
||||
R_AVR32_16_PCREL(5),
|
||||
// DATA: ((S + A - P) & 0x000000ff) (PC-relative)
|
||||
// <align:0 bitpos:0 bitsize:8 complain:signed>
|
||||
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)
|
||||
// <align:0 bitpos:0 bitsize:32 complain:dont>
|
||||
public static final int R_AVR32_DIFF32 = 7;
|
||||
R_AVR32_DIFF32(7),
|
||||
// DATA: (S & 0x0000ffff)
|
||||
// <align:0 bitpos:0 bitsize:16 complain:signed>
|
||||
public static final int R_AVR32_DIFF16 = 8;
|
||||
R_AVR32_DIFF16(8),
|
||||
// DATA: (S & 0x000000ff)
|
||||
// <align:0 bitpos:0 bitsize:8 complain:signed>
|
||||
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)
|
||||
// <align:0 bitpos:0 bitsize:32 complain:signed>
|
||||
public static final int R_AVR32_GOT32 = 10;
|
||||
R_AVR32_GOT32(10),
|
||||
// DATA: (G & 0x0000ffff)
|
||||
// <align:0 bitpos:0 bitsize:16 complain:signed>
|
||||
public static final int R_AVR32_GOT16 = 11;
|
||||
R_AVR32_GOT16(11),
|
||||
// DATA: (G & 0x000000ff)
|
||||
// <align:0 bitpos:0 bitsize:8 complain:signed>
|
||||
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)
|
||||
// <align:0 bitpos:0 bitsize:21 complain:signed>
|
||||
public static final int R_AVR32_21S = 13;
|
||||
R_AVR32_21S(13),
|
||||
// NORMAL CODE: ((S + A) & 0x0000ffff)
|
||||
// <align:0 bitpos:0 bitsize:16 complain:unsigned>
|
||||
public static final int R_AVR32_16U = 14;
|
||||
R_AVR32_16U(14),
|
||||
// NORMAL CODE: ((S + A) & 0x0000ffff)
|
||||
// <align:0 bitpos:0 bitsize:16 complain:signed>
|
||||
public static final int R_AVR32_16S = 15;
|
||||
R_AVR32_16S(15),
|
||||
// NORMAL CODE: (((S + A)) << 4) & 0x00000ff0)
|
||||
// <align:0 bitpos:4 bitsize:8 complain:signed>
|
||||
public static final int R_AVR32_8S = 16;
|
||||
R_AVR32_8S(16),
|
||||
// NORMAL CODE: ((S + A) & 0x000000ff)
|
||||
// <align:0 bitpos:0 bitsize:8 complain:signed>
|
||||
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)
|
||||
// <align:1 bitpos:0 bitsize:21 complain:signed>
|
||||
public static final int R_AVR32_22H_PCREL = 18;
|
||||
R_AVR32_22H_PCREL(18),
|
||||
// PC-REL CODE: (((S + A - P) >> 2) & 0x0000ffff)
|
||||
// <align:2 bitpos:0 bitsize:16 complain:signed>
|
||||
public static final int R_AVR32_18W_PCREL = 19;
|
||||
R_AVR32_18W_PCREL(19),
|
||||
// PC-REL CODE: ((S + A - P) & 0x0000ffff)
|
||||
// <align:0 bitpos:0 bitsize:16 complain:signed>
|
||||
public static final int R_AVR32_16B_PCREL = 20;
|
||||
R_AVR32_16B_PCREL(20),
|
||||
// PC-REL CODE: ((P - S - A) & 0x0000ffff)
|
||||
// <align:0 bitpos:0 bitsize:16 complain:signed>
|
||||
public static final int R_AVR32_16N_PCREL = 21;
|
||||
R_AVR32_16N_PCREL(21),
|
||||
// PC-REL CODE: (((S + A - P) >>> 2) & 0x0000f0ff)
|
||||
// <align:2 bitpos:0 bitsize:12 complain:unsigned>
|
||||
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)
|
||||
// <align:1 bitpos:4 bitsize:10 complain:signed>
|
||||
public static final int R_AVR32_11H_PCREL = 23;
|
||||
R_AVR32_11H_PCREL(23),
|
||||
// PC-REL CODE: (((S + A - P) >>> 2) & 0x000000ff)
|
||||
// <align:2 bitpos:0 bitsize:8 complain:unsigned>
|
||||
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)
|
||||
// <align:1 bitpos:4 bitsize:8 complain:signed>
|
||||
public static final int R_AVR32_9H_PCREL = 25;
|
||||
R_AVR32_9H_PCREL(25),
|
||||
// PC-REL CODE: ((((S + A) << 4) - P) >>> 2) & 0x000007f0)
|
||||
// <align:2 bitpos:4 bitsize:7 complain:unsigned>
|
||||
public static final int R_AVR32_9UW_PCREL = 26;
|
||||
R_AVR32_9UW_PCREL(26),
|
||||
/* Special Code Relocations */
|
||||
// Special CODE: (((S + A) >> 16) & 0x0000ffff)
|
||||
// <align:16 bitpos:0 bitsize:16 complain:dont>
|
||||
public static final int R_AVR32_HI16 = 27;
|
||||
R_AVR32_HI16(27),
|
||||
// Special CODE: ((S + A) & 0x0000ffff)
|
||||
// <align:0 bitpos:0 bitsize:16 complain:dont>
|
||||
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)
|
||||
// <align:0 bitpos:0 bitsize:32 complain:dont>
|
||||
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)
|
||||
// <align:2 bitpos:0 bitsize:21 complain:signed> (Call instructions)
|
||||
public static final int R_AVR32_GOTCALL = 30;
|
||||
R_AVR32_GOTCALL(30),
|
||||
// PIC: ((G >> 2) & 0x1e10ffff)
|
||||
// <align:2 bitpos:0 bitsize:21 complain:signed> (lda.w instructions)
|
||||
public static final int R_AVR32_LDA_GOT = 31;
|
||||
R_AVR32_LDA_GOT(31),
|
||||
// PIC: (G & 0x1e10ffff)
|
||||
// <align:0 bitpos:0 bitsize:21 complain:signed>
|
||||
public static final int R_AVR32_GOT21S = 32;
|
||||
R_AVR32_GOT21S(32),
|
||||
// PIC: ((G >> 2) & 0x0000ffff)
|
||||
// <align:2 bitpos:0 bitsize:16 complain:signed>
|
||||
public static final int R_AVR32_GOT18SW = 33;
|
||||
R_AVR32_GOT18SW(33),
|
||||
// PIC: (G & 0x0000ffff)
|
||||
// <align:0 bitpos:0 bitsize:16 complain:signed>
|
||||
public static final int R_AVR32_GOT16S = 34;
|
||||
R_AVR32_GOT16S(34),
|
||||
// PIC: (((G) << 4) >> 2) & 0x000001f0)
|
||||
// <align:2 bitpos:4 bitsize:5 complain:unsigned>
|
||||
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)
|
||||
// <align:0 bitpos:0 bitsize:32 complain:dont>
|
||||
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)
|
||||
// <align:2 bitpos:0 bitsize:16 complain:signed>
|
||||
public static final int R_AVR32_CPCALL = 37;
|
||||
R_AVR32_CPCALL(37),
|
||||
// CONST POOL: ((S + A - P) & 0x0000ffff)
|
||||
// <align:0 bitpos:0 bitsize:16 complain:signed>
|
||||
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)
|
||||
// <align:2 bitpos:4 bitsize:7 complain:unsigned>
|
||||
public static final int R_AVR32_9W_CP = 39;
|
||||
R_AVR32_9W_CP(39),
|
||||
/* Dynamic Relocations */
|
||||
// Dynamic: ((B + A) & 0xffffffff)
|
||||
// <align:0 bitpos:0 bitsize:32 complain:signed>
|
||||
public static final int R_AVR32_RELATIVE = 40;
|
||||
R_AVR32_RELATIVE(40),
|
||||
// Dynamic: ((S + A) & 0xffffffff)
|
||||
// <align:0 bitpos:0 bitsize:32 complain:dont>
|
||||
public static final int R_AVR32_GLOB_DAT = 41;
|
||||
R_AVR32_GLOB_DAT(41),
|
||||
// Dynamic: ((S + A) & 0xffffffff)
|
||||
// <align:0 bitpos:0 bitsize:32 complain:dont>
|
||||
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)
|
||||
// <align:0 bitpos:0 bitsize:0 complain:unsigned>
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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<AVR8_ElfRelocationType, ElfRelocationContext<?>> {
|
||||
|
||||
/**
|
||||
* 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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue