mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
123 lines
3.8 KiB
C++
123 lines
3.8 KiB
C++
/// \file Verify.cpp
|
|
|
|
//
|
|
// This file is distributed under the MIT License. See LICENSE.md for details.
|
|
//
|
|
|
|
#include "revng/Yield/BasicBlock.h"
|
|
#include "revng/Yield/CallEdge.h"
|
|
#include "revng/Yield/Function.h"
|
|
#include "revng/Yield/Instruction.h"
|
|
|
|
bool yield::TaggedString::verify(model::VerifyHelper &VH) const {
|
|
if (Type() == TagType::Invalid)
|
|
return VH.fail("The type of this tag is not valid.");
|
|
if (Content().empty())
|
|
return VH.fail("This tag doesn't have any data.");
|
|
if (Content().find('\n') != std::string::npos)
|
|
return VH.fail("String is not allowed to break the line, "
|
|
"use multiple strings instead.");
|
|
for (const yield::TagAttribute &Attribute : Attributes()) {
|
|
if (Attribute.Name().empty())
|
|
return VH.fail("Attributes without names are not allowed.");
|
|
if (Attribute.Name().empty())
|
|
return VH.fail("Attributes without values are not allowed.");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool yield::TaggedLine::verify(model::VerifyHelper &VH) const {
|
|
for (auto [Index, String] : llvm::enumerate(Tags())) {
|
|
if (Index != String.Index())
|
|
return VH.fail("Tagged string indexing is broken.");
|
|
|
|
if (!String.verify(VH))
|
|
return VH.fail();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool yield::Instruction::verify(model::VerifyHelper &VH) const {
|
|
if (Address().isInvalid())
|
|
return VH.fail("An instruction must have a valid address.");
|
|
if (RawBytes().empty())
|
|
return VH.fail("An instruction has to be at least one byte big.");
|
|
|
|
if (Disassembled().empty())
|
|
return VH.fail("An instruction must have at least one tag.");
|
|
for (auto [Index, Tagged] : llvm::enumerate(Disassembled())) {
|
|
if (Index != Tagged.Index())
|
|
return VH.fail("Tagged string indexing is broken.");
|
|
|
|
if (!Tagged.verify(VH))
|
|
return VH.fail();
|
|
}
|
|
|
|
for (auto [Index, Directive] : llvm::enumerate(PrecedingDirectives())) {
|
|
if (Index != Directive.Index())
|
|
return VH.fail("Preceding directive indexing is broken.");
|
|
|
|
if (!Directive.verify(VH))
|
|
return VH.fail();
|
|
}
|
|
for (auto [Index, Directive] : llvm::enumerate(FollowingDirectives())) {
|
|
if (Index != Directive.Index())
|
|
return VH.fail("Following directive indexing is broken.");
|
|
|
|
if (!Directive.verify(VH))
|
|
return VH.fail();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool yield::BasicBlock::verify(model::VerifyHelper &VH) const {
|
|
if (not ID().isValid())
|
|
return VH.fail("A basic block has to have a valid start address.");
|
|
if (End().isInvalid())
|
|
return VH.fail("A basic block has to have a valid end address.");
|
|
if (Instructions().empty())
|
|
return VH.fail("A basic block has to store at least a single instruction.");
|
|
|
|
if (IsLabelAlwaysRequired())
|
|
if (!Label().verify())
|
|
return false;
|
|
|
|
MetaAddress PreviousAddress = MetaAddress::invalid();
|
|
for (const auto &Instruction : Instructions()) {
|
|
if (!Instruction.verify(VH))
|
|
return VH.fail("Instruction verification failed.");
|
|
|
|
if (PreviousAddress.isValid() && Instruction.Address() < PreviousAddress) {
|
|
return VH.fail("Instructions must be strongly ordered and their size "
|
|
"must be bigger than zero.");
|
|
}
|
|
PreviousAddress = Instruction.Address();
|
|
}
|
|
|
|
if (PreviousAddress.isInvalid() || PreviousAddress >= End()) {
|
|
return VH.fail("The size of the last instruction must be bigger than "
|
|
"zero.");
|
|
}
|
|
|
|
if (HasDelaySlot() && Instructions().size() < 2) {
|
|
return VH.fail("A basic block with a delay slot must contain at least two "
|
|
"instructions.");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool yield::Function::verify(model::VerifyHelper &VH) const {
|
|
if (Entry().isInvalid())
|
|
return VH.fail("A function has to have a valid entry point.");
|
|
|
|
for (const auto &BasicBlock : Blocks())
|
|
if (!BasicBlock.verify(VH))
|
|
return VH.fail("Basic block verification failed.");
|
|
|
|
return true;
|
|
}
|