diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp index 25cf054f453563711e7cd7308468729c877f0b8f..e959fce17e6ad8218c40dc0c331ea572da60bf68 100644 --- a/src/base/SMPFunction.cpp +++ b/src/base/SMPFunction.cpp @@ -9558,7 +9558,9 @@ void SMPFunction::EmitAnnotations(FILE *AnnotFile, FILE *InfoAnnotFile) { #endif bool AllocSeen = false; // Reached LocalVarsAllocInstr yet? bool DeallocTrigger = false; - for ( ; InstIter != Instrs.end(); ++InstIter) { + bool PrefetchInstSeenLast = false; // inst before current inst was a prefetch + bool UndefinedOpcodeSeenLast = false; // inst before current inst was an undefined opcode + for (; InstIter != Instrs.end(); ++InstIter) { SMPInstr *CurrInst = (*InstIter); STARS_ea_t addr = CurrInst->GetAddr(); if (CurrInst->IsFloatNop()) { @@ -9634,6 +9636,29 @@ void SMPFunction::EmitAnnotations(FILE *AnnotFile, FILE *InfoAnnotFile) { if (CurrInst->MDIsReturnInstr() && this->GetReturnAddressStatus() == FUNC_SAFE) CurrInst->EmitSafeReturn(AnnotFile); + + // Emit IBT annotations for instructions that fit computed-goto patterns in libc/glibc, such + // as prefetch instructions and the instructions that follow them (computed goto often chooses + // between going to the prefetch or jumping just past it, and IDA Pro cannot analyze these libc + // macro-generated computed gotos even if they are not orphaned code). Likewise, an undefined opcode + // often separates an indirect jump and its first target, so inst after undefined opcode is IBT. + bool EmitIBTAnnotation = (PrefetchInstSeenLast || UndefinedOpcodeSeenLast); + if (CurrInst->MDIsPrefetchOpcode()) { + PrefetchInstSeenLast = true; + UndefinedOpcodeSeenLast = false; + EmitIBTAnnotation = true; + } + else if (CurrInst->MDIsUndefinedOpcode()) { + UndefinedOpcodeSeenLast = true; + PrefetchInstSeenLast = false; + } + else { + PrefetchInstSeenLast = false; + UndefinedOpcodeSeenLast = false; + } + if (EmitIBTAnnotation) { + global_STARS_program->PrintUnknownCodeXref(addr, CurrInst->GetSize()); + } } // end for all instructions // Loop through all basic blocks and emit profiling request annotations