Merge remote-tracking branch

'origin/GP-1352_ghidra1_ElfAndroidRelocMarkup' (Closes #3462)
This commit is contained in:
ghidra1 2021-10-01 11:48:55 -04:00
commit be13d9047a
5 changed files with 60 additions and 37 deletions

View File

@ -15,6 +15,8 @@
*/
package ghidra.app.util.bin.format.elf;
import javax.help.UnsupportedOperationException;
import ghidra.app.plugin.exceptionhandlers.gcc.datatype.AbstractLeb128DataType;
import ghidra.docking.settings.Settings;
import ghidra.docking.settings.SettingsDefinition;
@ -48,10 +50,8 @@ class AndroidElfRelocationData extends AbstractLeb128DataType {
@Override
public DataType clone(DataTypeManager dtm) {
if (dtm == getDataTypeManager()) {
return this;
}
return new AndroidElfRelocationData(dtm, relocationOffset);
// specific instances are used by AndroidElfRelocationTableDataType
throw new UnsupportedOperationException("may not be cloned");
}
@Override

View File

@ -18,6 +18,8 @@ package ghidra.app.util.bin.format.elf;
import java.io.IOException;
import java.util.ArrayList;
import javax.help.UnsupportedOperationException;
import ghidra.app.util.bin.*;
import ghidra.app.util.bin.format.elf.AndroidElfRelocationTableDataType.LEB128Info;
import ghidra.docking.settings.Settings;
@ -48,10 +50,8 @@ class AndroidElfRelocationGroup extends DynamicDataType {
@Override
public DataType clone(DataTypeManager dtm) {
if (dtm == dataMgr) {
return this;
}
return new AndroidElfRelocationGroup(dtm, baseRelocOffset);
// specific instances are used by AndroidElfRelocationTableDatatype
throw new UnsupportedOperationException("may not be cloned");
}
@Override
@ -125,9 +125,10 @@ class AndroidElfRelocationGroup extends DynamicDataType {
}
else {
sleb128 = LEB128Info.parse(reader, true);
long baseOffset = relocOffset;
relocOffset += sleb128.value;
DataTypeComponent dtc = new ReadOnlyDataTypeComponent(
new AndroidElfRelocationOffset(dataMgr, relocOffset), this,
new AndroidElfRelocationOffset(dataMgr, baseOffset, relocOffset), this,
sleb128.byteLength, list.size(), sleb128.offset, "reloc_offset_" + i,
null);
list.add(dtc);
@ -161,6 +162,7 @@ class AndroidElfRelocationGroup extends DynamicDataType {
return -1;
}
// group_size component
Scalar s = (Scalar) comps[0].getDataType().getValue(buf, null, comps[0].getLength());
int groupSize = (int) s.getValue();
@ -170,10 +172,7 @@ class AndroidElfRelocationGroup extends DynamicDataType {
WrappedMemBuffer cbuf = new WrappedMemBuffer(buf, comps[2].getOffset());
s = (Scalar) comps[2].getDataType().getValue(cbuf, null, comps[2].getLength());
long groupOffsetDelta = s.getValue();
if (lastDtc.getFieldName().startsWith("group_")) {
// must compute final offset for group
return baseRelocOffset + (groupSize * groupOffsetDelta);
}
return baseRelocOffset + ((groupSize - 1) * groupOffsetDelta);
}
if (lastDtc.getFieldName().startsWith("group_")) {
@ -189,7 +188,6 @@ class AndroidElfRelocationGroup extends DynamicDataType {
AndroidElfRelocationData d = (AndroidElfRelocationData) dt;
return d.getRelocationOffset(); // return stashed offset
}
return -1; // unexpected
}
}

View File

@ -15,14 +15,19 @@
*/
package ghidra.app.util.bin.format.elf;
import javax.help.UnsupportedOperationException;
import ghidra.app.plugin.exceptionhandlers.gcc.datatype.AbstractLeb128DataType;
import ghidra.app.util.opinion.ElfLoader;
import ghidra.docking.settings.Settings;
import ghidra.docking.settings.SettingsDefinition;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeManager;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.MemBuffer;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.scalar.Scalar;
/**
@ -46,18 +51,21 @@ class AndroidElfRelocationOffset extends AbstractLeb128DataType {
* value adjusted by baseOffset.
* @param dtm the data type manager to associate with this data type.
* @param baseOffset base offset to which LEB128 offset data should be added
* @param relocationOffset the actual relocation offset value assciated with this
* instance (used by {@link #getValue(MemBuffer, Settings, int)} and
* returned by {@link #getRelocationOffset()}. This value should equals
* <code>baseOffset</code> plus decoded value of sleb128 data.
*/
AndroidElfRelocationOffset(DataTypeManager dtm, long baseOffset) {
AndroidElfRelocationOffset(DataTypeManager dtm, long baseOffset, long relocationOffset) {
super("sleb128_offset", true, dtm);
this.baseOffset = baseOffset;
this.relocationOffset = relocationOffset;
}
@Override
public DataType clone(DataTypeManager dtm) {
if (dtm == getDataTypeManager()) {
return this;
}
return new AndroidElfRelocationOffset(dtm, baseOffset);
// specific instances are used by AndroidElfRelocationGroup
throw new UnsupportedOperationException("may not be cloned");
}
@Override
@ -85,15 +93,29 @@ class AndroidElfRelocationOffset extends AbstractLeb128DataType {
return Address.class;
}
private long getImageBaseAdjustment(Program program) {
Long originalimageBase = ElfLoader.getElfOriginalImageBase(program);
if (originalimageBase != null) {
return program.getImageBase().getOffset() - originalimageBase;
}
return 0;
}
@Override
public Object getValue(MemBuffer buf, Settings settings, int length) {
Scalar s = (Scalar) super.getValue(buf, settings, length);
if (s == null) {
return null;
}
long imageBaseAdj = 0;
Memory mem = buf.getMemory();
if (mem != null) {
imageBaseAdj = getImageBaseAdjustment(mem.getProgram());
}
// assume pointer into physical space associated with buf
AddressSpace space = buf.getAddress().getAddressSpace().getPhysicalSpace();
return space.getAddress(s.getUnsignedValue() + baseOffset);
return space.getAddress(s.getSignedValue() + baseOffset + imageBaseAdj);
}
@Override
@ -110,7 +132,7 @@ class AndroidElfRelocationOffset extends AbstractLeb128DataType {
b.append(" + ");
}
b.append("0x");
b.append(Long.toHexString(s.getUnsignedValue()));
b.append(Long.toHexString(s.getSignedValue()));
return b.toString();
}
@ -122,12 +144,4 @@ class AndroidElfRelocationOffset extends AbstractLeb128DataType {
return relocationOffset;
}
/**
* Set the computed relocation offset location associated with this
* component.
* @param relocationOffset stashed relocation offset
*/
void setRelocationOffset(long relocationOffset) {
this.relocationOffset = relocationOffset;
}
}

View File

@ -205,12 +205,15 @@ public class ElfRelocationTable implements ElfFileSection, ByteArrayConverter {
try {
int relocationIndex = 0;
long remainingRelocations = LEB128.readAsLong(reader, true);
long offset = LEB128.readAsLong(reader, true);
long addend = 0;
long remainingRelocations = LEB128.readAsLong(reader, true); // reloc_count
long offset = LEB128.readAsLong(reader, true); // reloc_baseOffset
while (remainingRelocations > 0) {
// start new group
long addend = 0;
// group_size
long groupSize = LEB128.readAsLong(reader, true);
if (groupSize > remainingRelocations) {
Msg.warn(this, "Group relocation count " + groupSize +
@ -218,6 +221,7 @@ public class ElfRelocationTable implements ElfFileSection, ByteArrayConverter {
break;
}
// group_flags
long groupFlags = LEB128.readAsLong(reader, true);
boolean groupedByInfo =
(groupFlags & AndroidElfRelocationGroup.RELOCATION_GROUPED_BY_INFO_FLAG) != 0;
@ -228,34 +232,36 @@ public class ElfRelocationTable implements ElfFileSection, ByteArrayConverter {
boolean groupHasAddend =
(groupFlags & AndroidElfRelocationGroup.RELOCATION_GROUP_HAS_ADDEND_FLAG) != 0;
// group_offsetDelta (optional)
long groupOffsetDelta = groupedByDelta ? LEB128.readAsLong(reader, true) : 0;
// group_info (optional)
long groupRInfo = groupedByInfo ? LEB128.readAsLong(reader, true) : 0;
if (groupedByAddend && groupHasAddend) {
// group_addend (optional)
addend += LEB128.readAsLong(reader, true);
}
for (int i = 0; i < groupSize; i++) {
// reloc_offset (optional)
offset += groupedByDelta ? groupOffsetDelta : LEB128.readAsLong(reader, true);
// reloc_info (optional)
long info = groupedByInfo ? groupRInfo : LEB128.readAsLong(reader, true);
long rAddend = 0;
if (groupHasAddend) {
if (!groupedByAddend) {
// reloc_addend (optional)
addend += LEB128.readAsLong(reader, true);
}
rAddend = addend;
}
relocations.add(ElfRelocation.createElfRelocation(reader.getFactory(),
elfHeader, relocationIndex++, addendTypeReloc, offset, info, rAddend));
}
if (!groupHasAddend) {
addend = 0;
}
remainingRelocations -= groupSize;
}
}

View File

@ -29,6 +29,11 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
return elf.e_machine() == ElfConstants.EM_ARM;
}
@Override
public int getRelrRelocationType() {
return ARM_ElfRelocationConstants.R_ARM_RELATIVE;
}
@Override
public void relocate(ElfRelocationContext elfRelocationContext, ElfRelocation relocation,
Address relocationAddress) throws MemoryAccessException, NotFoundException {