GP-4239 Transitioned to new AbstractElfRelocationHandler implementation which uses ElfRelocationType enums specific to each handler.

This commit is contained in:
ghidra1 2024-02-12 10:52:25 -05:00
parent f01a7172c7
commit 3ead54f0ac
71 changed files with 4921 additions and 4934 deletions

View file

@ -1,62 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.bin.format.elf.relocation;
public class SPARC_ElfRelocationConstants {
public static final int R_SPARC_NONE = 0; // No calculation
public static final int R_SPARC_5 = 44; // S + A
public static final int R_SPARC_6 = 45; // S + A
public static final int R_SPARC_7 = 43; // S + A
public static final int R_SPARC_8 = 1; // S + A
public static final int R_SPARC_10 = 30; // S + A
public static final int R_SPARC_11 = 31; // S + A
public static final int R_SPARC_13 = 11; // S + A
public static final int R_SPARC_16 = 2; // S + A
public static final int R_SPARC_22 = 10; // S + A
public static final int R_SPARC_32 = 3; // S + A
public static final int R_SPARC_LO10 = 12; // (S + A) & 0x3FF
public static final int R_SPARC_HI22 = 9; // (S + A) >> 10
public static final int R_SPARC_DISP8 = 4; // S + A - P
public static final int R_SPARC_DISP16 = 5; // S + A - P
public static final int R_SPARC_DISP32 = 6; // S + A - P
public static final int R_SPARC_WDISP16 = 40; // (S + A - P) >> 2
public static final int R_SPARC_WDISP19 = 41; // (S + A - P) >> 2
public static final int R_SPARC_WDISP22 = 8; // (S + A - P) >> 2
public static final int R_SPARC_WDISP30 = 7; // (S + A - P) >> 2
public static final int R_SPARC_PC10 = 16; // (S + A - P) & 0x3FF
public static final int R_SPARC_PC22 = 17; // (S + A - P) >> 10
public static final int R_SPARC_PLT32 = 24; // L + A
public static final int R_SPARC_PCPLT10 = 29; // (L + A - P) & 0x3FF
public static final int R_SPARC_PCPLT22 = 28; // (L + A - P) >> 10
public static final int R_SPARC_PCPLT32 = 27; // L + A - P
public static final int R_SPARC_GOT10 = 13; // G & 0x3FF
public static final int R_SPARC_GOT13 = 14; // G
public static final int R_SPARC_GOT22 = 15; // G >> 10
public static final int R_SPARC_WPLT30 = 18; // (L + A - P) >> 2
public static final int R_SPARC_LOPLT10 = 26; // (L + A) & 0x3FF
public static final int R_SPARC_HIPLT22 = 25; // (L + A) >> 10
public static final int R_SPARC_JMP_SLOT = 21;
public static final int R_SPARC_UA32 = 23; // S + A
public static final int R_SPARC_GLOB_DAT = 20; // S + A
public static final int R_SPARC_RELATIVE = 22; // B + A
public static final int R_SPARC_COPY = 19; // No calculation
private SPARC_ElfRelocationConstants() {
// no construct
}
}

View file

@ -20,11 +20,18 @@ import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.reloc.RelocationResult;
import ghidra.program.model.reloc.Relocation.Status;
import ghidra.util.exception.NotFoundException;
import ghidra.program.model.reloc.RelocationResult;
public class SPARC_ElfRelocationHandler extends ElfRelocationHandler {
public class SPARC_ElfRelocationHandler
extends AbstractElfRelocationHandler<SPARC_ElfRelocationType, ElfRelocationContext<?>> {
/**
* Constructor
*/
public SPARC_ElfRelocationHandler() {
super(SPARC_ElfRelocationType.class);
}
@Override
public boolean canRelocate(ElfHeader elf) {
@ -34,78 +41,62 @@ public class SPARC_ElfRelocationHandler extends ElfRelocationHandler {
}
@Override
public RelocationResult relocate(ElfRelocationContext elfRelocationContext,
ElfRelocation relocation,
Address relocationAddress) throws MemoryAccessException, NotFoundException {
ElfHeader elf = elfRelocationContext.getElfHeader();
if (elf.e_machine() != ElfConstants.EM_SPARC &&
elf.e_machine() != ElfConstants.EM_SPARC32PLUS) {
return RelocationResult.FAILURE;
}
protected RelocationResult relocate(ElfRelocationContext<?> elfRelocationContext,
ElfRelocation relocation, SPARC_ElfRelocationType type, Address relocationAddress,
ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName)
throws MemoryAccessException {
Program program = elfRelocationContext.getProgram();
Memory memory = program.getMemory();
int type = relocation.getType();
if (type == SPARC_ElfRelocationConstants.R_SPARC_NONE) {
return RelocationResult.SKIPPED;
}
int symbolIndex = relocation.getSymbolIndex();
long addend = relocation.getAddend(); // will be 0 for REL case
// TODO: possible sign-extension seems wrong; there are both 32-bit and 64-bit variants
long offset = (int) relocationAddress.getOffset();
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null
String symbolName = elfRelocationContext.getSymbolName(symbolIndex);
long symbolValue = elfRelocationContext.getSymbolValue(sym);
int symbolIndex = relocation.getSymbolIndex();
int oldValue = memory.getInt(relocationAddress);
int newValue = 0;
int byteLength = 4; // most relocations affect 4-bytes (change if different)
switch (type) {
case SPARC_ElfRelocationConstants.R_SPARC_DISP32:
case R_SPARC_DISP32:
newValue = (int) (symbolValue + addend - offset);
memory.setInt(relocationAddress, oldValue | newValue);
break;
case SPARC_ElfRelocationConstants.R_SPARC_WDISP30:
case R_SPARC_WDISP30:
newValue = (int) (symbolValue + addend - offset) >>> 2;
memory.setInt(relocationAddress, oldValue | newValue);
break;
case SPARC_ElfRelocationConstants.R_SPARC_HI22:
case R_SPARC_HI22:
newValue = ((int) symbolValue + (int) addend) >>> 10;
memory.setInt(relocationAddress, oldValue | newValue);
break;
case SPARC_ElfRelocationConstants.R_SPARC_LO10:
case R_SPARC_LO10:
newValue = ((int) symbolValue + (int) addend) & 0x3FF;
memory.setInt(relocationAddress, oldValue | newValue);
break;
case SPARC_ElfRelocationConstants.R_SPARC_JMP_SLOT:
case R_SPARC_JMP_SLOT:
// should copy address of symbol in EXTERNAL block
case SPARC_ElfRelocationConstants.R_SPARC_32:
case R_SPARC_32:
newValue = (int) symbolValue + (int) addend;
memory.setInt(relocationAddress, newValue);
break;
// we punt on this because it's not linked yet!
case SPARC_ElfRelocationConstants.R_SPARC_GLOB_DAT:
case R_SPARC_GLOB_DAT:
newValue = (int) symbolValue;
memory.setInt(relocationAddress, newValue);
break;
case SPARC_ElfRelocationConstants.R_SPARC_RELATIVE:
newValue = (int) elf.getImageBase() + (int) addend;
case R_SPARC_RELATIVE:
newValue = (int) elfRelocationContext.getElfHeader().getImageBase() + (int) addend;
memory.setInt(relocationAddress, newValue);
break;
case SPARC_ElfRelocationConstants.R_SPARC_UA32:
case R_SPARC_UA32:
newValue = (int) symbolValue + (int) addend;
memory.setInt(relocationAddress, newValue);
break;
case SPARC_ElfRelocationConstants.R_SPARC_COPY:
markAsWarning(program, relocationAddress, "R_SPARC_COPY", symbolName, symbolIndex,
case R_SPARC_COPY:
markAsWarning(program, relocationAddress, type, symbolName, symbolIndex,
"Runtime copy not supported", elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
default:

View file

@ -0,0 +1,70 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.bin.format.elf.relocation;
public enum SPARC_ElfRelocationType implements ElfRelocationType {
R_SPARC_NONE(0), // No calculation
R_SPARC_5(44), // S + A
R_SPARC_6(45), // S + A
R_SPARC_7(43), // S + A
R_SPARC_8(1), // S + A
R_SPARC_10(30), // S + A
R_SPARC_11(31), // S + A
R_SPARC_13(11), // S + A
R_SPARC_16(2), // S + A
R_SPARC_22(10), // S + A
R_SPARC_32(3), // S + A
R_SPARC_LO10(12), // (S + A) & 0x3FF
R_SPARC_HI22(9), // (S + A) >> 10
R_SPARC_DISP8(4), // S + A - P
R_SPARC_DISP16(5), // S + A - P
R_SPARC_DISP32(6), // S + A - P
R_SPARC_WDISP16(40), // (S + A - P) >> 2
R_SPARC_WDISP19(41), // (S + A - P) >> 2
R_SPARC_WDISP22(8), // (S + A - P) >> 2
R_SPARC_WDISP30(7), // (S + A - P) >> 2
R_SPARC_PC10(16), // (S + A - P) & 0x3FF
R_SPARC_PC22(17), // (S + A - P) >> 10
R_SPARC_PLT32(24), // L + A
R_SPARC_PCPLT10(29), // (L + A - P) & 0x3FF
R_SPARC_PCPLT22(28), // (L + A - P) >> 10
R_SPARC_PCPLT32(27), // L + A - P
R_SPARC_GOT10(13), // G & 0x3FF
R_SPARC_GOT13(14), // G
R_SPARC_GOT22(15), // G >> 10
R_SPARC_WPLT30(18), // (L + A - P) >> 2
R_SPARC_LOPLT10(26), // (L + A) & 0x3FF
R_SPARC_HIPLT22(25), // (L + A) >> 10
R_SPARC_JMP_SLOT(21),
R_SPARC_UA32(23), // S + A
R_SPARC_GLOB_DAT(20), // S + A
R_SPARC_RELATIVE(22), // B + A
R_SPARC_COPY(19); // No calculation
public final int typeId;
private SPARC_ElfRelocationType(int typeId) {
this.typeId = typeId;
}
@Override
public int typeId() {
return typeId;
}
}