summaryrefslogtreecommitdiff
path: root/bolt/lib/Core/BinaryFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'bolt/lib/Core/BinaryFunction.cpp')
-rw-r--r--bolt/lib/Core/BinaryFunction.cpp16
1 files changed, 16 insertions, 0 deletions
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index a9ccaea3c438..1c5cd62a095b 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -1504,6 +1504,20 @@ MCSymbol *BinaryFunction::registerBranch(uint64_t Src, uint64_t Dst) {
return Target;
}
+void BinaryFunction::analyzeInstructionForFuncReference(const MCInst &Inst) {
+ for (const MCOperand &Op : MCPlus::primeOperands(Inst)) {
+ if (!Op.isExpr())
+ continue;
+ const MCExpr &Expr = *Op.getExpr();
+ if (Expr.getKind() != MCExpr::SymbolRef)
+ continue;
+ const MCSymbol &Symbol = cast<MCSymbolRefExpr>(Expr).getSymbol();
+ // Set HasAddressTaken for a function regardless of the ICF level.
+ if (BinaryFunction *BF = BC.getFunctionForSymbol(&Symbol))
+ BF->setHasAddressTaken(true);
+ }
+}
+
bool BinaryFunction::scanExternalRefs() {
bool Success = true;
bool DisassemblyFailed = false;
@@ -1624,6 +1638,8 @@ bool BinaryFunction::scanExternalRefs() {
[](const MCOperand &Op) { return Op.isExpr(); })) {
// Skip assembly if the instruction may not have any symbolic operands.
continue;
+ } else {
+ analyzeInstructionForFuncReference(Instruction);
}
// Emit the instruction using temp emitter and generate relocations.