mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
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:
@@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user