GP-3526: Restoring Mach-O indirect symbol creation when binding info is

absent
This commit is contained in:
Ryan Kurtz
2023-06-07 15:18:34 -04:00
parent 6b2bd61588
commit 1e107554cf
@@ -133,6 +133,7 @@ public class MachoProgramBuilder {
processUnsupportedLoadCommands();
boolean exportsFound = processExports(machoHeader);
processSymbolTables(machoHeader, !exportsFound);
processIndirectSymbols();
setRelocatableProperty();
processLibraries();
processProgramDescription();
@@ -593,6 +594,84 @@ public class MachoProgramBuilder {
}
}
protected void processIndirectSymbols() throws Exception {
// We only want to directly handle indirect symbols on incomplete dylibs that were extracted
// from a dyld_shared_cache. If the Mach-O is fully-formed and contains binding information
// (found in the DyldChainedFixupsCommand or DyldInfoCommand), thunk analysis properly
// associates indirect symbols with their "real" symbol and we shouldn't do anything here.
if (machoHeader.getFirstLoadCommand(DyldChainedFixupsCommand.class) != null ||
machoHeader.getFirstLoadCommand(DyldInfoCommand.class) != null) {
return;
}
monitor.setMessage("Processing indirect symbols...");
SymbolTableCommand symbolTableCommand =
machoHeader.getFirstLoadCommand(SymbolTableCommand.class);
DynamicSymbolTableCommand dynamicCommand =
machoHeader.getFirstLoadCommand(DynamicSymbolTableCommand.class);
if (dynamicCommand == null) {
return;
}
int[] indirectSymbols = dynamicCommand.getIndirectSymbols();
if (indirectSymbols.length == 0) {
return;
}
List<Integer> sectionTypes = List.of(SectionTypes.S_NON_LAZY_SYMBOL_POINTERS,
SectionTypes.S_LAZY_SYMBOL_POINTERS, SectionTypes.S_SYMBOL_STUBS);
List<Section> sections = machoHeader.getAllSections()
.stream()
.filter(s -> sectionTypes.contains(s.getType()))
.toList();
for (Section section : sections) {
if (monitor.isCancelled()) {
return;
}
if (section.getSize() == 0) {
continue;
}
Namespace namespace = createNamespace(section.getSectionName());
int indirectSymbolTableIndex = section.getReserved1();
int symbolSize = machoHeader.getAddressSize();
if (section.getType() == SectionTypes.S_SYMBOL_STUBS) {
symbolSize = section.getReserved2();
}
int nSymbols = (int) section.getSize() / symbolSize;
Address startAddr = space.getAddress(section.getAddress());
for (int i = indirectSymbolTableIndex; i < indirectSymbolTableIndex + nSymbols; ++i) {
if (monitor.isCancelled()) {
break;
}
int symbolIndex = indirectSymbols[i];
NList symbol = symbolTableCommand.getSymbolAt(symbolIndex);
if (symbol != null) {
String name = generateValidName(symbol.getString());
if (name != null && name.length() > 0) {
try {
program.getSymbolTable()
.createLabel(startAddr, name, namespace, SourceType.IMPORTED);
}
catch (Exception e) {
log.appendMsg("Unable to create indirect symbol " + name);
log.appendException(e);
}
}
}
startAddr = startAddr.add(symbolSize);
}
}
}
protected void setRelocatableProperty() {
Options props = program.getOptions(Program.PROGRAM_INFO);
switch (machoHeader.getFileType()) {