From e82b80f571ad9ab1ed3eb4a04efc50bcd761481e Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Boric Date: Thu, 9 May 2024 00:43:32 +0200 Subject: [PATCH] fix(ELF): precompute set of symbol names targeted by a relocation --- .../ElfRelocatableObjectExporter.java | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/main/java/ghidra/app/util/exporter/ElfRelocatableObjectExporter.java b/src/main/java/ghidra/app/util/exporter/ElfRelocatableObjectExporter.java index f0e190a..8df9f37 100644 --- a/src/main/java/ghidra/app/util/exporter/ElfRelocatableObjectExporter.java +++ b/src/main/java/ghidra/app/util/exporter/ElfRelocatableObjectExporter.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.TreeMap; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -64,7 +65,6 @@ import ghidra.program.model.symbol.Symbol; import ghidra.util.classfinder.ClassSearcher; import ghidra.util.task.TaskMonitor; - import ghidra_delinker_extension.BuildConfig; /** @@ -96,6 +96,7 @@ public class ElfRelocatableObjectExporter extends Exporter { private Map symbolsByName; private List
sections = new ArrayList<>(); + private Set symbolNamesRelocationFileSet; private static final String OPTION_GROUP_ELF_HEADER = "ELF header"; private static final String OPTION_GROUP_SYMBOLS = "Symbols"; @@ -469,14 +470,9 @@ private boolean isSymbolInteresting(Symbol symbol, RelocationTable relocationTab if (symbol.isDynamic() && !includeDynamicSymbols) { // Even if we don't want dynamic symbols, we still need them for internal relocations. // FIXME: investigate section-relative relocations for internal relocations with dynamic symbols. - Iterable itRelocations = - () -> relocationTable.getRelocations(fileSet, predicateRelocation); - Stream relocations = - StreamSupport.stream(itRelocations.spliterator(), false); String symbolName = getSymbolName(symbol.getName()); - return relocations - .anyMatch(r -> getSymbolName(r.getSymbolName()).equals(symbolName)); + return symbolNamesRelocationFileSet.contains(symbolName); } return true; @@ -618,6 +614,12 @@ public boolean export(File file, DomainObject domainObj, AddressSetView fileSet, Predicate predicateRelocation = relocationTable.predicateInterestingRelocations(fileSet); + for (MemoryBlock memoryBlock : program.getMemory().getBlocks()) { + addSectionForMemoryBlock(memoryBlock, predicateRelocation); + } + + taskMonitor.setIndeterminate(true); + try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) { elf = new ElfRelocatableObject.Builder(file.getName()) .setType(ElfConstants.ET_REL) @@ -626,13 +628,16 @@ public boolean export(File file, DomainObject domainObj, AddressSetView fileSet, .setData(e_ident_data) .build(); + if (generateSectionComment) { + addSectionComment(); + } + if (generateStringAndSymbolTables) { addStringAndSymbolTables(); } - for (MemoryBlock memoryBlock : program.getMemory().getBlocks()) { - addSectionForMemoryBlock(memoryBlock, predicateRelocation); - } + taskMonitor.setMessage("Compute file symbol set..."); + computeSymbolNamesRelocationFileSet(relocationTable, predicateRelocation); for (Section section : sections) { taskMonitor.setMessage(String.format("Creating section %s...", section.getName())); @@ -657,10 +662,6 @@ public boolean export(File file, DomainObject domainObj, AddressSetView fileSet, } } - if (generateSectionComment) { - addSectionComment(); - } - if (generateSectionNamesStringTable) { taskMonitor.setMessage("Generating section names string table..."); addSectionNameStringTable(); @@ -683,6 +684,16 @@ public static Program getProgram(DomainObject domainObj) { return (Program) domainObj; } + private void computeSymbolNamesRelocationFileSet(RelocationTable relocationTable, + Predicate predicateRelocation) { + Iterable itRelocations = + () -> relocationTable.getRelocations(fileSet, predicateRelocation); + Stream relocations = + StreamSupport.stream(itRelocations.spliterator(), false); + symbolNamesRelocationFileSet = + relocations.map(r -> r.getSymbolName()).collect(Collectors.toSet()); + } + private void addStringAndSymbolTables() { strtab = new ElfRelocatableSectionStringTable(elf, ElfSectionHeaderConstants.dot_strtab); symtab =