mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-24 00:22:42 +08:00
Merge remote-tracking branch 'origin/GT-3661_ghidra1_ElfStrippedImprovements'
This commit is contained in:
@@ -42,7 +42,7 @@ public class ElfHeader implements StructConverter, Writeable {
|
||||
private static final int MAX_HEADERS_TO_CHECK_FOR_IMAGEBASE = 20;
|
||||
|
||||
private static final int PAD_LENGTH = 7;
|
||||
|
||||
|
||||
private HashMap<Integer, ElfProgramHeaderType> programHeaderTypeMap;
|
||||
private HashMap<Integer, ElfSectionHeaderType> sectionHeaderTypeMap;
|
||||
private HashMap<Integer, ElfDynamicType> dynamicTypeMap;
|
||||
@@ -357,8 +357,8 @@ public class ElfHeader implements StructConverter, Writeable {
|
||||
try {
|
||||
boolean isRela = (dynamicTable
|
||||
.getDynamicValue(ElfDynamicType.DT_PLTREL) == ElfDynamicType.DT_RELA.value);
|
||||
parseDynamicRelocTable(relocationTableList, ElfDynamicType.DT_JMPREL,
|
||||
null, ElfDynamicType.DT_PLTRELSZ, isRela);
|
||||
parseDynamicRelocTable(relocationTableList, ElfDynamicType.DT_JMPREL, null,
|
||||
ElfDynamicType.DT_PLTRELSZ, isRela);
|
||||
}
|
||||
catch (NotFoundException e) {
|
||||
// ignore - skip (required dynamic table value is missing)
|
||||
@@ -746,8 +746,8 @@ public class ElfHeader implements StructConverter, Writeable {
|
||||
" linked to string table section " +
|
||||
stringTableSectionHeader.getNameAsString());
|
||||
|
||||
boolean isDyanmic = ElfSectionHeaderConstants.dot_dynsym.equals(
|
||||
symbolTableSectionHeader.getNameAsString());
|
||||
boolean isDyanmic = ElfSectionHeaderConstants.dot_dynsym
|
||||
.equals(symbolTableSectionHeader.getNameAsString());
|
||||
|
||||
ElfSymbolTable symbolTable = ElfSymbolTable.createElfSymbolTable(reader, this,
|
||||
symbolTableSectionHeader, symbolTableSectionHeader.getOffset(),
|
||||
@@ -967,6 +967,16 @@ public class ElfHeader implements StructConverter, Writeable {
|
||||
return e_ident_class == ElfConstants.ELF_CLASS_64;
|
||||
}
|
||||
|
||||
private long getMinBase(long addr, long minBase) {
|
||||
if (is32Bit()) {
|
||||
addr &= Conv.INT_MASK;
|
||||
}
|
||||
if (Long.compareUnsigned(addr, minBase) < 0) {
|
||||
minBase = addr;
|
||||
}
|
||||
return minBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspect the Elf image and determine the default image base prior
|
||||
* to the {@link #parse()} method being invoked (i.e., only the main Elf
|
||||
@@ -981,10 +991,9 @@ public class ElfHeader implements StructConverter, Writeable {
|
||||
// FIXME! This needs to be consistent with the getImageBase() method
|
||||
// which currently considers prelink.
|
||||
|
||||
int n = Math.min(e_phnum, MAX_HEADERS_TO_CHECK_FOR_IMAGEBASE);
|
||||
|
||||
long minBase = -1;
|
||||
|
||||
int n = Math.min(e_phnum, MAX_HEADERS_TO_CHECK_FOR_IMAGEBASE);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
long index = e_phoff + (i * e_phentsize);
|
||||
reader.setPointerIndex(index);
|
||||
@@ -992,14 +1001,7 @@ public class ElfHeader implements StructConverter, Writeable {
|
||||
int headerType = reader.peekNextInt();
|
||||
if (headerType == ElfProgramHeaderConstants.PT_LOAD) {
|
||||
ElfProgramHeader header = ElfProgramHeader.createElfProgramHeader(reader, this);
|
||||
long addr = header.getVirtualAddress();
|
||||
// TODO: not sure why we need to mask value
|
||||
if (is32Bit()) {
|
||||
addr &= Conv.INT_MASK;
|
||||
}
|
||||
if (Long.compareUnsigned(addr, minBase) < 0) {
|
||||
minBase = addr;
|
||||
}
|
||||
minBase = getMinBase(header.getVirtualAddress(), minBase);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
@@ -1033,15 +1035,9 @@ public class ElfHeader implements StructConverter, Writeable {
|
||||
int n = Math.min(programHeaders.length, MAX_HEADERS_TO_CHECK_FOR_IMAGEBASE);
|
||||
long minBase = -1;
|
||||
for (int i = 0; i < n; i++) {
|
||||
ElfProgramHeader header = programHeaders[i];
|
||||
if (programHeaders[i].getType() == ElfProgramHeaderConstants.PT_LOAD) {
|
||||
long addr = programHeaders[i].getVirtualAddress();
|
||||
// TODO: not sure why we need to mask value
|
||||
if (is32Bit()) {
|
||||
addr &= Conv.INT_MASK;
|
||||
}
|
||||
if (Long.compareUnsigned(addr, minBase) < 0) {
|
||||
minBase = addr;
|
||||
}
|
||||
minBase = getMinBase(header.getVirtualAddress(), minBase);
|
||||
}
|
||||
}
|
||||
elfImageBase = (minBase == -1 ? 0 : minBase);
|
||||
@@ -1197,7 +1193,7 @@ public class ElfHeader implements StructConverter, Writeable {
|
||||
public short e_machine() {
|
||||
return e_machine;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This member identifies the target operating system and ABI.
|
||||
* @return the target operating system and ABI
|
||||
@@ -1205,7 +1201,7 @@ public class ElfHeader implements StructConverter, Writeable {
|
||||
public byte e_ident_osabi() {
|
||||
return e_ident_osabi;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This member identifies the target ABI version.
|
||||
* @return the target ABI version
|
||||
|
||||
+6
-6
@@ -339,7 +339,7 @@ public class ElfSectionHeader implements StructConverter, Writeable, MemoryLoada
|
||||
return sh_name;
|
||||
}
|
||||
|
||||
void updateName() throws IOException {
|
||||
void updateName() {
|
||||
if (reader == null) {
|
||||
throw new UnsupportedOperationException("This ElfSectionHeader does not have a reader");
|
||||
}
|
||||
@@ -349,11 +349,11 @@ public class ElfSectionHeader implements StructConverter, Writeable, MemoryLoada
|
||||
name = null;
|
||||
try {
|
||||
if (sh_name >= 0 && e_shstrndx >= 0 && e_shstrndx < sections.length) {
|
||||
ElfSectionHeader stringTableSectionHeader = sections[e_shstrndx];
|
||||
if (sh_name < stringTableSectionHeader.sh_size) {
|
||||
// read section name from string table
|
||||
long stringTableOffset = sections[e_shstrndx].getOffset();
|
||||
if (stringTableOffset >= 0) {
|
||||
// read section name from string table
|
||||
long stringTableOffset = sections[e_shstrndx].getOffset();
|
||||
if (stringTableOffset >= 0) {
|
||||
long offset = stringTableOffset + sh_name;
|
||||
if (offset < reader.length()) {
|
||||
name = reader.readAsciiString(stringTableOffset + sh_name);
|
||||
if ("".equals(name)) {
|
||||
name = null;
|
||||
|
||||
+177
-51
@@ -38,6 +38,7 @@ import ghidra.program.database.mem.FileBytes;
|
||||
import ghidra.program.database.register.AddressRangeObjectMap;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.Array;
|
||||
import ghidra.program.model.data.DataUtilities.ClearDataMode;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.mem.*;
|
||||
@@ -47,15 +48,16 @@ import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.model.util.AddressSetPropertyMap;
|
||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.datastruct.*;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
|
||||
class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
|
||||
public static final String BLOCK_SOURCE_NAME = "Elf Loader";
|
||||
|
||||
private static final String SEGMENT_NAME_PREFIX = "segment_";
|
||||
private static final String UNALLOCATED_NAME_PREFIX = "unallocated_";
|
||||
|
||||
private static final String ELF_HEADER_BLOCK_NAME = "_elfHeader";
|
||||
private static final String ELF_PROGRAM_HEADERS_BLOCK_NAME = "_elfProgramHeaders";
|
||||
@@ -118,10 +120,13 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
// resolve segment/sections and create program memory blocks
|
||||
ByteProvider byteProvider = elf.getReader().getByteProvider();
|
||||
try (InputStream fileIn = byteProvider.getInputStream(0)) {
|
||||
fileBytes = program.getMemory().createFileBytes(byteProvider.getName(), 0,
|
||||
byteProvider.length(), fileIn, monitor);
|
||||
fileBytes = program.getMemory()
|
||||
.createFileBytes(byteProvider.getName(), 0, byteProvider.length(), fileIn,
|
||||
monitor);
|
||||
}
|
||||
|
||||
adjustSegmentAndSectionFileAllocations(byteProvider);
|
||||
|
||||
// process headers and define "section" within memory elfProgramBuilder
|
||||
processProgramHeaders(monitor);
|
||||
processSectionHeaders(monitor);
|
||||
@@ -179,20 +184,138 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private void adjustSegmentAndSectionFileAllocations(ByteProvider byteProvider)
|
||||
throws IOException {
|
||||
|
||||
// Identify file ranges not consumed by segments and sections
|
||||
RangeMap fileMap = new RangeMap();
|
||||
fileMap.paintRange(0, byteProvider.length() - 1, -1); // -1: unallocated
|
||||
|
||||
ElfProgramHeader[] segments = elf.getProgramHeaders();
|
||||
ElfSectionHeader[] sections = elf.getSections();
|
||||
|
||||
for (ElfProgramHeader segment : segments) {
|
||||
if (segment.getType() == ElfProgramHeaderConstants.PT_NULL) {
|
||||
continue;
|
||||
}
|
||||
long size = segment.getFileSize();
|
||||
long offset = segment.getOffset();
|
||||
if (size > 0) {
|
||||
fileMap.paintRange(offset, offset + size - 1, -2); // -2: used by segment
|
||||
}
|
||||
}
|
||||
|
||||
for (ElfSectionHeader section : sections) {
|
||||
if (section.getType() == ElfSectionHeaderConstants.SHT_NULL) {
|
||||
continue;
|
||||
}
|
||||
section.getSize();
|
||||
section.getOffset();
|
||||
long size = section.getSize();
|
||||
long offset = section.getOffset();
|
||||
if (size > 0) {
|
||||
fileMap.paintRange(offset, offset + size - 1, -3); // -3: used by section
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate unused file ranges (0: first segment index, segments.length: first section index)
|
||||
|
||||
// Make segment file allocations
|
||||
for (int i = 0; i < segments.length; i++) {
|
||||
ElfProgramHeader segment = segments[i];
|
||||
if (segment.getType() == ElfProgramHeaderConstants.PT_NULL) {
|
||||
continue;
|
||||
}
|
||||
long size = segment.getFileSize();
|
||||
long offset = segment.getOffset();
|
||||
if (size == 0 && offset > 0) {
|
||||
ValueRange valueRange = fileMap.getValueRange(offset);
|
||||
if (valueRange == null || valueRange.getValue() < -1) {
|
||||
continue;
|
||||
}
|
||||
if (valueRange.getValue() >= 0 && valueRange.getStart() < segment.getOffset()) {
|
||||
ElfProgramHeader otherSegment = segments[valueRange.getValue()];
|
||||
otherSegment.setSize(offset - valueRange.getStart(), 0); // reduce previous segment allocation
|
||||
}
|
||||
segment.setSize(valueRange.getEnd() - offset + 1, 0);
|
||||
fileMap.paintRange(offset, valueRange.getEnd(), i); // allocated to segment
|
||||
}
|
||||
}
|
||||
|
||||
// Make section file allocations
|
||||
int firstSectionIndex = segments.length;
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
ElfSectionHeader section = sections[i];
|
||||
if (section.getType() == ElfSectionHeaderConstants.SHT_NULL) {
|
||||
continue;
|
||||
}
|
||||
long size = section.getSize();
|
||||
long offset = section.getOffset();
|
||||
if (size == 0 && offset > 0) {
|
||||
ValueRange valueRange = fileMap.getValueRange(offset);
|
||||
if (valueRange == null || valueRange.getValue() < -1) {
|
||||
continue;
|
||||
}
|
||||
if (valueRange.getValue() >= firstSectionIndex &&
|
||||
valueRange.getStart() < section.getOffset()) {
|
||||
ElfSectionHeader otherSection =
|
||||
sections[valueRange.getValue() - firstSectionIndex];
|
||||
otherSection.setSize(offset - valueRange.getStart()); // reduce previous section allocation
|
||||
}
|
||||
section.setSize(valueRange.getEnd() - offset + 1);
|
||||
Msg.info(this, "Forced section " + i + " size: " + section.getSize());
|
||||
fileMap.paintRange(offset, valueRange.getEnd(), firstSectionIndex + i); // allocated to section
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore header regions which will always be allocated to blocks
|
||||
int elfHeaderSize = elf.toDataType().getLength();
|
||||
fileMap.paintRange(0, elfHeaderSize - 1, -4);
|
||||
int programHeaderSize = elf.e_phentsize() * elf.e_phnum();
|
||||
if (programHeaderSize != 0) {
|
||||
fileMap.paintRange(elf.e_phoff(), elf.e_phoff() + programHeaderSize - 1, -4);
|
||||
}
|
||||
int sectionHeaderSize = elf.e_shentsize() * elf.e_shnum();
|
||||
if (sectionHeaderSize != 0) {
|
||||
fileMap.paintRange(elf.e_shoff(), elf.e_shoff() + sectionHeaderSize - 1, -4);
|
||||
}
|
||||
|
||||
// Unused file ranges - add as OTHER blocks
|
||||
IndexRangeIterator rangeIterator = fileMap.getIndexRangeIterator(0);
|
||||
int unallocatedIndex = 0;
|
||||
while (rangeIterator.hasNext()) {
|
||||
IndexRange range = rangeIterator.next();
|
||||
int value = fileMap.getValue(range.getStart());
|
||||
if (value != -1) {
|
||||
continue;
|
||||
}
|
||||
String name = UNALLOCATED_NAME_PREFIX + unallocatedIndex++;
|
||||
try {
|
||||
addInitializedMemorySection(null, range.getStart(),
|
||||
range.getEnd() - range.getStart() + 1, AddressSpace.OTHER_SPACE.getMinAddress(),
|
||||
name, false, false, false, null, false, false);
|
||||
}
|
||||
catch (AddressOverflowException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void pruneDiscardableBlocks() {
|
||||
byte[] bytes = new byte[DISCARDABLE_SEGMENT_SIZE];
|
||||
try {
|
||||
for (MemoryBlock block : memory.getBlocks()) {
|
||||
long size = block.getSize();
|
||||
if (size > DISCARDABLE_SEGMENT_SIZE ||
|
||||
!block.getName().startsWith(SEGMENT_NAME_PREFIX)) {
|
||||
!(block.getName().startsWith(SEGMENT_NAME_PREFIX) ||
|
||||
block.getName().startsWith(UNALLOCATED_NAME_PREFIX))) {
|
||||
continue;
|
||||
}
|
||||
block.getBytes(block.getStart(), bytes, 0, (int) size);
|
||||
if (isZeroedArray(bytes, (int) size)) {
|
||||
Msg.debug(this,
|
||||
"Removing discardable alignment/filler segment at " + block.getStart());
|
||||
memory.removeBlock(block, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
memory.removeBlock(block, TaskMonitor.DUMMY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,7 +373,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
Msg.error(this, "Can't set image base.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private long getImageDataBase() {
|
||||
if (dataImageBase == null) {
|
||||
dataImageBase = 0L;
|
||||
@@ -448,8 +571,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
}
|
||||
|
||||
monitor.setMessage("Processing GNU Definitions");
|
||||
for (ElfProgramHeader roSegment : elf.getProgramHeaders(
|
||||
ElfProgramHeaderConstants.PT_GNU_RELRO)) {
|
||||
for (ElfProgramHeader roSegment : elf
|
||||
.getProgramHeaders(ElfProgramHeaderConstants.PT_GNU_RELRO)) {
|
||||
ElfProgramHeader loadedSegment =
|
||||
elf.getProgramLoadHeaderContaining(roSegment.getVirtualAddress());
|
||||
if (loadedSegment != null) {
|
||||
@@ -747,11 +870,12 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
symbolName = symbols[symbolIndex].getNameAsString();
|
||||
}
|
||||
|
||||
Address baseAddress = relocationSpace.getTruncatedAddress(baseWordOffset, true);
|
||||
// long relocationOffset = baseWordOffset + reloc.getOffset();
|
||||
// r_offset is defined to be a byte offset (assume byte size is 1)
|
||||
Address relocAddr = context != null ? context.getRelocationAddress(baseAddress, reloc.getOffset()) : baseAddress.addWrap(reloc.getOffset());
|
||||
// Address relocAddr = relocationSpace.getTruncatedAddress(relocationOffset, true);
|
||||
Address baseAddress = relocationSpace.getTruncatedAddress(baseWordOffset, true);
|
||||
|
||||
// relocation offset (r_offset) is defined to be a byte offset (assume byte size is 1)
|
||||
Address relocAddr =
|
||||
context != null ? context.getRelocationAddress(baseAddress, reloc.getOffset())
|
||||
: baseAddress.addWrap(reloc.getOffset());
|
||||
|
||||
long[] values = new long[] { reloc.getSymbolIndex() };
|
||||
|
||||
@@ -774,8 +898,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.error(this, "Unexpected Exception", e);
|
||||
ElfRelocationHandler.markAsUninitializedMemory(program, relocAddr,
|
||||
type, reloc.getSymbolIndex(), symbolName, log);
|
||||
ElfRelocationHandler.markAsUninitializedMemory(program, relocAddr, type,
|
||||
reloc.getSymbolIndex(), symbolName, log);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -800,8 +924,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
}
|
||||
finally {
|
||||
// Save relocation data
|
||||
program.getRelocationTable().add(relocAddr, reloc.getType(), values, bytes,
|
||||
symbolName);
|
||||
program.getRelocationTable()
|
||||
.add(relocAddr, reloc.getType(), values, bytes, symbolName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1171,9 +1295,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
Address externalBlockAddress = externalBlockLimits.getMinAddress();
|
||||
long size = lastExternalBlockEntryAddress.subtract(externalBlockAddress) + 1;
|
||||
try {
|
||||
MemoryBlock block =
|
||||
memory.createUninitializedBlock(MemoryBlock.EXTERNAL_BLOCK_NAME,
|
||||
externalBlockAddress, size, false);
|
||||
MemoryBlock block = memory.createUninitializedBlock(MemoryBlock.EXTERNAL_BLOCK_NAME,
|
||||
externalBlockAddress, size, false);
|
||||
|
||||
// assume any value in external is writable.
|
||||
block.setWrite(true);
|
||||
@@ -1530,7 +1653,6 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
/**
|
||||
* Find a specific named symbol within the fake EXTERNAL block.
|
||||
* NOTE: It is assumed that ELF will never produced duplicate names.
|
||||
* @param programSymbolTable program's symbol table
|
||||
* @param name symbol name
|
||||
* @param extMin EXTERNAL block minimum address
|
||||
* @param extMax EXTERNAL block maximum address
|
||||
@@ -1613,9 +1735,9 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
Function f = createOneByteFunction(null, address, false);
|
||||
if (f != null) {
|
||||
if (isFakeExternal && !f.isThunk()) {
|
||||
ExternalLocation extLoc =
|
||||
program.getExternalManager().addExtFunction(Library.UNKNOWN,
|
||||
name, null, SourceType.IMPORTED);
|
||||
ExternalLocation extLoc = program.getExternalManager()
|
||||
.addExtFunction(Library.UNKNOWN, name, null,
|
||||
SourceType.IMPORTED);
|
||||
f.setThunkedFunction(extLoc.getFunction());
|
||||
// revert thunk function symbol to default source
|
||||
Symbol s = f.getSymbol();
|
||||
@@ -1709,8 +1831,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
|
||||
ExternalLocation extLoc = null;
|
||||
try {
|
||||
extLoc = program.getExternalManager().addExtFunction(Library.UNKNOWN, name, null,
|
||||
SourceType.IMPORTED);
|
||||
extLoc = program.getExternalManager()
|
||||
.addExtFunction(Library.UNKNOWN, name, null, SourceType.IMPORTED);
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
log.appendMsg("Failed to create external function '" + name + "': " + getMessage(e));
|
||||
@@ -1770,9 +1892,9 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
/**
|
||||
* When transitioning to an external thunk, remove the old symbol on the linkage pointer/thunk
|
||||
* if it is the only symbol at that address.
|
||||
* @param address
|
||||
* @param name
|
||||
* @return
|
||||
* @param address symbol address
|
||||
* @param name symbol name
|
||||
* @return true if symbol removed, else false
|
||||
*/
|
||||
private boolean removeOldSymbol(Address address, String name) {
|
||||
SymbolTable symbolTable = program.getSymbolTable();
|
||||
@@ -2168,8 +2290,9 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
}
|
||||
Address refAddr = getDefaultAddress(elf.adjustAddressForPrelink(value.getValue()));
|
||||
if (!definedMemoryOnly || memory.getBlock(refAddr) != null) {
|
||||
program.getReferenceManager().addMemoryReference(valueData.getAddress(), refAddr,
|
||||
RefType.DATA, SourceType.ANALYSIS, 0);
|
||||
program.getReferenceManager()
|
||||
.addMemoryReference(valueData.getAddress(), refAddr, RefType.DATA,
|
||||
SourceType.ANALYSIS, 0);
|
||||
if (label != null) {
|
||||
// add label if a non-default label does not exist
|
||||
Symbol[] symbols = program.getSymbolTable().getSymbols(refAddr);
|
||||
@@ -2390,8 +2513,10 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
if (!resolvedLoadAddresses.isEmpty()) {
|
||||
// Not contained within loaded bytes - compute relative to block start.
|
||||
// Always return non-overlay address
|
||||
return resolvedLoadAddresses.get(0).getMinAddress().add(
|
||||
byteOffsetWithinSection).getPhysicalAddress();
|
||||
return resolvedLoadAddresses.get(0)
|
||||
.getMinAddress()
|
||||
.add(byteOffsetWithinSection)
|
||||
.getPhysicalAddress();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -2614,9 +2739,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
* @param segmentNumber program header index number
|
||||
* @throws AddressOutOfBoundsException if an invalid memory address is encountered
|
||||
*/
|
||||
private void processProgramHeader(
|
||||
ElfProgramHeader elfProgramHeader,
|
||||
int segmentNumber) throws AddressOutOfBoundsException {
|
||||
private void processProgramHeader(ElfProgramHeader elfProgramHeader, int segmentNumber)
|
||||
throws AddressOutOfBoundsException {
|
||||
|
||||
// FIXME: If physical and virtual addresses do not match this may be an overlay situation.
|
||||
// If sections exist they should use file offsets to correlate to overlay segment - the
|
||||
@@ -2640,7 +2764,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
elfProgramHeader.getDescription() + "] at address " + address.toString(true));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!space.isValidRange(address.getOffset(), fullSizeBytes)) {
|
||||
log("Skipping unloadable segment [" + segmentNumber + "] at address " +
|
||||
address.toString(true) + " (size=" + fullSizeBytes + ")");
|
||||
@@ -2687,8 +2811,9 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
if (buf.length() != 0) {
|
||||
buf.append(' ');
|
||||
}
|
||||
BigInteger max = BigInteger.valueOf(addr).add(
|
||||
BigInteger.valueOf(byteSize / addressableUnitSize)).subtract(BigInteger.ONE);
|
||||
BigInteger max = BigInteger.valueOf(addr)
|
||||
.add(BigInteger.valueOf(byteSize / addressableUnitSize))
|
||||
.subtract(BigInteger.ONE);
|
||||
buf.append(String.format("[0x%x - 0x%s]", addr, max.toString(16)));
|
||||
}
|
||||
else {
|
||||
@@ -2771,13 +2896,13 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
monitor.setMessage("Processing section headers...");
|
||||
|
||||
boolean includeOtherBlocks = ElfLoaderOptionsFactory.includeOtherBlocks(options);
|
||||
|
||||
|
||||
// establish section address provider for relocatable ELF binaries
|
||||
RelocatableImageBaseProvider relocatableImageBaseProvider = null;
|
||||
if (elf.isRelocatable()) {
|
||||
relocatableImageBaseProvider = new RelocatableImageBaseProvider(monitor);
|
||||
}
|
||||
|
||||
|
||||
ElfSectionHeader[] sections = elf.getSections();
|
||||
for (ElfSectionHeader elfSectionToLoad : sections) {
|
||||
monitor.checkCanceled();
|
||||
@@ -2821,15 +2946,14 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
// In a relocatable ELF (object module), the address of all sections is zero.
|
||||
// Therefore, we shall assign an arbitrary address that
|
||||
// will pack the sections together with proper alignment.
|
||||
|
||||
|
||||
if (elfSectionToLoad.isAlloc() && elf.isRelocatable() && addr == 0) {
|
||||
// TODO: if program headers are present (very unlikely for object module)
|
||||
// they should be used to determine section load address since they would
|
||||
// be assigned first.
|
||||
AddressSpace space = getSectionAddressSpace(elfSectionToLoad);
|
||||
long relocOffset = relocatableImageBaseProvider.getNextRelocatableOffset(space);
|
||||
addr = NumericUtilities.getUnsignedAlignedValue(
|
||||
relocOffset,
|
||||
addr = NumericUtilities.getUnsignedAlignedValue(relocOffset,
|
||||
elfSectionToLoad.getAddressAlignment());
|
||||
elfSectionToLoad.setAddress(addr);
|
||||
nextRelocOffset = addr + (sectionByteLength / space.getAddressableUnitSize());
|
||||
@@ -2880,8 +3004,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
final String blockName = elfSectionToLoad.getNameAsString();
|
||||
|
||||
try {
|
||||
if (loadOffset == -1 ||
|
||||
elfSectionToLoad.getType() == ElfSectionHeaderConstants.SHT_NOBITS) {
|
||||
if (loadOffset == -1 || (loadOffset == 0 &&
|
||||
elfSectionToLoad.getType() == ElfSectionHeaderConstants.SHT_NOBITS)) {
|
||||
if (!elfSectionToLoad.isAlloc() &&
|
||||
elfSectionToLoad.getType() != ElfSectionHeaderConstants.SHT_PROGBITS) {
|
||||
return; // non-allocate at runtime
|
||||
@@ -2906,7 +3030,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
log("Failed to load section [" + elfSectionToLoad.getNameAsString() + "]: " +
|
||||
getMessage(e));
|
||||
}
|
||||
|
||||
|
||||
if (nextRelocOffset != null) {
|
||||
relocatableImageBaseProvider.setNextRelocatableOffset(space, nextRelocOffset);
|
||||
}
|
||||
@@ -2997,8 +3121,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
private InputStream getInitializedBlockInputStream(MemoryLoadable loadable, Address start,
|
||||
long fileOffset, long dataLength) throws IOException {
|
||||
InputStream dataInput = elf.getReader().getByteProvider().getInputStream(fileOffset);
|
||||
return elf.getLoadAdapter().getFilteredLoadInputStream(this, loadable, start, dataLength,
|
||||
dataInput);
|
||||
return elf.getLoadAdapter()
|
||||
.getFilteredLoadInputStream(this, loadable, start, dataLength, dataInput);
|
||||
}
|
||||
|
||||
private String formatFloat(float value, int maxDecimalPlaces) {
|
||||
@@ -3109,10 +3233,12 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||
RelocatableImageBaseProvider(TaskMonitor monitor) throws CancelledException {
|
||||
AddressSpace defaultSpace = getDefaultAddressSpace();
|
||||
AddressSpace defaultDataSpace = getDefaultDataSpace();
|
||||
long baseOffset = computeRelocationStartAddress(defaultSpace, elf.getImageBase(), monitor);
|
||||
long baseOffset =
|
||||
computeRelocationStartAddress(defaultSpace, elf.getImageBase(), monitor);
|
||||
nextRelocationOffsetMap.put(defaultSpace.getUnique(), baseOffset);
|
||||
if (defaultDataSpace != defaultSpace) {
|
||||
baseOffset = computeRelocationStartAddress(defaultDataSpace, getImageDataBase(), monitor);
|
||||
baseOffset =
|
||||
computeRelocationStartAddress(defaultDataSpace, getImageDataBase(), monitor);
|
||||
nextRelocationOffsetMap.put(defaultDataSpace.getUnique(), baseOffset);
|
||||
}
|
||||
// In the future, an extension could introduce additional space entries
|
||||
|
||||
Reference in New Issue
Block a user