Tag function_call targeting external symbols

This commit uses SET, information about canonical values and labels to
detect if an indirect function call is targeting an external symbol.

The strings used for the name of external symbols are uniqued global
variables. This commit also uses this approach for the disassembly of
original instructions, which used to be metadata.
This commit is contained in:
Alessandro Di Federico
2018-11-14 13:53:31 +01:00
parent abb47bb964
commit e21eed118c
13 changed files with 422 additions and 105 deletions
+34 -34
View File
@@ -26,13 +26,13 @@ using namespace llvm;
/// Boring code to get the text of the metadata with the specified kind
/// associated to the given instruction
static MDString *getMD(const Instruction *Instruction, unsigned Kind) {
static StringRef getText(const Instruction *Instruction, unsigned Kind) {
revng_assert(Instruction != nullptr);
Metadata *MD = Instruction->getMetadata(Kind);
if (MD == nullptr)
return nullptr;
return StringRef();
auto Node = dyn_cast<MDNode>(MD);
@@ -43,26 +43,30 @@ static MDString *getMD(const Instruction *Instruction, unsigned Kind) {
Metadata *MDOperand = Operand.get();
if (MDOperand == nullptr)
return nullptr;
return StringRef();
auto *String = dyn_cast<MDString>(MDOperand);
revng_assert(String != nullptr);
return String;
if (auto *String = dyn_cast<MDString>(MDOperand)) {
return String->getString();
} else if (auto *CAM = dyn_cast<ConstantAsMetadata>(MDOperand)) {
auto *Cast = cast<ConstantExpr>(CAM->getValue());
auto *GV = cast<GlobalVariable>(Cast->getOperand(0));
auto *Initializer = GV->getInitializer();
return cast<ConstantDataArray>(Initializer)->getAsString().drop_back();
} else {
revng_abort();
}
}
static void replaceAll(std::string &Input,
const std::string &From,
const std::string &To) {
if(From.empty())
static void
replaceAll(std::string &Input, const std::string &From, const std::string &To) {
if (From.empty())
return;
size_t Start = 0;
while((Start = Input.find(From, Start)) != std::string::npos) {
while ((Start = Input.find(From, Start)) != std::string::npos) {
Input.replace(Start, From.length(), To);
Start += To.length();
}
}
/// Writes the text contained in the metadata with the specified kind ID to the
@@ -72,23 +76,24 @@ static void writeMetadataIfNew(const Instruction *TheInstruction,
unsigned MDKind,
formatted_raw_ostream &Output,
StringRef Prefix) {
MDString *MD = getMD(TheInstruction, MDKind);
if (MD != nullptr) {
MDString *PrevMD = nullptr;
auto BeginIt = TheInstruction->getParent()->begin();
StringRef Text = getText(TheInstruction, MDKind);
if (Text.size()) {
StringRef LastText;
do {
if (TheInstruction->getIterator() == TheInstruction->getParent()->begin())
if (TheInstruction->getIterator() == BeginIt) {
TheInstruction = nullptr;
else {
} else {
TheInstruction = TheInstruction->getPrevNode();
PrevMD = getMD(TheInstruction, MDKind);
LastText = getText(TheInstruction, MDKind);
}
} while (TheInstruction != nullptr && PrevMD == nullptr);
} while (TheInstruction != nullptr && LastText.size() == 0);
if (TheInstruction == nullptr || PrevMD != MD) {
std::string Text = MD->getString().str();
replaceAll(Text, "\n", " ");
Output << Prefix << Text << "\n";
if (TheInstruction == nullptr or LastText != Text) {
std::string TextToSerialize = Text.str();
replaceAll(TextToSerialize, "\n", " ");
Output << Prefix << TextToSerialize << "\n";
}
}
}
@@ -134,7 +139,6 @@ void DAW::emitInstructionAnnot(const Instruction *Instr,
// Flushing is required to have correct line and column numbers
Output.flush();
StringRef FunctionName = Instr->getParent()->getParent()->getName();
auto *Location = DILocation::get(Context,
Output.getLine() + 1,
Output.getColumn(),
@@ -223,7 +227,7 @@ void DebugHelper::generateDebugInfo() {
PTCInstrMDKind :
OriginalInstrMDKind;
MDString *Last = nullptr;
StringRef Last;
std::ofstream Source(DebugPath);
for (Function &F : TheModule->functions()) {
@@ -233,22 +237,18 @@ void DebugHelper::generateDebugInfo() {
if (DISubprogram *CurrentSubprogram = F.getSubprogram()) {
for (BasicBlock &Block : F) {
for (Instruction &Instruction : Block) {
MDString *Body = getMD(&Instruction, MetadataKind);
StringRef Body = getText(&Instruction, MetadataKind);
if (Body != nullptr && Last != Body) {
if (Body.size() != 0 && Last != Body) {
Last = Body;
std::string BodyString = Body->getString().str();
Source << BodyString;
Source << Body.data();
auto *Location = DILocation::get(TheModule->getContext(),
LineIndex,
0,
CurrentSubprogram);
Instruction.setMetadata(DbgMDKind, Location);
LineIndex += std::count(BodyString.begin(),
BodyString.end(),
'\n');
LineIndex += std::count(Body.begin(), Body.end(), '\n');
}
}
}