diff --git a/include/revng/BasicAnalyses/GeneratedCodeBasicInfo.h b/include/revng/BasicAnalyses/GeneratedCodeBasicInfo.h index dffae01c2..15a6ac44e 100644 --- a/include/revng/BasicAnalyses/GeneratedCodeBasicInfo.h +++ b/include/revng/BasicAnalyses/GeneratedCodeBasicInfo.h @@ -164,7 +164,7 @@ public: if (not PCH) { llvm::Module *M = RootFunction->getParent(); using namespace model::Architecture; - auto Architecture = toLLVMArchitecture(Binary->Architecture); + auto Architecture = toLLVMArchitecture(Binary->Architecture()); PCH = ProgramCounterHandler::fromModule(Architecture, M); } @@ -316,7 +316,7 @@ public: MetaAddress fromPC(uint64_t PC) const { using namespace model::Architecture; - auto Architecture = toLLVMArchitecture(Binary->Architecture); + auto Architecture = toLLVMArchitecture(Binary->Architecture()); return MetaAddress::fromPC(Architecture, PC); } diff --git a/include/revng/EarlyFunctionAnalysis/CallEdge.h b/include/revng/EarlyFunctionAnalysis/CallEdge.h index a7344463c..e02cd3577 100644 --- a/include/revng/EarlyFunctionAnalysis/CallEdge.h +++ b/include/revng/EarlyFunctionAnalysis/CallEdge.h @@ -46,7 +46,7 @@ private: AssociatedType = FunctionEdgeType::FunctionCall; public: - CallEdge() : efa::generated::CallEdge() { Type = AssociatedType; } + CallEdge() : efa::generated::CallEdge() { Type() = AssociatedType; } CallEdge(MetaAddress Destination, FunctionEdgeType::Values Type) : efa::generated::CallEdge(Destination, Type) {} @@ -62,7 +62,7 @@ public: model::FunctionAttribute::Values Attribute) const { using namespace model; - if (Attributes.count(Attribute) != 0) + if (Attributes().count(Attribute) != 0) return true; if (const auto *CalleeAttributes = calleeAttributes(Binary)) @@ -75,7 +75,7 @@ public: attributes(const model::Binary &Binary) const { MutableSet Result; auto Inserter = Result.batch_insert(); - for (auto &Attribute : Attributes) + for (auto &Attribute : Attributes()) Inserter.insert(Attribute); if (const auto *CalleeAttributes = calleeAttributes(Binary)) @@ -94,11 +94,11 @@ public: private: const MutableSet * calleeAttributes(const model::Binary &Binary) const { - if (not DynamicFunction.empty()) { - const auto &F = Binary.ImportedDynamicFunctions.at(DynamicFunction); - return &F.Attributes; - } else if (Destination.isValid()) { - return &Binary.Functions.at(Destination).Attributes; + if (not DynamicFunction().empty()) { + const auto &F = Binary.ImportedDynamicFunctions().at(DynamicFunction()); + return &F.Attributes(); + } else if (Destination().isValid()) { + return &Binary.Functions().at(Destination()).Attributes(); } else { return nullptr; } @@ -111,24 +111,27 @@ inline model::TypePath getPrototype(const model::Binary &Binary, const efa::CallEdge &Edge) { model::TypePath Result; - auto It = Binary.Functions.at(CallerFunctionAddress) - .CallSitePrototypes.find(CallerBlockAddress); - if (It != Binary.Functions.at(CallerFunctionAddress).CallSitePrototypes.end()) - Result = It->Prototype; + auto &CallSitePrototypes = Binary.Functions() + .at(CallerFunctionAddress) + .CallSitePrototypes(); + auto It = CallSitePrototypes.find(CallerBlockAddress); + if (It != CallSitePrototypes.end()) + Result = It->Prototype(); - if (Edge.Type == efa::FunctionEdgeType::FunctionCall) { - if (not Edge.DynamicFunction.empty()) { + if (Edge.Type() == efa::FunctionEdgeType::FunctionCall) { + if (not Edge.DynamicFunction().empty()) { // Get the dynamic function prototype - Result = Binary.ImportedDynamicFunctions.at(Edge.DynamicFunction) - .Prototype; - } else if (Edge.Destination.isValid()) { + Result = Binary.ImportedDynamicFunctions() + .at(Edge.DynamicFunction()) + .Prototype(); + } else if (Edge.Destination().isValid()) { // Get the function prototype - Result = Binary.Functions.at(Edge.Destination).Prototype; + Result = Binary.Functions().at(Edge.Destination()).Prototype(); } } if (not Result.isValid()) - Result = Binary.DefaultPrototype; + Result = Binary.DefaultPrototype(); return Result; } diff --git a/include/revng/EarlyFunctionAnalysis/ControlFlowGraph.h b/include/revng/EarlyFunctionAnalysis/ControlFlowGraph.h index 1a70b5d79..13be67160 100644 --- a/include/revng/EarlyFunctionAnalysis/ControlFlowGraph.h +++ b/include/revng/EarlyFunctionAnalysis/ControlFlowGraph.h @@ -19,9 +19,9 @@ using SuccessorContainer = SortedVector>; } template -concept SpecializationOfBasicBlock = requires { - { T::Start } -> convertible_to; - { T::End } -> convertible_to; +concept SpecializationOfBasicBlock = requires(T Instance) { + { Instance.Start() } -> convertible_to; + { Instance.End() } -> convertible_to; }; struct ParsedSuccessor { @@ -33,14 +33,14 @@ template inline ParsedSuccessor parseSuccessor(const T &Edge, const MetaAddress &FallthroughAddress, const model::Binary &Binary) { - using FunctionEdgeType = decltype(Edge.Type); - switch (Edge.Type) { + using FunctionEdgeType = std::decay_t; + switch (Edge.Type()) { case FunctionEdgeType::DirectBranch: case FunctionEdgeType::Return: case FunctionEdgeType::BrokenReturn: case FunctionEdgeType::LongJmp: case FunctionEdgeType::Unreachable: - return ParsedSuccessor{ .NextInstructionAddress = Edge.Destination, + return ParsedSuccessor{ .NextInstructionAddress = Edge.Destination(), .OptionalCallAddress = MetaAddress::invalid() }; case FunctionEdgeType::FunctionCall: { @@ -52,11 +52,11 @@ inline ParsedSuccessor parseSuccessor(const T &Edge, MetaAddress NextInstructionAddress = MetaAddress::invalid(); if (not CE->hasAttribute(Binary, model::FunctionAttribute::NoReturn) - and not CE->IsTailCall) { + and not CE->IsTailCall()) { NextInstructionAddress = FallthroughAddress; } return ParsedSuccessor{ .NextInstructionAddress = NextInstructionAddress, - .OptionalCallAddress = Edge.Destination }; + .OptionalCallAddress = Edge.Destination() }; } case FunctionEdgeType::Killer: return ParsedSuccessor{ .NextInstructionAddress = MetaAddress::invalid(), @@ -104,20 +104,20 @@ requires std::is_constructible_v auto &[Graph, AddressToNodeMap] = Res; for (const BasicBlockType &Block : BB) { - revng_assert(Block.Start.isValid()); - auto *NewNode = Graph.addNode(Node{ Block.Start }); - auto [_, Success] = AddressToNodeMap.try_emplace(Block.Start, NewNode); + revng_assert(Block.Start().isValid()); + auto *NewNode = Graph.addNode(Node{ Block.Start() }); + auto [_, Success] = AddressToNodeMap.try_emplace(Block.Start(), NewNode); revng_assert(Success != false, "Different basic blocks with the same `Start` address"); } Node *ExitNode = nullptr; for (const BasicBlockType &Block : BB) { - auto FromNodeIterator = AddressToNodeMap.find(Block.Start); + auto FromNodeIterator = AddressToNodeMap.find(Block.Start()); revng_assert(FromNodeIterator != AddressToNodeMap.end()); - for (const auto &Edge : Block.Successors) { - auto [NextInstruction, _] = parseSuccessor(*Edge, Block.End, Binary); + for (const auto &Edge : Block.Successors()) { + auto [NextInstruction, _] = parseSuccessor(*Edge, Block.End(), Binary); if (NextInstruction.isValid()) { auto ToNodeIterator = AddressToNodeMap.find(NextInstruction); revng_assert(ToNodeIterator != AddressToNodeMap.end()); diff --git a/include/revng/EarlyFunctionAnalysis/FunctionEdge.h b/include/revng/EarlyFunctionAnalysis/FunctionEdge.h index 969708280..ceacf7de1 100644 --- a/include/revng/EarlyFunctionAnalysis/FunctionEdge.h +++ b/include/revng/EarlyFunctionAnalysis/FunctionEdge.h @@ -23,7 +23,7 @@ private: AssociatedType = FunctionEdgeType::DirectBranch; public: - FunctionEdge() : efa::generated::FunctionEdge() { Type = AssociatedType; } + FunctionEdge() : efa::generated::FunctionEdge() { Type() = AssociatedType; } FunctionEdge(MetaAddress Destination, FunctionEdgeType::Values Type) : efa::generated::FunctionEdge(Destination, Type) {} diff --git a/include/revng/EarlyFunctionAnalysis/FunctionEdgeBase.h b/include/revng/EarlyFunctionAnalysis/FunctionEdgeBase.h index ad0537a6a..02bdbc0e5 100644 --- a/include/revng/EarlyFunctionAnalysis/FunctionEdgeBase.h +++ b/include/revng/EarlyFunctionAnalysis/FunctionEdgeBase.h @@ -46,7 +46,7 @@ public: static bool classof(const Key &K) { return true; } public: - bool isDirect() const { return Destination.isValid(); } + bool isDirect() const { return Destination().isValid(); } bool isIndirect() const { return not isDirect(); } public: diff --git a/include/revng/EarlyFunctionAnalysis/FunctionMetadataCache.h b/include/revng/EarlyFunctionAnalysis/FunctionMetadataCache.h index 9d514b4fc..852b239ff 100644 --- a/include/revng/EarlyFunctionAnalysis/FunctionMetadataCache.h +++ b/include/revng/EarlyFunctionAnalysis/FunctionMetadataCache.h @@ -86,11 +86,11 @@ public: auto *ParentFunction = Call->getParent()->getParent(); const efa::FunctionMetadata &FM = getFunctionMetadata(ParentFunction); - const efa::BasicBlock &Block = FM.ControlFlowGraph.at(BlockAddress); + const efa::BasicBlock &Block = FM.ControlFlowGraph().at(BlockAddress); // Find the call edge efa::CallEdge *ModelCall = nullptr; - for (auto &Edge : Block.Successors) { + for (auto &Edge : Block.Successors()) { if (auto *CE = dyn_cast(Edge.get())) { revng_assert(ModelCall == nullptr); ModelCall = CE; @@ -98,7 +98,7 @@ public: } revng_assert(ModelCall != nullptr); - return { *ModelCall, Block.Start }; + return { *ModelCall, Block.Start() }; } /// \return the prototype associated to a CallInst. @@ -124,7 +124,7 @@ public: if (not Edge) return {}; - return getPrototype(Binary, ParentFunction->Entry, BlockAddress, *Edge); + return getPrototype(Binary, ParentFunction->Entry(), BlockAddress, *Edge); } }; diff --git a/include/revng/Model/Binary.h b/include/revng/Model/Binary.h index 798582af3..7c53e2886 100644 --- a/include/revng/Model/Binary.h +++ b/include/revng/Model/Binary.h @@ -141,10 +141,10 @@ public: inline model::TypePath getPrototype(const model::Binary &Binary, const model::DynamicFunction &DynamicFunction) { - if (DynamicFunction.Prototype.isValid()) - return DynamicFunction.Prototype; + if (DynamicFunction.Prototype().isValid()) + return DynamicFunction.Prototype(); else - return Binary.DefaultPrototype; + return Binary.DefaultPrototype(); } #include "revng/Model/Generated/Late/Binary.h" diff --git a/include/revng/Model/CABIFunctionType.h b/include/revng/Model/CABIFunctionType.h index 03af9c6b0..5395507b7 100644 --- a/include/revng/Model/CABIFunctionType.h +++ b/include/revng/Model/CABIFunctionType.h @@ -46,9 +46,9 @@ public: const llvm::SmallVector edges() const { llvm::SmallVector Result; - for (const model::Argument &Argument : Arguments) - Result.push_back(Argument.Type); - Result.push_back(ReturnType); + for (const model::Argument &Argument : Arguments()) + Result.push_back(Argument.Type()); + Result.push_back(ReturnType()); return Result; } diff --git a/include/revng/Model/CallSitePrototype.h b/include/revng/Model/CallSitePrototype.h index 6277a3d26..186a1b7b7 100644 --- a/include/revng/Model/CallSitePrototype.h +++ b/include/revng/Model/CallSitePrototype.h @@ -47,7 +47,7 @@ public: bool verify(bool Assert) const debug_function; bool verify(VerifyHelper &VH) const; void dump() const debug_function; - bool isDirect() const { return not Prototype.isValid(); } + bool isDirect() const { return not Prototype().isValid(); } }; #include "revng/Model/Generated/Late/CallSitePrototype.h" diff --git a/include/revng/Model/EnumType.h b/include/revng/Model/EnumType.h index 08f6172a8..e836a272a 100644 --- a/include/revng/Model/EnumType.h +++ b/include/revng/Model/EnumType.h @@ -37,7 +37,7 @@ public: public: const llvm::SmallVector edges() const { - return { UnderlyingType }; + return { UnderlyingType() }; } public: diff --git a/include/revng/Model/IRHelpers.h b/include/revng/Model/IRHelpers.h index 85aaddda1..c82f4e534 100644 --- a/include/revng/Model/IRHelpers.h +++ b/include/revng/Model/IRHelpers.h @@ -22,8 +22,8 @@ llvmToModelFunction(model::Binary &Binary, const llvm::Function &F) { auto MaybeMetaAddress = getMetaAddressMetadata(&F, FunctionEntryMDNName); if (MaybeMetaAddress == MetaAddress::invalid()) return nullptr; - if (auto It = Binary.Functions.find(MaybeMetaAddress); - It != Binary.Functions.end()) + if (auto It = Binary.Functions().find(MaybeMetaAddress); + It != Binary.Functions().end()) return &(*It); return nullptr; @@ -34,8 +34,8 @@ llvmToModelFunction(const model::Binary &Binary, const llvm::Function &F) { auto MaybeMetaAddress = getMetaAddressMetadata(&F, FunctionEntryMDNName); if (MaybeMetaAddress == MetaAddress::invalid()) return nullptr; - if (auto It = Binary.Functions.find(MaybeMetaAddress); - It != Binary.Functions.end()) + if (auto It = Binary.Functions().find(MaybeMetaAddress); + It != Binary.Functions().end()) return &*It; return nullptr; @@ -55,6 +55,6 @@ inline model::TypePath createEmptyStruct(model::Binary &Binary, uint64_t Size) { revng_assert(Size > 0 and Size < std::numeric_limits::max()); TypePath Path = Binary.recordNewType(makeType()); model::StructType *NewStruct = llvm::cast(Path.get()); - NewStruct->Size = Size; + NewStruct->Size() = Size; return Path; } diff --git a/include/revng/Model/Pass/ConvertFunctionTypes.h b/include/revng/Model/Pass/ConvertFunctionTypes.h index 2b171338d..1edf612ea 100644 --- a/include/revng/Model/Pass/ConvertFunctionTypes.h +++ b/include/revng/Model/Pass/ConvertFunctionTypes.h @@ -20,7 +20,7 @@ void convertAllFunctionsToCABI(TupleTree &Model, /// /// Internally uses `model::convertToCABIFunctionType`. inline void convertAllFunctionsToCABI(TupleTree &Model) { - convertAllFunctionsToCABI(Model, Model->DefaultABI); + convertAllFunctionsToCABI(Model, Model->DefaultABI()); } /// Tries to convert all the `model::CABIFunctionType`s within the input `Model` diff --git a/include/revng/Model/QualifiedType.h b/include/revng/Model/QualifiedType.h index aceaf5448..b150beda4 100644 --- a/include/revng/Model/QualifiedType.h +++ b/include/revng/Model/QualifiedType.h @@ -65,8 +65,8 @@ public: public: model::QualifiedType getPointerTo(model::Architecture::Values Arch) const { QualifiedType Result = *this; - Result.Qualifiers.insert(Result.Qualifiers.begin(), - model::Qualifier::createPointer(Arch)); + Result.Qualifiers().insert(Result.Qualifiers().begin(), + model::Qualifier::createPointer(Arch)); return Result; } @@ -78,13 +78,13 @@ public: bool operator==(const QualifiedType &) const = default; std::strong_ordering operator<=>(const QualifiedType &Other) const { - if (Qualifiers < Other.Qualifiers) + if (Qualifiers() < Other.Qualifiers()) return std::strong_ordering::less; - if (Qualifiers > Other.Qualifiers) + if (Qualifiers() > Other.Qualifiers()) return std::strong_ordering::greater; - return UnqualifiedType <=> Other.UnqualifiedType; + return UnqualifiedType() <=> Other.UnqualifiedType(); } }; diff --git a/include/revng/Model/Qualifier.h b/include/revng/Model/Qualifier.h index 6c3a8ba4a..8adfaa99a 100644 --- a/include/revng/Model/Qualifier.h +++ b/include/revng/Model/Qualifier.h @@ -55,22 +55,24 @@ public: public: static bool isConst(const Qualifier &Q) { revng_assert(Q.verify(true)); - return Q.Kind == QualifierKind::Const; + return Q.Kind() == QualifierKind::Const; } static bool isArray(const Qualifier &Q) { revng_assert(Q.verify(true)); - return Q.Kind == QualifierKind::Array; + return Q.Kind() == QualifierKind::Array; } static bool isPointer(const Qualifier &Q) { revng_assert(Q.verify(true)); - return Q.Kind == QualifierKind::Pointer; + return Q.Kind() == QualifierKind::Pointer; } public: auto operator<(const Qualifier &Other) const { - return std::tie(this->Kind, this->Size) < std::tie(Other.Kind, Other.Size); + auto Me = std::tie(this->Kind(), this->Size()); + auto It = std::tie(Other.Kind(), Other.Size()); + return Me < It; } }; diff --git a/include/revng/Model/RawBinaryView.h b/include/revng/Model/RawBinaryView.h index 54476eb2b..483b94b83 100644 --- a/include/revng/Model/RawBinaryView.h +++ b/include/revng/Model/RawBinaryView.h @@ -81,7 +81,7 @@ public: std::optional readInteger(MetaAddress Address, uint64_t Size) const { - auto Architecture = Binary.Architecture; + auto Architecture = Binary.Architecture(); bool IsLittleEndian = model::Architecture::isLittleEndian(Architecture); return readInteger(Address, Size, IsLittleEndian); } @@ -92,7 +92,8 @@ public: if (Segment == nullptr) return std::nullopt; - auto StartOffset = OverflowSafeInt(Segment->StartOffset) + OffsetInSegment; + auto StartOffset = OverflowSafeInt(Segment->StartOffset()) + + OffsetInSegment; auto Size = OverflowSafeInt(Segment->endOffset()) - StartOffset; if (not Size or not StartOffset) return std::nullopt; @@ -108,7 +109,7 @@ public: if (Segment == nullptr) { return std::nullopt; } else { - auto Offset = OverflowSafeInt(Segment->StartOffset) + OffsetInSegment; + auto Offset = OverflowSafeInt(Segment->StartOffset()) + OffsetInSegment; if (not Offset) return std::nullopt; @@ -122,8 +123,8 @@ public: using namespace model; const Segment *Match = nullptr; - for (const Segment &Segment : Binary.Segments) { - if (Segment.StartOffset <= Offset and Offset < Segment.endOffset()) { + for (const Segment &Segment : Binary.Segments()) { + if (Segment.StartOffset() <= Offset and Offset < Segment.endOffset()) { if (Match != nullptr) { // We have more than one match! Match = nullptr; @@ -135,9 +136,9 @@ public: } if (Match != nullptr) { - auto OffsetInSegment = OverflowSafeInt(Offset) - Match->StartOffset; + auto OffsetInSegment = OverflowSafeInt(Offset) - Match->StartOffset(); if (OffsetInSegment) { - return Match->StartAddress + *OffsetInSegment; + return Match->StartAddress() + *OffsetInSegment; } } @@ -147,8 +148,8 @@ public: using SegmentDataPair = std::pair>; cppcoro::generator segments() const { - for (const model::Segment &Segment : Binary.Segments) { - auto MaybeData = getByOffset(Segment.StartOffset, Segment.FileSize); + for (const model::Segment &Segment : Binary.Segments()) { + auto MaybeData = getByOffset(Segment.StartOffset(), Segment.FileSize()); if (MaybeData) co_yield SegmentDataPair(Segment, *MaybeData); } @@ -158,7 +159,7 @@ private: std::pair findOffsetInSegment(MetaAddress Address, uint64_t Size) const { const model::Segment *Match = nullptr; - for (const model::Segment &Segment : Binary.Segments) { + for (const model::Segment &Segment : Binary.Segments()) { if (Segment.contains(Address, Size)) { if (Match != nullptr) { @@ -173,7 +174,7 @@ private: if (Match != nullptr) { auto Offset = OverflowSafeInt(Address.address()) - - Match->StartAddress.address(); + - Match->StartAddress().address(); if (Offset) return { Match, *Offset }; } diff --git a/include/revng/Model/RawFunctionType.h b/include/revng/Model/RawFunctionType.h index 3b7206162..85554d956 100644 --- a/include/revng/Model/RawFunctionType.h +++ b/include/revng/Model/RawFunctionType.h @@ -50,12 +50,12 @@ public: const llvm::SmallVector edges() const { llvm::SmallVector Result; - for (auto &Argument : Arguments) - Result.push_back(Argument.Type); - for (auto &RV : ReturnValues) - Result.push_back(RV.Type); - if (StackArgumentsType.UnqualifiedType.isValid()) - Result.push_back(StackArgumentsType); + for (auto &Argument : Arguments()) + Result.push_back(Argument.Type()); + for (auto &RV : ReturnValues()) + Result.push_back(RV.Type()); + if (StackArgumentsType().UnqualifiedType().isValid()) + Result.push_back(StackArgumentsType()); return Result; } diff --git a/include/revng/Model/Relocation.h b/include/revng/Model/Relocation.h index 35b892a4f..eafcd08d1 100644 --- a/include/revng/Model/Relocation.h +++ b/include/revng/Model/Relocation.h @@ -32,10 +32,10 @@ public: using generated::Relocation::Relocation; public: - uint64_t size() const { return model::RelocationType::getSize(Type); } + uint64_t size() const { return model::RelocationType::getSize(Type()); } /// \return a valid end address. - MetaAddress endAddress() const { return Address + size(); } + MetaAddress endAddress() const { return Address() + size(); } public: bool verify() const debug_function; diff --git a/include/revng/Model/Section.h b/include/revng/Model/Section.h index e1ecec00c..faa5a3072 100644 --- a/include/revng/Model/Section.h +++ b/include/revng/Model/Section.h @@ -33,7 +33,7 @@ public: using generated::Section::Section; public: - MetaAddress endAddress() const { return StartAddress + Size; } + MetaAddress endAddress() const { return StartAddress() + Size(); } public: bool verify() const debug_function; diff --git a/include/revng/Model/Segment.h b/include/revng/Model/Segment.h index 1291787a0..d649b3a09 100644 --- a/include/revng/Model/Segment.h +++ b/include/revng/Model/Segment.h @@ -73,8 +73,9 @@ public: public: bool contains(MetaAddress Address) const { - auto EndAddress = StartAddress + VirtualSize; - return (Address.isValid() and StartAddress.addressLowerThanOrEqual(Address) + auto EndAddress = StartAddress() + VirtualSize(); + return (Address.isValid() + and StartAddress().addressLowerThanOrEqual(Address) and Address.addressLowerThan(EndAddress)); } @@ -83,13 +84,13 @@ public: } /// \return the end offset (guaranteed to be greater than StartOffset). - auto endOffset() const { return StartOffset + FileSize; } + auto endOffset() const { return StartOffset() + FileSize(); } /// \return a valid MetaAddress. - auto endAddress() const { return StartAddress + VirtualSize; } + auto endAddress() const { return StartAddress() + VirtualSize(); } std::pair pagesRange() const { - MetaAddress Start = StartAddress; + MetaAddress Start = StartAddress(); Start = Start - (Start.address() % 4096); MetaAddress End = endAddress(); diff --git a/include/revng/Model/StructType.h b/include/revng/Model/StructType.h index bbf98bddb..44cfce83c 100644 --- a/include/revng/Model/StructType.h +++ b/include/revng/Model/StructType.h @@ -42,8 +42,8 @@ public: const llvm::SmallVector edges() const { llvm::SmallVector Result; - for (auto &Field : Fields) - Result.push_back(Field.Type); + for (auto &Field : Fields()) + Result.push_back(Field.Type()); return Result; } diff --git a/include/revng/Model/TypedefType.h b/include/revng/Model/TypedefType.h index aac56aa7d..81552fe73 100644 --- a/include/revng/Model/TypedefType.h +++ b/include/revng/Model/TypedefType.h @@ -33,7 +33,7 @@ public: public: const llvm::SmallVector edges() const { - return { UnderlyingType }; + return { UnderlyingType() }; } public: diff --git a/include/revng/Model/UnionType.h b/include/revng/Model/UnionType.h index 2c914c1b3..19d84cb0b 100644 --- a/include/revng/Model/UnionType.h +++ b/include/revng/Model/UnionType.h @@ -39,8 +39,8 @@ public: const llvm::SmallVector edges() const { llvm::SmallVector Result; - for (auto &Field : Fields) - Result.push_back(Field.Type); + for (auto &Field : Fields()) + Result.push_back(Field.Type()); return Result; } diff --git a/include/revng/Pipes/FunctionKind.h b/include/revng/Pipes/FunctionKind.h index 119e2ea7b..d115c7f9e 100644 --- a/include/revng/Pipes/FunctionKind.h +++ b/include/revng/Pipes/FunctionKind.h @@ -19,8 +19,8 @@ public: pipeline::TargetsList &Out) const override { using namespace pipeline; const auto &Model = getModelFromContext(Ctx); - for (const auto &Function : Model->Functions) { - Out.push_back(Target(Function.Entry.toString(), *this)); + for (const auto &Function : Model->Functions()) { + Out.push_back(Target(Function.Entry().toString(), *this)); } } }; diff --git a/include/revng/Runtime/PrintPlainMetaAddress.h b/include/revng/Runtime/PrintPlainMetaAddress.h index 36309c4d8..cc85c4474 100644 --- a/include/revng/Runtime/PrintPlainMetaAddress.h +++ b/include/revng/Runtime/PrintPlainMetaAddress.h @@ -9,7 +9,7 @@ #include "revng/Runtime/PlainMetaAddress.h" -inline int fprint_metaaddress(FILE *stream, PlainMetaAddress *address) { +static int fprint_metaaddress(FILE *stream, PlainMetaAddress *address) { return fprintf(stream, "{ 0x%" PRIx32 ", 0x%" PRIx16 ", 0x%" PRIx16 ", 0x%" PRIx64 " }\n", diff --git a/include/revng/Yield/CallEdge.h b/include/revng/Yield/CallEdge.h index d0c0ff41a..fecb6426a 100644 --- a/include/revng/Yield/CallEdge.h +++ b/include/revng/Yield/CallEdge.h @@ -50,7 +50,7 @@ private: AssociatedType = FunctionEdgeType::FunctionCall; public: - CallEdge() : yield::generated::CallEdge() { Type = AssociatedType; } + CallEdge() : yield::generated::CallEdge() { Type() = AssociatedType; } CallEdge(MetaAddress Destination, FunctionEdgeType::Values Type) : yield::generated::CallEdge(Destination, Type) {} @@ -68,7 +68,7 @@ public: model::FunctionAttribute::Values Attribute) const { using namespace model; - if (Attributes.count(Attribute) != 0) + if (Attributes().count(Attribute) != 0) return true; if (const auto *CalleeAttributes = calleeAttributes(Binary)) @@ -81,7 +81,7 @@ public: attributes(const model::Binary &Binary) const { MutableSet Result; auto Inserter = Result.batch_insert(); - for (auto &Attribute : Attributes) + for (auto &Attribute : Attributes()) Inserter.insert(Attribute); if (const auto *CalleeAttributes = calleeAttributes(Binary)) @@ -100,11 +100,11 @@ public: private: const MutableSet * calleeAttributes(const model::Binary &Binary) const { - if (not DynamicFunction.empty()) { - const auto &F = Binary.ImportedDynamicFunctions.at(DynamicFunction); - return &F.Attributes; - } else if (Destination.isValid()) { - return &Binary.Functions.at(Destination).Attributes; + if (not DynamicFunction().empty()) { + const auto &F = Binary.ImportedDynamicFunctions().at(DynamicFunction()); + return &F.Attributes(); + } else if (Destination().isValid()) { + return &Binary.Functions().at(Destination()).Attributes(); } else { return nullptr; } @@ -117,24 +117,24 @@ inline model::TypePath getPrototype(const model::Binary &Binary, const yield::CallEdge &Edge) { model::TypePath Result; - auto It = Binary.Functions.at(CallerFunctionAddress) - .CallSitePrototypes.find(CallerBlockAddress); - if (It != Binary.Functions.at(CallerFunctionAddress).CallSitePrototypes.end()) - Result = It->Prototype; + auto It = Binary.Functions().at(CallerFunctionAddress) + .CallSitePrototypes().find(CallerBlockAddress); + if (It != Binary.Functions().at(CallerFunctionAddress).CallSitePrototypes().end()) + Result = It->Prototype(); - if (Edge.Type == yield::FunctionEdgeType::FunctionCall) { - if (not Edge.DynamicFunction.empty()) { + if (Edge.Type() == yield::FunctionEdgeType::FunctionCall) { + if (not Edge.DynamicFunction().empty()) { // Get the dynamic function prototype - Result = Binary.ImportedDynamicFunctions.at(Edge.DynamicFunction) - .Prototype; - } else if (Edge.Destination.isValid()) { + Result = Binary.ImportedDynamicFunctions().at(Edge.DynamicFunction()) + .Prototype(); + } else if (Edge.Destination().isValid()) { // Get the function prototype - Result = Binary.Functions.at(Edge.Destination).Prototype; + Result = Binary.Functions().at(Edge.Destination()).Prototype(); } } if (not Result.isValid()) - Result = Binary.DefaultPrototype; + Result = Binary.DefaultPrototype(); return Result; } diff --git a/include/revng/Yield/FunctionEdge.h b/include/revng/Yield/FunctionEdge.h index e927adf62..059cff16f 100644 --- a/include/revng/Yield/FunctionEdge.h +++ b/include/revng/Yield/FunctionEdge.h @@ -27,7 +27,7 @@ private: AssociatedType = FunctionEdgeType::DirectBranch; public: - FunctionEdge() : yield::generated::FunctionEdge() { Type = AssociatedType; } + FunctionEdge() : yield::generated::FunctionEdge() { Type() = AssociatedType; } FunctionEdge(MetaAddress Destination, FunctionEdgeType::Values Type) : yield::generated::FunctionEdge(Destination, Type) {} diff --git a/include/revng/Yield/FunctionEdgeBase.h b/include/revng/Yield/FunctionEdgeBase.h index ac290991b..1bf40b209 100644 --- a/include/revng/Yield/FunctionEdgeBase.h +++ b/include/revng/Yield/FunctionEdgeBase.h @@ -46,7 +46,7 @@ public: static bool classof(const Key &K) { return true; } public: - bool isDirect() const { return Destination.isValid(); } + bool isDirect() const { return Destination().isValid(); } bool isIndirect() const { return not isDirect(); } public: diff --git a/include/revng/Yield/Tag.h b/include/revng/Yield/Tag.h index e6e9ec145..2ab3c8b4e 100644 --- a/include/revng/Yield/Tag.h +++ b/include/revng/Yield/Tag.h @@ -40,12 +40,12 @@ public: generated::Tag(Type, From, To) {} std::strong_ordering operator<=>(const Tag &Another) const { - if (From != Another.From) - return From <=> Another.From; - else if (To != Another.To) - return Another.To <=> To; // reversed order + if (From() != Another.From()) + return From() <=> Another.From(); + else if (To() != Another.To()) + return Another.To() <=> To(); // reversed order else - return Type <=> Another.Type; + return Type() <=> Another.Type(); } public: diff --git a/lib/ABI/DefaultFunctionPrototype.cpp b/lib/ABI/DefaultFunctionPrototype.cpp index 3de69a387..15fa436a1 100644 --- a/lib/ABI/DefaultFunctionPrototype.cpp +++ b/lib/ABI/DefaultFunctionPrototype.cpp @@ -32,21 +32,21 @@ TypePath defaultPrototype(Binary &TheBinary) { for (const auto &Reg : abi::Trait::GeneralPurposeArgumentRegisters) { NamedTypedRegister Argument(Reg); - Argument.Type = buildType(Reg, TheBinary); - Prototype.Arguments.insert(Argument); + Argument.Type() = buildType(Reg, TheBinary); + Prototype.Arguments().insert(Argument); } for (const auto &Rg : abi::Trait::GeneralPurposeReturnValueRegisters) { TypedRegister ReturnValue(Rg); - ReturnValue.Type = buildType(Rg, TheBinary); - Prototype.ReturnValues.insert(ReturnValue); + ReturnValue.Type() = buildType(Rg, TheBinary); + Prototype.ReturnValues().insert(ReturnValue); } for (const auto &Register : abi::Trait::CalleeSavedRegisters) - Prototype.PreservedRegisters.insert(Register); + Prototype.PreservedRegisters().insert(Register); using namespace Architecture; - Prototype.FinalStackOffset = getCallPushSize(TheBinary.Architecture); + Prototype.FinalStackOffset() = getCallPushSize(TheBinary.Architecture()); return TypePath; } @@ -55,7 +55,7 @@ model::TypePath abi::registerDefaultFunctionPrototype(Binary &Binary, std::optional MaybeABI) { if (!MaybeABI.has_value()) - MaybeABI = Binary.DefaultABI; + MaybeABI = Binary.DefaultABI(); revng_assert(*MaybeABI != ABI::Invalid); return skippingEnumSwitch<1>(*MaybeABI, [&]() { return defaultPrototype(Binary); diff --git a/lib/ABI/FunctionType.cpp b/lib/ABI/FunctionType.cpp index 69e3afc52..fc28d8b49 100644 --- a/lib/ABI/FunctionType.cpp +++ b/lib/ABI/FunctionType.cpp @@ -41,13 +41,13 @@ bool verify(const SortedVector &UsedRegisters, for (const RegisterType &Register : UsedRegisters) { // Verify the architecture of used registers. - if (model::Register::getArchitecture(Register.Location) != Architecture) + if (model::Register::getArchitecture(Register.Location()) != Architecture) revng_abort(); } // Verify that every used register is also allowed. for (const RegisterType &Register : UsedRegisters) - if (llvm::count(AllowedRegisters, Register.Location) != 1) + if (llvm::count(AllowedRegisters, Register.Location()) != 1) return false; return true; @@ -95,7 +95,7 @@ buildDoubleType(model::Register::Values UpperRegister, static model::QualifiedType getTypeOrDefault(const model::QualifiedType &Type, model::Register::Values Register, model::Binary &Binary) { - if (Type.UnqualifiedType.get() != nullptr) + if (Type.UnqualifiedType().get() != nullptr) return Type; else return buildType(Register, Binary); @@ -115,7 +115,7 @@ static void replaceReferences(const model::Type::Key &OldKey, Visited = NewTypePath; }; Model.visitReferences(Visitor); - Model->Types.erase(OldKey); + Model->Types().erase(OldKey); } /// A helper used to differentiate vector registers. @@ -176,7 +176,7 @@ class ConversionHelper { static constexpr auto Architecture = model::ABI::getArchitecture(ABI); static constexpr auto RegisterSize = ModelArch::getPointerSize(Architecture); - using IndexType = decltype(model::Argument::Index); + using IndexType = decay_t; using RegisterList = llvm::SmallVector; struct DistributedArgument { RegisterList Registers = {}; @@ -191,9 +191,10 @@ public: toCABI(const model::RawFunctionType &Function, TupleTree &TheBinary) { static constexpr auto Arch = model::ABI::getArchitecture(ABI); - if (!verify(Function.Arguments, AT::GeneralPurposeArgumentRegisters)) + if (!verify(Function.Arguments(), + AT::GeneralPurposeArgumentRegisters)) return std::nullopt; - if (!verify(Function.ReturnValues, + if (!verify(Function.ReturnValues(), AT::GeneralPurposeReturnValueRegisters)) return std::nullopt; @@ -207,43 +208,44 @@ public: revng_assert(model::Register::getArchitecture(SavedRegister) == Arch); model::CABIFunctionType Result; - Result.CustomName = Function.CustomName; - Result.OriginalName = Function.OriginalName; - Result.ABI = ABI; + Result.CustomName() = Function.CustomName(); + Result.OriginalName() = Function.OriginalName(); + Result.ABI() = ABI; - if (!verifyArgumentsToBeConvertible(Function.Arguments, + if (!verifyArgumentsToBeConvertible(Function.Arguments(), AT::GeneralPurposeArgumentRegisters, *TheBinary)) return std::nullopt; using C = AT; - if (!verifyReturnValueToBeConvertible(Function.ReturnValues, + if (!verifyReturnValueToBeConvertible(Function.ReturnValues(), C::GeneralPurposeReturnValueRegisters, C::ReturnValueLocationRegister, *TheBinary)) return std::nullopt; - auto ArgumentList = convertArguments(Function.Arguments, + auto ArgumentList = convertArguments(Function.Arguments(), AT::GeneralPurposeArgumentRegisters, *TheBinary); revng_assert(ArgumentList != std::nullopt); for (auto &Argument : *ArgumentList) - Result.Arguments.insert(Argument); + Result.Arguments().insert(Argument); - auto StackArgumentList = convertStackArguments(Function.StackArgumentsType, - Result.Arguments.size()); + auto StackArgumentList = convertStackArguments(Function + .StackArgumentsType(), + Result.Arguments().size()); for (auto &Argument : StackArgumentList) - Result.Arguments.insert(Argument); + Result.Arguments().insert(Argument); - auto ReturnValue = convertReturnValue(Function.ReturnValues, + auto ReturnValue = convertReturnValue(Function.ReturnValues(), C::GeneralPurposeReturnValueRegisters, C::ReturnValueLocationRegister, *TheBinary); revng_assert(ReturnValue != std::nullopt); - Result.ReturnType = *ReturnValue; + Result.ReturnType() = *ReturnValue; // Steal the ID - Result.ID = Function.ID; + Result.ID() = Function.ID(); // Add converted type to the model. using UT = model::UpcastableType; @@ -259,120 +261,122 @@ public: static model::TypePath toRaw(const model::CABIFunctionType &Function, TupleTree &TheBinary) { // TODO: fix the return value distribution. - auto Arguments = distributeArguments(Function.Arguments, 0); + auto Arguments = distributeArguments(Function.Arguments(), 0); model::RawFunctionType Result; - Result.CustomName = Function.CustomName; - Result.OriginalName = Function.OriginalName; + Result.CustomName() = Function.CustomName(); + Result.OriginalName() = Function.OriginalName(); model::StructType StackArguments; uint64_t CombinedStackArgumentSize = 0; for (size_t ArgIndex = 0; ArgIndex < Arguments.size(); ++ArgIndex) { auto &ArgumentStorage = Arguments[ArgIndex]; - const auto &ArgumentType = Function.Arguments.at(ArgIndex).Type; + const auto &ArgumentType = Function.Arguments().at(ArgIndex).Type(); if (!ArgumentStorage.Registers.empty()) { // Handle the registers - auto ArgumentName = Function.Arguments.at(ArgIndex).name(); + auto ArgumentName = Function.Arguments().at(ArgIndex).name(); for (size_t Index = 0; auto Register : ArgumentStorage.Registers) { model::NamedTypedRegister Argument(Register); - Argument.Type = chooseArgumentType(ArgumentType, - Register, - ArgumentStorage.Registers, - *TheBinary); + Argument.Type() = chooseArgumentType(ArgumentType, + Register, + ArgumentStorage.Registers, + *TheBinary); // TODO: see what can be done to preserve names better if (llvm::StringRef{ ArgumentName.str() }.take_front(8) != "unnamed_") - Argument.CustomName = ArgumentName; + Argument.CustomName() = ArgumentName; - Result.Arguments.insert(Argument); + Result.Arguments().insert(Argument); } } if (ArgumentStorage.SizeOnStack != 0) { // Handle the stack - auto ArgumentIterator = Function.Arguments.find(ArgIndex); - revng_assert(ArgumentIterator != Function.Arguments.end()); + auto ArgumentIterator = Function.Arguments().find(ArgIndex); + revng_assert(ArgumentIterator != Function.Arguments().end()); const model::Argument &Argument = *ArgumentIterator; model::StructField Field; - Field.Offset = CombinedStackArgumentSize; - Field.CustomName = Argument.CustomName; - Field.OriginalName = Argument.OriginalName; - Field.Type = Argument.Type; - StackArguments.Fields.insert(std::move(Field)); + Field.Offset() = CombinedStackArgumentSize; + Field.CustomName() = Argument.CustomName(); + Field.OriginalName() = Argument.OriginalName(); + Field.Type() = Argument.Type(); + StackArguments.Fields().insert(std::move(Field)); // Compute the full size of the argument (including padding if needed). - auto MaybeSize = Argument.Type.size(); + auto MaybeSize = Argument.Type().size(); revng_assert(MaybeSize.has_value() && MaybeSize.value() != 0); CombinedStackArgumentSize += paddedSizeOnStack(MaybeSize.value()); } } if (CombinedStackArgumentSize != 0) { - StackArguments.Size = CombinedStackArgumentSize; + StackArguments.Size() = CombinedStackArgumentSize; using namespace model; auto Type = UpcastableType::make(std::move(StackArguments)); - Result.StackArgumentsType = { TheBinary->recordNewType(std::move(Type)), - {} }; + Result.StackArgumentsType() = { TheBinary->recordNewType(std::move(Type)), + {} }; } - Result.FinalStackOffset = finalStackOffset(Arguments); + Result.FinalStackOffset() = finalStackOffset(Arguments); - if (!Function.ReturnType.isVoid()) { - auto ReturnValue = distributeReturnValue(Function.ReturnType); + if (!Function.ReturnType().isVoid()) { + auto ReturnValue = distributeReturnValue(Function.ReturnType()); if (!ReturnValue.Registers.empty()) { // Handle a register-based return value. for (model::Register::Values Register : ReturnValue.Registers) { model::TypedRegister ReturnValueRegister; - ReturnValueRegister.Location = Register; - ReturnValueRegister.Type = chooseArgumentType(Function.ReturnType, - Register, - ReturnValue.Registers, - *TheBinary); + ReturnValueRegister.Location() = Register; + ReturnValueRegister.Type() = chooseArgumentType(Function.ReturnType(), + Register, + ReturnValue.Registers, + *TheBinary); - Result.ReturnValues.insert(std::move(ReturnValueRegister)); + Result.ReturnValues().insert(std::move(ReturnValueRegister)); } // Try and recover types from the struct if possible - if (Function.ReturnType.Qualifiers.empty()) { - const model::Type *Type = Function.ReturnType.UnqualifiedType.get(); + if (Function.ReturnType().Qualifiers().empty()) { + const model::Type + *Type = Function.ReturnType().UnqualifiedType().get(); revng_assert(Type != nullptr); const auto *Struct = llvm::dyn_cast(Type); - if (Struct && Struct->Fields.size() == Result.ReturnValues.size()) { + if (Struct + && Struct->Fields().size() == Result.ReturnValues().size()) { using RegisterEnum = model::Register::Values; SmallMap RecoveredTypes; size_t StructOffset = 0; - for (size_t Index = 0; Index < Struct->Fields.size(); ++Index) { + for (size_t Index = 0; Index < Struct->Fields().size(); ++Index) { if (Index >= AT::GeneralPurposeReturnValueRegisters.size()) break; auto Register = AT::GeneralPurposeReturnValueRegisters[Index]; - auto TypedRegisterIterator = Result.ReturnValues.find(Register); - if (TypedRegisterIterator == Result.ReturnValues.end()) + auto TypedRegisterIterator = Result.ReturnValues().find(Register); + if (TypedRegisterIterator == Result.ReturnValues().end()) break; - const model::StructField &Field = Struct->Fields.at(StructOffset); + const auto &Field = Struct->Fields().at(StructOffset); - auto MaybeFieldSize = Field.Type.size(); + auto MaybeFieldSize = Field.Type().size(); revng_assert(MaybeFieldSize != std::nullopt); - auto MaybeRegisterSize = TypedRegisterIterator->Type.size(); + auto MaybeRegisterSize = TypedRegisterIterator->Type().size(); revng_assert(MaybeRegisterSize != std::nullopt); if (MaybeFieldSize.value() != MaybeRegisterSize.value()) break; - auto Tie = std::tie(Register, Field.Type); + auto Tie = std::tie(Register, Field.Type()); auto [Iterator, Success] = RecoveredTypes.insert(std::move(Tie)); revng_assert(Success); StructOffset += MaybeFieldSize.value(); } - if (RecoveredTypes.size() == Result.ReturnValues.size()) + if (RecoveredTypes.size() == Result.ReturnValues().size()) for (auto [Register, Type] : RecoveredTypes) - Result.ReturnValues.at(Register).Type = Type; + Result.ReturnValues().at(Register).Type() = Type; } } } else { @@ -382,25 +386,25 @@ public: auto RegisterSize = model::Register::getSize(Register); auto PointerQualifier = model::Qualifier::createPointer(RegisterSize); - auto MaybeReturnValueSize = Function.ReturnType.size(); + auto MaybeReturnValueSize = Function.ReturnType().size(); revng_assert(MaybeReturnValueSize != std::nullopt); revng_assert(ReturnValue.Size == *MaybeReturnValueSize); - model::QualifiedType ReturnType = Function.ReturnType; - ReturnType.Qualifiers.emplace_back(PointerQualifier); + model::QualifiedType ReturnType = Function.ReturnType(); + ReturnType.Qualifiers().emplace_back(PointerQualifier); model::TypedRegister ReturnPointer(Register); - ReturnPointer.Type = std::move(ReturnType); - Result.ReturnValues.insert(std::move(ReturnPointer)); + ReturnPointer.Type() = std::move(ReturnType); + Result.ReturnValues().insert(std::move(ReturnPointer)); } } // Populate the list of preserved registers for (model::Register::Values Register : AT::CalleeSavedRegisters) - Result.PreservedRegisters.insert(Register); + Result.PreservedRegisters().insert(Register); // Steal the ID - Result.ID = Function.ID; + Result.ID() = Function.ID(); // Add converted type to the model. using UT = model::UpcastableType; @@ -470,10 +474,10 @@ private: if (IsUsed) { model::Argument Temporary; if constexpr (!DryRun) - Temporary.Type = getTypeOrDefault(UsedRegisters.at(Register).Type, - Register, - TheBinary); - Temporary.CustomName = UsedRegisters.at(Register).CustomName; + Temporary.Type() = getTypeOrDefault(UsedRegisters.at(Register).Type(), + Register, + TheBinary); + Temporary.CustomName() = UsedRegisters.at(Register).CustomName(); Result.emplace_back(Temporary); } else if (MustUseTheNextOne) { if constexpr (!AT::OnlyStartDoubleArgumentsFromAnEvenRegister) { @@ -485,8 +489,8 @@ private: auto &Second = Result[Result.size() - 2]; // TODO: see what can be done to preserve names better - if (First.CustomName.empty() && !Second.CustomName.empty()) - First.CustomName = Second.CustomName; + if (First.CustomName().empty() && !Second.CustomName().empty()) + First.CustomName() = Second.CustomName(); if constexpr (!DryRun) { auto NewType = buildDoubleType(AllowedRegisters.at(Index - 2), @@ -496,7 +500,7 @@ private: if (NewType == std::nullopt) return std::nullopt; - First.Type = *NewType; + First.Type() = *NewType; } Result.pop_back(); @@ -509,7 +513,7 @@ private: } for (auto Pair : llvm::enumerate(llvm::reverse(Result))) - Pair.value().Index = Pair.index(); + Pair.value().Index() = Pair.index(); return Result; } @@ -517,8 +521,8 @@ private: static llvm::SmallVector convertStackArguments(model::QualifiedType StackArgumentTypes, size_t IndexOffset) { - revng_assert(StackArgumentTypes.Qualifiers.empty()); - auto *Unqualified = StackArgumentTypes.UnqualifiedType.get(); + revng_assert(StackArgumentTypes.Qualifiers().empty()); + auto *Unqualified = StackArgumentTypes.UnqualifiedType().get(); if (not Unqualified) return {}; @@ -528,12 +532,12 @@ private: const model::StructType &Types = *Pointer; llvm::SmallVector Result; - for (const model::StructField &Field : Types.Fields) { + for (const model::StructField &Field : Types.Fields()) { model::Argument &New = Result.emplace_back(); - New.Index = IndexOffset++; - New.Type = Field.Type; - New.CustomName = Field.CustomName; - New.OriginalName = Field.OriginalName; + New.Index() = IndexOffset++; + New.Type() = Field.Type(); + New.CustomName() = Field.CustomName(); + New.OriginalName() = Field.OriginalName(); } return Result; @@ -551,22 +555,22 @@ private: } if (UsedRegisters.size() == 1) { - if (UsedRegisters.begin()->Location == PointerToCopyLocation) { + if (UsedRegisters.begin()->Location() == PointerToCopyLocation) { if constexpr (DryRun) return model::QualifiedType{}; else - return getTypeOrDefault(UsedRegisters.begin()->Type, + return getTypeOrDefault(UsedRegisters.begin()->Type(), PointerToCopyLocation, TheBinary); } else { if constexpr (RegisterCount == 0) return std::nullopt; - if (AllowedRegisters.front() == UsedRegisters.begin()->Location) { + if (AllowedRegisters.front() == UsedRegisters.begin()->Location()) { if constexpr (DryRun) return model::QualifiedType{}; else - return getTypeOrDefault(UsedRegisters.begin()->Type, - UsedRegisters.begin()->Location, + return getTypeOrDefault(UsedRegisters.begin()->Type(), + UsedRegisters.begin()->Location(), TheBinary); } else { return std::nullopt; @@ -586,18 +590,18 @@ private: bool IsCurrentRegisterUsed = UsedIterator != UsedRegisters.end(); if (IsCurrentRegisterUsed) { model::StructField CurrentField; - CurrentField.Offset = ReturnStruct->Size; + CurrentField.Offset() = ReturnStruct->Size(); if constexpr (!DryRun) - CurrentField.Type = getTypeOrDefault(UsedIterator->Type, - UsedIterator->Location, - TheBinary); - ReturnStruct->Fields.insert(std::move(CurrentField)); + CurrentField.Type() = getTypeOrDefault(UsedIterator->Type(), + UsedIterator->Location(), + TheBinary); + ReturnStruct->Fields().insert(std::move(CurrentField)); - ReturnStruct->Size += model::Register::getSize(Register); + ReturnStruct->Size() += model::Register::getSize(Register); } else if (MustUseTheNextOne) { if constexpr (!AT::OnlyStartDoubleArgumentsFromAnEvenRegister) return std::nullopt; - else if ((Index & 1) == 0 || ReturnStruct->Fields.size() <= 1 + else if ((Index & 1) == 0 || ReturnStruct->Fields().size() <= 1 || Index <= 1) return std::nullopt; } @@ -605,7 +609,8 @@ private: MustUseTheNextOne = MustUseTheNextOne || IsCurrentRegisterUsed; } - revng_assert(ReturnStruct->Size != 0 && !ReturnStruct->Fields.empty()); + revng_assert(ReturnStruct->Size() != 0 + && !ReturnStruct->Fields().empty()); if constexpr (!DryRun) { auto ReturnStructTypePath = TheBinary.recordNewType(std::move(Result)); @@ -641,16 +646,16 @@ private: DistributedArguments Result; for (const model::Argument &Argument : Arguments) { - std::size_t RegisterIndex = Argument.Index + SkippedRegisters; + std::size_t RegisterIndex = Argument.Index() + SkippedRegisters; if (Result.size() <= RegisterIndex) Result.resize(RegisterIndex + 1); auto &Distributed = Result[RegisterIndex]; - auto MaybeSize = Argument.Type.size(); + auto MaybeSize = Argument.Type().size(); revng_assert(MaybeSize.has_value()); Distributed.Size = *MaybeSize; - if (Argument.Type.isFloat()) { + if (Argument.Type().isFloat()) { if (RegisterIndex < AT::VectorArgumentRegisters.size()) { auto Register = AT::VectorArgumentRegisters[RegisterIndex]; Distributed.Registers.emplace_back(Register); @@ -730,11 +735,11 @@ private: size_t UsedVectorRegisterCount = 0; for (const model::Argument &Argument : Arguments) { - auto MaybeSize = Argument.Type.size(); + auto MaybeSize = Argument.Type().size(); revng_assert(MaybeSize.has_value()); constexpr bool CanSplit = AT::ArgumentsCanBeSplitBetweenRegistersAndStack; - if (Argument.Type.isFloat()) { + if (Argument.Type().isFloat()) { // The conventional non-position based approach is not applicable for // vector registers since it's rare for multiple registers to be used // to pass a single argument. @@ -746,27 +751,27 @@ private: static constexpr auto &Registers = AT::VectorArgumentRegisters; if (UsedVectorRegisterCount < Registers.size()) { // There is a free register to put the argument in. - if (Result.size() <= Argument.Index) - Result.resize(Argument.Index + 1); + if (Result.size() <= Argument.Index()) + Result.resize(Argument.Index() + 1); auto Register = Registers[UsedVectorRegisterCount]; - Result[Argument.Index].Registers.emplace_back(Register); - Result[Argument.Index].Size = *MaybeSize; - Result[Argument.Index].SizeOnStack = 0; + Result[Argument.Index()].Registers.emplace_back(Register); + Result[Argument.Index()].Size = *MaybeSize; + Result[Argument.Index()].SizeOnStack = 0; UsedVectorRegisterCount++; } else { // There are no more free registers left, // pass the argument on the stack. - if (Result.size() <= Argument.Index) - Result.resize(Argument.Index + 1); - Result[Argument.Index].Size = *MaybeSize; - Result[Argument.Index].SizeOnStack = paddedSizeOnStack(*MaybeSize); + if (Result.size() <= Argument.Index()) + Result.resize(Argument.Index() + 1); + Result[Argument.Index()].Size = *MaybeSize; + Result[Argument.Index()].SizeOnStack = paddedSizeOnStack(*MaybeSize); } } else { static constexpr auto &Registers = AT::GeneralPurposeArgumentRegisters; size_t &Counter = UsedGeneralPurposeRegisterCount; - if (Argument.Type.isScalar()) { + if (Argument.Type().isScalar()) { const size_t Limit = AT::MaximumGPRsPerScalarArgument; auto [Distributed, NextIndex] = considerRegisters(*MaybeSize, @@ -774,9 +779,9 @@ private: Counter, Registers, CanSplit); - if (Result.size() <= Argument.Index) - Result.resize(Argument.Index + 1); - Result[Argument.Index] = Distributed; + if (Result.size() <= Argument.Index()) + Result.resize(Argument.Index() + 1); + Result[Argument.Index()] = Distributed; Counter = NextIndex; } else { const size_t Limit = AT::MaximumGPRsPerAggregateArgument; @@ -786,9 +791,9 @@ private: Counter, Registers, CanSplit); - if (Result.size() <= Argument.Index) - Result.resize(Argument.Index + 1); - Result[Argument.Index] = Distributed; + if (Result.size() <= Argument.Index()) + Result.resize(Argument.Index() + 1); + Result[Argument.Index()] = Distributed; Counter = NextIndex; } } @@ -872,7 +877,7 @@ private: return buildType(Register, TheBinary); } else if (*MaybeSize > TargetSize) { auto Qualifier = model::Qualifier::createPointer(TargetSize); - ResultType.Qualifiers.emplace_back(Qualifier); + ResultType.Qualifiers().emplace_back(Qualifier); } else if (!ResultType.isScalar()) { return buildGenericType(Register, TheBinary); } @@ -887,7 +892,7 @@ tryConvertToCABI(const model::RawFunctionType &Function, TupleTree &TheBinary, std::optional MaybeABI) { if (!MaybeABI.has_value()) - MaybeABI = TheBinary->DefaultABI; + MaybeABI = TheBinary->DefaultABI(); revng_assert(*MaybeABI != model::ABI::Invalid); return skippingEnumSwitch<1>(*MaybeABI, [&]() { return ConversionHelper::toCABI(Function, TheBinary); @@ -896,23 +901,23 @@ tryConvertToCABI(const model::RawFunctionType &Function, model::TypePath convertToRaw(const model::CABIFunctionType &Function, TupleTree &TheBinary) { - revng_assert(Function.ABI != model::ABI::Invalid); - return skippingEnumSwitch<1>(Function.ABI, [&]() { + revng_assert(Function.ABI() != model::ABI::Invalid); + return skippingEnumSwitch<1>(Function.ABI(), [&]() { return ConversionHelper::toRaw(Function, TheBinary); }); } Layout::Layout(const model::CABIFunctionType &Function) : - Layout(skippingEnumSwitch<1>(Function.ABI, [&]() { + Layout(skippingEnumSwitch<1>(Function.ABI(), [&]() { Layout Result; using AT = abi::Trait; static constexpr auto Arch = model::ABI::getArchitecture(A); - auto RV = ConversionHelper::distributeReturnValue(Function.ReturnType); + auto RV = ConversionHelper::distributeReturnValue(Function.ReturnType()); if (RV.SizeOnStack == 0) { // Nothing on the stack, the return value fits into the registers. auto &ReturnValue = Result.ReturnValues.emplace_back(); - ReturnValue.Type = Function.ReturnType; + ReturnValue.Type = Function.ReturnType(); ReturnValue.Registers = std::move(RV.Registers); } else { revng_assert(RV.Registers.empty(), @@ -922,18 +927,18 @@ Layout::Layout(const model::CABIFunctionType &Function) : "Big return values are not supported by the current ABI"); auto &RVLocationArg = Result.Arguments.emplace_back(); RVLocationArg.Registers.emplace_back(AT::ReturnValueLocationRegister); - RVLocationArg.Type = Function.ReturnType.getPointerTo(Arch); + RVLocationArg.Type = Function.ReturnType().getPointerTo(Arch); RVLocationArg.Kind = ArgumentKind::ShadowPointerToAggregateReturnValue; } size_t CurrentOffset = 0; - auto Args = ConversionHelper::distributeArguments(Function.Arguments, + auto Args = ConversionHelper::distributeArguments(Function.Arguments(), RV.SizeOnStack != 0); - revng_assert(Args.size() == Function.Arguments.size()); + revng_assert(Args.size() == Function.Arguments().size()); for (size_t Index = 0; Index < Args.size(); ++Index) { auto &Current = Result.Arguments.emplace_back(); - const model::QualifiedType &ArgumentType = Function.Arguments.at(Index) - .Type; + const model::QualifiedType + &ArgumentType = Function.Arguments().at(Index).Type(); // Disambiguate scalar and aggregate arguments. Scalars are passed by // value, aggregate by pointer. @@ -963,48 +968,48 @@ Layout::Layout(const model::CABIFunctionType &Function) : Layout::Layout(const model::RawFunctionType &Function) { // Lay register arguments out. - for (const model::NamedTypedRegister &Register : Function.Arguments) { - revng_assert(Register.Type.isScalar()); + for (const model::NamedTypedRegister &Register : Function.Arguments()) { + revng_assert(Register.Type().isScalar()); auto &Argument = Arguments.emplace_back(); - Argument.Registers = { Register.Location }; - Argument.Type = Register.Type; + Argument.Registers = { Register.Location() }; + Argument.Type = Register.Type(); Argument.Kind = ArgumentKind::Scalar; } // Lay the return value out. - for (const model::TypedRegister &Register : Function.ReturnValues) { + for (const model::TypedRegister &Register : Function.ReturnValues()) { auto &ReturnValue = ReturnValues.emplace_back(); - ReturnValue.Registers = { Register.Location }; - ReturnValue.Type = Register.Type; + ReturnValue.Registers = { Register.Location() }; + ReturnValue.Type = Register.Type(); } // Lay stack arguments out. - if (Function.StackArgumentsType.UnqualifiedType.isValid()) { - const model::QualifiedType &StackArgType = Function.StackArgumentsType; + if (Function.StackArgumentsType().UnqualifiedType().isValid()) { + const model::QualifiedType &StackArgType = Function.StackArgumentsType(); // The stack argument, if present, should always be a struct. - revng_assert(StackArgType.Qualifiers.empty()); + revng_assert(StackArgType.Qualifiers().empty()); revng_assert(StackArgType.is(model::TypeKind::StructType)); auto &Argument = Arguments.emplace_back(); - const auto &Arch = StackArgType.UnqualifiedType.getRoot()->Architecture; + const auto &Arch = StackArgType.UnqualifiedType().getRoot()->Architecture(); // Stack argument is always passed by pointer for RawFunctionType Argument.Type = StackArgType; Argument.Kind = ArgumentKind::ReferenceToAggregate; // Record the size - const model::Type *OriginalStackType = StackArgType.UnqualifiedType.get(); + const model::Type *OriginalStackType = StackArgType.UnqualifiedType().get(); auto *StackStruct = llvm::cast(OriginalStackType); - if (StackStruct->Size != 0) - Argument.Stack = { 0, StackStruct->Size }; + if (StackStruct->Size() != 0) + Argument.Stack = { 0, StackStruct->Size() }; } // Fill callee saved registers. - append(Function.PreservedRegisters, CalleeSavedRegisters); + append(Function.PreservedRegisters(), CalleeSavedRegisters); // Set the final offset. - FinalStackOffset = Function.FinalStackOffset; + FinalStackOffset = Function.FinalStackOffset(); } bool Layout::verify() const { diff --git a/lib/BasicAnalyses/GeneratedCodeBasicInfo.cpp b/lib/BasicAnalyses/GeneratedCodeBasicInfo.cpp index d205068e1..498614287 100644 --- a/lib/BasicAnalyses/GeneratedCodeBasicInfo.cpp +++ b/lib/BasicAnalyses/GeneratedCodeBasicInfo.cpp @@ -37,7 +37,7 @@ void GeneratedCodeBasicInfo::run(Module &M) { revng_log(PassesLog, "Starting GeneratedCodeBasicInfo"); using namespace model::Architecture; - auto Architecture = Binary->Architecture; + auto Architecture = Binary->Architecture(); PC = M.getGlobalVariable(getPCCSVName(Architecture), true); SP = M.getGlobalVariable(getCSVName(getStackPointer(Architecture)), true); auto ReturnAddressRegister = getReturnAddressRegister(Architecture); diff --git a/lib/EarlyFunctionAnalysis/CFGAnalyzer.cpp b/lib/EarlyFunctionAnalysis/CFGAnalyzer.cpp index 3614f5d33..b79d4ccff 100644 --- a/lib/EarlyFunctionAnalysis/CFGAnalyzer.cpp +++ b/lib/EarlyFunctionAnalysis/CFGAnalyzer.cpp @@ -193,7 +193,7 @@ CFGAnalyzer::handleCall(llvm::CallInst *PreCallHookCall) { bool IsDirectCall = false; if (isa(CalleePC)) { auto Address = MetaAddress::fromConstant(CalleePC); - IsDirectCall = Binary->Functions.count(Address) != 0; + IsDirectCall = Binary->Functions().count(Address) != 0; if (IsDirectCall) CalleeAddress = Address; } @@ -221,9 +221,9 @@ CFGAnalyzer::handleCall(llvm::CallInst *PreCallHookCall) { UpcastablePointer Edge = makeCall(CalleeAddress); auto *CE = cast(Edge.get()); - CE->IsTailCall = IsTailCall; + CE->IsTailCall() = IsTailCall; if (IsDynamicCall) - CE->DynamicFunction = SymbolName.str(); + CE->DynamicFunction() = SymbolName.str(); return Edge; } @@ -247,12 +247,12 @@ CFGAnalyzer::collectDirectCFG(OutlinedFunction *OF) { bool ReachesUnexpectedPC = false; // Initialize the end address of the basic block, we'll extend it later on - Block.End = getFinalAddressOfBasicBlock(&BB); - revng_assert(Block.End.isValid()); + Block.End() = getFinalAddressOfBasicBlock(&BB); + revng_assert(Block.End().isValid()); revng_log(Log, "Creating block starting at " << Start.toString() << " (preliminary ending is " - << Block.End.toString() << ")"); + << Block.End().toString() << ")"); LoggerIndent<> Indent(Log); OnceQueue Queue; @@ -266,10 +266,10 @@ CFGAnalyzer::collectDirectCFG(OutlinedFunction *OF) { // If this block belongs to a single `newpc`, record its address MetaAddress CurrentBlockEnd = getFinalAddressOfBasicBlock(Current); - if (CurrentBlockEnd.isValid() and CurrentBlockEnd > Block.End) { + if (CurrentBlockEnd.isValid() and CurrentBlockEnd > Block.End()) { revng_log(Log, "Extending block end to " << CurrentBlockEnd.toString()); - Block.End = CurrentBlockEnd; + Block.End() = CurrentBlockEnd; } if (isa(Current->getTerminator())) { @@ -293,7 +293,7 @@ CFGAnalyzer::collectDirectCFG(OutlinedFunction *OF) { // Handle edge for regular function calls if (auto MaybeEdge = handleCall(Call); MaybeEdge) { revng_log(Log, "It's a direct call, emitting a CallEdge"); - Block.Successors.insert(*MaybeEdge); + Block.Successors().insert(*MaybeEdge); } } else if (GeneratedCodeBasicInfo::isJumpTarget(Succ)) { // TODO: handle situation in which it's a *direct* tail call. @@ -305,7 +305,7 @@ CFGAnalyzer::collectDirectCFG(OutlinedFunction *OF) { << Destination.toString()); auto Edge = makeEdge(Destination, efa::FunctionEdgeType::DirectBranch); - Block.Successors.insert(Edge); + Block.Successors().insert(Edge); } else if (Succ == OF->UnexpectedPCCloned) { revng_log(Log, "Reaches UnexpectedPC"); ReachesUnexpectedPC = true; @@ -318,16 +318,16 @@ CFGAnalyzer::collectDirectCFG(OutlinedFunction *OF) { } } - bool HasNoSuccessor = Block.Successors.size() == 0; + bool HasNoSuccessor = Block.Successors().size() == 0; if (HasNoSuccessor) { if (ReachesUnreachable) { // If we reach any unreachable instruction, add a single unreachable // edge revng_log(Log, "Reaches unreachable, add to successors"); - revng_assert(Block.Successors.empty()); + revng_assert(Block.Successors().empty()); using namespace efa::FunctionEdgeType; auto NewEdge = makeEdge(MetaAddress::invalid(), Unreachable); - Block.Successors.insert(NewEdge); + Block.Successors().insert(NewEdge); } else if (ReachesUnexpectedPC) { // successor of the current basic block. revng_log(Log, @@ -335,7 +335,7 @@ CFGAnalyzer::collectDirectCFG(OutlinedFunction *OF) { "LongJmp"); auto Edge = makeEdge(MetaAddress::invalid(), efa::FunctionEdgeType::LongJmp); - Block.Successors.insert(Edge); + Block.Successors().insert(Edge); } } @@ -365,7 +365,7 @@ CFGAnalyzer::State CFGAnalyzer::loadState(llvm::IRBuilder<> &Builder) const { } // Load the PC - auto LLVMArchitecture = toLLVMArchitecture(Binary->Architecture); + auto LLVMArchitecture = toLLVMArchitecture(Binary->Architecture()); auto DissectedPC = PCH->dissectJumpablePC(Builder, ReturnAddress, LLVMArchitecture); @@ -677,7 +677,7 @@ FunctionSummary CFGAnalyzer::milkInfo(OutlinedFunction *OutlinedFunction, using namespace llvm; using namespace efa::FunctionEdgeType; using namespace model::Architecture; - int64_t CallPushSize = getCallPushSize(Binary->Architecture); + int64_t CallPushSize = getCallPushSize(Binary->Architecture()); using EdgeType = UpcastablePointer; SmallVector, 4> IBIResult; @@ -789,10 +789,10 @@ FunctionSummary CFGAnalyzer::milkInfo(OutlinedFunction *OutlinedFunction, auto *Argument = CI->getArgOperand(CallerBlockAddressIndex); auto BlockAddress = MetaAddress::fromConstant(Argument); efa::BasicBlock &Block = CFG.at(BlockAddress); - revng_assert(Block.Successors.size() == 1); - auto OldEdge = cast(Block.Successors.begin()->get()); - revng_assert(OldEdge->IsTailCall); - Block.Successors = { makeIndirectEdge(LongJmp) }; + revng_assert(Block.Successors().size() == 1); + auto OldEdge = cast(Block.Successors().begin()->get()); + revng_assert(OldEdge->IsTailCall()); + Block.Successors() = { makeIndirectEdge(LongJmp) }; } } @@ -842,9 +842,9 @@ FunctionSummary CFGAnalyzer::milkInfo(OutlinedFunction *OutlinedFunction, if (MaybeWinFSO.has_value() && FSO == *MaybeWinFSO) { auto NewEdge = makeCall(MetaAddress::invalid()); auto *Call = cast(NewEdge.get()); - Call->IsTailCall = true; + Call->IsTailCall() = true; auto *Argument = CI->getArgOperand(CalledSymbolIndex); - Call->DynamicFunction = extractFromConstantStringPtr(Argument); + Call->DynamicFunction() = extractFromConstantStringPtr(Argument); IBIResult.emplace_back(CI, std::move(NewEdge)); ClobberedRegisters.recordClobberedRegisters(CI); ClobberedRegisters.add(Summary->ClobberedRegisters); @@ -860,7 +860,7 @@ FunctionSummary CFGAnalyzer::milkInfo(OutlinedFunction *OutlinedFunction, auto *Argument = CI->getArgOperand(CallerBlockAddressIndex); auto PC = MetaAddress::fromConstant(Argument); efa::BasicBlock &Block = CFG.at(PC); - Block.Successors.insert(std::move(Edge)); + Block.Successors().insert(std::move(Edge)); } // Collect summary for information @@ -870,12 +870,12 @@ FunctionSummary CFGAnalyzer::milkInfo(OutlinedFunction *OutlinedFunction, int BrokenReturnCount = 0; int NoReturnCount = 0; for (const auto &[CI, Edge] : IBIResult) { - if (Edge->Type == Return) { + if (Edge->Type() == Return) { FoundReturn = true; - } else if (Edge->Type == FunctionCall - and cast(Edge.get())->IsTailCall) { + } else if (Edge->Type() == FunctionCall + and cast(Edge.get())->IsTailCall()) { FoundReturn = true; - } else if (Edge->Type == BrokenReturn) { + } else if (Edge->Type() == BrokenReturn) { FoundBrokenReturn = true; BrokenReturnCount++; } else { @@ -896,7 +896,7 @@ FunctionSummary CFGAnalyzer::milkInfo(OutlinedFunction *OutlinedFunction, revng_assert(CFG.size() > 0); for (efa::BasicBlock &Block : CFG) - revng_assert(Block.Successors.size() > 0); + revng_assert(Block.Successors().size() > 0); return FunctionSummary(Attributes, ClobberedRegisters.getClobberedRegisters(), diff --git a/lib/EarlyFunctionAnalysis/CollectCFG.cpp b/lib/EarlyFunctionAnalysis/CollectCFG.cpp index da13b713c..b10ae82c0 100644 --- a/lib/EarlyFunctionAnalysis/CollectCFG.cpp +++ b/lib/EarlyFunctionAnalysis/CollectCFG.cpp @@ -50,7 +50,7 @@ void CollectCFG::serializeFunctionMetadata(const CFGVector &CFGs) { for (const efa::FunctionMetadata &FM : CFGs) { FM.verify(*Binary, true); - BasicBlock *BB = GCBI.getBlockAt(FM.Entry); + BasicBlock *BB = GCBI.getBlockAt(FM.Entry()); std::string Buffer; { raw_string_ostream Stream(Buffer); @@ -65,21 +65,21 @@ void CollectCFG::serializeFunctionMetadata(const CFGVector &CFGs) { std::vector CollectCFG::recoverCFGs() { std::vector Result; - for (const auto &Function : Binary->Functions) { - auto *Entry = GCBI.getBlockAt(Function.Entry); + for (const auto &Function : Binary->Functions()) { + auto *Entry = GCBI.getBlockAt(Function.Entry()); revng_assert(Entry != nullptr); // Recover the control-flow graph of the function efa::FunctionMetadata New; - New.Entry = Function.Entry; - New.ControlFlowGraph = std::move(Analyzer.analyze(Entry).CFG); + New.Entry() = Function.Entry(); + New.ControlFlowGraph() = std::move(Analyzer.analyze(Entry).CFG); - revng_assert(New.ControlFlowGraph.count(New.Entry) != 0); + revng_assert(New.ControlFlowGraph().count(New.Entry()) != 0); // Run final steps on the CFG New.simplify(*Binary); - revng_assert(New.ControlFlowGraph.count(New.Entry) != 0); + revng_assert(New.ControlFlowGraph().count(New.Entry()) != 0); Result.emplace_back(std::move(New)); } diff --git a/lib/EarlyFunctionAnalysis/CollectFunctionsFromCalleesPass.cpp b/lib/EarlyFunctionAnalysis/CollectFunctionsFromCalleesPass.cpp index 713b2a983..028d40e3b 100644 --- a/lib/EarlyFunctionAnalysis/CollectFunctionsFromCalleesPass.cpp +++ b/lib/EarlyFunctionAnalysis/CollectFunctionsFromCalleesPass.cpp @@ -42,7 +42,7 @@ static void collectFunctionsFromCallees(Module &M, continue; MetaAddress Entry = GCBI.getJumpTarget(&BB); - if (Binary.Functions.find(Entry) != Binary.Functions.end()) + if (Binary.Functions().find(Entry) != Binary.Functions().end()) continue; uint32_t Reasons = GCBI.getJTReasons(&BB); @@ -50,7 +50,7 @@ static void collectFunctionsFromCallees(Module &M, if (IsCallee) { // Create the function - Binary.Functions[Entry]; + Binary.Functions()[Entry]; revng_log(Log, "Found function from callee: " << BB.getName().str()); } } diff --git a/lib/EarlyFunctionAnalysis/CollectFunctionsFromUnusedAddressesPass.cpp b/lib/EarlyFunctionAnalysis/CollectFunctionsFromUnusedAddressesPass.cpp index b9a27c029..b8fcc0570 100644 --- a/lib/EarlyFunctionAnalysis/CollectFunctionsFromUnusedAddressesPass.cpp +++ b/lib/EarlyFunctionAnalysis/CollectFunctionsFromUnusedAddressesPass.cpp @@ -35,8 +35,8 @@ public: private: void loadAllCFGs(FunctionMetadataCache &MDCache) { - for (auto &Function : Binary.Functions) { - llvm::BasicBlock *Entry = GCBI.getBlockAt(Function.Entry); + for (auto &Function : Binary.Functions()) { + llvm::BasicBlock *Entry = GCBI.getBlockAt(Function.Entry()); llvm::Instruction *Term = Entry->getTerminator(); auto *FMMDNode = Term->getMetadata(FunctionMetadataMDName); // CFG not serialized for this function? Skip it @@ -44,8 +44,8 @@ private: continue; const efa::FunctionMetadata &FM = MDCache.getFunctionMetadata(Entry); - for (const efa::BasicBlock &Block : FM.ControlFlowGraph) - VisitedBlocks.insert(Block.Start); + for (const efa::BasicBlock &Block : FM.ControlFlowGraph()) + VisitedBlocks.insert(Block.Start()); } } @@ -58,7 +58,7 @@ private: continue; MetaAddress Entry = GCBI.getJumpTarget(&BB); - if (Binary.Functions.find(Entry) != Binary.Functions.end()) + if (Binary.Functions().find(Entry) != Binary.Functions().end()) continue; uint32_t Reasons = GCBI.getJTReasons(&BB); @@ -79,7 +79,7 @@ private: // Consider addresses found in global data that have not been used or // addresses that are not return addresses and do not end up in the PC // directly. - Binary.Functions[Entry]; + Binary.Functions()[Entry]; revng_log(Log, "Found function from unused addresses: " << BB.getName().str()); diff --git a/lib/EarlyFunctionAnalysis/DetectABI.cpp b/lib/EarlyFunctionAnalysis/DetectABI.cpp index 09a31e91d..4f7382da1 100644 --- a/lib/EarlyFunctionAnalysis/DetectABI.cpp +++ b/lib/EarlyFunctionAnalysis/DetectABI.cpp @@ -140,8 +140,8 @@ public: // traversal (leafs first). runInterproceduralAnalysis(); - for (model::Function &Function : Binary->Functions) - analyzeABI(GCBI.getBlockAt(Function.Entry)); + for (model::Function &Function : Binary->Functions()) + analyzeABI(GCBI.getBlockAt(Function.Entry())); // Propagate results between call-sites and functions interproceduralPropagation(); @@ -193,8 +193,8 @@ void DetectABI::initializeInterproceduralQueue() { // The intraprocedural analysis will be scheduled only for those functions // which have `Invalid` as type. - auto &Function = Binary->Functions.at(Node->Address); - if (not Function.Prototype.isValid()) + auto &Function = Binary->Functions().at(Node->Address); + if (not Function.Prototype().isValid()) EntrypointsQueue.insert(Node); } } @@ -209,16 +209,16 @@ void DetectABI::computeApproximateCallGraph() { llvm::SmallVector Worklist; // Create an over-approximated call graph - for (const auto &Function : Binary->Functions) { - auto *Entry = GCBI.getBlockAt(Function.Entry); - BasicBlockNode Node{ Function.Entry }; + for (const auto &Function : Binary->Functions()) { + auto *Entry = GCBI.getBlockAt(Function.Entry()); + BasicBlockNode Node{ Function.Entry() }; BasicBlockNode *GraphNode = ApproximateCallGraph.addNode(Node); BasicBlockNodeMap[Entry] = GraphNode; } - for (const auto &Function : Binary->Functions) { + for (const auto &Function : Binary->Functions()) { llvm::SmallSet Visited; - auto *Entry = GCBI.getBlockAt(Function.Entry); + auto *Entry = GCBI.getBlockAt(Function.Entry()); BasicBlockNode *StartNode = BasicBlockNodeMap[Entry]; revng_assert(StartNode != nullptr); Worklist.emplace_back(Entry); @@ -278,12 +278,12 @@ DetectABI::buildPrototypeForIndirectCall(const FunctionSummary &CallerSummary, auto NewType = makeType(); auto &CallType = *llvm::cast(NewType.get()); { - auto ArgumentsInserter = CallType.Arguments.batch_insert(); - auto ReturnValuesInserter = CallType.ReturnValues.batch_insert(); + auto ArgumentsInserter = CallType.Arguments().batch_insert(); + auto ReturnValuesInserter = CallType.ReturnValues().batch_insert(); bool Found = false; for (const auto &[PC, CallSites] : CallerSummary.ABIResults.CallSites) { - if (PC != CallerBlock.Start) + if (PC != CallerBlock.Start()) continue; revng_assert(!Found); @@ -298,7 +298,7 @@ DetectABI::buildPrototypeForIndirectCall(const FunctionSummary &CallerSummary, RegisterState RSRV = RV == nullptr ? RegisterState::Maybe : RV->second; auto RegisterID = model::Register::fromCSVName(CSV->getName(), - Binary->Architecture); + Binary->Architecture()); if (RegisterID == Register::Invalid || CSV == GCBI.spReg()) continue; @@ -310,13 +310,13 @@ DetectABI::buildPrototypeForIndirectCall(const FunctionSummary &CallerSummary, if (abi::RegisterState::shouldEmit(RSArg)) { NamedTypedRegister TR(RegisterID); - TR.Type = { GenericType, {} }; + TR.Type() = { GenericType, {} }; ArgumentsInserter.insert(TR); } if (abi::RegisterState::shouldEmit(RSRV)) { TypedRegister TR(RegisterID); - TR.Type = { GenericType, {} }; + TR.Type() = { GenericType, {} }; ReturnValuesInserter.insert(TR); } } @@ -326,10 +326,10 @@ DetectABI::buildPrototypeForIndirectCall(const FunctionSummary &CallerSummary, // Import FinalStackOffset and CalleeSavedRegisters from the default // prototype const FunctionSummary &DefaultSummary = Oracle.getDefault(); - const auto &ClobberedRegisters = DefaultSummary.ClobberedRegisters; - CallType.PreservedRegisters = computePreservedRegisters(ClobberedRegisters); + const auto &Clobbered = DefaultSummary.ClobberedRegisters; + CallType.PreservedRegisters() = computePreservedRegisters(Clobbered); - CallType.FinalStackOffset = DefaultSummary.ElectedFSO.value_or(0); + CallType.FinalStackOffset() = DefaultSummary.ElectedFSO.value_or(0); } return NewType; @@ -342,23 +342,23 @@ void DetectABI::finalizeModel() { // Fill up the model and build its prototype for each function std::set Functions; - for (model::Function &Function : Binary->Functions) { + for (model::Function &Function : Binary->Functions()) { // Ignore if we already have a prototype - if (Function.Prototype.isValid()) + if (Function.Prototype().isValid()) continue; - MetaAddress EntryPC = Function.Entry; + MetaAddress EntryPC = Function.Entry(); revng_assert(EntryPC.isValid()); auto &Summary = Oracle.getLocalFunction(EntryPC); // Replace function attributes - Function.Attributes = Summary.Attributes; + Function.Attributes() = Summary.Attributes; auto NewType = makeType(); auto &FunctionType = *llvm::cast(NewType.get()); { - auto ArgumentsInserter = FunctionType.Arguments.batch_insert(); - auto ReturnValuesInserter = FunctionType.ReturnValues.batch_insert(); + auto ArgumentsInserter = FunctionType.Arguments().batch_insert(); + auto ReturnValuesInserter = FunctionType.ReturnValues().batch_insert(); // Argument and return values for (const auto &[Arg, RV] : @@ -370,7 +370,7 @@ void DetectABI::finalizeModel() { RegisterState RSRV = RV == nullptr ? RegisterState::Maybe : RV->second; auto RegisterID = model::Register::fromCSVName(CSV->getName(), - Binary->Architecture); + Binary->Architecture()); if (RegisterID == Register::Invalid || CSV == GCBI.spReg()) continue; @@ -379,7 +379,7 @@ void DetectABI::finalizeModel() { if (abi::RegisterState::shouldEmit(RSArg)) { NamedTypedRegister TR(RegisterID); - TR.Type = { + TR.Type() = { Binary->getPrimitiveType(PrimitiveTypeKind::Generic, CSVSize), {} }; ArgumentsInserter.insert(TR); @@ -387,7 +387,7 @@ void DetectABI::finalizeModel() { if (abi::RegisterState::shouldEmit(RSRV)) { TypedRegister TR(RegisterID); - TR.Type = { + TR.Type() = { Binary->getPrimitiveType(PrimitiveTypeKind::Generic, CSVSize), {} }; ReturnValuesInserter.insert(TR); @@ -397,26 +397,26 @@ void DetectABI::finalizeModel() { // Preserved registers const auto &ClobberedRegisters = Summary.ClobberedRegisters; auto PreservedRegisters = computePreservedRegisters(ClobberedRegisters); - FunctionType.PreservedRegisters = std::move(PreservedRegisters); + FunctionType.PreservedRegisters() = std::move(PreservedRegisters); // Final stack offset - FunctionType.FinalStackOffset = Summary.ElectedFSO.value_or(0); + FunctionType.FinalStackOffset() = Summary.ElectedFSO.value_or(0); } - Function.Prototype = Binary->recordNewType(std::move(NewType)); + Function.Prototype() = Binary->recordNewType(std::move(NewType)); Functions.insert(&Function); } // Build prototype for indirect function calls for (auto &Function : Functions) { - auto &Summary = Oracle.getLocalFunction(Function->Entry); + auto &Summary = Oracle.getLocalFunction(Function->Entry()); for (auto &Block : Summary.CFG) { - for (auto &Edge : Block.Successors) { + for (auto &Edge : Block.Successors()) { if (auto *CE = llvm::dyn_cast(Edge.get())) { - auto &CallSitePrototypes = Function->CallSitePrototypes; - bool IsDirect = CE->Destination.isValid(); - bool IsDynamic = not CE->DynamicFunction.empty(); - bool HasInfoOnEdge = CallSitePrototypes.count(Block.Start) != 0; + auto &CallSitePrototypes = Function->CallSitePrototypes(); + bool IsDirect = CE->Destination().isValid(); + bool IsDynamic = not CE->DynamicFunction().empty(); + bool HasInfoOnEdge = CallSitePrototypes.count(Block.Start()) != 0; if (not IsDynamic and not IsDirect and not HasInfoOnEdge) { // It's an indirect call for which we have now call site information auto Prototype = buildPrototypeForIndirectCall(Summary, Block); @@ -428,17 +428,17 @@ void DetectABI::finalizeModel() { AttributesSet Attributes = {}; // Register new prototype - model::CallSitePrototype ThePrototype(Block.Start, + model::CallSitePrototype ThePrototype(Block.Start(), Path, IsTailCall, Attributes); - Function->CallSitePrototypes.insert(std::move(ThePrototype)); + Function->CallSitePrototypes().insert(std::move(ThePrototype)); } } } } - efa::FunctionMetadata FM(Function->Entry, Summary.CFG); + efa::FunctionMetadata FM(Function->Entry(), Summary.CFG); FM.verify(*Binary, true); } @@ -461,10 +461,10 @@ static void combineCrossCallSites(auto &CallSite, auto &Callee) { /// Perform cross-call site propagation void DetectABI::interproceduralPropagation() { - for (const model::Function &Function : Binary->Functions) { - auto &Summary = Oracle.getLocalFunction(Function.Entry); + for (const model::Function &Function : Binary->Functions()) { + auto &Summary = Oracle.getLocalFunction(Function.Entry()); for (auto &[PC, CallSite] : Summary.ABIResults.CallSites) { - if (PC == Function.Entry) + if (PC == Function.Entry()) combineCrossCallSites(CallSite, Summary.ABIResults); } } @@ -492,8 +492,8 @@ DetectABI::tryGetRegisterState(model::Register::Values RegisterValue, void DetectABI::initializeMapForDeductions(FunctionSummary &Summary, abi::RegisterState::Map &Map) { - auto Arch = model::ABI::getArchitecture(Binary->DefaultABI); - revng_assert(Arch == Binary->Architecture); + auto Arch = model::ABI::getArchitecture(Binary->DefaultABI()); + revng_assert(Arch == Binary->Architecture()); for (const auto &Reg : model::Architecture::registers(Arch)) { const auto &ArgRegisters = Summary.ABIResults.ArgumentsRegisters; @@ -513,19 +513,21 @@ void DetectABI::applyABIDeductions() { if (ABIEnforcement == NoABIEnforcement) return; - for (const model::Function &Function : Binary->Functions) { - auto &Summary = Oracle.getLocalFunction(Function.Entry); + for (const model::Function &Function : Binary->Functions()) { + auto &Summary = Oracle.getLocalFunction(Function.Entry()); - RegisterState::Map StateMap(Binary->Architecture); + RegisterState::Map StateMap(Binary->Architecture()); initializeMapForDeductions(Summary, StateMap); bool EnforceABIConformance = ABIEnforcement == FullABIEnforcement; std::optional ResultMap; if (EnforceABIConformance) { - ResultMap = enforceRegisterStateDeductions(StateMap, Binary->DefaultABI); + ResultMap = enforceRegisterStateDeductions(StateMap, + Binary->DefaultABI()); } else { - ResultMap = tryApplyRegisterStateDeductions(StateMap, Binary->DefaultABI); + ResultMap = tryApplyRegisterStateDeductions(StateMap, + Binary->DefaultABI()); } if (!ResultMap.has_value()) @@ -546,10 +548,10 @@ void DetectABI::applyABIDeductions() { // ABI-refined results per indirect call-site for (auto &Block : Summary.CFG) { - for (auto &Edge : Block.Successors) { - if (efa::FunctionEdgeType::isCall(Edge->Type) - && Edge->Type != efa::FunctionEdgeType::FunctionCall) { - auto &CSSummary = Summary.ABIResults.CallSites.at(Block.Start); + for (auto &Edge : Block.Successors()) { + if (efa::FunctionEdgeType::isCall(Edge->Type()) + && Edge->Type() != efa::FunctionEdgeType::FunctionCall) { + auto &CSSummary = Summary.ABIResults.CallSites.at(Block.Start()); if (CSSummary.ArgumentsRegisters.count(CSV) != 0) CSSummary.ArgumentsRegisters[CSV] = MaybeArg; @@ -563,7 +565,7 @@ void DetectABI::applyABIDeductions() { } if (Log.isEnabled()) { - Log << "Summary for " << Function.OriginalName << ":\n"; + Log << "Summary for " << Function.OriginalName() << ":\n"; Summary.dump(Log); Log << DoLog; } @@ -612,7 +614,7 @@ DetectABI::computePreservedRegisters(const CSVSet &ClobberedRegisters) const { auto PreservedRegistersInserter = Result.batch_insert(); for (auto *CSV : PreservedRegisters) { auto RegisterID = model::Register::fromCSVName(CSV->getName(), - Binary->Architecture); + Binary->Architecture()); if (RegisterID == Register::Invalid) continue; @@ -761,7 +763,7 @@ void DetectABI::runInterproceduralAnalysis() { if (IsInline) InlineFunctionWorklist.insert(Caller); - if (not Binary->Functions.at(CallerPC).Prototype.isValid()) { + if (not Binary->Functions().at(CallerPC).Prototype().isValid()) { revng_log(Log, CallerPC.toString()); EntrypointsQueue.insert(Caller); } diff --git a/lib/EarlyFunctionAnalysis/FunctionMetadata.cpp b/lib/EarlyFunctionAnalysis/FunctionMetadata.cpp index 4fbe50863..2a137ea65 100644 --- a/lib/EarlyFunctionAnalysis/FunctionMetadata.cpp +++ b/lib/EarlyFunctionAnalysis/FunctionMetadata.cpp @@ -39,8 +39,8 @@ public: FunctionCFGVerificationHelper(const efa::FunctionMetadata &Metadata, const model::Binary &Binary) { using G = FunctionCFG; - std::tie(Graph, Map) = buildControlFlowGraph(Metadata.ControlFlowGraph, - Metadata.Entry, + std::tie(Graph, Map) = buildControlFlowGraph(Metadata.ControlFlowGraph(), + Metadata.Entry(), Binary); } @@ -83,9 +83,9 @@ const efa::BasicBlock *FunctionMetadata::findBlock(GeneratedCodeBasicInfo &GCBI, MetaAddress CallerBlockAddress = GCBI.getPCFromNewPC(JumpTargetBB); revng_assert(CallerBlockAddress.isValid()); - auto It = ControlFlowGraph.find(CallerBlockAddress); + auto It = ControlFlowGraph().find(CallerBlockAddress); - while (It == ControlFlowGraph.end()) { + while (It == ControlFlowGraph().end()) { llvm::BasicBlock *PredecessorJumpTargetBB = nullptr; for (llvm::BasicBlock *Predecessor : predecessors(JumpTargetBB)) { @@ -104,7 +104,7 @@ const efa::BasicBlock *FunctionMetadata::findBlock(GeneratedCodeBasicInfo &GCBI, revng_assert(JumpTargetBB != nullptr); CallerBlockAddress = GCBI.getPCFromNewPC(JumpTargetBB); revng_assert(CallerBlockAddress.isValid()); - It = ControlFlowGraph.find(CallerBlockAddress); + It = ControlFlowGraph().find(CallerBlockAddress); } return &*It; @@ -116,16 +116,16 @@ void FunctionMetadata::simplify(const model::Binary &Binary) { // Create quick map of predecessors std::map> Predecessors; - for (efa::BasicBlock &Block : ControlFlowGraph) { - for (auto &Successor : Block.Successors) { - if (Successor->Type == efa::FunctionEdgeType::DirectBranch - and Successor->Destination.isValid()) { - Predecessors[Successor->Destination].push_back(Block.Start); + for (efa::BasicBlock &Block : ControlFlowGraph()) { + for (auto &Successor : Block.Successors()) { + if (Successor->Type() == efa::FunctionEdgeType::DirectBranch + and Successor->Destination().isValid()) { + Predecessors[Successor->Destination()].push_back(Block.Start()); } else if (auto *Call = dyn_cast(Successor.get())) { - if (not Call->IsTailCall + if (not Call->IsTailCall() and not Call->hasAttribute(Binary, model::FunctionAttribute::NoReturn)) { - Predecessors[Block.End].push_back(Block.Start); + Predecessors[Block.End()].push_back(Block.Start()); } } } @@ -133,47 +133,47 @@ void FunctionMetadata::simplify(const model::Binary &Binary) { // Identify blocks that need to be merged in their predecessor SmallVector, 4> ToMerge; - for (efa::BasicBlock &Block : ControlFlowGraph) { + for (efa::BasicBlock &Block : ControlFlowGraph()) { // Ignore entry block entirely - if (Block.End == Entry) + if (Block.End() == Entry()) continue; // Do we have only one successor? - if (Block.Successors.size() != 1) + if (Block.Successors().size() != 1) continue; // Is the successor a direct branch to the end of the block? - auto &OnlySuccessor = *Block.Successors.begin(); - if (not(OnlySuccessor->Type == efa::FunctionEdgeType::DirectBranch - and OnlySuccessor->Destination == Block.End)) + auto &OnlySuccessor = *Block.Successors().begin(); + if (not(OnlySuccessor->Type() == efa::FunctionEdgeType::DirectBranch + and OnlySuccessor->Destination() == Block.End())) continue; // Does the only successor has only one predeccessor? - auto PredecessorsAddress = Predecessors.at(Block.End); + auto PredecessorsAddress = Predecessors.at(Block.End()); if (PredecessorsAddress.size() != 1) continue; // Are we the only predecessor? - if (*PredecessorsAddress.begin() != Block.Start) + if (*PredecessorsAddress.begin() != Block.Start()) continue; - ToMerge.emplace_back(Block.Start, Block.End); + ToMerge.emplace_back(Block.Start(), Block.End()); } for (auto [PredecessorAddress, BlockAddress] : llvm::reverse(ToMerge)) { - efa::BasicBlock &Predecessor = ControlFlowGraph.at(PredecessorAddress); - efa::BasicBlock &Block = ControlFlowGraph.at(BlockAddress); + efa::BasicBlock &Predecessor = ControlFlowGraph().at(PredecessorAddress); + efa::BasicBlock &Block = ControlFlowGraph().at(BlockAddress); // Safety checks - revng_assert(Predecessor.Successors.size() == 1); - revng_assert(Predecessor.End == Block.Start); + revng_assert(Predecessor.Successors().size() == 1); + revng_assert(Predecessor.End() == Block.Start()); // Merge Block into Predecessor - Predecessor.End = Block.End; - Predecessor.Successors = std::move(Block.Successors); + Predecessor.End() = Block.End(); + Predecessor.Successors() = std::move(Block.Successors()); // Drop Block - ControlFlowGraph.erase(BlockAddress); + ControlFlowGraph().erase(BlockAddress); } } @@ -188,9 +188,9 @@ bool FunctionMetadata::verify(const model::Binary &Binary, bool Assert) const { bool FunctionMetadata::verify(const model::Binary &Binary, model::VerifyHelper &VH) const { - const auto &Function = Binary.Functions.at(Entry); + const auto &Function = Binary.Functions().at(Entry()); - if (ControlFlowGraph.size() == 0) + if (ControlFlowGraph().size() == 0) return VH.fail("The function has no CFG"); // Populate graph @@ -205,20 +205,20 @@ bool FunctionMetadata::verify(const model::Binary &Binary, return VH.fail(); // Verify blocks - if (ControlFlowGraph.size() > 0) { + if (ControlFlowGraph().size() > 0) { bool HasEntry = false; - for (const BasicBlock &Block : ControlFlowGraph) { + for (const BasicBlock &Block : ControlFlowGraph()) { - if (Block.Start == Entry) { + if (Block.Start() == Entry()) { if (HasEntry) return VH.fail("Multiple entry point blocks found"); HasEntry = true; } - if (Block.Successors.size() == 0) + if (Block.Successors().size() == 0) return VH.fail("A block has no successors", Block); - for (const auto &Edge : Block.Successors) + for (const auto &Edge : Block.Successors()) if (not Edge->verify(VH)) return VH.fail(); } @@ -231,26 +231,27 @@ bool FunctionMetadata::verify(const model::Binary &Binary, } // Check function calls - for (const auto &Block : ControlFlowGraph) { - for (const auto &Edge : Block.Successors) { - if (Edge->Type == efa::FunctionEdgeType::FunctionCall) { + for (const auto &Block : ControlFlowGraph()) { + for (const auto &Edge : Block.Successors()) { + if (Edge->Type() == efa::FunctionEdgeType::FunctionCall) { // We're in a direct call, get the callee const auto *Call = dyn_cast(Edge.get()); - if (not Call->DynamicFunction.empty()) { + if (not Call->DynamicFunction().empty()) { // It's a dynamic call - auto It = Binary.ImportedDynamicFunctions.find(Call->DynamicFunction); + auto &Function = Call->DynamicFunction(); + auto It = Binary.ImportedDynamicFunctions().find(Function); // If missing, fail - if (It == Binary.ImportedDynamicFunctions.end()) - return VH.fail("Can't find callee \"" + Call->DynamicFunction + if (It == Binary.ImportedDynamicFunctions().end()) + return VH.fail("Can't find callee \"" + Call->DynamicFunction() + "\""); } else if (Call->isDirect()) { // Regular call - auto It = Binary.Functions.find(Call->Destination); + auto It = Binary.Functions().find(Call->Destination()); // If missing, fail - if (It == Binary.Functions.end()) + if (It == Binary.Functions().end()) return VH.fail("Can't find callee"); } } @@ -265,8 +266,8 @@ void FunctionMetadata::dump() const { } void FunctionMetadata::dumpCFG(const model::Binary &Binary) const { - auto [Graph, _] = buildControlFlowGraph(ControlFlowGraph, - Entry, + auto [Graph, _] = buildControlFlowGraph(ControlFlowGraph(), + Entry(), Binary); raw_os_ostream Stream(dbg); WriteGraph(Stream, &Graph); @@ -284,18 +285,18 @@ bool FunctionEdgeBase::verify(bool Assert) const { bool FunctionEdgeBase::verify(model::VerifyHelper &VH) const { using namespace efa::FunctionEdgeType; - switch (Type) { + switch (Type()) { case Invalid: case Count: return VH.fail(); case DirectBranch: - if (Destination.isInvalid()) + if (Destination().isInvalid()) return VH.fail(); break; case FunctionCall: { const auto &Call = cast(*this); - if (Destination.isValid() and not Call.DynamicFunction.empty()) + if (Destination().isValid() and not Call.DynamicFunction().empty()) return VH.fail("Dynamic function has destination address"); } break; @@ -304,7 +305,7 @@ bool FunctionEdgeBase::verify(model::VerifyHelper &VH) const { case LongJmp: case Killer: case Unreachable: - if (Destination.isValid()) + if (Destination().isValid()) return VH.fail(); break; } @@ -322,7 +323,7 @@ void CallEdge::dump() const { model::Identifier BasicBlock::name() const { using llvm::Twine; - return model::Identifier(std::string("bb_") + Start.toString()); + return model::Identifier(std::string("bb_") + Start().toString()); } void BasicBlock::dump() const { @@ -339,10 +340,10 @@ bool BasicBlock::verify(bool Assert) const { } bool BasicBlock::verify(model::VerifyHelper &VH) const { - if (Start.isInvalid() or End.isInvalid()) + if (Start().isInvalid() or End().isInvalid()) return VH.fail(); - for (auto &Edge : Successors) + for (auto &Edge : Successors()) if (not Edge->verify(VH)) return VH.fail(); diff --git a/lib/EarlyFunctionAnalysis/FunctionSummaryOracle.cpp b/lib/EarlyFunctionAnalysis/FunctionSummaryOracle.cpp index 88bd6f47f..cbc1d3875 100644 --- a/lib/EarlyFunctionAnalysis/FunctionSummaryOracle.cpp +++ b/lib/EarlyFunctionAnalysis/FunctionSummaryOracle.cpp @@ -154,45 +154,45 @@ void importModel(Module &M, ABICSVs.emplace_back(CSV); // Import the default prototype - revng_assert(Binary.DefaultPrototype.isValid()); - Oracle.setDefault(importPrototype(M, ABICSVs, {}, Binary.DefaultPrototype)); + revng_assert(Binary.DefaultPrototype().isValid()); + Oracle.setDefault(importPrototype(M, ABICSVs, {}, Binary.DefaultPrototype())); std::map InlineFunctions; // Import existing functions from model - for (const model::Function &Function : Binary.Functions) { + for (const model::Function &Function : Binary.Functions()) { // Import call-site specific information for (const model::CallSitePrototype &CallSite : - Function.CallSitePrototypes) { + Function.CallSitePrototypes()) { - Oracle.registerCallSite(Function.Entry, - CallSite.CallerBlockAddress, + Oracle.registerCallSite(Function.Entry(), + CallSite.CallerBlockAddress(), importPrototype(M, ABICSVs, - CallSite.Attributes, - CallSite.Prototype), - CallSite.IsTailCall); + CallSite.Attributes(), + CallSite.Prototype()), + CallSite.IsTailCall()); } auto Summary = importPrototype(M, ABICSVs, - Function.Attributes, + Function.Attributes(), Function.prototype(Binary)); // Create function to inline, if necessary if (Summary.Attributes.count(model::FunctionAttribute::Inline)) - InlineFunctions[GCBI.getBlockAt(Function.Entry)] = Function.Entry; + InlineFunctions[GCBI.getBlockAt(Function.Entry())] = Function.Entry(); - Oracle.registerLocalFunction(Function.Entry, std::move(Summary)); + Oracle.registerLocalFunction(Function.Entry(), std::move(Summary)); } // Register all dynamic symbols - for (const auto &DynamicFunction : Binary.ImportedDynamicFunctions) { + for (const auto &DynamicFunction : Binary.ImportedDynamicFunctions()) { const auto &Prototype = getPrototype(Binary, DynamicFunction); - Oracle.registerDynamicFunction(DynamicFunction.OriginalName, + Oracle.registerDynamicFunction(DynamicFunction.OriginalName(), importPrototype(M, ABICSVs, - DynamicFunction.Attributes, + DynamicFunction.Attributes(), Prototype)); } } diff --git a/lib/FunctionIsolation/EnforceABI.cpp b/lib/FunctionIsolation/EnforceABI.cpp index 9061be3d6..64b9d4f00 100644 --- a/lib/FunctionIsolation/EnforceABI.cpp +++ b/lib/FunctionIsolation/EnforceABI.cpp @@ -132,9 +132,9 @@ void EnforceABIImpl::run() { // Recreate dynamic functions with arguments for (const model::DynamicFunction &FunctionModel : - Binary.ImportedDynamicFunctions) { + Binary.ImportedDynamicFunctions()) { // TODO: have an API to go from model to llvm::Function - auto OldFunctionName = (Twine("dynamic_") + FunctionModel.OriginalName) + auto OldFunctionName = (Twine("dynamic_") + FunctionModel.OriginalName()) .str(); Function *OldFunction = M.getFunction(OldFunctionName); if (not OldFunction or OldFunction->isDeclaration()) @@ -157,7 +157,7 @@ void EnforceABIImpl::run() { } // Recreate isolated functions with arguments - for (const model::Function &FunctionModel : Binary.Functions) { + for (const model::Function &FunctionModel : Binary.Functions()) { revng_assert(not FunctionModel.name().empty()); auto OldFunctionName = (Twine("local_") + FunctionModel.name()).str(); Function *OldFunction = M.getFunction(OldFunctionName); @@ -338,7 +338,7 @@ void EnforceABIImpl::handleRegularFunctionCall(CallInst *Call) { // Find the CallEdge const efa::CallEdge *CallSite = nullptr; - for (const auto &Edge : CallerBlock->Successors) { + for (const auto &Edge : CallerBlock->Successors()) { using namespace efa::FunctionEdgeType; CallSite = dyn_cast(Edge.get()); if (CallSite != nullptr) @@ -369,14 +369,14 @@ void EnforceABIImpl::handleRegularFunctionCall(CallInst *Call) { // Generate the call IRBuilder<> Builder(Call); CallInst *NewCall = generateCall(Builder, - FunctionModel.Entry, + FunctionModel.Entry(), Callee, *CallerBlock, *CallSite); NewCall->copyMetadata(*Call); // Set PC to the expected value - GCBI.programCounterHandler()->setPC(Builder, CallerBlock->Start); + GCBI.programCounterHandler()->setPC(Builder, CallerBlock->Start()); // Drop the original call eraseFromParent(Call); @@ -407,7 +407,7 @@ CallInst *EnforceABIImpl::generateCall(IRBuilder<> &Builder, model::TypePath PrototypePath = getPrototype(Binary, Entry, - CallSiteBlock.Start, + CallSiteBlock.Start(), CallSite); auto Prototype = abi::FunctionType::Layout::make(PrototypePath); revng_assert(Prototype.verify()); @@ -442,7 +442,7 @@ CallInst *EnforceABIImpl::generateCall(IRBuilder<> &Builder, auto *Result = Builder.CreateCall(Callee, Arguments); GCBI.setMetaAddressMetadata(Result, CallerBlockStartMDName, - CallSiteBlock.Start); + CallSiteBlock.Start()); if (ReturnCSVs.size() != 1) { unsigned I = 0; for (Constant *ReturnCSV : ReturnCSVs) { diff --git a/lib/FunctionIsolation/InvokeIsolatedFunctions.cpp b/lib/FunctionIsolation/InvokeIsolatedFunctions.cpp index 66242a455..31e126726 100644 --- a/lib/FunctionIsolation/InvokeIsolatedFunctions.cpp +++ b/lib/FunctionIsolation/InvokeIsolatedFunctions.cpp @@ -63,12 +63,12 @@ public: Context(M->getContext()), GCBI(GCBI) { - for (const model::Function &Function : Binary.Functions) { + for (const model::Function &Function : Binary.Functions()) { // TODO: this temporary auto Name = (Twine("local_") + Function.name()).str(); llvm::Function *F = M->getFunction(Name); revng_assert(F != nullptr); - Map[Function.Entry] = { &Function, nullptr, F }; + Map[Function.Entry()] = { &Function, nullptr, F }; } for (BasicBlock &BB : *RootFunction) { @@ -154,7 +154,7 @@ public: RootFunction->setPersonalityFn(PersonalityFunction); for (auto [_, T] : Map) { - auto [ModelFunction, BB, F] = T; + auto [ModelF, BB, F] = T; // Create a new trampoline entry block and substitute it to the old entry // block @@ -167,7 +167,7 @@ public: // In case the isolated functions has arguments, provide them SmallVector Arguments; if (F->getFunctionType()->getNumParams() > 0) { - auto Layout = abi::FunctionType::Layout::make(ModelFunction->Prototype); + auto Layout = abi::FunctionType::Layout::make(ModelF->Prototype()); for (const auto &ArgumentLayout : Layout.Arguments) { for (model::Register::Values Register : ArgumentLayout.Registers) { auto Name = model::Register::getCSVName(Register); diff --git a/lib/FunctionIsolation/IsolateFunctions.cpp b/lib/FunctionIsolation/IsolateFunctions.cpp index af2f4406b..c7f262b92 100644 --- a/lib/FunctionIsolation/IsolateFunctions.cpp +++ b/lib/FunctionIsolation/IsolateFunctions.cpp @@ -433,7 +433,7 @@ private: else return dyn_cast(Result->get()); }; - const auto *CallEdge = ZeroOrOneCallEdge(Caller->Successors, IsCallEdge); + const auto *CallEdge = ZeroOrOneCallEdge(Caller->Successors(), IsCallEdge); if (CallEdge == nullptr) { // There's no CallEdge, this is likely a LongJmp @@ -441,8 +441,8 @@ private: } StringRef SymbolName = extractFromConstantStringPtr(SymbolNamePointer); - revng_assert(SymbolName == CallEdge->DynamicFunction); - revng_assert(Callee == CallEdge->Destination); + revng_assert(SymbolName == CallEdge->DynamicFunction()); + revng_assert(Callee == CallEdge->Destination()); // Identify callee Function *CalledFunction = nullptr; @@ -466,7 +466,7 @@ private: FunctionTags::CallToLifted.addTo(NewCall); IFI.gcbi().setMetaAddressMetadata(NewCall, CallerBlockStartMDName, - Caller->Start); + Caller->Start()); } }; @@ -532,11 +532,11 @@ void IsolateFunctionsImpl::run() { // Create the dynamic functions // for (const model::DynamicFunction &Function : - Binary.ImportedDynamicFunctions) { - StringRef Name = Function.OriginalName; + Binary.ImportedDynamicFunctions()) { + StringRef Name = Function.OriginalName(); auto *NewFunction = Function::Create(IsolatedFunctionType, GlobalValue::ExternalLinkage, - "dynamic_" + Function.OriginalName, + "dynamic_" + Function.OriginalName(), TheModule); FunctionTags::DynamicFunction.addTo(NewFunction); @@ -567,21 +567,21 @@ void IsolateFunctionsImpl::run() { // // Precreate the isolated functions // - for (const model::Function &Function : Binary.Functions) { + for (const model::Function &Function : Binary.Functions()) { auto *NewFunction = Function::Create(IsolatedFunctionType, GlobalValue::ExternalLinkage, "local_" + Function.name(), TheModule); NewFunction->addFnAttr(Attribute::NullPointerIsValid); - IsolatedFunctionsMap[Function.Entry] = NewFunction; + IsolatedFunctionsMap[Function.Entry()] = NewFunction; FunctionTags::Isolated.addTo(NewFunction); revng_assert(NewFunction != nullptr); GCBI.setMetaAddressMetadata(NewFunction, FunctionEntryMDNName, - Function.Entry); + Function.Entry()); - auto *OriginalEntryTerm = GCBI.getBlockAt(Function.Entry)->getTerminator(); - auto *MDNode = OriginalEntryTerm->getMetadata(FunctionMetadataMDName); + auto *OriginalEntry = GCBI.getBlockAt(Function.Entry())->getTerminator(); + auto *MDNode = OriginalEntry->getMetadata(FunctionMetadataMDName); NewFunction->setMetadata(FunctionMetadataMDName, MDNode); } @@ -626,14 +626,14 @@ void IsolateFunctionsImpl::run() { } bool AtLeastAMatch = false; - for (auto &Edge : Block->Successors) { - if (Edge->Type == efa::FunctionEdgeType::DirectBranch) + for (auto &Edge : Block->Successors()) { + if (Edge->Type() == efa::FunctionEdgeType::DirectBranch) continue; revng_assert(not AtLeastAMatch); AtLeastAMatch = true; - switch (Edge->Type) { + switch (Edge->Type()) { case efa::FunctionEdgeType::Return: Builder.CreateRetVoid(); break; @@ -658,7 +658,7 @@ void IsolateFunctionsImpl::run() { break; case efa::FunctionEdgeType::FunctionCall: { auto *Call = cast(Edge.get()); - revng_assert(Call->IsTailCall); + revng_assert(Call->IsTailCall()); Builder.CreateRetVoid(); } break; case efa::FunctionEdgeType::Invalid: diff --git a/lib/Lift/CodeGenerator.cpp b/lib/Lift/CodeGenerator.cpp index c0e6959e9..7dff1612c 100644 --- a/lib/Lift/CodeGenerator.cpp +++ b/lib/Lift/CodeGenerator.cpp @@ -191,17 +191,17 @@ CodeGenerator::CodeGenerator(const RawBinaryView &RawBinary, for (auto &[Segment, Data] : RawBinary.segments()) { // If it's executable register it as a valid code area - if (Segment.IsExecutable) { + if (Segment.IsExecutable()) { // We ignore possible p_filesz-p_memsz mismatches, zeros wouldn't be // useful code anyway - size_t Size = Segment.FileSize; - bool Success = ptc.mmap(Segment.StartAddress.address(), + size_t Size = Segment.FileSize(); + bool Success = ptc.mmap(Segment.StartAddress().address(), static_cast(Data.data()), Size); if (not Success) { revng_log(Log, "Couldn't mmap segment starting at " - << Segment.StartAddress.toString() << " with size 0x" + << Segment.StartAddress().toString() << " with size 0x" << Size); continue; } @@ -209,8 +209,8 @@ CodeGenerator::CodeGenerator(const RawBinaryView &RawBinary, bool Found = false; MetaAddress End = Segment.pagesRange().second; revng_assert(End.isValid() and End.address() % 4096 == 0); - for (const model::Segment &Segment : Model->Segments) { - if (Segment.IsExecutable and Segment.contains(End)) { + for (const model::Segment &Segment : Model->Segments()) { + if (Segment.IsExecutable() and Segment.contains(End)) { Found = true; break; } @@ -221,7 +221,7 @@ CodeGenerator::CodeGenerator(const RawBinaryView &RawBinary, revng_check(Segment.endAddress().address() != 0); NoMoreCodeBoundaries.insert(Segment.endAddress()); using namespace model::Architecture; - auto Architecture = Model->Architecture; + auto Architecture = Model->Architecture(); auto BasicBlockEndingPattern = getBasicBlockEndingPattern(Architecture); ptc.mmap(End.address(), BasicBlockEndingPattern.data(), @@ -725,7 +725,7 @@ void CodeGenerator::translate(Optional RawVirtualAddress) { // // Create well-known CSVs // - auto SP = model::Architecture::getStackPointer(Model->Architecture); + auto SP = model::Architecture::getStackPointer(Model->Architecture()); std::string SPName = model::Register::getCSVName(SP).str(); GlobalVariable *SPReg = Variables.getByEnvOffset(ptc.sp, SPName).first; @@ -750,7 +750,7 @@ void CodeGenerator::translate(Optional RawVirtualAddress) { return Variables.getByEnvOffset(Offset, Name.str()).first; }; - auto Architecture = toLLVMArchitecture(Model->Architecture); + auto Architecture = toLLVMArchitecture(Model->Architecture()); PCHOwner PCH = ProgramCounterHandler::create(Architecture, TheModule, Factory); @@ -804,7 +804,7 @@ void CodeGenerator::translate(Optional RawVirtualAddress) { VirtualAddress = JumpTargets.fromPC(*RawVirtualAddress); } else { JumpTargets.harvestGlobalData(); - VirtualAddress = Model->EntryPoint; + VirtualAddress = Model->EntryPoint(); revng_assert(VirtualAddress.isCode()); } @@ -831,7 +831,7 @@ void CodeGenerator::translate(Optional RawVirtualAddress) { bool EndianessMismatch; { using namespace model::Architecture; - bool SourceIsLittleEndian = isLittleEndian(Model->Architecture); + bool SourceIsLittleEndian = isLittleEndian(Model->Architecture()); EndianessMismatch = TargetIsLittleEndian != SourceIsLittleEndian; } diff --git a/lib/Lift/ExternalJumpsHandler.cpp b/lib/Lift/ExternalJumpsHandler.cpp index 441ed73e0..67c29f133 100644 --- a/lib/Lift/ExternalJumpsHandler.cpp +++ b/lib/Lift/ExternalJumpsHandler.cpp @@ -51,14 +51,15 @@ BasicBlock *ExternalJumpsHandler::createReturnFromExternal() { // completely broken using namespace model::Architecture; using namespace model::Register; - unsigned PCMContextIndex = getPCMContextIndex(Model.Architecture).value_or(0); + unsigned PCMContextIndex = getPCMContextIndex(Model.Architecture()) + .value_or(0); Value *GEP = Builder.CreateGEP(SavedRegisters, Builder.getInt32(PCMContextIndex)); LoadInst *PCAddress = Builder.CreateLoad(GEP); PCH->deserializePCFromSignalContext(Builder, PCAddress, SavedRegisters); // Deserialize the ABI registers - for (auto Register : registers(Model.Architecture)) { + for (auto Register : registers(Model.Architecture())) { auto Name = getCSVName(Register); GlobalVariable *CSV = TheModule.getGlobalVariable(Name); @@ -75,7 +76,7 @@ BasicBlock *ExternalJumpsHandler::createReturnFromExternal() { } else { - auto AsmString = getReadRegisterAssembly(Model.Architecture).str(); + auto AsmString = getReadRegisterAssembly(Model.Architecture()).str(); replace(AsmString, "REGISTER", getRegisterName(Register).str()); std::stringstream ConstraintStringStream; ConstraintStringStream << "*m,~{},~{dirflag},~{fpsr},~{flags}"; @@ -127,7 +128,7 @@ BasicBlock *ExternalJumpsHandler::createSerializeAndJumpOut() { Builder.CreateStore(PC, JumpablePC); // Serialize ABI CSVs - for (model::Register::Values Register : registers(Model.Architecture)) { + for (model::Register::Values Register : registers(Model.Architecture())) { using namespace model::Architecture; using namespace model::Register; GlobalVariable *CSV = TheModule.getGlobalVariable(getCSVName(Register)); @@ -136,7 +137,8 @@ BasicBlock *ExternalJumpsHandler::createSerializeAndJumpOut() { if (CSV == nullptr) continue; - std::string AsmString = getWriteRegisterAssembly(Model.Architecture).str(); + std::string AsmString = getWriteRegisterAssembly(Model.Architecture()) + .str(); StringRef RegisterName = getRegisterName(Register); replace(AsmString, "REGISTER", RegisterName); std::stringstream ConstraintStringStream; @@ -159,7 +161,7 @@ BasicBlock *ExternalJumpsHandler::createSerializeAndJumpOut() { { JumpablePC->getType() }, false); InlineAsm *Asm = InlineAsm::get(FT, - getJumpAssembly(Model.Architecture), + getJumpAssembly(Model.Architecture()), "*m,~{dirflag},~{fpsr},~{flags}", true, InlineAsm::AsmDialect::AD_ATT); @@ -201,9 +203,9 @@ void ExternalJumpsHandler::buildExecutableSegmentsList() { IntegerType *Int64 = Builder.getInt64Ty(); SmallVector ExecutableSegments; auto Int = [Int64](uint64_t V) { return ConstantInt::get(Int64, V); }; - for (auto &Segment : Model.Segments) { - if (Segment.IsExecutable) { - ExecutableSegments.push_back(Int(Segment.StartAddress.address())); + for (auto &Segment : Model.Segments()) { + if (Segment.IsExecutable()) { + ExecutableSegments.push_back(Int(Segment.StartAddress().address())); ExecutableSegments.push_back(Int(Segment.endAddress().address())); } } @@ -238,9 +240,9 @@ void ExternalJumpsHandler::buildExecutableSegmentsList() { } void ExternalJumpsHandler::createExternalJumpsHandler() { - auto JumpAssembly = model::Architecture::getJumpAssembly(Model.Architecture); + auto Assembly = model::Architecture::getJumpAssembly(Model.Architecture()); - if (JumpAssembly.size() == 0) { + if (Assembly.size() == 0) { buildExecutableSegmentsList(); return; } diff --git a/lib/Lift/JumpTargetManager.cpp b/lib/Lift/JumpTargetManager.cpp index 5093b96fa..3ef3d172e 100644 --- a/lib/Lift/JumpTargetManager.cpp +++ b/lib/Lift/JumpTargetManager.cpp @@ -434,25 +434,25 @@ JumpTargetManager::readFromPointer(Constant *Pointer, bool IsLittleEndian) { // Check dynamic functions-related relocations for (const model::DynamicFunction &Function : - Model->ImportedDynamicFunctions) { - for (const model::Relocation &Relocation : Function.Relocations) { - uint64_t Addend = Relocation.Addend; - auto RelocationSize = model::RelocationType::getSize(Relocation.Type); - if (LoadAddress == Relocation.Address and LoadSize == RelocationSize) { + Model->ImportedDynamicFunctions()) { + for (const model::Relocation &Relocation : Function.Relocations()) { + uint64_t Addend = Relocation.Addend(); + auto RelocationSize = model::RelocationType::getSize(Relocation.Type()); + if (LoadAddress == Relocation.Address() and LoadSize == RelocationSize) { revng_assert(not StringRef(Function.name()).contains('\0')); - Result = { Function.OriginalName, NewAPInt(Addend) }; + Result = { Function.OriginalName(), NewAPInt(Addend) }; ++MatchCount; } } } // Check segment-related relocations - for (const model::Segment &Segment : Model->Segments) { - for (const model::Relocation &Relocation : Segment.Relocations) { - uint64_t Addend = Relocation.Addend; - auto RelocationSize = model::RelocationType::getSize(Relocation.Type); - if (LoadAddress == Relocation.Address and LoadSize == RelocationSize) { - MetaAddress Address = Segment.StartAddress + Addend; + for (const model::Segment &Segment : Model->Segments()) { + for (const model::Relocation &Relocation : Segment.Relocations()) { + uint64_t Addend = Relocation.Addend(); + auto RelocationSize = model::RelocationType::getSize(Relocation.Type()); + if (LoadAddress == Relocation.Address() and LoadSize == RelocationSize) { + MetaAddress Address = Segment.StartAddress() + Addend; if (Address.isValid()) { Result = { NewAPInt(Address.address()) }; ++MatchCount; @@ -511,17 +511,17 @@ JumpTargetManager::JumpTargetManager(Function *TheFunction, // // Collect executable ranges from the model // - for (const model::Segment &Segment : Model->Segments) { - if (Segment.IsExecutable) { - if (Segment.Sections.size() > 0) { - for (const model::Section &Section : Segment.Sections) { - if (Section.ContainsCode) { - ExecutableRanges.emplace_back(Section.StartAddress, + for (const model::Segment &Segment : Model->Segments()) { + if (Segment.IsExecutable()) { + if (Segment.Sections().size() > 0) { + for (const model::Section &Section : Segment.Sections()) { + if (Section.ContainsCode()) { + ExecutableRanges.emplace_back(Section.StartAddress(), Section.endAddress()); } } } else { - ExecutableRanges.emplace_back(Segment.StartAddress, + ExecutableRanges.emplace_back(Segment.StartAddress(), Segment.endAddress()); } } @@ -537,21 +537,21 @@ JumpTargetManager::JumpTargetManager(Function *TheFunction, void JumpTargetManager::harvestGlobalData() { // Register symbols - for (const model::Function &Function : Model->Functions) - registerJT(Function.Entry, JTReason::FunctionSymbol); + for (const model::Function &Function : Model->Functions()) + registerJT(Function.Entry(), JTReason::FunctionSymbol); // Register ExtraCodeAddresses - for (MetaAddress Address : Model->ExtraCodeAddresses) + for (MetaAddress Address : Model->ExtraCodeAddresses()) registerJT(Address, JTReason::GlobalData); for (auto &[Segment, Data] : BinaryView.segments()) { - MetaAddress StartVirtualAddress = Segment.StartAddress; + MetaAddress StartVirtualAddress = Segment.StartAddress(); const unsigned char *DataStart = Data.begin(); const unsigned char *DataEnd = Data.end(); using namespace model::Architecture; - bool IsLittleEndian = isLittleEndian(Model->Architecture); - auto PointerSize = getPointerSize(Model->Architecture); + bool IsLittleEndian = isLittleEndian(Model->Architecture()); + auto PointerSize = getPointerSize(Model->Architecture()); using endianness = support::endianness; if (PointerSize == 8) { if (IsLittleEndian) @@ -1507,13 +1507,14 @@ void JumpTargetManager::harvestWithAVI() { revng_assert(BB->getTerminator() != nullptr); Builder.SetInsertPoint(BB->getFirstNonPHI()); - for (const model::Segment &Segment : Model->Segments) { + for (const model::Segment &Segment : Model->Segments()) { if (Segment.contains(getBasicBlockPC(BB))) { - for (const auto &CanonicalValue : Segment.CanonicalRegisterValues) { - auto Name = model::Register::getCSVName(CanonicalValue.Register); + for (const auto &CanonicalValue : Segment.CanonicalRegisterValues()) { + auto Name = model::Register::getCSVName(CanonicalValue.Register()); if (auto *CSV = M->getGlobalVariable(Name)) { auto *Type = getCSVType(CSV); - Builder.CreateStore(ConstantInt::get(Type, CanonicalValue.Value), + Builder.CreateStore(ConstantInt::get(Type, + CanonicalValue.Value()), CSV); } } @@ -1701,9 +1702,9 @@ void JumpTargetManager::harvestWithAVI() { using namespace model::Architecture; using namespace model::Register; - StringRef SyscallHelperName = getSyscallHelper(Model->Architecture); + StringRef SyscallHelperName = getSyscallHelper(Model->Architecture()); Function *SyscallHelper = M->getFunction(SyscallHelperName); - auto SyscallIDRegister = getSyscallNumberRegister(Model->Architecture); + auto SyscallIDRegister = getSyscallNumberRegister(Model->Architecture()); StringRef SyscallIDCSVName = getName(SyscallIDRegister); GlobalVariable *SyscallIDCSV = M->getGlobalVariable(SyscallIDCSVName); diff --git a/lib/Lift/JumpTargetManager.h b/lib/Lift/JumpTargetManager.h index acd8cb123..91f22c6df 100644 --- a/lib/Lift/JumpTargetManager.h +++ b/lib/Lift/JumpTargetManager.h @@ -417,7 +417,7 @@ public: translateIndirectJumps(); using namespace model::Architecture; - unsigned ReadSize = getPointerSize(Model->Architecture); + unsigned ReadSize = getPointerSize(Model->Architecture()); for (MetaAddress MemoryAddress : UnusedCodePointers) { // Read using the original endianess, we want the correct address auto MaybeRawPC = BinaryView.readInteger(MemoryAddress, ReadSize); @@ -442,13 +442,13 @@ public: MetaAddress fromPC(uint64_t PC) const { using namespace model::Architecture; - auto Architecture = toLLVMArchitecture(Model->Architecture); + auto Architecture = toLLVMArchitecture(Model->Architecture()); return MetaAddress::fromPC(Architecture, PC); } MetaAddress fromGeneric(uint64_t Address) const { using namespace model::Architecture; - auto Architecture = toLLVMArchitecture(Model->Architecture); + auto Architecture = toLLVMArchitecture(Model->Architecture()); return MetaAddress::fromGeneric(Architecture, Address); } diff --git a/lib/Lift/Lift.cpp b/lib/Lift/Lift.cpp index 15b44f62c..8ca20a639 100644 --- a/lib/Lift/Lift.cpp +++ b/lib/Lift/Lift.cpp @@ -116,7 +116,7 @@ bool LiftPass::runOnModule(llvm::Module &M) { const auto &ModelWrapper = getAnalysis().get(); const TupleTree &Model = ModelWrapper.getReadOnlyModel(); - findFiles(Model->Architecture); + findFiles(Model->Architecture()); // Load the appropriate libtyncode version LibraryPointer PTCLibrary; diff --git a/lib/Lift/LiftPipe.cpp b/lib/Lift/LiftPipe.cpp index 80914044a..9f8f7710e 100644 --- a/lib/Lift/LiftPipe.cpp +++ b/lib/Lift/LiftPipe.cpp @@ -49,7 +49,7 @@ void Lift::run(Context &Ctx, llvm::Error Lift::checkPrecondition(const pipeline::Context &Ctx) const { const auto &Model = *getModelFromContext(Ctx); - if (Model.Architecture == model::Architecture::Invalid) { + if (Model.Architecture() == model::Architecture::Invalid) { return llvm::createStringError(inconvertibleErrorCode(), "Cannot lift binary with architecture " "invalid."); diff --git a/lib/Lift/LinkSupportPipe.cpp b/lib/Lift/LinkSupportPipe.cpp index e9660b702..b3f342b76 100644 --- a/lib/Lift/LinkSupportPipe.cpp +++ b/lib/Lift/LinkSupportPipe.cpp @@ -62,7 +62,7 @@ static std::string getSupportPath(const Context &Ctx) { const auto &Model = getModelFromContext(Ctx); const char *SupportConfig = Tracing ? "trace" : "normal"; - auto ArchName = getSupportName(Model->Architecture).str(); + auto ArchName = getSupportName(Model->Architecture()).str(); std::string SupportSearchPath = ("/share/revng/support-" + ArchName + "-" + SupportConfig + ".ll"); diff --git a/lib/Model/Binary.cpp b/lib/Model/Binary.cpp index 9d7f59728..c3f4e180b 100644 --- a/lib/Model/Binary.cpp +++ b/lib/Model/Binary.cpp @@ -24,13 +24,13 @@ namespace model { model::TypePath Binary::getPrimitiveType(PrimitiveTypeKind::Values V, uint8_t ByteSize) { PrimitiveType Temporary(V, ByteSize); - Type::Key PrimitiveKey{ TypeKind::PrimitiveType, Temporary.ID }; - auto It = Types.find(PrimitiveKey); + Type::Key PrimitiveKey{ TypeKind::PrimitiveType, Temporary.ID() }; + auto It = Types().find(PrimitiveKey); // If we couldn't find it, create it - if (It == Types.end()) { + if (It == Types().end()) { auto *NewPrimitiveType = new PrimitiveType(V, ByteSize); - It = Types.insert(UpcastablePointer(NewPrimitiveType)).first; + It = Types().insert(UpcastablePointer(NewPrimitiveType)).first; } return getTypePath(It->get()); @@ -39,12 +39,12 @@ Binary::getPrimitiveType(PrimitiveTypeKind::Values V, uint8_t ByteSize) { model::TypePath Binary::getPrimitiveType(PrimitiveTypeKind::Values V, uint8_t ByteSize) const { PrimitiveType Temporary(V, ByteSize); - Type::Key PrimitiveKey{ TypeKind::PrimitiveType, Temporary.ID }; - return getTypePath(Types.at(PrimitiveKey).get()); + Type::Key PrimitiveKey{ TypeKind::PrimitiveType, Temporary.ID() }; + return getTypePath(Types().at(PrimitiveKey).get()); } TypePath Binary::recordNewType(UpcastablePointer &&T) { - auto It = Types.insert(T).first; + auto It = Types().insert(T).first; return getTypePath(It->get()); } @@ -60,7 +60,7 @@ bool Binary::verifyTypes(bool Assert) const { bool Binary::verifyTypes(VerifyHelper &VH) const { // All types on their own should verify std::set Names; - for (auto &Type : Types) { + for (auto &Type : Types()) { // Verify the type if (not Type.get()->verify(VH)) return VH.fail(); @@ -125,40 +125,40 @@ bool Binary::verify(VerifyHelper &VH) const { *this); }; - for (const Function &F : Functions) { + for (const Function &F : Functions()) { // Verify individual functions if (not F.verify(VH)) return VH.fail(); - if (not CheckCustomName(F.CustomName)) + if (not CheckCustomName(F.CustomName())) return VH.fail("Duplicate name", F); } // Verify DynamicFunctions - for (const DynamicFunction &DF : ImportedDynamicFunctions) { + for (const DynamicFunction &DF : ImportedDynamicFunctions()) { if (not DF.verify(VH)) return VH.fail(); - if (not CheckCustomName(DF.CustomName)) + if (not CheckCustomName(DF.CustomName())) return VH.fail(); } - for (auto &Type : Types) { - if (not CheckCustomName(Type->CustomName)) + for (auto &Type : Types()) { + if (not CheckCustomName(Type->CustomName())) return VH.fail(); if (auto *Enum = dyn_cast(Type.get())) - for (auto &Entry : Enum->Entries) - if (not CheckCustomName(Entry.CustomName)) + for (auto &Entry : Enum->Entries()) + if (not CheckCustomName(Entry.CustomName())) return VH.fail(); } // Verify Segments - for (const Segment &S : Segments) { + for (const Segment &S : Segments()) { if (not S.verify(VH)) return VH.fail(); - if (not CheckCustomName(S.CustomName)) + if (not CheckCustomName(S.CustomName())) return VH.fail(); } @@ -170,10 +170,10 @@ bool Binary::verify(VerifyHelper &VH) const { Identifier Function::name() const { using llvm::Twine; - if (not CustomName.empty()) { - return CustomName; + if (not CustomName().empty()) { + return CustomName(); } else { - auto AutomaticName = (Twine("function_") + Entry.toString()).str(); + auto AutomaticName = (Twine("function_") + Entry().toString()).str(); return Identifier::fromString(AutomaticName); } } @@ -188,22 +188,22 @@ prototypeOr(const model::TypePath &Prototype, const model::TypePath &Default) { } const model::TypePath &Function::prototype(const model::Binary &Root) const { - return prototypeOr(Prototype, Root.DefaultPrototype); + return prototypeOr(Prototype(), Root.DefaultPrototype()); } Identifier DynamicFunction::name() const { using llvm::Twine; - if (not CustomName.empty()) { - return CustomName; + if (not CustomName().empty()) { + return CustomName(); } else { - auto AutomaticName = (Twine("dynamic_function_") + OriginalName).str(); + auto AutomaticName = (Twine("dynamic_function_") + OriginalName()).str(); return Identifier::fromString(AutomaticName); } } const model::TypePath & DynamicFunction::prototype(const model::Binary &Root) const { - return prototypeOr(Prototype, Root.DefaultPrototype); + return prototypeOr(Prototype(), Root.DefaultPrototype()); } bool Relocation::verify() const { @@ -216,7 +216,7 @@ bool Relocation::verify(bool Assert) const { } bool Relocation::verify(VerifyHelper &VH) const { - if (Type == model::RelocationType::Invalid) + if (Type() == model::RelocationType::Invalid) return VH.fail("Invalid relocation", *this); return true; @@ -232,7 +232,7 @@ bool Section::verify(bool Assert) const { } bool Section::verify(VerifyHelper &VH) const { - auto EndAddress = StartAddress + Size; + auto EndAddress = StartAddress() + Size(); if (not EndAddress.isValid()) return VH.fail("Computing the end address leads to overflow"); @@ -241,11 +241,11 @@ bool Section::verify(VerifyHelper &VH) const { Identifier Segment::name() const { using llvm::Twine; - if (not CustomName.empty()) { - return CustomName; + if (not CustomName().empty()) { + return CustomName(); } else { - auto AutomaticName = (Twine("segment_") + StartAddress.toString() + "_" - + Twine(VirtualSize)) + auto AutomaticName = (Twine("segment_") + StartAddress().toString() + "_" + + Twine(VirtualSize())) .str(); return Identifier::fromString(AutomaticName); } @@ -263,35 +263,35 @@ bool Segment::verify(bool Assert) const { bool Segment::verify(VerifyHelper &VH) const { using OverflowSafeInt = OverflowSafeInt; - if (FileSize > VirtualSize) + if (FileSize() > VirtualSize()) return VH.fail("FileSize cannot be larger thatn VirtualSize", *this); - auto EndOffset = OverflowSafeInt(StartOffset) + FileSize; + auto EndOffset = OverflowSafeInt(StartOffset()) + FileSize(); if (not EndOffset) return VH.fail("Computing the segment end offset leads to overflow", *this); - auto EndAddress = StartAddress + VirtualSize; + auto EndAddress = StartAddress() + VirtualSize(); if (not EndAddress.isValid()) return VH.fail("Computing the end address leads to overflow", *this); - for (const model::Section &Section : Sections) { + for (const model::Section &Section : Sections()) { if (not Section.verify(VH)) return VH.fail("Invalid section", Section); - if (not contains(Section.StartAddress) - or (VirtualSize > 0 and not contains(Section.endAddress() - 1))) { + if (not contains(Section.StartAddress()) + or (VirtualSize() > 0 and not contains(Section.endAddress() - 1))) { return VH.fail("The segment contains a section out of its boundaries", Section); } - if (Section.ContainsCode and not IsExecutable) { + if (Section.ContainsCode() and not IsExecutable()) { return VH.fail("A Section is marked as containing code but the " "containing segment is not executable", *this); } } - for (const model::Relocation &Relocation : Relocations) { + for (const model::Relocation &Relocation : Relocations()) { if (not Relocation.verify(VH)) return VH.fail("Invalid relocation", Relocation); } @@ -323,12 +323,12 @@ bool Function::verify(bool Assert) const { } bool Function::verify(VerifyHelper &VH) const { - if (Prototype.isValid()) { + if (Prototype().isValid()) { // The function has a prototype - if (not Prototype.get()->verify(VH)) + if (not Prototype().get()->verify(VH)) return VH.fail("Function prototype does not verify", *this); - const model::Type *FunctionType = Prototype.get(); + const model::Type *FunctionType = Prototype().get(); if (not(isa(FunctionType) or isa(FunctionType))) { return VH.fail("Function prototype is not a RawFunctionType or " @@ -337,7 +337,7 @@ bool Function::verify(VerifyHelper &VH) const { } } - for (auto &CallSitePrototype : CallSitePrototypes) + for (auto &CallSitePrototype : CallSitePrototypes()) if (not CallSitePrototype.verify(VH)) return VH.fail(); @@ -359,15 +359,15 @@ bool DynamicFunction::verify(bool Assert) const { bool DynamicFunction::verify(VerifyHelper &VH) const { // Ensure we have a name - if (OriginalName.size() == 0) + if (OriginalName().size() == 0) return VH.fail("Dynamic functions must have a OriginalName", *this); // Prototype is valid - if (Prototype.isValid()) { - if (not Prototype.get()->verify(VH)) + if (Prototype().isValid()) { + if (not Prototype().get()->verify(VH)) return VH.fail(); - const model::Type *FunctionType = Prototype.get(); + const model::Type *FunctionType = Prototype().get(); if (not(isa(FunctionType) or isa(FunctionType))) { return VH.fail("The prototype is neither a RawFunctionType nor a " @@ -394,11 +394,11 @@ bool CallSitePrototype::verify(bool Assert) const { bool CallSitePrototype::verify(VerifyHelper &VH) const { // Prototype is present - if (not Prototype.isValid()) + if (not Prototype().isValid()) return VH.fail("Invalid prototype", *this); // Prototype is valid - if (not Prototype.get()->verify(VH)) + if (not Prototype().get()->verify(VH)) return VH.fail(); return true; diff --git a/lib/Model/Importer/Binary/BinaryImporter.cpp b/lib/Model/Importer/Binary/BinaryImporter.cpp index 3915cf1a4..33e3f6352 100644 --- a/lib/Model/Importer/Binary/BinaryImporter.cpp +++ b/lib/Model/Importer/Binary/BinaryImporter.cpp @@ -21,9 +21,9 @@ Error importBinary(TupleTree &Model, uint64_t PreferredBaseAddress) { using namespace llvm::object; using namespace model::Architecture; - Model->Architecture = fromLLVMArchitecture(ObjectFile.getArch()); + Model->Architecture() = fromLLVMArchitecture(ObjectFile.getArch()); - if (Model->Architecture == model::Architecture::Invalid) + if (Model->Architecture() == model::Architecture::Invalid) return createError("Invalid architecture"); if (auto *TheBinary = dyn_cast(&ObjectFile)) { diff --git a/lib/Model/Importer/Binary/ELFImporter.cpp b/lib/Model/Importer/Binary/ELFImporter.cpp index a7e1cf9ef..6c5b1cebc 100644 --- a/lib/Model/Importer/Binary/ELFImporter.cpp +++ b/lib/Model/Importer/Binary/ELFImporter.cpp @@ -161,11 +161,11 @@ Error ELFImporter::import() { return TheELFOrErr.takeError(); object::ELFFile &TheELF = *TheELFOrErr; - revng_assert(Model->Architecture != model::Architecture::Invalid); - Architecture = Model->Architecture; + revng_assert(Model->Architecture() != model::Architecture::Invalid); + Architecture = Model->Architecture(); // Set default ABI - Model->DefaultABI = model::ABI::getDefault(Model->Architecture); + Model->DefaultABI() = model::ABI::getDefault(Model->Architecture()); // BaseAddress makes sense only for shared (relocatable, PIC) objects auto Type = TheELF.getHeader().e_type; @@ -216,7 +216,7 @@ Error ELFImporter::import() { parseSymbols(TheELF, SymtabShdr); const auto &ElfHeader = TheELF.getHeader(); - Model->EntryPoint = relocate(fromPC(ElfHeader.e_entry)); + Model->EntryPoint() = relocate(fromPC(ElfHeader.e_entry)); parseProgramHeaders(TheELF); @@ -251,7 +251,7 @@ Error ELFImporter::import() { ReldynPortion = std::make_unique(File); RelpltPortion = std::make_unique(File); GotPortion = std::make_unique(File); - bool IsX86 = Model->Architecture == model::Architecture::x86; + bool IsX86 = Model->Architecture() == model::Architecture::x86; using Elf_Dyn = const typename object::ELFFile::Elf_Dyn; for (Elf_Dyn &DynamicTag : *DynamicEntries) { @@ -265,7 +265,7 @@ Error ELFImporter::import() { if (DynstrPortion->isAvailable()) { Dynstr = DynstrPortion->extractString(); - auto Inserter = Model->ImportedLibraries.batch_insert(); + auto Inserter = Model->ImportedLibraries().batch_insert(); for (auto Offset : NeededLibraryNameOffsets) { StringRef LibraryName = extractNullTerminatedStringAt(Dynstr, Offset); revng_assert(not endsWith(LibraryName, '\0')); @@ -299,9 +299,9 @@ Error ELFImporter::import() { } auto SetCanonicalValue = [this](model::Register::Values Register, uint64_t Value) { - for (model::Segment &Segment : Model->Segments) - if (Segment.IsExecutable) - Segment.CanonicalRegisterValues[Register].Value = Value; + for (model::Segment &Segment : Model->Segments()) + if (Segment.IsExecutable()) + Segment.CanonicalRegisterValues()[Register].Value() = Value; }; if (IsX86 and GotPortion->isAvailable()) { @@ -321,7 +321,9 @@ Error ELFImporter::import() { } // Create a default prototype - Model->DefaultPrototype = abi::registerDefaultFunctionPrototype(*Model.get()); + + auto &Ptr = *Model.get(); + Model->DefaultPrototype() = abi::registerDefaultFunctionPrototype(Ptr); // Import Dwarf DwarfImporter Importer(Model, PreferredBaseAddress); @@ -436,11 +438,11 @@ void ELFImporter::parseSymbols(object::ELFFile &TheELF, MetaAddress Address = MetaAddress::invalid(); Address = relocate(fromPC(Symbol.st_value)); - auto It = Model->Functions.find(Address); - if (It == Model->Functions.end()) { - model::Function &Function = Model->Functions[Address]; + auto It = Model->Functions().find(Address); + if (It == Model->Functions().end()) { + model::Function &Function = Model->Functions()[Address]; if (MaybeName) - Function.OriginalName = *MaybeName; + Function.OriginalName() = *MaybeName; } } } @@ -491,7 +493,7 @@ void ELFImporter::parseProgramHeaders(ELFFile &TheELF) { model::Segment NewSegment({ Start, ProgramHeader.p_memsz }); - NewSegment.StartOffset = ProgramHeader.p_offset; + NewSegment.StartOffset() = ProgramHeader.p_offset; auto MaybeEndOffset = (OverflowSafeInt(u64(ProgramHeader.p_offset)) + u64(ProgramHeader.p_filesz)); @@ -500,15 +502,15 @@ void ELFImporter::parseProgramHeaders(ELFFile &TheELF) { "Invalid segment found: overflow in computing end offset"); continue; } - NewSegment.FileSize = ProgramHeader.p_filesz; + NewSegment.FileSize() = ProgramHeader.p_filesz; - NewSegment.IsReadable = hasFlag(ProgramHeader.p_flags, ELF::PF_R); - NewSegment.IsWriteable = hasFlag(ProgramHeader.p_flags, ELF::PF_W); - NewSegment.IsExecutable = hasFlag(ProgramHeader.p_flags, ELF::PF_X); + NewSegment.IsReadable() = hasFlag(ProgramHeader.p_flags, ELF::PF_R); + NewSegment.IsWriteable() = hasFlag(ProgramHeader.p_flags, ELF::PF_W); + NewSegment.IsExecutable() = hasFlag(ProgramHeader.p_flags, ELF::PF_X); model::TypePath StructPath = createEmptyStruct(*Model, - NewSegment.VirtualSize); - NewSegment.Type = model::QualifiedType(std::move(StructPath), {}); + NewSegment.VirtualSize()); + NewSegment.Type() = model::QualifiedType(std::move(StructPath), {}); // If it's an executable segment, and we've been asked so, register // which sections actually contain code @@ -517,13 +519,13 @@ void ELFImporter::parseProgramHeaders(ELFFile &TheELF) { logAllUnhandledErrors(std::move(Sections.takeError()), errs(), ""); } else { using Elf_Shdr = const typename object::ELFFile::Elf_Shdr; - auto Inserter = NewSegment.Sections.batch_insert(); + auto Inserter = NewSegment.Sections().batch_insert(); for (Elf_Shdr &SectionHeader : *Sections) { if (not hasFlag(SectionHeader.sh_flags, ELF::SHF_ALLOC)) continue; - bool ContainsCode = (NewSegment.IsExecutable + bool ContainsCode = (NewSegment.IsExecutable() and hasFlag(SectionHeader.sh_flags, ELF::SHF_EXECINSTR)); auto SectionStart = relocate(fromGeneric(SectionHeader.sh_addr)); @@ -536,8 +538,8 @@ void ELFImporter::parseProgramHeaders(ELFFile &TheELF) { model::Section NewSection(SectionStart, SectionHeader.sh_size); if (auto SectionName = TheELF.getSectionName(SectionHeader); SectionName) - NewSection.Name = SectionName->str(); - NewSection.ContainsCode = ContainsCode; + NewSection.Name() = SectionName->str(); + NewSection.ContainsCode() = ContainsCode; NewSection.verify(true); Inserter.insert(std::move(NewSection)); } @@ -546,7 +548,7 @@ void ELFImporter::parseProgramHeaders(ELFFile &TheELF) { NewSegment.verify(true); - Model->Segments.insert(std::move(NewSegment)); + Model->Segments().insert(std::move(NewSegment)); } break; @@ -613,7 +615,7 @@ void ELFImporter::parseDynamicSymbol(Elf_Sym_Impl &Symbol, if (Symbol.st_shndx == ELF::SHN_UNDEF) { if (IsCode) { // Create dynamic function symbol - Model->ImportedDynamicFunctions[Name.str()]; + Model->ImportedDynamicFunctions()[Name.str()]; } else { // TODO: create dynamic global variable } @@ -623,10 +625,10 @@ void ELFImporter::parseDynamicSymbol(Elf_Sym_Impl &Symbol, if (IsCode) { Address = relocate(fromPC(Symbol.st_value)); // TODO: record model::Function::IsDynamic = true - auto It = Model->Functions.find(Address); - if (It == Model->Functions.end()) { - model::Function &Function = Model->Functions[Address]; - Function.OriginalName = Name; + auto It = Model->Functions().find(Address); + if (It == Model->Functions().end()) { + model::Function &Function = Model->Functions()[Address]; + Function.OriginalName() = Name; } } else { Address = relocate(fromGeneric(Symbol.st_value)); @@ -698,7 +700,7 @@ void ELFImporter::parseEHFrame(MetaAddress EHFrameAddress, llvm::ArrayRef EHFrame = *MaybeEHFrame; using namespace model::Architecture; - auto Architecture = toLLVMArchitecture(Model->Architecture); + auto Architecture = toLLVMArchitecture(Model->Architecture()); DwarfReader EHFrameReader(Architecture, EHFrame, EHFrameAddress); @@ -812,7 +814,7 @@ void ELFImporter::parseEHFrame(MetaAddress EHFrameAddress, PersonalityPtr); // Register in the model for exploration - Model->ExtraCodeAddresses.insert(PersonalityPtr); + Model->ExtraCodeAddresses().insert(PersonalityPtr); break; } case 'R': @@ -894,7 +896,7 @@ void ELFImporter::parseLSDA(MetaAddress FDEStart, llvm::ArrayRef LSDA = *MaybeLSDA; using namespace model::Architecture; - auto Architecture = toLLVMArchitecture(Model->Architecture); + auto Architecture = toLLVMArchitecture(Model->Architecture()); DwarfReader LSDAReader(Architecture, LSDA, LSDAAddress); uint32_t LandingPadBaseEncoding = LSDAReader.readNextU8(); @@ -932,7 +934,7 @@ void ELFImporter::parseLSDA(MetaAddress FDEStart, LSDAReader.readULEB128(); if (LandingPad.isValid()) { - auto &ExtraCodeAddresses = Model->ExtraCodeAddresses; + auto &ExtraCodeAddresses = Model->ExtraCodeAddresses(); if (ExtraCodeAddresses.count(LandingPad) == 0) logAddress(ELFImporterLog, "New landing pad found: ", LandingPad); @@ -967,7 +969,7 @@ void ELFImporter::registerRelocations(Elf_Rel_Array Relocations, using Elf_Sym = Elf_Sym_Impl; model::Segment *LowestSegment = nullptr; - if (auto It = Model->Segments.begin(); It != Model->Segments.end()) + if (auto It = Model->Segments().begin(); It != Model->Segments().end()) LowestSegment = &*It; ArrayRef Symbols; @@ -999,7 +1001,7 @@ void ELFImporter::registerRelocations(Elf_Rel_Array Relocations, } using namespace model::RelocationType; - auto RelocationType = fromELFRelocation(Model->Architecture, Type); + auto RelocationType = fromELFRelocation(Model->Architecture(), Type); auto RelocationName = getELFRelocationTypeName(TheBinary.getEMachine(), Type); @@ -1027,9 +1029,9 @@ void ELFImporter::registerRelocations(Elf_Rel_Array Relocations, } else if (HasName) { // Symbol-relative relcation if (SymbolType == ELF::STT_FUNC) { - auto It = Model->ImportedDynamicFunctions.find(SymbolName.str()); - if (It != Model->ImportedDynamicFunctions.end()) { - auto &Relocations = It->Relocations; + auto It = Model->ImportedDynamicFunctions().find(SymbolName.str()); + if (It != Model->ImportedDynamicFunctions().end()) { + auto &Relocations = It->Relocations(); NewRelocation.verify(true); Relocations.insert(NewRelocation); } @@ -1040,7 +1042,7 @@ void ELFImporter::registerRelocations(Elf_Rel_Array Relocations, // Base-relative relocation if (LowestSegment != nullptr) { NewRelocation.verify(true); - LowestSegment->Relocations.insert(NewRelocation); + LowestSegment->Relocations().insert(NewRelocation); } else { revng_log(ELFImporterLog, "Found a base-relative relocation, but no segment is " @@ -1060,8 +1062,8 @@ createELFImporter(TupleTree &M, // In the case of MIPS architecture, we handle some specific import // as a part of a separate derived (from ELFImporter) class. // TODO: Investigate other architectures as well. - bool IsMIPS = (M->Architecture == model::Architecture::mips - or M->Architecture == model::Architecture::mipsel); + bool IsMIPS = (M->Architecture() == model::Architecture::mips + or M->Architecture() == model::Architecture::mipsel); if (PointerSize == 4) { if (IsLittleEndian && HasRelocationAddend && !IsMIPS) { return make_unique>(M, @@ -1141,13 +1143,13 @@ Error importELF(TupleTree &Model, // In the case of MIPS architecture, we handle some specific import // as a part of a separate derived (from ELFImporter) class. // TODO: Investigate other architectures as well. - bool IsMIPS = (Model->Architecture == model::Architecture::mips - or Model->Architecture == model::Architecture::mipsel); + bool IsMIPS = (Model->Architecture() == model::Architecture::mips + or Model->Architecture() == model::Architecture::mipsel); using namespace model::Architecture; - bool IsLittleEndian = isLittleEndian(Model->Architecture); - size_t PointerSize = getPointerSize(Model->Architecture); - bool HasRelocationAddend = hasELFRelocationAddend(Model->Architecture); + bool IsLittleEndian = isLittleEndian(Model->Architecture()); + size_t PointerSize = getPointerSize(Model->Architecture()); + bool HasRelocationAddend = hasELFRelocationAddend(Model->Architecture()); auto Importer = createELFImporter(Model, TheBinary, diff --git a/lib/Model/Importer/Binary/ELFImporter.h b/lib/Model/Importer/Binary/ELFImporter.h index a0cbb3c80..32f30fc9b 100644 --- a/lib/Model/Importer/Binary/ELFImporter.h +++ b/lib/Model/Importer/Binary/ELFImporter.h @@ -106,7 +106,7 @@ private: MetaAddress getCodePointer(Pointer Ptr) const { using namespace model::Architecture; - auto Architecture = Model->Architecture; + auto Architecture = Model->Architecture(); return this->getGenericPointer(Ptr).toPC(toLLVMArchitecture(Architecture)); } diff --git a/lib/Model/Importer/Binary/MachOImporter.cpp b/lib/Model/Importer/Binary/MachOImporter.cpp index c330bb54e..9c0cc9a55 100644 --- a/lib/Model/Importer/Binary/MachOImporter.cpp +++ b/lib/Model/Importer/Binary/MachOImporter.cpp @@ -186,8 +186,8 @@ Error MachOImporter::import() { auto &MachO = cast(TheBinary); - revng_assert(Model->Architecture != Architecture::Invalid); - bool IsLittleEndian = Architecture::isLittleEndian(Model->Architecture); + revng_assert(Model->Architecture() != Architecture::Invalid); + bool IsLittleEndian = Architecture::isLittleEndian(Model->Architecture()); StringRef StringDataRef = TheBinary.getData(); auto RawDataRef = ArrayRef(StringDataRef.bytes_begin(), StringDataRef.size()); @@ -218,9 +218,9 @@ Error MachOImporter::import() { LCI.C.cmdsize - sizeof(thread_command)); if (contains(RawDataRef, CommandBuffer)) { - Model->EntryPoint = getInitialPC(Model->Architecture, - MustSwap, - CommandBuffer); + Model->EntryPoint() = getInitialPC(Model->Architecture(), + MustSwap, + CommandBuffer); } else { revng_log(Log, "LC_UNIXTHREAD Ptr is out of bounds. Ignoring."); } @@ -249,9 +249,9 @@ Error MachOImporter::import() { if (EntryPointOffset) { using namespace model::Architecture; - auto LLVMArchitecture = toLLVMArchitecture(Model->Architecture); - Model->EntryPoint = File.offsetToAddress(*EntryPointOffset) - .toPC(LLVMArchitecture); + auto LLVMArchitecture = toLLVMArchitecture(Model->Architecture()); + Model->EntryPoint() = File.offsetToAddress(*EntryPointOffset) + .toPC(LLVMArchitecture); } Error TheError = Error::success(); @@ -281,7 +281,7 @@ void MachOImporter::parseMachOSegment(ArrayRef RawDataRef, MetaAddress Start = fromGeneric(SegmentCommand.vmaddr); Segment Segment({ Start, SegmentCommand.vmsize }); - Segment.StartOffset = SegmentCommand.fileoff; + Segment.StartOffset() = SegmentCommand.fileoff; auto MaybeEndOffset = OverflowSafeInt(SegmentCommand.fileoff) + SegmentCommand.filesize; if (not MaybeEndOffset) { @@ -290,19 +290,19 @@ void MachOImporter::parseMachOSegment(ArrayRef RawDataRef, return; } - Segment.OriginalName = SegmentCommand.segname; - Segment.FileSize = SegmentCommand.filesize; + Segment.OriginalName() = SegmentCommand.segname; + Segment.FileSize() = SegmentCommand.filesize; - Segment.IsReadable = SegmentCommand.initprot & VM_PROT_READ; - Segment.IsWriteable = SegmentCommand.initprot & VM_PROT_WRITE; - Segment.IsExecutable = SegmentCommand.initprot & VM_PROT_EXECUTE; + Segment.IsReadable() = SegmentCommand.initprot & VM_PROT_READ; + Segment.IsWriteable() = SegmentCommand.initprot & VM_PROT_WRITE; + Segment.IsExecutable() = SegmentCommand.initprot & VM_PROT_EXECUTE; - model::TypePath StructPath = createEmptyStruct(*Model, Segment.VirtualSize); - Segment.Type = model::QualifiedType(std::move(StructPath), {}); + model::TypePath StructPath = createEmptyStruct(*Model, Segment.VirtualSize()); + Segment.Type() = model::QualifiedType(std::move(StructPath), {}); Segment.verify(true); - Model->Segments.insert(std::move(Segment)); + Model->Segments().insert(std::move(Segment)); // TODO: parse sections contained in segments LC_SEGMENT and LC_SEGMENT_64 } @@ -311,7 +311,7 @@ void MachOImporter::registerBindEntry(const object::MachOBindEntry *Entry) { MetaAddress Target = fromGeneric(Entry->address()); uint64_t Addend = static_cast(Entry->addend()); RelocationType::Values Type = RelocationType::Invalid; - auto PointerSize = Architecture::getPointerSize(Model->Architecture); + auto PointerSize = Architecture::getPointerSize(Model->Architecture()); switch (Entry->type()) { case BIND_TYPE_POINTER: diff --git a/lib/Model/Importer/Binary/PECOFFImporter.cpp b/lib/Model/Importer/Binary/PECOFFImporter.cpp index fdb744ec7..f304b64c4 100644 --- a/lib/Model/Importer/Binary/PECOFFImporter.cpp +++ b/lib/Model/Importer/Binary/PECOFFImporter.cpp @@ -55,8 +55,8 @@ private: Error PECOFFImporter::parseSectionsHeaders() { using namespace model; - revng_assert(Model->Architecture != Architecture::Invalid); - Architecture = Model->Architecture; + revng_assert(Model->Architecture() != Architecture::Invalid); + Architecture = Model->Architecture(); auto PointerSize = Architecture::getPointerSize(Architecture); bool IsLittleEndian = Architecture::isLittleEndian(Architecture); @@ -70,7 +70,7 @@ Error PECOFFImporter::parseSectionsHeaders() { // TODO: ImageBase should aligned to 4kb pages, should we check that? ImageBase = fromPC(PE32Header->ImageBase); - Model->EntryPoint = ImageBase + u64(PE32Header->AddressOfEntryPoint); + Model->EntryPoint() = ImageBase + u64(PE32Header->AddressOfEntryPoint); } else { const object::pe32plus_header *PE32PlusHeader = TheBinary .getPE32PlusHeader(); @@ -79,7 +79,7 @@ Error PECOFFImporter::parseSectionsHeaders() { // PE32+ Header ImageBase = fromPC(PE32PlusHeader->ImageBase); - Model->EntryPoint = ImageBase + u64(PE32PlusHeader->AddressOfEntryPoint); + Model->EntryPoint() = ImageBase + u64(PE32PlusHeader->AddressOfEntryPoint); } // Read sections @@ -97,26 +97,28 @@ Error PECOFFImporter::parseSectionsHeaders() { MetaAddress Start = ImageBase + u64(CoffRef->VirtualAddress); Segment Segment({ Start, u64(CoffRef->VirtualSize) }); - Segment.StartOffset = CoffRef->PointerToRawData; + Segment.StartOffset() = CoffRef->PointerToRawData; // VirtualSize might be larger than SizeOfRawData (extra data at the end of // the section) or viceversa (data mapped in memory but not present in // memory, e.g., .bss) - Segment.FileSize = CoffRef->SizeOfRawData; + Segment.FileSize() = CoffRef->SizeOfRawData; // Since it is possible that the file size is greater than VirtualSize // because SizeOfRawData is rounded, but VirtualSize is not, we work it // around here by using maximum of these two values for the VirtSize. - if (Segment.FileSize > Segment.VirtualSize) - Segment.VirtualSize = Segment.FileSize; + if (Segment.FileSize() > Segment.VirtualSize()) + Segment.VirtualSize() = Segment.FileSize(); - Segment.IsReadable = CoffRef->Characteristics & COFF::IMAGE_SCN_MEM_READ; - Segment.IsWriteable = CoffRef->Characteristics & COFF::IMAGE_SCN_MEM_WRITE; - Segment.IsExecutable = CoffRef->Characteristics - & COFF::IMAGE_SCN_MEM_EXECUTE; + Segment.IsReadable() = CoffRef->Characteristics & COFF::IMAGE_SCN_MEM_READ; + Segment.IsWriteable() = CoffRef->Characteristics + & COFF::IMAGE_SCN_MEM_WRITE; + Segment.IsExecutable() = CoffRef->Characteristics + & COFF::IMAGE_SCN_MEM_EXECUTE; - model::TypePath StructPath = createEmptyStruct(*Model, Segment.VirtualSize); - Segment.Type = model::QualifiedType(std::move(StructPath), {}); + model::TypePath StructPath = createEmptyStruct(*Model, + Segment.VirtualSize()); + Segment.Type() = model::QualifiedType(std::move(StructPath), {}); // NOTE: Unlike ELF, PE/COFF does not have segments. Instead, it has // sections only. All the raw data in a section must be loaded @@ -130,16 +132,16 @@ Error PECOFFImporter::parseSectionsHeaders() { and SectionStart.addressLowerThan(SectionEnd)) { model::Section NewSection(SectionStart, Size); if (auto SectionName = TheBinary.getSectionName(CoffRef)) - NewSection.Name = SectionName->str(); - NewSection.ContainsCode = Segment.IsExecutable; + NewSection.Name() = SectionName->str(); + NewSection.ContainsCode() = Segment.IsExecutable(); revng_assert(NewSection.verify(true)); - Segment.Sections.insert(std::move(NewSection)); + Segment.Sections().insert(std::move(NewSection)); } else { revng_log(Log, "Found an invalid section"); } Segment.verify(true); - Model->Segments.insert(std::move(Segment)); + Model->Segments().insert(std::move(Segment)); } return Error::success(); @@ -160,11 +162,11 @@ void PECOFFImporter::parseSymbols() { // Relocate the symbol. MetaAddress Address = ImageBase + Symbol.getValue(); - if (Model->Functions.count(Address)) + if (Model->Functions().count(Address)) continue; - model::Function &Function = Model->Functions[Address]; - Function.OriginalName = *NameOrErr; + model::Function &Function = Model->Functions()[Address]; + Function.OriginalName() = *NameOrErr; } } @@ -190,24 +192,24 @@ void PECOFFImporter::recordImportedFunctions(ImportedSymbolRange Range, // Dynamic functions must have a name, so skip those without it. // TODO: handle imports by ordinal - if (Sym.empty() or Model->ImportedDynamicFunctions.count(Sym.str())) + if (Sym.empty() or Model->ImportedDynamicFunctions().count(Sym.str())) continue; // NOTE: This address will occur in the .text section as a target of a jump. // Once we have the address of the entry within .idata, we can access // the information about symbol. - auto PointerSize = getPointerSize(Model->Architecture); + auto PointerSize = getPointerSize(Model->Architecture()); MetaAddress AddressOfImportEntry = ImageBase + u64(ImportAddressTableEntry) + u64(Index * PointerSize); // Lets make a Relocation. using namespace model::RelocationType; - auto RelocationType = formCOFFRelocation(Model->Architecture); + auto RelocationType = formCOFFRelocation(Model->Architecture()); model::Relocation NewRelocation(AddressOfImportEntry, RelocationType); - auto It = Model->ImportedDynamicFunctions.insert(Sym.str()).first; + auto It = Model->ImportedDynamicFunctions().insert(Sym.str()).first; revng_assert(NewRelocation.verify(true)); - It->Relocations.insert(NewRelocation); + It->Relocations().insert(NewRelocation); ++Index; } } @@ -234,7 +236,7 @@ void PECOFFImporter::parseImportedSymbols() { continue; } - if (not Model->ImportedLibraries.insert(Name.str()).second) + if (not Model->ImportedLibraries().insert(Name.str()).second) continue; // The import lookup table can be missing with certain older linkers, so @@ -275,18 +277,18 @@ void PECOFFImporter::recordDelayImportedFunctions(DelayDirectoryRef &I, // Dynamic functions must have a name, so skip those without it. // TODO: handle imports by ordinal - if (Sym.empty() or Model->ImportedDynamicFunctions.count(Sym.str())) + if (Sym.empty() or Model->ImportedDynamicFunctions().count(Sym.str())) continue; MetaAddress AddressOfDelayImportEntry = ImageBase + u64(Addr); // Lets make Relocation. using namespace model::RelocationType; - auto RelocationType = formCOFFRelocation(Model->Architecture); + auto RelocationType = formCOFFRelocation(Model->Architecture()); model::Relocation NewRelocation(AddressOfDelayImportEntry, RelocationType); - auto NewIt = Model->ImportedDynamicFunctions.insert(Sym.str()).first; + auto NewIt = Model->ImportedDynamicFunctions().insert(Sym.str()).first; revng_assert(NewRelocation.verify(true)); - NewIt->Relocations.insert(NewRelocation); + NewIt->Relocations().insert(NewRelocation); } } @@ -304,7 +306,7 @@ void PECOFFImporter::parseDelayImportedSymbols() { continue; } - if (not Model->ImportedLibraries.insert(Name.str()).second) + if (not Model->ImportedLibraries().insert(Name.str()).second) continue; recordDelayImportedFunctions(I, I.imported_symbols()); @@ -325,11 +327,13 @@ Error PECOFFImporter::import() { // linking). parseDelayImportedSymbols(); - if (Model->DefaultABI == model::ABI::Invalid) - Model->DefaultABI = model::ABI::getDefaultMicrosoftABI(Model->Architecture); + if (Model->DefaultABI() == model::ABI::Invalid) { + auto &Architecture = Model->Architecture(); + Model->DefaultABI() = model::ABI::getDefaultMicrosoftABI(Architecture); + } // Create a default prototype. - Model->DefaultPrototype = abi::registerDefaultFunctionPrototype(*Model); + Model->DefaultPrototype() = abi::registerDefaultFunctionPrototype(*Model); PDBImporter PDBI(Model, ImageBase); PDBI.import(TheBinary); diff --git a/lib/Model/Importer/DebugInfo/DwarfImporter.cpp b/lib/Model/Importer/DebugInfo/DwarfImporter.cpp index ad818df62..f9d401aee 100644 --- a/lib/Model/Importer/DebugInfo/DwarfImporter.cpp +++ b/lib/Model/Importer/DebugInfo/DwarfImporter.cpp @@ -163,17 +163,17 @@ public: AltIndex(AltIndex), DICtx(DICtx) { - Architecture = Model->Architecture; + Architecture = Model->Architecture(); BaseAddress = PreferredBaseAddress; // Ensure the architecture is consistent. auto Arch = model::Architecture::fromLLVMArchitecture(DICtx.getArch()); - if (Model->Architecture == model::Architecture::Invalid) - Model->Architecture = Arch; + if (Model->Architecture() == model::Architecture::Invalid) + Model->Architecture() = Arch; // Detect default ABI from the architecture. - if (Model->DefaultABI == model::ABI::Invalid) - Model->DefaultABI = model::ABI::getDefault(Model->Architecture); + if (Model->DefaultABI() == model::ABI::Invalid) + Model->DefaultABI() = model::ABI::getDefault(Model->Architecture()); } private: @@ -181,7 +181,7 @@ private: if (CC != DW_CC_normal) return model::ABI::Invalid; - return Model->DefaultABI; + return Model->DefaultABI(); } const model::QualifiedType &record(const DWARFDie &Die, @@ -194,10 +194,10 @@ private: const model::QualifiedType &QT, bool IsNotPlaceholder) { size_t Offset = Die.getOffset(); - revng_assert(QT.UnqualifiedType.isValid()); + revng_assert(QT.UnqualifiedType().isValid()); if (not IsNotPlaceholder) { - revng_assert(QT.Qualifiers.size() == 0); - Placeholders[Offset] = QT.UnqualifiedType.get(); + revng_assert(QT.Qualifiers().size() == 0); + Placeholders[Offset] = QT.UnqualifiedType().get(); } return Importer.recordType({ Index, Die.getOffset() }, QT); @@ -419,8 +419,8 @@ private: auto Tag = Die.getTag(); revng_assert(Placeholders.count(Offset) != 0); - revng_assert(TypePath->Qualifiers.empty()); - model::Type *T = TypePath->UnqualifiedType.get(); + revng_assert(TypePath->Qualifiers().empty()); + model::Type *T = TypePath->UnqualifiedType().get(); std::string Name = getName(Die); @@ -430,16 +430,16 @@ private: switch (Tag) { case llvm::dwarf::DW_TAG_subroutine_type: { auto *FunctionType = cast(T); - FunctionType->OriginalName = Name; - FunctionType->ABI = getABI(); + FunctionType->OriginalName() = Name; + FunctionType->ABI() = getABI(); - if (FunctionType->ABI == model::ABI::Invalid) { + if (FunctionType->ABI() == model::ABI::Invalid) { reportIgnoredDie(Die, "Unknown calling convention"); rc_return nullptr; } - FunctionType->ReturnType = rc_recur getTypeOrVoid(Die); - revng_assert(FunctionType->ReturnType.UnqualifiedType.isValid()); + FunctionType->ReturnType() = rc_recur getTypeOrVoid(Die); + revng_assert(FunctionType->ReturnType().UnqualifiedType().isValid()); uint64_t Index = 0; for (const DWARFDie &ChildDie : Die.children()) { @@ -454,8 +454,8 @@ private: rc_return nullptr; } - model::Argument &NewArgument = FunctionType->Arguments[Index]; - NewArgument.Type = *ArgumentType; + model::Argument &NewArgument = FunctionType->Arguments()[Index]; + NewArgument.Type() = *ArgumentType; Index += 1; } } @@ -467,9 +467,9 @@ private: case llvm::dwarf::DW_TAG_volatile_type: { model::QualifiedType TargetType = rc_recur getTypeOrVoid(Die); auto *Typedef = cast(T); - Typedef->OriginalName = Name; - Typedef->UnderlyingType = TargetType; - revng_assert(Typedef->UnderlyingType.UnqualifiedType.isValid()); + Typedef->OriginalName() = Name; + Typedef->UnderlyingType() = TargetType; + revng_assert(Typedef->UnderlyingType().UnqualifiedType().isValid()); } break; @@ -482,8 +482,8 @@ private: } auto *Struct = cast(T); - Struct->OriginalName = Name; - Struct->Size = *MaybeSize->getAsUnsignedConstant(); + Struct->OriginalName() = Name; + Struct->Size() = *MaybeSize->getAsUnsignedConstant(); uint64_t Index = 0; for (const DWARFDie &ChildDie : Die.children()) { @@ -514,9 +514,9 @@ private: } // Create new field - auto &Field = Struct->Fields[Offset]; - Field.OriginalName = getName(ChildDie); - Field.Type = *MemberType; + auto &Field = Struct->Fields()[Offset]; + Field.OriginalName() = getName(ChildDie); + Field.Type() = *MemberType; ++Index; } @@ -531,7 +531,7 @@ private: case llvm::dwarf::DW_TAG_union_type: { auto *Union = cast(T); - Union->OriginalName = Name; + Union->OriginalName() = Name; uint64_t Index = 0; for (const DWARFDie &ChildDie : Die.children()) { @@ -545,9 +545,9 @@ private: } // Create new field - auto &Field = Union->Fields[Index]; - Field.OriginalName = getName(ChildDie); - Field.Type = *MemberType; + auto &Field = Union->Fields()[Index]; + Field.OriginalName() = getName(ChildDie); + Field.Type() = *MemberType; // Increment union index Index += 1; @@ -563,7 +563,7 @@ private: case llvm::dwarf::DW_TAG_enumeration_type: { auto *Enum = cast(T); - Enum->OriginalName = Name; + Enum->OriginalName() = Name; const QualifiedType *QualifiedUnderlyingType = rc_recur getType(Die); if (QualifiedUnderlyingType == nullptr) { @@ -571,8 +571,8 @@ private: rc_return nullptr; } - revng_assert(QualifiedUnderlyingType->Qualifiers.empty()); - Enum->UnderlyingType = *QualifiedUnderlyingType; + revng_assert(QualifiedUnderlyingType->Qualifiers().empty()); + Enum->UnderlyingType() = *QualifiedUnderlyingType; uint64_t Index = 0; for (const DWARFDie &ChildDie : Die.children()) { @@ -592,10 +592,10 @@ private: std::string EntryName = getName(ChildDie); // If it's the first time, set OriginalName - auto It = Enum->Entries.find(Value); - if (It == Enum->Entries.end()) { - auto &Entry = Enum->Entries[Value]; - Entry.OriginalName = EntryName; + auto It = Enum->Entries().find(Value); + if (It == Enum->Entries().end()) { + auto &Entry = Enum->Entries()[Value]; + Entry.OriginalName() = EntryName; } else { // Ignore aliases } @@ -646,8 +646,8 @@ private: case llvm::dwarf::DW_TAG_const_type: { model::Qualifier NewQualifier; - NewQualifier.Kind = model::QualifierKind::Const; - Type.Qualifiers.insert(Type.Qualifiers.begin(), NewQualifier); + NewQualifier.Kind() = model::QualifierKind::Const; + Type.Qualifiers().insert(Type.Qualifiers().begin(), NewQualifier); } break; case llvm::dwarf::DW_TAG_array_type: { @@ -660,8 +660,8 @@ private: for (const DWARFDie &ChildDie : Die.children()) { if (ChildDie.getTag() == llvm::dwarf::DW_TAG_subrange_type) { model::Qualifier NewQualifier; - NewQualifier.Kind = model::QualifierKind::Array; - NewQualifier.Size = 0; + NewQualifier.Kind() = model::QualifierKind::Array; + NewQualifier.Size() = 0; auto MaybeUpperBound = getUnsignedOrSigned(ChildDie, DW_AT_upper_bound); @@ -674,19 +674,19 @@ private: } if (MaybeUpperBound) { - NewQualifier.Size = *MaybeUpperBound + 1; + NewQualifier.Size() = *MaybeUpperBound + 1; } else if (MaybeCount) { - NewQualifier.Size = *MaybeCount; + NewQualifier.Size() = *MaybeCount; } - if (NewQualifier.Size == 0) { + if (NewQualifier.Size() == 0) { reportIgnoredDie(Die, "Array upper bound/elements count missing or " "invalid"); rc_return nullptr; } - Type.Qualifiers.insert(Type.Qualifiers.begin(), NewQualifier); + Type.Qualifiers().insert(Type.Qualifiers().begin(), NewQualifier); } } } break; @@ -701,9 +701,9 @@ private: rc_return nullptr; } - NewQualifier.Kind = model::QualifierKind::Pointer; - NewQualifier.Size = *MaybeByteSize->getAsUnsignedConstant(); - Type.Qualifiers.insert(Type.Qualifiers.begin(), NewQualifier); + NewQualifier.Kind() = model::QualifierKind::Pointer; + NewQualifier.Size() = *MaybeByteSize->getAsUnsignedConstant(); + Type.Qualifiers().insert(Type.Qualifiers().begin(), NewQualifier); } break; default: @@ -767,9 +767,9 @@ private: auto MaybeCC = getUnsignedOrSigned(Die, DW_AT_calling_convention); if (MaybeCC) CC = static_cast(*MaybeCC); - FunctionType->ABI = getABI(CC); + FunctionType->ABI() = getABI(CC); - if (FunctionType->ABI == model::ABI::Invalid) { + if (FunctionType->ABI() == model::ABI::Invalid) { reportIgnoredDie(Die, "Unknown calling convention"); return std::nullopt; } @@ -786,16 +786,16 @@ private: return std::nullopt; } - model::Argument &NewArgument = FunctionType->Arguments[Index]; - NewArgument.OriginalName = getName(ChildDie); - NewArgument.Type = *ArgumenType; + model::Argument &NewArgument = FunctionType->Arguments()[Index]; + NewArgument.OriginalName() = getName(ChildDie); + NewArgument.Type() = *ArgumenType; Index += 1; } } // Return type - FunctionType->ReturnType = getTypeOrVoid(Die); - revng_assert(FunctionType->ReturnType.UnqualifiedType.isValid()); + FunctionType->ReturnType() = getTypeOrVoid(Die); + revng_assert(FunctionType->ReturnType().UnqualifiedType().isValid()); return Model->recordNewType(std::move(NewType)); } @@ -814,16 +814,17 @@ private: if (MaybeLowPC) { // Get/create the local function MetaAddress LowPC = relocate(fromPC(*MaybeLowPC)); - auto &Function = Model->Functions[LowPC]; + auto &Function = Model->Functions()[LowPC]; - if (not Function.Prototype.isValid()) - Function.Prototype = *MaybePath; + if (not Function.Prototype().isValid()) + Function.Prototype() = *MaybePath; - if (SymbolName.size() != 0 and Function.OriginalName.size() == 0) - Function.OriginalName = SymbolName; + if (SymbolName.size() != 0 and Function.OriginalName().size() == 0) + Function.OriginalName() = SymbolName; - } else if (not SymbolName.empty() - and Model->ImportedDynamicFunctions.count(SymbolName) != 0) { + } else if (auto &Functions = Model->ImportedDynamicFunctions(); + not SymbolName.empty() + and Functions.count(SymbolName) != 0) { // It's a dynamic function if (not MaybePath) { @@ -832,12 +833,12 @@ private: } // Get/create dynamic function - auto &DynamicFunction = Model->ImportedDynamicFunctions[SymbolName]; + auto &DynamicFunction = Model->ImportedDynamicFunctions()[SymbolName]; // If a function already has a valid prototype, don't override it - if (DynamicFunction.Prototype.isValid()) + if (DynamicFunction.Prototype().isValid()) continue; - DynamicFunction.Prototype = *MaybePath; + DynamicFunction.Prototype() = *MaybePath; } else { reportIgnoredDie(Die, "Ignoring subprogram"); @@ -849,17 +850,17 @@ private: void cleanupTypeSystem() { std::set ToDrop; - for (auto &Type : Model->Types) { + for (auto &Type : Model->Types()) { // // Drop zero-sized struct/union fields // if (auto *Struct = dyn_cast(Type.get())) { - llvm::erase_if(Struct->Fields, [](model::StructField &Field) { - return not Field.Type.size(); + llvm::erase_if(Struct->Fields(), [](model::StructField &Field) { + return not Field.Type().size(); }); } else if (auto *Union = dyn_cast(Type.get())) { - llvm::erase_if(Union->Fields, [](model::UnionField &Field) { - return not Field.Type.size(); + llvm::erase_if(Union->Fields(), [](model::UnionField &Field) { + return not Field.Type().size(); }); } @@ -868,10 +869,10 @@ private: // for (const model::QualifiedType &QT : Type->edges()) { auto IsArray = [](const model::Qualifier &Q) { - return Q.Kind == model::QualifierKind::Array; + return Q.Kind() == model::QualifierKind::Array; }; - if (llvm::any_of(QT.Qualifiers, IsArray) - and not QT.UnqualifiedType.get()->size()) { + if (llvm::any_of(QT.Qualifiers(), IsArray) + and not QT.UnqualifiedType().get()->size()) { ToDrop.insert(Type.get()); } } @@ -1079,7 +1080,7 @@ computeEquivalentSymbols(const llvm::object::ObjectFile &ELF) { inline void detectAliases(const llvm::object::ObjectFile &ELF, TupleTree &Model) { EquivalenceClasses Aliases = computeEquivalentSymbols(ELF); - auto &ImportedDynamicFunctions = Model->ImportedDynamicFunctions; + auto &ImportedDynamicFunctions = Model->ImportedDynamicFunctions(); for (auto AliasesIt = Aliases.begin(), E = Aliases.end(); AliasesIt != E; ++AliasesIt) { @@ -1098,8 +1099,8 @@ inline void detectAliases(const llvm::object::ObjectFile &ELF, // If DynamicFunction doesn't have a prototype, register it for copying // it from the leader. // Otherwise, record the type as the leader. - if (Found and It->Prototype.isValid()) { - Prototype = It->Prototype; + if (Found and It->Prototype().isValid()) { + Prototype = It->Prototype(); } else { UnprototypedFunctionsNames.push_back(Name); } @@ -1110,7 +1111,7 @@ inline void detectAliases(const llvm::object::ObjectFile &ELF, auto It = ImportedDynamicFunctions.find(Name); if (It == ImportedDynamicFunctions.end()) It = ImportedDynamicFunctions.insert({ Name }).first; - It->Prototype = Prototype; + It->Prototype() = Prototype; } } } @@ -1125,8 +1126,8 @@ void DwarfImporter::import(const llvm::object::Binary &TheBinary, { using namespace model::Architecture; - if (Model->Architecture == Invalid) - Model->Architecture = fromLLVMArchitecture(ELF->getArch()); + if (Model->Architecture() == Invalid) + Model->Architecture() = fromLLVMArchitecture(ELF->getArch()); } // Check if we already loaded the alt debug info file diff --git a/lib/Model/Importer/DebugInfo/PDBImporter.cpp b/lib/Model/Importer/DebugInfo/PDBImporter.cpp index 70fc93df9..5128b589b 100644 --- a/lib/Model/Importer/DebugInfo/PDBImporter.cpp +++ b/lib/Model/Importer/DebugInfo/PDBImporter.cpp @@ -383,7 +383,7 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, QualifiedType TheUnderlyingType(*ReferencedTypeFromModel, Qualifiers); auto TheTypeTypeDef = cast(TypeTypedef.get()); - TheTypeTypeDef->UnderlyingType = TheUnderlyingType; + TheTypeTypeDef->UnderlyingType() = TheUnderlyingType; auto TypePath = Model->recordNewType(std::move(TypeTypedef)); ProcessedTypes[CurrentTypeIndex] = TypePath; @@ -416,7 +416,7 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, QualifiedType TheUnderlyingType(*ElementTypeFromModel, Qualifiers); auto TheTypeTypeDef = cast(TypeTypedef.get()); - TheTypeTypeDef->UnderlyingType = TheUnderlyingType; + TheTypeTypeDef->UnderlyingType() = TheUnderlyingType; auto TypePath = Model->recordNewType(std::move(TypeTypedef)); ProcessedTypes[CurrentTypeIndex] = TypePath; @@ -447,7 +447,7 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, Qualifiers); auto TheTypeTypeDef = cast(TypeTypedef.get()); - TheTypeTypeDef->UnderlyingType = TheUnderlyingType; + TheTypeTypeDef->UnderlyingType() = TheUnderlyingType; auto TypePath = Model->recordNewType(std::move(TypeTypedef)); ProcessedTypes[CurrentTypeIndex] = TypePath; @@ -494,13 +494,13 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, // 0-sized structs are typedefed to void. if (not Class.getSize()) { auto TypeTypedef = makeType(); - TypeTypedef->OriginalName = Class.getName(); + TypeTypedef->OriginalName() = Class.getName(); using Values = model::PrimitiveTypeKind::Values; QualifiedType TheUnderlyingType(Model->getPrimitiveType(Values::Void, 0), {}); auto TheTypeTypeDef = cast(TypeTypedef.get()); - TheTypeTypeDef->UnderlyingType = TheUnderlyingType; + TheTypeTypeDef->UnderlyingType() = TheUnderlyingType; auto TypePath = Model->recordNewType(std::move(TypeTypedef)); ProcessedTypes[CurrentTypeIndex] = TypePath; @@ -511,10 +511,10 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, TypeIndex FieldsTypeIndex = Class.getFieldList(); if (InProgressMemberTypes.count(FieldsTypeIndex)) { auto NewType = makeType(); - NewType->OriginalName = Class.getName(); + NewType->OriginalName() = Class.getName(); auto Struct = cast(NewType.get()); - Struct->Size = Class.getSize(); + Struct->Size() = Class.getSize(); auto &TheFields = InProgressMemberTypes[FieldsTypeIndex]; uint64_t MaxOffset = 0; @@ -552,16 +552,16 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, // TODO: How is this posible? // Trigers: // `Last field ends outside the struct`. - if (CurrFieldOffset > Struct->Size) { + if (CurrFieldOffset > Struct->Size()) { revng_log(DILogger, "Skipping struct field that is outside the struct."); continue; } - auto &FieldType = Struct->Fields[Offset]; - FieldType.OriginalName = Field.getName().str(); + auto &FieldType = Struct->Fields()[Offset]; + FieldType.OriginalName() = Field.getName().str(); QualifiedType TheUnderlyingType(*FiledTypeFromModel, {}); - FieldType.Type = TheUnderlyingType; + FieldType.Type() = TheUnderlyingType; } } auto TypePath = Model->recordNewType(std::move(NewType)); @@ -589,10 +589,10 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, auto NewType = makeType(); auto TypeFunction = cast(NewType.get()); - TypeFunction->ABI = Model->DefaultABI; + TypeFunction->ABI() = Model->DefaultABI(); QualifiedType TheReturnType(*ReferencedTypeFromModel, {}); - TypeFunction->ReturnType = TheReturnType; + TypeFunction->ReturnType() = TheReturnType; TypeIndex ArgListTyIndex = MemberFunction.getArgumentList(); revng_assert(InProgressArgumentsTypes.count(ArgListTyIndex)); @@ -609,11 +609,11 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, and ProcessedTypes.count(CurrentTypeIndex)) { auto MaybeSize = ProcessedTypes[CurrentTypeIndex].get()->size(); if (MaybeSize and *MaybeSize != 0) { - Argument &NewArgument = TypeFunction->Arguments[Index]; - auto PointerSize = getPointerSize(Model->Architecture); + Argument &NewArgument = TypeFunction->Arguments()[Index]; + auto PointerSize = getPointerSize(Model->Architecture()); QualifiedType TheType(ProcessedTypes[CurrentTypeIndex], { Qualifier::createPointer(PointerSize) }); - NewArgument.Type = TheType; + NewArgument.Type() = TheType; ++Index; } else { revng_log(DILogger, "Skipping 0-sized argument."); @@ -636,10 +636,10 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, continue; } - Argument &NewArgument = TypeFunction->Arguments[Index]; + Argument &NewArgument = TypeFunction->Arguments()[Index]; QualifiedType TheUnderlyingType(*ArgumentTypeFromModel, {}); - NewArgument.Type = TheUnderlyingType; + NewArgument.Type() = TheUnderlyingType; ++Index; } } @@ -657,7 +657,7 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, EnumRecord &Enum) { TypeIndex FieldsTypeIndex = Enum.getFieldList(); auto NewType = model::makeType(); - NewType->OriginalName = Enum.getName(); + NewType->OriginalName() = Enum.getName(); TypeIndex UnderlyingTypeIndex = Enum.getUnderlyingType(); auto UnderlynigTypeFromModel = getModelTypeForIndex(UnderlyingTypeIndex); @@ -670,15 +670,15 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, model::QualifiedType TheUnderlyingType(*UnderlynigTypeFromModel, {}); auto TypeEnum = cast(NewType.get()); - TypeEnum->UnderlyingType = TheUnderlyingType; + TypeEnum->UnderlyingType() = TheUnderlyingType; auto &TheFields = InProgressEnumeratorTypes[FieldsTypeIndex]; if (TheFields.empty()) return Error::success(); for (const auto &Entry : TheFields) { - auto &EnumEntry = TypeEnum->Entries[Entry.getValue().getExtValue()]; - EnumEntry.OriginalName = Entry.getName().str(); + auto &EnumEntry = TypeEnum->Entries()[Entry.getValue().getExtValue()]; + EnumEntry.OriginalName() = Entry.getName().str(); } auto TypePath = Model->recordNewType(std::move(NewType)); @@ -753,11 +753,11 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, } else { auto NewType = model::makeType(); auto TypeFunction = cast(NewType.get()); - TypeFunction->ABI = getMicrosoftABI(Proc.getCallConv(), - Model->Architecture); + TypeFunction->ABI() = getMicrosoftABI(Proc.getCallConv(), + Model->Architecture()); model::QualifiedType TheReturnType(*ReturnTypeFromModel, {}); - TypeFunction->ReturnType = TheReturnType; + TypeFunction->ReturnType() = TheReturnType; TypeIndex ArgListTyIndex = Proc.getArgumentList(); auto ArgumentList = InProgressArgumentsTypes[ArgListTyIndex]; @@ -781,10 +781,10 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, continue; } - model::Argument &NewArgument = TypeFunction->Arguments[Index]; + model::Argument &NewArgument = TypeFunction->Arguments()[Index]; model::QualifiedType TheArgumentType(*ArgumentTypeFromModel, {}); - NewArgument.Type = TheArgumentType; + NewArgument.Type() = TheArgumentType; ++Index; } } @@ -801,7 +801,7 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, UnionRecord &Union) { TypeIndex FieldsTypeIndex = Union.getFieldList(); auto NewType = model::makeType(); - NewType->OriginalName = Union.getName().str(); + NewType->OriginalName() = Union.getName().str(); uint64_t Index = 0; auto &TheFields = InProgressMemberTypes[FieldsTypeIndex]; @@ -810,13 +810,13 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, // Typedef it to void. if (TheFields.size() == 0) { auto TypeTypedef = model::makeType(); - TypeTypedef->OriginalName = Union.getName().str(); + TypeTypedef->OriginalName() = Union.getName().str(); auto TheTypeTypeDef = cast(TypeTypedef.get()); using Values = model::PrimitiveTypeKind::Values; auto ThePrimitiveType = Model->getPrimitiveType(Values::Void, 0); model::QualifiedType TheUnderlyingType(ThePrimitiveType, {}); - TheTypeTypeDef->UnderlyingType = TheUnderlyingType; + TheTypeTypeDef->UnderlyingType() = TheUnderlyingType; auto TypePath = Model->recordNewType(std::move(TypeTypedef)); ProcessedTypes[CurrentTypeIndex] = TypePath; @@ -843,10 +843,10 @@ Error PDBImporterTypeVisitor::visitKnownRecord(CVType &Record, GeneratedOneFieldAtleast = true; auto TypeUnion = cast(NewType.get()); - auto &FieldType = TypeUnion->Fields[Index]; - FieldType.OriginalName = Field.getName().str(); + auto &FieldType = TypeUnion->Fields()[Index]; + FieldType.OriginalName() = Field.getName().str(); model::QualifiedType TheFieldType(*FiledTypeFromModel, {}); - FieldType.Type = TheFieldType; + FieldType.Type() = TheFieldType; Index++; } @@ -1066,7 +1066,7 @@ void PDBImporterTypeVisitor::createPrimitiveType(TypeIndex SimpleType) { auto TypeTypedef = makeType(); auto TheTypeTypeDef = cast(TypeTypedef.get()); QualifiedType TheUnderlyingType(VoidModelType, {}); - TheTypeTypeDef->UnderlyingType = TheUnderlyingType; + TheTypeTypeDef->UnderlyingType() = TheUnderlyingType; ProcessedTypes[SimpleType] = VoidModelType; } else { @@ -1095,7 +1095,7 @@ void PDBImporterTypeVisitor::createPrimitiveType(TypeIndex SimpleType) { Qualifiers.push_back({ Qualifier::createPointer(*PointerSize) }); QualifiedType TheUnderlyingType(PrimitiveModelType, Qualifiers); - TheTypeTypeDef->UnderlyingType = TheUnderlyingType; + TheTypeTypeDef->UnderlyingType() = TheUnderlyingType; auto TypePath = Model->recordNewType(std::move(TypeTypedef)); ProcessedTypes[SimpleType] = TypePath; @@ -1132,29 +1132,29 @@ Error PDBImporterSymbolVisitor::visitSymbolBegin(CVSymbol &Record, Error PDBImporterSymbolVisitor::visitKnownRecord(CVSymbol &Record, ProcSym &Proc) { // If it is not in the .idata already, we assume it is a static symbol. - if (not Model->ImportedDynamicFunctions.count(Proc.Name.str())) { + if (not Model->ImportedDynamicFunctions().count(Proc.Name.str())) { uint64_t FunctionVirtualAddress = Session .getRVAFromSectOffset(Proc.Segment, Proc.CodeOffset); // Relocate the symbol. MetaAddress FunctionAddress = ImageBase + FunctionVirtualAddress; - if (not Model->Functions.count(FunctionAddress)) { - model::Function &Function = Model->Functions[FunctionAddress]; - Function.OriginalName = Proc.Name; + if (not Model->Functions().count(FunctionAddress)) { + model::Function &Function = Model->Functions()[FunctionAddress]; + Function.OriginalName() = Proc.Name; TypeIndex FunctionTypeIndex = Proc.FunctionType; if (ProcessedTypes.count(FunctionTypeIndex)) { model::QualifiedType ThePrototype(ProcessedTypes[FunctionTypeIndex], {}); - Function.Prototype = ThePrototype.UnqualifiedType; + Function.Prototype() = ThePrototype.UnqualifiedType(); } } else { - auto It = Model->Functions.find(FunctionAddress); + auto It = Model->Functions().find(FunctionAddress); TypeIndex FunctionTypeIndex = Proc.FunctionType; if (ProcessedTypes.count(FunctionTypeIndex)) { model::QualifiedType ThePrototype(ProcessedTypes[FunctionTypeIndex], {}); - It->Prototype = ThePrototype.UnqualifiedType; + It->Prototype() = ThePrototype.UnqualifiedType(); } } } diff --git a/lib/Model/Pass/ConvertFunctionTypes.cpp b/lib/Model/Pass/ConvertFunctionTypes.cpp index 9b90f2e92..dc4baad68 100644 --- a/lib/Model/Pass/ConvertFunctionTypes.cpp +++ b/lib/Model/Pass/ConvertFunctionTypes.cpp @@ -68,7 +68,7 @@ void model::convertAllFunctionsToRaw(TupleTree &Model) { return; } - auto ToConvert = chooseTypes(Model->Types); + auto ToConvert = chooseTypes(Model->Types()); for (model::CABIFunctionType *Old : ToConvert) { auto New = abi::FunctionType::convertToRaw(*Old, Model); revng_assert(New.isValid()); @@ -89,7 +89,7 @@ void model::convertAllFunctionsToCABI(TupleTree &Model, return; } - auto ToConvert = chooseTypes(Model->Types); + auto ToConvert = chooseTypes(Model->Types()); for (model::RawFunctionType *Old : ToConvert) if (auto New = abi::FunctionType::tryConvertToCABI(*Old, Model, ABI)) revng_assert(New->isValid()); diff --git a/lib/Model/Pass/DeduplicateEquivalentTypes.cpp b/lib/Model/Pass/DeduplicateEquivalentTypes.cpp index 6cd7b4e89..063b8b2c7 100644 --- a/lib/Model/Pass/DeduplicateEquivalentTypes.cpp +++ b/lib/Model/Pass/DeduplicateEquivalentTypes.cpp @@ -58,7 +58,7 @@ private: private: TypeSystemDeduplicator(TupleTree &Model) { - for (auto &T : Model->Types) + for (auto &T : Model->Types()) Types.push_back(&*T); } @@ -79,7 +79,7 @@ private: LoggerIndent Indent(Log); auto ComputeKey = [](model::Type *T) { - return std::pair{ T->OriginalName, T->Kind }; + return std::pair{ T->OriginalName(), T->Kind() }; }; // Sort types by the key (the name) @@ -112,8 +112,8 @@ private: and not WeakEquivalence.isEquivalent(Left, Right)); if (Left->localCompare(*Right)) { revng_log(Log, - Left->ID << " and " << Right->ID - << " are weakly equivalent"); + Left->ID() + << " and " << Right->ID() << " are weakly equivalent"); // Record as weakly equivalent WeakEquivalence.unionSets(Left, Right); @@ -186,10 +186,10 @@ private: LoggerIndent Indent(Log); for (model::Type *Leader : VisitOrder) { - revng_log(Log, "Considering " << Leader->OriginalName); + revng_log(Log, "Considering " << Leader->OriginalName()); LoggerIndent Indent2(Log); - revng_assert(not Leader->OriginalName.empty()); + revng_assert(not Leader->OriginalName().empty()); auto LeaderIt = WeakEquivalence.findValue(Leader); revng_assert(LeaderIt->isLeader()); @@ -202,7 +202,7 @@ private: if (Left == Right or StrongEquivalence.isEquivalent(Left, Right)) return true; - revng_log(Log, "Comparing " << Left->ID << " and " << Right->ID); + revng_log(Log, "Comparing " << Left->ID() << " and " << Right->ID()); LoggerIndent Indent(Log); bool Result = deepCompare(Left, Right); @@ -218,7 +218,7 @@ private: private: void addEdge(const model::Type *T, const model::QualifiedType &QT) { - auto *DependantType = QT.UnqualifiedType.get(); + auto *DependantType = QT.UnqualifiedType().get(); TypeToNode.at(T)->addSuccessor(TypeToNode.at(DependantType)); } @@ -240,7 +240,7 @@ private: df_iterator_default_set Visited; for (Node *LeftNode : depth_first_ext(Left, Visited)) { - revng_log(Log, "Visiting " << LeftNode->T->ID); + revng_log(Log, "Visiting " << LeftNode->T->ID()); LoggerIndent Indent2(Log); auto RightIt = LeftToRight.find(LeftNode); @@ -253,7 +253,7 @@ private: // Zip out edges of the node pair: consider the destinations. for (auto [LeftSuccessor, RightSuccessor] : zip(LeftNode->successors(), RightNode->successors())) { - revng_log(Log, "Visiting successor " << LeftSuccessor->T->ID); + revng_log(Log, "Visiting successor " << LeftSuccessor->T->ID()); if (not compareSuccessor(LeftToRight, RightToLeft, Visited, @@ -282,8 +282,8 @@ private: if (LeftToRightIt != LeftToRight.end()) { if (LeftToRightIt->second != Right) { revng_log(Log, - "We were expecting " << LeftToRightIt->second->T->ID - << " but we got " << Right->T->ID); + "We were expecting " << LeftToRightIt->second->T->ID() + << " but we got " << Right->T->ID()); return false; } else { revng_assert(RightToLeft.at(Right) == Left); @@ -295,8 +295,8 @@ private: if (RightToLeftIt != RightToLeft.end()) { if (RightToLeftIt->second != Left) { revng_log(Log, - "We were expecting " << RightToLeftIt->second->T->ID - << " but we got " << Left->T->ID); + "We were expecting " << RightToLeftIt->second->T->ID() + << " but we got " << Left->T->ID()); return false; } else { revng_assert(LeftToRight.at(Left) == Right); @@ -316,8 +316,8 @@ private: Visited.insert(Left); return true; } else if (WeakEquivalence.isEquivalent(Right->T, Left->T) - or (Left->T->OriginalName.empty() - and Right->T->OriginalName.empty() + or (Left->T->OriginalName().empty() + and Right->T->OriginalName().empty() and Left->T->localCompare(*Right->T))) { // Weak equivalence return true; @@ -325,8 +325,8 @@ private: // Otherwise, the nodes are not equivalent revng_assert(not Left->T->localCompare(*Right->T)); revng_log(Log, - Left->T->ID << " and " << Right->T->ID - << " are locally different"); + Left->T->ID() + << " and " << Right->T->ID() << " are locally different"); return false; } } @@ -364,7 +364,7 @@ void model::deduplicateEquivalentTypes(TupleTree &Model) { Model.replaceReferences(Replacements); // Actually drop the types - llvm::erase_if(Model->Types, [&ToErase](UpcastablePointer &P) { + llvm::erase_if(Model->Types(), [&ToErase](UpcastablePointer &P) { return ToErase.count(P.get()) != 0; }); } diff --git a/lib/Model/Pass/FixModel.cpp b/lib/Model/Pass/FixModel.cpp index 111850eff..30be04618 100644 --- a/lib/Model/Pass/FixModel.cpp +++ b/lib/Model/Pass/FixModel.cpp @@ -19,7 +19,7 @@ static Logger<> ModelFixLogger("model-fix"); void model::fixModel(TupleTree &Model) { std::set ToDrop; - for (UpcastablePointer &T : Model->Types) { + for (UpcastablePointer &T : Model->Types()) { // Filter out empty structs and unions. if (!T->size()) { if (isa(T.get()) or isa(T.get())) { @@ -31,7 +31,7 @@ void model::fixModel(TupleTree &Model) { // Filter out invalid PrimitiveTypes. auto *ThePrimitiveType = dyn_cast(T.get()); if (ThePrimitiveType) { - if (ThePrimitiveType->PrimitiveKind == PrimitiveTypeKind::Invalid) + if (ThePrimitiveType->PrimitiveKind() == PrimitiveTypeKind::Invalid) ToDrop.insert(T.get()); } @@ -39,9 +39,10 @@ void model::fixModel(TupleTree &Model) { auto *FunctionType = dyn_cast(T.get()); if (FunctionType) { // Remove functions with more than one `void` argument. - for (auto &Group : llvm::enumerate(FunctionType->Arguments)) { + for (auto &Group : llvm::enumerate(FunctionType->Arguments())) { auto &Argument = Group.value(); - if (*Argument.Type.size() == 0 and FunctionType->Arguments.size() > 1) + if (*Argument.Type().size() == 0 + and FunctionType->Arguments().size() > 1) ToDrop.insert(T.get()); } } diff --git a/lib/Model/Pass/PromoteOriginalName.cpp b/lib/Model/Pass/PromoteOriginalName.cpp index 8e8e81601..9731950c2 100644 --- a/lib/Model/Pass/PromoteOriginalName.cpp +++ b/lib/Model/Pass/PromoteOriginalName.cpp @@ -24,8 +24,8 @@ void recordCustomNamesInList(auto &Collection, std::set &UsedNames) { for (auto &Entry2 : Collection) { auto *Entry = Unwrap(Entry2); - if (not Entry->CustomName.empty()) - UsedNames.insert(Entry->CustomName.str().str()); + if (not Entry->CustomName().empty()) + UsedNames.insert(Entry->CustomName().str().str()); } } @@ -36,15 +36,15 @@ void promoteOriginalNamesInList(auto &Collection, for (auto &Entry2 : Collection) { auto *Entry = Unwrap(Entry2); - if (Entry->CustomName.empty() and not Entry->OriginalName.empty()) { + if (Entry->CustomName().empty() and not Entry->OriginalName().empty()) { // We have an OriginalName but not CustomName - auto Name = Identifier::fromString(Entry->OriginalName); + auto Name = Identifier::fromString(Entry->OriginalName()); while (UsedNames.count(Name.str().str()) != 0) Name += "_"; // Assign name - Entry->CustomName = Name; + Entry->CustomName() = Name; // Record new name UsedNames.insert(Name.str().str()); @@ -65,42 +65,44 @@ void model::promoteOriginalName(TupleTree &Model) { // Collect all the already used CustomNames for symbols std::set Symbols; - recordCustomNamesInList(Model->Types, Unwrap, Symbols); - recordCustomNamesInList(Model->Functions, AddressOf, Symbols); - recordCustomNamesInList(Model->ImportedDynamicFunctions, AddressOf, Symbols); - for (auto &UP : Model->Types) + recordCustomNamesInList(Model->Types(), Unwrap, Symbols); + recordCustomNamesInList(Model->Functions(), AddressOf, Symbols); + recordCustomNamesInList(Model->ImportedDynamicFunctions(), + AddressOf, + Symbols); + for (auto &UP : Model->Types()) if (auto *Enum = dyn_cast(UP.get())) - recordCustomNamesInList(Enum->Entries, AddressOf, Symbols); + recordCustomNamesInList(Enum->Entries(), AddressOf, Symbols); // Promote type names - promoteOriginalNamesInList(Model->Types, Unwrap, Symbols); + promoteOriginalNamesInList(Model->Types(), Unwrap, Symbols); // Promote function names - promoteOriginalNamesInList(Model->Functions, AddressOf, Symbols); + promoteOriginalNamesInList(Model->Functions(), AddressOf, Symbols); // Promote dynamic function names - promoteOriginalNamesInList(Model->ImportedDynamicFunctions, + promoteOriginalNamesInList(Model->ImportedDynamicFunctions(), AddressOf, Symbols); // Promote segment names - promoteOriginalNamesInList(Model->Segments, AddressOf, Symbols); + promoteOriginalNamesInList(Model->Segments(), AddressOf, Symbols); - for (auto &UP : Model->Types) { + for (auto &UP : Model->Types()) { model::Type *T = UP.get(); if (auto *Struct = dyn_cast(T)) { // Promote struct fields names (they have their own namespace) - promoteOriginalNamesInList(Struct->Fields, AddressOf); + promoteOriginalNamesInList(Struct->Fields(), AddressOf); } else if (auto *Union = dyn_cast(T)) { // Promote union fields names (they have their own namespace) - promoteOriginalNamesInList(Union->Fields, AddressOf); + promoteOriginalNamesInList(Union->Fields(), AddressOf); } else if (auto *CFT = dyn_cast(T)) { // Promote argument names (they have their own namespace) - promoteOriginalNamesInList(CFT->Arguments, AddressOf); + promoteOriginalNamesInList(CFT->Arguments(), AddressOf); } else if (auto *Enum = dyn_cast(T)) { // Promote enum entries names (they are symbols) - promoteOriginalNamesInList(Enum->Entries, AddressOf, Symbols); + promoteOriginalNamesInList(Enum->Entries(), AddressOf, Symbols); } } } diff --git a/lib/Model/Pass/PurgeUnnamedAndUnreachableTypes.cpp b/lib/Model/Pass/PurgeUnnamedAndUnreachableTypes.cpp index 55c8a2347..70202c138 100644 --- a/lib/Model/Pass/PurgeUnnamedAndUnreachableTypes.cpp +++ b/lib/Model/Pass/PurgeUnnamedAndUnreachableTypes.cpp @@ -76,19 +76,19 @@ void model::purgeTypesImpl(TupleTree &Model) { // Remember those types we want to preserve. if constexpr (PruneAllUnusedTypes) { - for (const auto &Function : Model->Functions) { - if (Function.Prototype.isValid()) { - ToKeep.insert(const_cast(Function.Prototype.get())); + for (const auto &Function : Model->Functions()) { + if (Function.Prototype().isValid()) { + ToKeep.insert(const_cast(Function.Prototype().get())); } } - for (UpcastablePointer &T : Model->Types) { + for (UpcastablePointer &T : Model->Types()) { TypeToNode[T.get()] = TypeGraph.addNode(NodeData{ T.get() }); } } else { - for (UpcastablePointer &T : Model->Types) { + for (UpcastablePointer &T : Model->Types()) { - if (not T->CustomName.empty() or not T->OriginalName.empty()) + if (not T->CustomName().empty() or not T->OriginalName().empty()) ToKeep.insert(T.get()); TypeToNode[T.get()] = TypeGraph.addNode(NodeData{ T.get() }); @@ -96,9 +96,9 @@ void model::purgeTypesImpl(TupleTree &Model) { } // Create type system edges - for (UpcastablePointer &T : Model->Types) { + for (UpcastablePointer &T : Model->Types()) { for (const model::QualifiedType &QT : T->edges()) { - auto *DependantType = QT.UnqualifiedType.get(); + auto *DependantType = QT.UnqualifiedType().get(); TypeToNode.at(T.get())->addSuccessor(TypeToNode.at(DependantType)); } } @@ -114,12 +114,12 @@ void model::purgeTypesImpl(TupleTree &Model) { }; visitTupleTree(Field, Visitor, [](auto) {}); }; - visitTupleExcept(VisitBinary, *Model, &Model->Types); + visitTupleExcept(VisitBinary, *Model, &Model->Types()); } // Visit all the nodes reachable from ToKeep df_iterator_default_set Visited; - for (const UpcastablePointer &T : Model->Types) + for (const UpcastablePointer &T : Model->Types()) if (isa(T.get())) Visited.insert(TypeToNode.at(T.get())); @@ -128,7 +128,7 @@ void model::purgeTypesImpl(TupleTree &Model) { ; // Purge the non-visited - llvm::erase_if(Model->Types, [&](UpcastablePointer &P) { + llvm::erase_if(Model->Types(), [&](UpcastablePointer &P) { return not Visited.contains(TypeToNode.at(P.get())); }); } diff --git a/lib/Model/Processing.cpp b/lib/Model/Processing.cpp index 01e4ea102..b2db01b32 100644 --- a/lib/Model/Processing.cpp +++ b/lib/Model/Processing.cpp @@ -30,17 +30,17 @@ unsigned dropTypesDependingOnTypes(TupleTree &Model, // Create nodes in reverse dependency graph std::map *> TypeToNode; - for (UpcastablePointer &T : Model->Types) + for (UpcastablePointer &T : Model->Types()) TypeToNode[T.get()] = ReverseDependencyGraph.addNode(TypeNode{ T.get() }); // Register edges - for (UpcastablePointer &T : Model->Types) { + for (UpcastablePointer &T : Model->Types()) { // Ignore dependencies of types we need to drop if (Types.count(T.get()) != 0) continue; for (const model::QualifiedType &QT : T->edges()) { - auto *DependantType = QT.UnqualifiedType.get(); + auto *DependantType = QT.UnqualifiedType().get(); TypeToNode.at(DependantType)->addSuccessor(TypeToNode.at(T.get())); } } @@ -54,20 +54,20 @@ unsigned dropTypesDependingOnTypes(TupleTree &Model, } // Purge dynamic functions depending on Types - auto Begin = Model->ImportedDynamicFunctions.begin(); - for (auto It = Begin; It != Model->ImportedDynamicFunctions.end(); /**/) { - if (not It->Prototype.isValid() - or ToDelete.count(It->Prototype.get()) == 0) { + auto Begin = Model->ImportedDynamicFunctions().begin(); + for (auto It = Begin; It != Model->ImportedDynamicFunctions().end(); /**/) { + if (not It->Prototype().isValid() + or ToDelete.count(It->Prototype().get()) == 0) { ++It; } else { - It = Model->ImportedDynamicFunctions.erase(It); + It = Model->ImportedDynamicFunctions().erase(It); } } // Purge types depending on unresolved Types - for (auto It = Model->Types.begin(); It != Model->Types.end();) { + for (auto It = Model->Types().begin(); It != Model->Types().end();) { if (ToDelete.count(It->get()) != 0) - It = Model->Types.erase(It); + It = Model->Types().erase(It); else ++It; } diff --git a/lib/Model/Type.cpp b/lib/Model/Type.cpp index 046f7527b..1c30f1779 100644 --- a/lib/Model/Type.cpp +++ b/lib/Model/Type.cpp @@ -333,28 +333,28 @@ makeTypeWithID(model::TypeKind::Values Kind, uint64_t ID) { Identifier model::UnionField::name() const { Identifier Result; - if (CustomName.empty()) - (Twine("unnamed_field_") + Twine(Index)).toVector(Result); + if (CustomName().empty()) + (Twine("unnamed_field_") + Twine(Index())).toVector(Result); else - Result = CustomName; + Result = CustomName(); return Result; } Identifier model::StructField::name() const { Identifier Result; - if (CustomName.empty()) - (Twine("unnamed_field_at_offset_") + Twine(Offset)).toVector(Result); + if (CustomName().empty()) + (Twine("unnamed_field_at_offset_") + Twine(Offset())).toVector(Result); else - Result = CustomName; + Result = CustomName(); return Result; } Identifier model::Argument::name() const { Identifier Result; - if (CustomName.empty()) - (Twine("unnamed_arg_") + Twine(Index)).toVector(Result); + if (CustomName().empty()) + (Twine("unnamed_arg_") + Twine(Index())).toVector(Result); else - Result = CustomName; + Result = CustomName(); return Result; } @@ -378,17 +378,17 @@ bool Qualifier::verify(bool Assert) const { } bool Qualifier::verify(VerifyHelper &VH) const { - switch (Kind) { + switch (Kind()) { case QualifierKind::Invalid: return VH.fail("Invalid qualifier found", *this); case QualifierKind::Pointer: - return VH.maybeFail(Size > 0 and llvm::isPowerOf2_64(Size), + return VH.maybeFail(Size() > 0 and llvm::isPowerOf2_64(Size()), "Pointer qualifier size is not a power of 2", *this); case QualifierKind::Const: - return VH.maybeFail(Size == 0, "const qualifier has non-0 size", *this); + return VH.maybeFail(Size() == 0, "const qualifier has non-0 size", *this); case QualifierKind::Array: - return VH.maybeFail(Size > 0, "Array qualifier size is 0"); + return VH.maybeFail(Size() > 0, "Array qualifier size is 0"); default: revng_abort(); } @@ -435,33 +435,33 @@ isValidPrimitiveSize(PrimitiveTypeKind::Values PrimKind, uint8_t BS) { Identifier model::PrimitiveType::name() const { Identifier Result; - switch (PrimitiveKind) { + switch (PrimitiveKind()) { case PrimitiveTypeKind::Void: Result = "void"; break; case PrimitiveTypeKind::Unsigned: - (Twine("uint") + Twine(Size * 8) + Twine("_t")).toVector(Result); + (Twine("uint") + Twine(Size() * 8) + Twine("_t")).toVector(Result); break; case PrimitiveTypeKind::Number: - (Twine("number") + Twine(Size * 8) + Twine("_t")).toVector(Result); + (Twine("number") + Twine(Size() * 8) + Twine("_t")).toVector(Result); break; case PrimitiveTypeKind::PointerOrNumber: - ("pointer_or_number" + Twine(Size * 8) + "_t").toVector(Result); + ("pointer_or_number" + Twine(Size() * 8) + "_t").toVector(Result); break; case PrimitiveTypeKind::Generic: - (Twine("generic") + Twine(Size * 8) + Twine("_t")).toVector(Result); + (Twine("generic") + Twine(Size() * 8) + Twine("_t")).toVector(Result); break; case PrimitiveTypeKind::Signed: - (Twine("int") + Twine(Size * 8) + Twine("_t")).toVector(Result); + (Twine("int") + Twine(Size() * 8) + Twine("_t")).toVector(Result); break; case PrimitiveTypeKind::Float: - (Twine("float") + Twine(Size * 8) + Twine("_t")).toVector(Result); + (Twine("float") + Twine(Size() * 8) + Twine("_t")).toVector(Result); break; default: @@ -473,10 +473,12 @@ Identifier model::PrimitiveType::name() const { template Identifier customNameOrAutomatic(T *This) { - if (not This->CustomName.empty()) - return This->CustomName; - else - return Identifier((Twine(T::AutomaticNamePrefix) + Twine(This->ID)).str()); + if (not This->CustomName().empty()) + return This->CustomName(); + else { + auto IdentText = (Twine(T::AutomaticNamePrefix) + Twine(This->ID())).str(); + return Identifier(IdentText); + } } Identifier model::StructType::name() const { @@ -496,10 +498,10 @@ Identifier model::UnionType::name() const { } Identifier model::NamedTypedRegister::name() const { - if (not CustomName.empty()) - return CustomName; + if (not CustomName().empty()) + return CustomName(); else - return Identifier(model::Register::getRegisterName(Location)); + return Identifier(model::Register::getRegisterName(Location())); } Identifier model::RawFunctionType::name() const { @@ -563,14 +565,14 @@ bool EnumEntry::verify(bool Assert) const { } bool EnumEntry::verify(VerifyHelper &VH) const { - return VH.maybeFail(CustomName.verify(VH)); + return VH.maybeFail(CustomName().verify(VH)); } static bool isOnlyConstQualified(const QualifiedType &QT) { - if (QT.Qualifiers.empty() or QT.Qualifiers.size() > 1) + if (QT.Qualifiers().empty() or QT.Qualifiers().size() > 1) return false; - return Qualifier::isConst(QT.Qualifiers[0]); + return Qualifier::isConst(QT.Qualifiers()[0]); } struct VoidConstResult { @@ -588,7 +590,7 @@ static VoidConstResult isVoidConst(const QualifiedType *QualType) { // Warning: we only skip const-qualifiers here, cause the other qualifiers // actually produce a different type. const Type *UnqualType = nullptr; - if (not QualType->Qualifiers.empty()) { + if (not QualType->Qualifiers().empty()) { // If it has a non-const qualifier, it can never be void because it's a // pointer or array, so we can break out. @@ -603,19 +605,19 @@ static VoidConstResult isVoidConst(const QualifiedType *QualType) { return Result; } - UnqualType = QualType->UnqualifiedType.get(); + UnqualType = QualType->UnqualifiedType().get(); - switch (UnqualType->Kind) { + switch (UnqualType->Kind()) { // If we still have a typedef in our way, unwrap it and keep looking. case TypeKind::TypedefType: { - QualType = &cast(UnqualType)->UnderlyingType; + QualType = &cast(UnqualType)->UnderlyingType(); } break; // If we have a primitive type, check the name, and we're done. case TypeKind::PrimitiveType: { auto *P = cast(UnqualType); - Result.IsVoid = P->PrimitiveKind == PrimitiveTypeKind::Void; + Result.IsVoid = P->PrimitiveKind() == PrimitiveTypeKind::Void; Done = true; } break; @@ -651,31 +653,31 @@ QualifiedType::size(VerifyHelper &VH) const { RecursiveCoroutine> QualifiedType::trySize(VerifyHelper &VH) const { // This code assumes that the QualifiedType QT is well formed. - auto QIt = Qualifiers.begin(); - auto QEnd = Qualifiers.end(); + auto QIt = Qualifiers().begin(); + auto QEnd = Qualifiers().end(); for (; QIt != QEnd; ++QIt) { auto &Q = *QIt; - switch (Q.Kind) { + switch (Q.Kind()) { case QualifierKind::Invalid: rc_return std::nullopt; case QualifierKind::Pointer: // If we find a pointer, we're done - rc_return Q.Size; + rc_return Q.Size(); case QualifierKind::Array: { // The size is equal to (number of elements of the array) * (size of a // single element). - const QualifiedType ArrayElem{ UnqualifiedType, + const QualifiedType ArrayElem{ UnqualifiedType(), { std::next(QIt), QEnd } }; auto MaybeSize = rc_recur ArrayElem.trySize(VH); if (not MaybeSize) rc_return std::nullopt; else - rc_return *MaybeSize *Q.Size; + rc_return *MaybeSize *Q.Size(); } case QualifierKind::Const: @@ -687,12 +689,12 @@ QualifiedType::trySize(VerifyHelper &VH) const { } } - rc_return rc_recur UnqualifiedType.get()->trySize(VH); + rc_return rc_recur UnqualifiedType().get()->trySize(VH); } static RecursiveCoroutine isArrayImpl(const model::QualifiedType &QT) { const auto &NotIsConst = std::not_fn(model::Qualifier::isConst); - for (const auto &Q : llvm::make_filter_range(QT.Qualifiers, NotIsConst)) { + for (const auto &Q : llvm::make_filter_range(QT.Qualifiers(), NotIsConst)) { // If we find an array first, it's definitely an array, otherwise we // found a pointer first, so it's definitely not an array @@ -702,8 +704,8 @@ static RecursiveCoroutine isArrayImpl(const model::QualifiedType &QT) { rc_return false; } - if (auto *TD = dyn_cast(QT.UnqualifiedType.get())) - rc_return rc_recur isArrayImpl(TD->UnderlyingType); + if (auto *TD = dyn_cast(QT.UnqualifiedType().get())) + rc_return rc_recur isArrayImpl(TD->UnderlyingType()); // If there are no non-const qualifiers, it's not an array rc_return false; @@ -715,7 +717,7 @@ bool QualifiedType::isArray() const { static RecursiveCoroutine isPointerImpl(const model::QualifiedType &QT) { const auto &NotIsConst = std::not_fn(Qualifier::isConst); - for (const auto &Q : llvm::make_filter_range(QT.Qualifiers, NotIsConst)) { + for (const auto &Q : llvm::make_filter_range(QT.Qualifiers(), NotIsConst)) { // If we find a pointer first, it's definitely a pointer, otherwise we // found an array first, so it's definitely not a pointer @@ -725,8 +727,8 @@ static RecursiveCoroutine isPointerImpl(const model::QualifiedType &QT) { rc_return false; } - if (auto *TD = dyn_cast(QT.UnqualifiedType.get())) - rc_return rc_recur isPointerImpl(TD->UnderlyingType); + if (auto *TD = dyn_cast(QT.UnqualifiedType().get())) + rc_return rc_recur isPointerImpl(TD->UnderlyingType()); // If there are no non-const qualifiers, it's not a pointer rc_return false; @@ -737,13 +739,13 @@ bool QualifiedType::isPointer() const { } static RecursiveCoroutine isConstImpl(const model::QualifiedType &QT) { - auto *TD = dyn_cast(QT.UnqualifiedType.get()); - if (not QT.Qualifiers.empty()) { + auto *TD = dyn_cast(QT.UnqualifiedType().get()); + if (not QT.Qualifiers().empty()) { // If there are qualifiers, just look at the first - rc_return Qualifier::isConst(QT.Qualifiers.front()); + rc_return Qualifier::isConst(QT.Qualifiers().front()); } else if (TD != nullptr) { // If there are no qualifiers, but it's a typedef, traverse it - rc_return rc_recur isConstImpl(TD->UnderlyingType); + rc_return rc_recur isConstImpl(TD->UnderlyingType()); } // If there are no qualifiers, and it's not a typedef, it's not const. @@ -757,16 +759,16 @@ bool QualifiedType::isConst() const { static RecursiveCoroutine isPrimitiveImpl(const model::QualifiedType &QT, std::optional V) { - if (QT.Qualifiers.size() != 0 - and not llvm::all_of(QT.Qualifiers, Qualifier::isConst)) + if (QT.Qualifiers().size() != 0 + and not llvm::all_of(QT.Qualifiers(), Qualifier::isConst)) rc_return false; - const model::Type *UnqualifiedType = QT.UnqualifiedType.get(); + const model::Type *UnqualifiedType = QT.UnqualifiedType().get(); if (auto *Primitive = llvm::dyn_cast(UnqualifiedType)) - rc_return !V.has_value() || Primitive->PrimitiveKind == *V; + rc_return !V.has_value() || Primitive->PrimitiveKind() == *V; if (auto *Typedef = llvm::dyn_cast(UnqualifiedType)) - rc_return rc_recur isPrimitiveImpl(Typedef->UnderlyingType, V); + rc_return rc_recur isPrimitiveImpl(Typedef->UnderlyingType(), V); rc_return false; } @@ -781,17 +783,17 @@ bool QualifiedType::isPrimitive(PrimitiveTypeKind::Values V) const { static RecursiveCoroutine isImpl(const model::QualifiedType &QT, model::TypeKind::Values K) { - if (QT.Qualifiers.size() != 0 - and not llvm::all_of(QT.Qualifiers, Qualifier::isConst)) + if (QT.Qualifiers().size() != 0 + and not llvm::all_of(QT.Qualifiers(), Qualifier::isConst)) rc_return false; - const model::Type *UnqualifiedType = QT.UnqualifiedType.get(); + const model::Type *UnqualifiedType = QT.UnqualifiedType().get(); - if (UnqualifiedType->Kind == K) + if (UnqualifiedType->Kind() == K) rc_return true; if (auto *Typedef = llvm::dyn_cast(UnqualifiedType)) - rc_return rc_recur isImpl(Typedef->UnderlyingType, K); + rc_return rc_recur isImpl(Typedef->UnderlyingType(), K); rc_return false; } @@ -828,7 +830,7 @@ Type::trySize(VerifyHelper &VH) const { // This code assumes that the type T is well formed. uint64_t Size; - switch (Kind) { + switch (Kind()) { case TypeKind::Invalid: rc_return std::nullopt; @@ -841,23 +843,23 @@ Type::trySize(VerifyHelper &VH) const { case TypeKind::PrimitiveType: { auto *P = cast(this); - if (P->PrimitiveKind == model::PrimitiveTypeKind::Void) { + if (P->PrimitiveKind() == model::PrimitiveTypeKind::Void) { // Void types have no size - if (P->Size != 0) { + if (P->Size() != 0) { // Not valid rc_return std::nullopt; } Size = 0; } else { - Size = P->Size; + Size = P->Size(); } } break; case TypeKind::EnumType: { auto *U = llvm::cast(this); - auto MaybeSize = rc_recur U->UnderlyingType.trySize(VH); + auto MaybeSize = rc_recur U->UnderlyingType().trySize(VH); if (not MaybeSize) rc_return std::nullopt; @@ -867,7 +869,7 @@ Type::trySize(VerifyHelper &VH) const { case TypeKind::TypedefType: { auto *Typedef = llvm::cast(this); - auto MaybeSize = rc_recur Typedef->UnderlyingType.trySize(VH); + auto MaybeSize = rc_recur Typedef->UnderlyingType().trySize(VH); if (not MaybeSize) rc_return std::nullopt; @@ -875,15 +877,15 @@ Type::trySize(VerifyHelper &VH) const { } break; case TypeKind::StructType: { - Size = llvm::cast(this)->Size; + Size = llvm::cast(this)->Size(); } break; case TypeKind::UnionType: { auto *U = llvm::cast(this); uint64_t Max = 0ULL; - for (const auto &Field : U->Fields) { - auto MaybeFieldSize = rc_recur Field.Type.trySize(VH); + for (const auto &Field : U->Fields()) { + auto MaybeFieldSize = rc_recur Field.Type().trySize(VH); if (not MaybeFieldSize) rc_return std::nullopt; @@ -904,20 +906,21 @@ Type::trySize(VerifyHelper &VH) const { static RecursiveCoroutine verifyImpl(VerifyHelper &VH, const PrimitiveType *T) { - revng_assert(T->Kind == TypeKind::PrimitiveType); + revng_assert(T->Kind() == TypeKind::PrimitiveType); - if (not T->CustomName.empty() or not T->OriginalName.empty()) + if (not T->CustomName().empty() or not T->OriginalName().empty()) rc_return VH.fail("PrimitiveTypes cannot have OriginalName or CustomName", *T); - auto ExpectedID = makePrimitiveID(T->PrimitiveKind, T->Size); - if (T->ID != ExpectedID) - rc_return VH.fail(Twine("Wrong ID for PrimitiveType. Got: ") + Twine(T->ID) - + ". Expected: " + Twine(ExpectedID) + ".", + auto ExpectedID = makePrimitiveID(T->PrimitiveKind(), T->Size()); + if (T->ID() != ExpectedID) + rc_return VH.fail(Twine("Wrong ID for PrimitiveType. Got: ") + + Twine(T->ID()) + ". Expected: " + Twine(ExpectedID) + + ".", *T); - if (not isValidPrimitiveSize(T->PrimitiveKind, T->Size)) - rc_return VH.fail("Invalid PrimitiveType size: " + Twine(T->Size), *T); + if (not isValidPrimitiveSize(T->PrimitiveKind(), T->Size())) + rc_return VH.fail("Invalid PrimitiveType size: " + Twine(T->Size()), *T); rc_return true; } @@ -954,32 +957,32 @@ bool Identifier::verify(VerifyHelper &VH) const { static RecursiveCoroutine verifyImpl(VerifyHelper &VH, const EnumType *T) { - if (T->Kind != TypeKind::EnumType or T->Entries.empty() - or not T->CustomName.verify(VH)) + if (T->Kind() != TypeKind::EnumType or T->Entries().empty() + or not T->CustomName().verify(VH)) rc_return VH.fail(); // The underlying type has to be an unqualified primitive type - if (not rc_recur T->UnderlyingType.verify(VH) - or not T->UnderlyingType.Qualifiers.empty()) + if (not rc_recur T->UnderlyingType().verify(VH) + or not T->UnderlyingType().Qualifiers().empty()) rc_return VH.fail(); // We only allow signed/unsigned as underlying type - if (not T->UnderlyingType.isPrimitive(PrimitiveTypeKind::Signed) - and not T->UnderlyingType.isPrimitive(PrimitiveTypeKind::Unsigned)) + if (not T->UnderlyingType().isPrimitive(PrimitiveTypeKind::Signed) + and not T->UnderlyingType().isPrimitive(PrimitiveTypeKind::Unsigned)) rc_return VH.fail("UnderlyingType of a EnumType can only be Signed or " "Unsigned", *T); llvm::SmallSet Names; - for (auto &Entry : T->Entries) { + for (auto &Entry : T->Entries()) { if (not Entry.verify(VH)) rc_return VH.fail(); // TODO: verify Entry.Value is within boundaries - if (not Entry.CustomName.empty()) { - if (not Names.insert(Entry.CustomName).second) + if (not Entry.CustomName().empty()) { + if (not Names.insert(Entry.CustomName()).second) rc_return VH.fail(); } } @@ -989,14 +992,14 @@ verifyImpl(VerifyHelper &VH, const EnumType *T) { static RecursiveCoroutine verifyImpl(VerifyHelper &VH, const TypedefType *T) { - rc_return VH.maybeFail(T->CustomName.verify(VH) - and T->Kind == TypeKind::TypedefType - and rc_recur T->UnderlyingType.verify(VH)); + rc_return VH.maybeFail(T->CustomName().verify(VH) + and T->Kind() == TypeKind::TypedefType + and rc_recur T->UnderlyingType().verify(VH)); } inline RecursiveCoroutine isScalarImpl(const QualifiedType &QT) { - for (const Qualifier &Q : QT.Qualifiers) { - switch (Q.Kind) { + for (const Qualifier &Q : QT.Qualifiers()) { + switch (Q.Kind()) { case QualifierKind::Invalid: revng_abort(); case QualifierKind::Pointer: @@ -1010,7 +1013,7 @@ inline RecursiveCoroutine isScalarImpl(const QualifiedType &QT) { } } - const Type *Unqualified = QT.UnqualifiedType.get(); + const Type *Unqualified = QT.UnqualifiedType().get(); revng_assert(Unqualified != nullptr); if (llvm::isa(Unqualified) or llvm::isa(Unqualified)) { @@ -1018,7 +1021,7 @@ inline RecursiveCoroutine isScalarImpl(const QualifiedType &QT) { } if (auto *Typedef = llvm::dyn_cast(Unqualified)) - rc_return rc_recur isScalarImpl(Typedef->UnderlyingType); + rc_return rc_recur isScalarImpl(Typedef->UnderlyingType()); rc_return false; } @@ -1031,56 +1034,56 @@ static RecursiveCoroutine verifyImpl(VerifyHelper &VH, const StructType *T) { using namespace llvm; - revng_assert(T->Kind == TypeKind::StructType); + revng_assert(T->Kind() == TypeKind::StructType); - if (not T->CustomName.verify(VH)) + if (not T->CustomName().verify(VH)) rc_return VH.fail("Invalid name", *T); - if (T->Size == 0) + if (T->Size() == 0) rc_return VH.fail("Struct type has zero size", *T); size_t Index = 0; llvm::SmallSet Names; - auto FieldIt = T->Fields.begin(); - auto FieldEnd = T->Fields.end(); + auto FieldIt = T->Fields().begin(); + auto FieldEnd = T->Fields().end(); for (; FieldIt != FieldEnd; ++FieldIt) { auto &Field = *FieldIt; if (not rc_recur Field.verify(VH)) rc_return VH.fail("Can't verify type of field " + Twine(Index + 1), *T); - if (Field.Offset >= T->Size) + if (Field.Offset() >= T->Size()) rc_return VH.fail("Field " + Twine(Index + 1) + " out of struct boundaries (offset: " - + Twine(Field.Offset) + ", size: " + Twine(T->Size) - + ")", + + Twine(Field.Offset()) + + ", size: " + Twine(T->Size()) + ")", *T); - auto MaybeSize = rc_recur Field.Type.size(VH); + auto MaybeSize = rc_recur Field.Type().size(VH); // This is verified AggregateField::verify revng_assert(MaybeSize); - auto FieldEndOffset = Field.Offset + *MaybeSize; + auto FieldEndOffset = Field.Offset() + *MaybeSize; auto NextFieldIt = std::next(FieldIt); if (NextFieldIt != FieldEnd) { // If this field is not the last, check that it does not overlap with the // following field. - if (FieldEndOffset > NextFieldIt->Offset) { + if (FieldEndOffset > NextFieldIt->Offset()) { rc_return VH.fail("Field " + Twine(Index + 1) + " overlaps with the next one", *T); } - } else if (FieldEndOffset > T->Size) { + } else if (FieldEndOffset > T->Size()) { // Otherwise, if this field is the last, check that it's not larger than // size. rc_return VH.fail("Last field ends outside the struct", *T); } - if (isVoidConst(&Field.Type).IsVoid) + if (isVoidConst(&Field.Type()).IsVoid) rc_return VH.fail("Field " + Twine(Index + 1) + " is void", *T); - if (not Field.CustomName.empty() - and not Names.insert(Field.CustomName).second) + if (not Field.CustomName().empty() + and not Names.insert(Field.CustomName()).second) rc_return VH.fail("Collision in struct fields names", *T); ++Index; @@ -1091,20 +1094,20 @@ verifyImpl(VerifyHelper &VH, const StructType *T) { static RecursiveCoroutine verifyImpl(VerifyHelper &VH, const UnionType *T) { - revng_assert(T->Kind == TypeKind::UnionType); + revng_assert(T->Kind() == TypeKind::UnionType); - if (not T->CustomName.verify(VH)) + if (not T->CustomName().verify(VH)) rc_return VH.fail("Invalid name", *T); - if (T->Fields.empty()) + if (T->Fields().empty()) rc_return VH.fail("Union type has zero fields", *T); llvm::SmallSet Names; - for (auto &Group : llvm::enumerate(T->Fields)) { + for (auto &Group : llvm::enumerate(T->Fields())) { auto &Field = Group.value(); uint64_t ExpectedIndex = Group.index(); - if (Field.Index != ExpectedIndex) { + if (Field.Index() != ExpectedIndex) { rc_return VH.fail(Twine("Union type is missing field ") + Twine(ExpectedIndex), *T); @@ -1113,16 +1116,16 @@ verifyImpl(VerifyHelper &VH, const UnionType *T) { if (not rc_recur Field.verify(VH)) rc_return VH.fail(); - auto MaybeSize = rc_recur Field.Type.size(VH); + auto MaybeSize = rc_recur Field.Type().size(VH); // This is verified AggregateField::verify revng_assert(MaybeSize); - if (isVoidConst(&Field.Type).IsVoid) { - rc_return VH.fail("Field " + Twine(Field.Index) + " is void", *T); + if (isVoidConst(&Field.Type()).IsVoid) { + rc_return VH.fail("Field " + Twine(Field.Index()) + " is void", *T); } - if (not Field.CustomName.empty() - and not Names.insert(Field.CustomName).second) + if (not Field.CustomName().empty() + and not Names.insert(Field.CustomName()).second) rc_return VH.fail("Collision in union fields names", *T); } @@ -1131,31 +1134,31 @@ verifyImpl(VerifyHelper &VH, const UnionType *T) { static RecursiveCoroutine verifyImpl(VerifyHelper &VH, const CABIFunctionType *T) { - if (not T->CustomName.verify(VH) or T->Kind != TypeKind::CABIFunctionType - or not rc_recur T->ReturnType.verify(VH)) + if (not T->CustomName().verify(VH) or T->Kind() != TypeKind::CABIFunctionType + or not rc_recur T->ReturnType().verify(VH)) rc_return VH.fail(); - if (T->ABI == model::ABI::Invalid) + if (T->ABI() == model::ABI::Invalid) rc_return VH.fail("An invalid ABI", *T); - for (auto &Group : llvm::enumerate(T->Arguments)) { + for (auto &Group : llvm::enumerate(T->Arguments())) { auto &Argument = Group.value(); uint64_t ArgPos = Group.index(); - if (not Argument.CustomName.verify(VH)) + if (not Argument.CustomName().verify(VH)) rc_return VH.fail("An argument has invalid CustomName", *T); - if (Argument.Index != ArgPos) + if (Argument.Index() != ArgPos) rc_return VH.fail("An argument has invalid index", *T); - if (not rc_recur Argument.Type.verify(VH)) + if (not rc_recur Argument.Type().verify(VH)) rc_return VH.fail("An argument has invalid type", *T); - VoidConstResult VoidConst = isVoidConst(&Argument.Type); + VoidConstResult VoidConst = isVoidConst(&Argument.Type()); if (VoidConst.IsVoid) { // If we have a void argument it must be the only one, and the function // cannot be vararg. - if (T->Arguments.size() > 1) + if (T->Arguments().size() > 1) rc_return VH.fail("More than 1 void argument", *T); // Cannot have const-qualified void as argument. @@ -1170,25 +1173,25 @@ verifyImpl(VerifyHelper &VH, const CABIFunctionType *T) { static RecursiveCoroutine verifyImpl(VerifyHelper &VH, const RawFunctionType *T) { - for (const NamedTypedRegister &Argument : T->Arguments) + for (const NamedTypedRegister &Argument : T->Arguments()) if (not rc_recur Argument.verify(VH)) rc_return VH.fail(); - for (const TypedRegister &Return : T->ReturnValues) + for (const TypedRegister &Return : T->ReturnValues()) if (not rc_recur Return.verify(VH)) rc_return VH.fail(); - for (const Register::Values &Preserved : T->PreservedRegisters) + for (const Register::Values &Preserved : T->PreservedRegisters()) if (Preserved == Register::Invalid) rc_return VH.fail(); - if (not T->StackArgumentsType.Qualifiers.empty()) + if (not T->StackArgumentsType().Qualifiers().empty()) rc_return VH.fail(); - if (T->StackArgumentsType.UnqualifiedType.isValid() - and not rc_recur T->StackArgumentsType.UnqualifiedType.get()->verify(VH)) + if (auto &Type = T->StackArgumentsType().UnqualifiedType(); + Type.isValid() and not rc_recur Type.get()->verify(VH)) rc_return VH.fail(); - rc_return VH.maybeFail(T->CustomName.verify(VH)); + rc_return VH.maybeFail(T->CustomName().verify(VH)); } void Type::dump() const { @@ -1226,13 +1229,13 @@ RecursiveCoroutine Type::verify(VerifyHelper &VH) const { VH.verificationInProgess(this); - if (ID == 0) + if (ID() == 0) rc_return VH.fail(); bool Result = false; // We could use upcast() but we'd need to workaround coroutines. - switch (Kind) { + switch (Kind()) { case TypeKind::PrimitiveType: Result = rc_recur verifyImpl(VH, cast(this)); break; @@ -1287,16 +1290,16 @@ bool QualifiedType::verify(bool Assert) const { } RecursiveCoroutine QualifiedType::verify(VerifyHelper &VH) const { - if (not UnqualifiedType.isValid()) + if (not UnqualifiedType().isValid()) rc_return VH.fail("Underlying type is invalid", *this); // Verify the qualifiers are valid - for (const auto &Q : Qualifiers) + for (const auto &Q : Qualifiers()) if (not Q.verify(VH)) rc_return VH.fail("Invalid qualifier", Q); - auto QIt = Qualifiers.begin(); - auto QEnd = Qualifiers.end(); + auto QIt = Qualifiers().begin(); + auto QEnd = Qualifiers().end(); for (; QIt != QEnd; ++QIt) { const auto &Q = *QIt; auto NextQIt = std::next(QIt); @@ -1310,7 +1313,7 @@ RecursiveCoroutine QualifiedType::verify(VerifyHelper &VH) const { if (Qualifier::isPointer(Q)) { // Don't proceed the verification, just make sure the pointer is either // 32- or 64-bit - rc_return VH.maybeFail(Q.Size == 4 or Q.Size == 8, + rc_return VH.maybeFail(Q.Size() == 4 or Q.Size() == 8, "Only 32-bit and 64-bit pointers " "are currently " "supported", @@ -1318,11 +1321,11 @@ RecursiveCoroutine QualifiedType::verify(VerifyHelper &VH) const { } else if (Qualifier::isArray(Q)) { // Ensure there's at least one element - if (Q.Size < 1) + if (Q.Size() < 1) rc_return VH.fail("Arrays need to have at least an element", *this); // Verify element type - QualifiedType ElementType{ UnqualifiedType, { NextQIt, QEnd } }; + QualifiedType ElementType{ UnqualifiedType(), { NextQIt, QEnd } }; if (not rc_recur ElementType.verify(VH)) rc_return VH.fail("Array element invalid", ElementType); @@ -1333,7 +1336,7 @@ RecursiveCoroutine QualifiedType::verify(VerifyHelper &VH) const { ElementType); } else if (Qualifier::isConst(Q)) { // const qualifiers must have zero size - if (Q.Size != 0) + if (Q.Size() != 0) rc_return VH.fail("const qualifier has non-0 size"); } else { @@ -1343,31 +1346,31 @@ RecursiveCoroutine QualifiedType::verify(VerifyHelper &VH) const { // If we get here, we either have no qualifiers or just const qualifiers: // recur on the underlying type - rc_return VH.maybeFail(rc_recur UnqualifiedType.get()->verify(VH)); + rc_return VH.maybeFail(rc_recur UnqualifiedType().get()->verify(VH)); } template RecursiveCoroutine verifyTypedRegisterCommon(const T &TypedRegister, VerifyHelper &VH) { // Ensure the type we're pointing to is scalar - if (not TypedRegister->Type.isScalar()) + if (not TypedRegister->Type().isScalar()) rc_return VH.fail(); - if (TypedRegister->Location == Register::Invalid) + if (TypedRegister->Location() == Register::Invalid) rc_return VH.fail(); // Ensure if fits in the corresponding register - auto MaybeTypeSize = rc_recur TypedRegister->Type.size(VH); + auto MaybeTypeSize = rc_recur TypedRegister->Type().size(VH); // Zero-sized types are not allowed if (not MaybeTypeSize) rc_return VH.fail(); - size_t RegisterSize = model::Register::getSize(TypedRegister->Location); + size_t RegisterSize = model::Register::getSize(TypedRegister->Location()); if (*MaybeTypeSize > RegisterSize) rc_return VH.fail(); - rc_return VH.maybeFail(rc_recur TypedRegister->Type.verify(VH)); + rc_return VH.maybeFail(rc_recur TypedRegister->Type().verify(VH)); } void TypedRegister::dump() const { @@ -1402,7 +1405,7 @@ bool NamedTypedRegister::verify(bool Assert) const { RecursiveCoroutine NamedTypedRegister::verify(VerifyHelper &VH) const { // Ensure the name is valid - if (not CustomName.verify(VH)) + if (not CustomName().verify(VH)) rc_return VH.fail(); rc_return verifyTypedRegisterCommon(this, VH); @@ -1418,15 +1421,15 @@ bool StructField::verify(bool Assert) const { } RecursiveCoroutine StructField::verify(VerifyHelper &VH) const { - if (not rc_recur Type.verify(VH)) + if (not rc_recur Type().verify(VH)) rc_return VH.fail("Aggregate field type is not valid"); // Aggregated fields cannot be zero-sized fields - auto MaybeSize = rc_recur Type.size(VH); + auto MaybeSize = rc_recur Type().size(VH); if (not MaybeSize) rc_return VH.fail("Aggregate field is zero-sized"); - rc_return VH.maybeFail(CustomName.verify(VH)); + rc_return VH.maybeFail(CustomName().verify(VH)); } bool UnionField::verify() const { @@ -1439,15 +1442,15 @@ bool UnionField::verify(bool Assert) const { } RecursiveCoroutine UnionField::verify(VerifyHelper &VH) const { - if (not rc_recur Type.verify(VH)) + if (not rc_recur Type().verify(VH)) rc_return VH.fail("Aggregate field type is not valid"); // Aggregated fields cannot be zero-sized fields - auto MaybeSize = rc_recur Type.size(VH); + auto MaybeSize = rc_recur Type().size(VH); if (not MaybeSize) - rc_return VH.fail("Aggregate field is zero-sized", Type); + rc_return VH.fail("Aggregate field is zero-sized", Type()); - rc_return VH.maybeFail(CustomName.verify(VH)); + rc_return VH.maybeFail(CustomName().verify(VH)); } void Argument::dump() const { @@ -1464,7 +1467,8 @@ bool Argument::verify(bool Assert) const { } RecursiveCoroutine Argument::verify(VerifyHelper &VH) const { - rc_return VH.maybeFail(CustomName.verify(VH) and rc_recur Type.verify(VH)); + rc_return VH.maybeFail(CustomName().verify(VH) + and rc_recur Type().verify(VH)); } } // namespace model diff --git a/lib/Model/TypeSystemPrinter.cpp b/lib/Model/TypeSystemPrinter.cpp index 9103871d6..60eb0ced0 100644 --- a/lib/Model/TypeSystemPrinter.cpp +++ b/lib/Model/TypeSystemPrinter.cpp @@ -78,32 +78,32 @@ static FieldList collectFields(const model::Type *T) { FieldList Fields; if (auto *Struct = llvm::dyn_cast(T)) { - for (auto &Field : Struct->Fields) - Fields.push_back(Field.Type); + for (auto &Field : Struct->Fields()) + Fields.push_back(Field.Type()); } else if (auto *Union = llvm::dyn_cast(T)) { - for (auto &Field : Union->Fields) - Fields.push_back(Field.Type); + for (auto &Field : Union->Fields()) + Fields.push_back(Field.Type()); } else if (auto *CABIFunc = llvm::dyn_cast(T)) { - Fields.push_back(CABIFunc->ReturnType); - for (auto &Field : CABIFunc->Arguments) - Fields.push_back(Field.Type); + Fields.push_back(CABIFunc->ReturnType()); + for (auto &Field : CABIFunc->Arguments()) + Fields.push_back(Field.Type()); } else if (auto *RawFunc = llvm::dyn_cast(T)) { - for (auto &Field : RawFunc->ReturnValues) - Fields.push_back(Field.Type); + for (auto &Field : RawFunc->ReturnValues()) + Fields.push_back(Field.Type()); if (Fields.empty()) Fields.push_back({}); - for (auto &Field : RawFunc->Arguments) - Fields.push_back(Field.Type); + for (auto &Field : RawFunc->Arguments()) + Fields.push_back(Field.Type()); - if (RawFunc->StackArgumentsType.UnqualifiedType.isValid()) - Fields.push_back(RawFunc->StackArgumentsType); + if (RawFunc->StackArgumentsType().UnqualifiedType().isValid()) + Fields.push_back(RawFunc->StackArgumentsType()); } else if (auto *Typedef = llvm::dyn_cast(T)) { - Fields.push_back(Typedef->UnderlyingType); + Fields.push_back(Typedef->UnderlyingType()); } return Fields; @@ -130,20 +130,20 @@ static llvm::SmallString<32> buildFieldName(const model::QualifiedType &FieldQT) { llvm::SmallString<32> FieldName; - if (FieldQT.UnqualifiedType.isValid()) { - FieldName += FieldQT.UnqualifiedType.get()->name(); + if (FieldQT.UnqualifiedType().isValid()) { + FieldName += FieldQT.UnqualifiedType().get()->name(); FieldName += " "; } else { FieldName += "void "; } - for (auto &Q : FieldQT.Qualifiers) { - switch (Q.Kind) { + for (auto &Q : FieldQT.Qualifiers()) { + switch (Q.Kind()) { case model::QualifierKind::Pointer: FieldName += "*"; break; case model::QualifierKind::Array: - FieldName += "[" + to_string(Q.Size) + "]"; + FieldName += "[" + to_string(Q.Size()) + "]"; break; default: break; @@ -169,7 +169,7 @@ static void addStructField(llvm::raw_ostream &Out, /// Generate the inner table of a struct type static void dumpStructFields(llvm::raw_ostream &Out, const model::StructType *T) { - if (T->Fields.size() == 0) { + if (T->Fields().size() == 0) { Out << ""; return; } @@ -184,17 +184,17 @@ dumpStructFields(llvm::raw_ostream &Out, const model::StructType *T) { // Struct fields are stacked vertically uint64_t LastOffset = 0; - for (auto FieldEnum : llvm::enumerate(T->Fields)) { + for (auto FieldEnum : llvm::enumerate(T->Fields())) { const auto &Field = FieldEnum.value(); - const auto &FieldQT = Field.Type; - const auto FieldOffset = Field.Offset; + const auto &FieldQT = Field.Type(); + const auto FieldOffset = Field.Offset(); // Check if there's padding to be added before this field if (FieldOffset > LastOffset) addStructField(Out, LastOffset, FieldOffset - LastOffset, "padding"); addStructField(Out, - Field.Offset, + Field.Offset(), FieldQT.size().value_or(0), buildFieldName(FieldQT), FieldEnum.index()); @@ -210,7 +210,7 @@ dumpStructFields(llvm::raw_ostream &Out, const model::StructType *T) { /// Generate the inner table of a union type static void dumpUnionFields(llvm::raw_ostream &Out, const model::UnionType *T) { - if (T->Fields.size() == 0) { + if (T->Fields().size() == 0) { Out << ""; return; } @@ -218,9 +218,9 @@ static void dumpUnionFields(llvm::raw_ostream &Out, const model::UnionType *T) { Out << ""; // Union fields are disposed horizontally - for (auto FieldEnum : llvm::enumerate(T->Fields)) { + for (auto FieldEnum : llvm::enumerate(T->Fields())) { const auto &Field = FieldEnum.value(); - const auto &FieldQT = Field.Type; + const auto &FieldQT = Field.Type(); const auto FieldSize = FieldQT.size().value_or(0); paddedCell(Out, @@ -239,27 +239,27 @@ static void dumpFunctionType(llvm::raw_ostream &Out, const model::Type *T) { // Collect arguments and return types if (auto *RawFunc = dyn_cast(T)) { - for (auto &RetTy : RawFunc->ReturnValues) - ReturnTypes.push_back(RetTy.Type); + for (auto &RetTy : RawFunc->ReturnValues()) + ReturnTypes.push_back(RetTy.Type()); - for (auto &ArgTy : RawFunc->Arguments) - Arguments.push_back(ArgTy.Type); + for (auto &ArgTy : RawFunc->Arguments()) + Arguments.push_back(ArgTy.Type()); - if (RawFunc->StackArgumentsType.UnqualifiedType.isValid()) - Arguments.push_back(RawFunc->StackArgumentsType); + if (RawFunc->StackArgumentsType().UnqualifiedType().isValid()) + Arguments.push_back(RawFunc->StackArgumentsType()); } else if (auto *CABIFunc = dyn_cast(T)) { - ReturnTypes.push_back(CABIFunc->ReturnType); + ReturnTypes.push_back(CABIFunc->ReturnType()); - for (auto &ArgTy : CABIFunc->Arguments) - Arguments.push_back(ArgTy.Type); + for (auto &ArgTy : CABIFunc->Arguments()) + Arguments.push_back(ArgTy.Type()); } // Inner table that divides return types and arguments Out << ""; // Header - auto Color = getColor(T->Kind); + auto Color = getColor(T->Kind()); Out << ""; headerCell(Out, Color, "Return Types"); headerCell(Out, Color, "Arguments"); @@ -302,7 +302,7 @@ static void dumpFunctionType(llvm::raw_ostream &Out, const model::Type *T) { static void dumpTypedefUnderlying(llvm::raw_ostream &Out, const model::TypedefType *T) { Out << ""; - paddedCell(Out, buildFieldName(T->UnderlyingType), 0); + paddedCell(Out, buildFieldName(T->UnderlyingType()), 0); Out << ""; } @@ -311,7 +311,7 @@ void TypeSystemPrinter::dumpTypeNode(const model::Type *T, int NodeID) { Out << "node_" << to_string(NodeID) << "["; // Choose the node's border color - auto Color = getColor(T->Kind); + auto Color = getColor(T->Kind()); Out << "color=" << Color << ", "; // Start of HTML-style label @@ -360,15 +360,15 @@ void TypeSystemPrinter::addFieldEdge(const model::QualifiedType &QT, Out << "[label=\""; const char *Prefix = ""; - for (auto &Qual : QT.Qualifiers) { + for (auto &Qual : QT.Qualifiers()) { Out << Prefix; Prefix = ",\\n"; - switch (Qual.Kind) { + switch (Qual.Kind()) { case model::QualifierKind::Array: - Out << "Array[" << Qual.Size << "]"; + Out << "Array[" << Qual.Size() << "]"; break; case model::QualifierKind::Pointer: - Out << "Pointer (size " << Qual.Size << ")"; + Out << "Pointer (size " << Qual.Size() << ")"; break; default: break; @@ -414,13 +414,13 @@ void TypeSystemPrinter::print(const model::Type &T) { const model::Type *FieldUnqualType = nullptr; - if (FieldQT.UnqualifiedType.isValid()) - FieldUnqualType = FieldQT.UnqualifiedType.getConst(); + if (FieldQT.UnqualifiedType().isValid()) + FieldUnqualType = FieldQT.UnqualifiedType().getConst(); // Don't add edges for primitive types, as they would pollute the graph // and add no information regarding the type system structure if (not FieldUnqualType - or FieldUnqualType->Kind == model::TypeKind::PrimitiveType) + or FieldUnqualType->Kind() == model::TypeKind::PrimitiveType) continue; uint64_t SuccID; @@ -452,8 +452,8 @@ void TypeSystemPrinter::print(const model::Type &T) { } void TypeSystemPrinter::dumpFunctionNode(const model::Function &F, int NodeID) { - const model::Type *PrototypeT = F.Prototype.getConst(); - const model::Type *StackT = F.StackFrameType.getConst(); + const model::Type *PrototypeT = F.Prototype().getConst(); + const model::Type *StackT = F.StackFrameType().getConst(); // Print the name of the node Out << "node_" << to_string(NodeID) << "["; @@ -480,7 +480,7 @@ void TypeSystemPrinter::dumpFunctionNode(const model::Function &F, int NodeID) { // Second row of the inner table (actual types) Out << ""; paddedCell(Out, PrototypeT->name(), /*port=*/0); - if (F.StackFrameType.isValid()) + if (F.StackFrameType().isValid()) paddedCell(Out, StackT->name(), /*port=*/1); else Out << ""; @@ -500,9 +500,9 @@ void TypeSystemPrinter::print(const model::Function &F) { NextID++; // Nodes of the subtypes if they do not already exist - const model::Type *PrototypeT = F.Prototype.getConst(); - const model::Type *StackT = F.StackFrameType.getConst(); - bool HasStackFrame = F.StackFrameType.isValid(); + const model::Type *PrototypeT = F.Prototype().getConst(); + const model::Type *StackT = F.StackFrameType().getConst(); + bool HasStackFrame = F.StackFrameType().isValid(); print(*PrototypeT); if (HasStackFrame) @@ -519,16 +519,16 @@ void TypeSystemPrinter::print(const model::Function &F) { void TypeSystemPrinter::print(const model::Binary &Model) { // Print all functions and related types - for (auto &F : Model.Functions) + for (auto &F : Model.Functions()) print(F); // Print remaining types, if any - for (auto &T : Model.Types) { + for (auto &T : Model.Types()) { if (NodesMap.contains(T.get())) continue; // Avoid polluting the graph with uninformative nodes - if (T->Kind != model::TypeKind::PrimitiveType and not T->edges().empty()) + if (T->Kind() != model::TypeKind::PrimitiveType and not T->edges().empty()) print(*T); } } diff --git a/lib/Pipes/TaggedFunctionKind.cpp b/lib/Pipes/TaggedFunctionKind.cpp index 9dc453cae..193b453c0 100644 --- a/lib/Pipes/TaggedFunctionKind.cpp +++ b/lib/Pipes/TaggedFunctionKind.cpp @@ -61,7 +61,7 @@ void TaggedFK::getInvalidations(const Context &Ctx, void TaggedFunctionKind::appendAllTargets(const pipeline::Context &Ctx, pipeline::TargetsList &Out) const { const auto &Model = getModelFromContext(Ctx); - for (const auto &Function : Model->Functions) { - Out.push_back(Target(Function.Entry.toString(), *this)); + for (const auto &Function : Model->Functions()) { + Out.push_back(Target(Function.Entry().toString(), *this)); } } diff --git a/lib/Recompile/LinkForTranslation.cpp b/lib/Recompile/LinkForTranslation.cpp index b5cb34c90..00ad2af0d 100644 --- a/lib/Recompile/LinkForTranslation.cpp +++ b/lib/Recompile/LinkForTranslation.cpp @@ -187,9 +187,9 @@ static CommandList linkingArgs(const model::Binary &Model, // Output file appendTo({ "-o", LinkerOutput.path().str() }, Linker.Arguments); - revng_assert(Model.Segments.size() > 0); - uint64_t Min = Model.Segments.begin()->StartAddress.address(); - uint64_t Max = Model.Segments.begin()->endAddress().address(); + revng_assert(Model.Segments().size() > 0); + uint64_t Min = Model.Segments().begin()->StartAddress().address(); + uint64_t Max = Model.Segments().begin()->endAddress().address(); // Link opening crt files appendTo({ "-l:crt1.o", "-l:crti.o", "-l:crtbegin.o" }, Linker.Arguments); @@ -201,7 +201,7 @@ static CommandList linkingArgs(const model::Binary &Model, std::string SectionName; { llvm::raw_string_ostream NameStream(SectionName); - NameStream << "segment-" << Segment.StartAddress.toString() << "-" + NameStream << "segment-" << Segment.StartAddress().toString() << "-" << Segment.endAddress().toString(); } @@ -212,14 +212,14 @@ static CommandList linkingArgs(const model::Binary &Model, Command DD("dd"); DD.Arguments = { { "status=none", "bs=1", - ("skip=" + Twine(Segment.StartOffset)).str(), + ("skip=" + Twine(Segment.StartOffset())).str(), ("if=" + InputBinary).str(), - ("count=" + Twine(Segment.FileSize)).str(), + ("count=" + Twine(Segment.FileSize())).str(), ("of=" + RawSegment.path()).str() } }; Result.enqueueCommand(std::move(DD)); Command Truncate("truncate"); - Truncate.Arguments = { { ("--size=" + Twine(Segment.VirtualSize)).str(), + Truncate.Arguments = { { ("--size=" + Twine(Segment.VirtualSize())).str(), RawSegment.path().str() } }; Result.enqueueCommand(std::move(Truncate)); @@ -231,7 +231,7 @@ static CommandList linkingArgs(const model::Binary &Model, "o"); std::string SectionFlags = "alloc"; - if (not Segment.IsWriteable) + if (not Segment.IsWriteable()) SectionFlags += ",readonly"; ObjCopy.Arguments = { "-Ibinary", @@ -245,14 +245,14 @@ static CommandList linkingArgs(const model::Binary &Model, // Register the objcopy invocation Result.enqueueCommand(ObjCopy); - Min = std::min(Min, Segment.StartAddress.address()); + Min = std::min(Min, Segment.StartAddress().address()); Max = std::max(Max, Segment.endAddress().address()); // Add to linker command line Linker.Arguments.push_back(SegmentELF.path().str()); // Force section address at link-time - const auto &StartAddr = Segment.StartAddress.address(); + const auto &StartAddr = Segment.StartAddress().address(); Linker.Arguments.push_back((Twine("--section-start=.") + SectionName + Twine("=0x") + UToHexStr(StartAddr)) .str()); @@ -285,7 +285,7 @@ static CommandList linkingArgs(const model::Binary &Model, // Link required dynamic libraries Linker.Arguments.push_back("--no-as-needed"); - for (const std::string &ImportedLibrary : Model.ImportedLibraries) + for (const std::string &ImportedLibrary : Model.ImportedLibraries()) Linker.Arguments.push_back(linkFunctionArgument(ImportedLibrary)); Linker.Arguments.push_back("--as-needed"); diff --git a/lib/Yield/Assembly/DisassemblyHelper.cpp b/lib/Yield/Assembly/DisassemblyHelper.cpp index b1e3cc5dd..2af114c96 100644 --- a/lib/Yield/Assembly/DisassemblyHelper.cpp +++ b/lib/Yield/Assembly/DisassemblyHelper.cpp @@ -51,22 +51,22 @@ static void analyzeBasicBlocks(yield::Function &Function, // Gather all the basic blocks that only have a single predecessor. std::map> Predecessors; - for (const efa::BasicBlock &BasicBlock : Metadata.ControlFlowGraph) { - auto [It, Success] = Predecessors.try_emplace(BasicBlock.Start); + for (const efa::BasicBlock &BasicBlock : Metadata.ControlFlowGraph()) { + auto [It, Success] = Predecessors.try_emplace(BasicBlock.Start()); revng_assert(Success, "Duplicate basic blocks in a `SortedVector`? " "Something is clearly very wrong."); } // Remove the entry block from the analysis - its label is always required. - size_t RemovedCount = Predecessors.erase(Function.Entry); + size_t RemovedCount = Predecessors.erase(Function.Entry()); revng_assert(RemovedCount == 1, "No basic block at the function entry address!"); - for (const efa::BasicBlock &BasicBlock : Metadata.ControlFlowGraph) { - for (const auto &Edge : BasicBlock.Successors) { + for (const efa::BasicBlock &BasicBlock : Metadata.ControlFlowGraph()) { + for (const auto &Edge : BasicBlock.Successors()) { auto [NextBlock, _] = efa::parseSuccessor(*convert(Edge).get(), - BasicBlock.End, + BasicBlock.End(), Binary); if (NextBlock.isInvalid()) { // Ignore edges with unknown destinations (like indirect jumps). @@ -80,7 +80,7 @@ static void analyzeBasicBlocks(yield::Function &Function, Predecessors.erase(Iterator); } else { // First predecessor found - save it. - Iterator->second = BasicBlock.Start; + Iterator->second = BasicBlock.Start(); } } } @@ -89,17 +89,17 @@ static void analyzeBasicBlocks(yield::Function &Function, // Save the results of the analysis for (auto [CurrentAddress, PredecessorAddress] : Predecessors) { if (PredecessorAddress.has_value()) { - auto Current = Metadata.ControlFlowGraph.find(CurrentAddress); - revng_assert(Current != Metadata.ControlFlowGraph.end()); + auto Current = Metadata.ControlFlowGraph().find(CurrentAddress); + revng_assert(Current != Metadata.ControlFlowGraph().end()); - auto Predecessor = Metadata.ControlFlowGraph.find(*PredecessorAddress); - revng_assert(Predecessor != Metadata.ControlFlowGraph.end()); + auto Predecessor = Metadata.ControlFlowGraph().find(*PredecessorAddress); + revng_assert(Predecessor != Metadata.ControlFlowGraph().end()); - auto CurrentBlock = Function.ControlFlowGraph.find(CurrentAddress); - revng_assert(CurrentBlock != Function.ControlFlowGraph.end()); + auto CurrentBlock = Function.ControlFlowGraph().find(CurrentAddress); + revng_assert(CurrentBlock != Function.ControlFlowGraph().end()); - if (Predecessor->End == Current->Start) - CurrentBlock->IsLabelAlwaysRequired = false; + if (Predecessor->End() == Current->Start()) + CurrentBlock->IsLabelAlwaysRequired() = false; } } } @@ -108,70 +108,71 @@ yield::Function DH::disassemble(const model::Function &Function, const efa::FunctionMetadata &Metadata, const RawBinaryView &BinaryView, const model::Binary &Binary) { - auto &Helper = getDisassemblerFor(Function.Entry.type()); + auto &Helper = getDisassemblerFor(Function.Entry().type()); yield::Function ResultFunction; - ResultFunction.Entry = Function.Entry; - for (auto BasicBlockInserter = ResultFunction.ControlFlowGraph.batch_insert(); - const efa::BasicBlock &BasicBlock : Metadata.ControlFlowGraph) { + ResultFunction.Entry() = Function.Entry(); + for (auto BasicBlockInserter = + ResultFunction.ControlFlowGraph().batch_insert(); + const efa::BasicBlock &BasicBlock : Metadata.ControlFlowGraph()) { yield::BasicBlock ResultBasicBlock; - ResultBasicBlock.Start = BasicBlock.Start; - ResultBasicBlock.End = BasicBlock.End; - for (const auto &Successor : BasicBlock.Successors) - ResultBasicBlock.Successors.insert(convert(Successor)); - ResultBasicBlock.IsLabelAlwaysRequired = true; + ResultBasicBlock.Start() = BasicBlock.Start(); + ResultBasicBlock.End() = BasicBlock.End(); + for (const auto &Successor : BasicBlock.Successors()) + ResultBasicBlock.Successors().insert(convert(Successor)); + ResultBasicBlock.IsLabelAlwaysRequired() = true; namespace Arch = model::Architecture; - auto Comment = Arch::getAssemblyCommentIndicator(Binary.Architecture); + auto Comment = Arch::getAssemblyCommentIndicator(Binary.Architecture()); revng_assert(Helper.getCommentString() == llvm::StringRef{ Comment }); - auto Label = Arch::getAssemblyLabelIndicator(Binary.Architecture); + auto Label = Arch::getAssemblyLabelIndicator(Binary.Architecture()); revng_assert(Helper.getLabelSuffix() == llvm::StringRef{ Label }); - auto MaybeBBSize = BasicBlock.End - BasicBlock.Start; + auto MaybeBBSize = BasicBlock.End() - BasicBlock.Start(); revng_assert(MaybeBBSize.has_value()); - auto RawBytes = BinaryView.getByAddress(BasicBlock.Start, *MaybeBBSize); + auto RawBytes = BinaryView.getByAddress(BasicBlock.Start(), *MaybeBBSize); revng_assert(RawBytes.has_value()); - MetaAddress CurrentAddress = BasicBlock.Start; + MetaAddress CurrentAddress = BasicBlock.Start(); MetaAddress InstructionWithTheDelaySlot = MetaAddress::invalid(); - for (auto InstrInserter = ResultBasicBlock.Instructions.batch_insert(); - CurrentAddress < BasicBlock.End;) { - auto MaybeInstructionOffset = CurrentAddress - BasicBlock.Start; + for (auto InstrInserter = ResultBasicBlock.Instructions().batch_insert(); + CurrentAddress < BasicBlock.End();) { + auto MaybeInstructionOffset = CurrentAddress - BasicBlock.Start(); revng_assert(MaybeInstructionOffset.has_value()); auto InstructionBytes = RawBytes->drop_front(*MaybeInstructionOffset); auto [Instruction, HasDelaySlot, Size] = Helper.instruction(CurrentAddress, InstructionBytes); - revng_assert(Instruction.Address.isValid()); + revng_assert(Instruction.Address().isValid()); if (HasDelaySlot) { revng_assert(InstructionWithTheDelaySlot.isInvalid(), "Multiple instructions with delay slots are not allowed " "in the same basic block."); - InstructionWithTheDelaySlot = Instruction.Address; + InstructionWithTheDelaySlot = Instruction.Address(); } auto MaybeBytes = BinaryView.getByAddress(CurrentAddress, Size); revng_assert(MaybeBytes.has_value()); using ByteContainer = yield::ByteContainer; - Instruction.RawBytes = ByteContainer(MaybeBytes->begin(), - MaybeBytes->end()); + Instruction.RawBytes() = ByteContainer(MaybeBytes->begin(), + MaybeBytes->end()); CurrentAddress += Size; revng_assert(CurrentAddress.isValid()); - revng_assert(CurrentAddress <= BasicBlock.End); + revng_assert(CurrentAddress <= BasicBlock.End()); InstrInserter.insert(std::move(Instruction)); } if (InstructionWithTheDelaySlot.isValid()) { - revng_assert(ResultBasicBlock.Instructions.size() > 1); - auto Last = std::prev(ResultBasicBlock.Instructions.end()); - revng_assert(InstructionWithTheDelaySlot == std::prev(Last)->Address); + revng_assert(ResultBasicBlock.Instructions().size() > 1); + auto Last = std::prev(ResultBasicBlock.Instructions().end()); + revng_assert(InstructionWithTheDelaySlot == std::prev(Last)->Address()); - ResultBasicBlock.HasDelaySlot = true; + ResultBasicBlock.HasDelaySlot() = true; } BasicBlockInserter.insert(std::move(ResultBasicBlock)); diff --git a/lib/Yield/Assembly/LLVMDisassemblerInterface.cpp b/lib/Yield/Assembly/LLVMDisassemblerInterface.cpp index d9d996776..f6b37f1cf 100644 --- a/lib/Yield/Assembly/LLVMDisassemblerInterface.cpp +++ b/lib/Yield/Assembly/LLVMDisassemblerInterface.cpp @@ -193,11 +193,11 @@ static yield::Instruction makeInvalidInstruction(MetaAddress Where, size_t Size, std::string Reason) { yield::Instruction Result; - Result.Address = Where; - Result.Disassembled = "(invalid)"; - Result.Tags.insert({ yield::TagType::Mnemonic, 0, 9 }); - Result.Comment = std::to_string(Size) + " bytes"; - Result.Error = std::move(Reason); + Result.Address() = Where; + Result.Disassembled() = "(invalid)"; + Result.Tags().insert({ yield::TagType::Mnemonic, 0, 9 }); + Result.Comment() = std::to_string(Size) + " bytes"; + Result.Error() = std::move(Reason); return Result; } @@ -286,12 +286,12 @@ yield::Instruction DI::parse(const llvm::MCInst &Instruction, llvm::MCInstPrinter &Printer, const llvm::MCSubtargetInfo &SI) { yield::Instruction Result; - Result.Address = Address; + Result.Address() = Address; // Save the opcode for future use. if (auto Opcode = Printer.getOpcodeName(Instruction.getOpcode()); !Opcode.empty()) - Result.OpcodeIdentifier = Opcode.str(); + Result.OpcodeIdentifier() = Opcode.str(); std::string MarkupStorage; llvm::raw_string_ostream MarkupStream(MarkupStorage); @@ -307,7 +307,7 @@ yield::Instruction DI::parse(const llvm::MCInst &Instruction, auto Mnemonic = tryDetectMnemonic(Markup, Printer.getMnemonic(&Instruction).first); if (!Mnemonic.has_value()) - Result.Error = "Impossible to detect mnemonic."; + Result.Error() = "Impossible to detect mnemonic."; auto WhitespaceCheck = [](char C) { constexpr llvm::StringRef Whitespaces = " \t\n\v\f\r"; @@ -323,10 +323,10 @@ yield::Instruction DI::parse(const llvm::MCInst &Instruction, WhitespaceCheck, Position); if (WhitespaceCount != 0) { - Result.Tags.insert({ yield::TagType::Whitespace, - Result.Disassembled.size(), - Result.Disassembled.size() + WhitespaceCount }); - Result.Disassembled += Markup.substr(Position, WhitespaceCount); + Result.Tags().insert({ yield::TagType::Whitespace, + Result.Disassembled().size(), + Result.Disassembled().size() + WhitespaceCount }); + Result.Disassembled() += Markup.substr(Position, WhitespaceCount); Position += WhitespaceCount - 1; continue; } @@ -335,52 +335,52 @@ yield::Instruction DI::parse(const llvm::MCInst &Instruction, // Opens a new markup tag. llvm::StringRef Tag = Markup.slice(Position + 1, Position + 5); yield::TagType::Values TagType = parseMarkupTag(Tag); - OpenTagStack.emplace_back(TagType, Result.Disassembled.size(), 0); + OpenTagStack.emplace_back(TagType, Result.Disassembled().size(), 0); Position += 4; } else if (Markup[Position] == '>') { // Closes the current markup tag revng_assert(not OpenTagStack.empty()); yield::Tag CurrentTag = OpenTagStack.back(); - CurrentTag.To = Result.Disassembled.size(); + CurrentTag.To() = Result.Disassembled().size(); OpenTagStack.pop_back(); - Result.Tags.insert(CurrentTag); + Result.Tags().insert(CurrentTag); } else if (Mnemonic.has_value() && Position == Mnemonic->FullPosition) { // Mnemonic if (!OpenTagStack.empty()) { - Result.Error = "Mnemonic could not be detected correctly"; - Result.Disassembled += Markup[Position]; + Result.Error() = "Mnemonic could not be detected correctly"; + Result.Disassembled() += Markup[Position]; continue; } - size_t MnemonicFullStart = Result.Disassembled.size(); + size_t MnemonicFullStart = Result.Disassembled().size(); size_t MnemonicPrefixEnd = MnemonicFullStart + Mnemonic->PrefixSize; size_t MnemonicSuffixStart = MnemonicPrefixEnd + Mnemonic->Size; size_t MnemonicFullEnd = MnemonicSuffixStart + Mnemonic->SuffixSize; - Result.Tags.insert({ yield::TagType::Mnemonic, - Result.Disassembled.size(), - MnemonicFullEnd }); - if (Mnemonic->PrefixSize != 0) - Result.Tags.insert({ yield::TagType::MnemonicPrefix, - Result.Disassembled.size(), - MnemonicPrefixEnd }); - if (Mnemonic->SuffixSize != 0) - Result.Tags.insert({ yield::TagType::MnemonicSuffix, - MnemonicSuffixStart, + Result.Tags().insert({ yield::TagType::Mnemonic, + Result.Disassembled().size(), MnemonicFullEnd }); + if (Mnemonic->PrefixSize != 0) + Result.Tags().insert({ yield::TagType::MnemonicPrefix, + Result.Disassembled().size(), + MnemonicPrefixEnd }); + if (Mnemonic->SuffixSize != 0) + Result.Tags().insert({ yield::TagType::MnemonicSuffix, + MnemonicSuffixStart, + MnemonicFullEnd }); - Result.Disassembled += Markup.substr(Mnemonic->FullPosition, - Mnemonic->FullSize); + Result.Disassembled() += Markup.substr(Mnemonic->FullPosition, + Mnemonic->FullSize); Position += Mnemonic->FullSize - 1; } else { // Nothing special, just a character. - Result.Disassembled += Markup[Position]; + Result.Disassembled() += Markup[Position]; } } if (!OpenTagStack.empty()) - Result.Error = "A tag doesn't have a closing bracket."; + Result.Error() = "A tag doesn't have a closing bracket."; return Result; } diff --git a/lib/Yield/ControlFlow/ConvertFromEFA.cpp b/lib/Yield/ControlFlow/ConvertFromEFA.cpp index 33723e5fa..e1fff922c 100644 --- a/lib/Yield/ControlFlow/ConvertFromEFA.cpp +++ b/lib/Yield/ControlFlow/ConvertFromEFA.cpp @@ -13,16 +13,16 @@ #include "revng/Yield/FunctionEdgeBase.h" yield::CallEdge::CallEdge(const efa::CallEdge &Source) { - Kind = yield::FunctionEdgeBaseKind::CallEdge; - Destination = Source.Destination; - Type = yield::FunctionEdgeType::from(Source.Type); - DynamicFunction = Source.DynamicFunction; - IsTailCall = Source.IsTailCall; - Attributes = Source.Attributes; + Kind() = yield::FunctionEdgeBaseKind::CallEdge; + Destination() = Source.Destination(); + Type() = yield::FunctionEdgeType::from(Source.Type()); + DynamicFunction() = Source.DynamicFunction(); + IsTailCall() = Source.IsTailCall(); + Attributes() = Source.Attributes(); } yield::FunctionEdge::FunctionEdge(const efa::FunctionEdge &Source) { - Kind = yield::FunctionEdgeBaseKind::FunctionEdge; - Destination = Source.Destination; - Type = yield::FunctionEdgeType::from(Source.Type); + Kind() = yield::FunctionEdgeBaseKind::FunctionEdge; + Destination() = Source.Destination(); + Type() = yield::FunctionEdgeType::from(Source.Type()); } diff --git a/lib/Yield/ControlFlow/Extraction.cpp b/lib/Yield/ControlFlow/Extraction.cpp index 691f5e5ec..848fcfaf4 100644 --- a/lib/Yield/ControlFlow/Extraction.cpp +++ b/lib/Yield/ControlFlow/Extraction.cpp @@ -18,9 +18,9 @@ yield::Graph yield::cfg::extractFromInternal(const yield::Function &Function, const model::Binary &Binary, const Configuration &Configuration) { - const auto &ControlFlowGraph = Function.ControlFlowGraph; + const auto &ControlFlowGraph = Function.ControlFlowGraph(); auto [Result, Table] = efa::buildControlFlowGraph(ControlFlowGraph, - Function.Entry, + Function.Entry(), Binary); if (!Configuration.AddExitNode) { @@ -30,7 +30,7 @@ yield::cfg::extractFromInternal(const yield::Function &Function, } if (Configuration.AddEntryNode) { - auto EntryIterator = Table.find(Function.Entry); + auto EntryIterator = Table.find(Function.Entry()); revng_assert(EntryIterator != Table.end()); auto *RootNode = Result.addNode(); RootNode->Address = MetaAddress::invalid(); @@ -39,31 +39,31 @@ yield::cfg::extractFromInternal(const yield::Function &Function, } // Colour taken and refused edges. - for (const auto &BasicBlock : Function.ControlFlowGraph) { - auto NodeIterator = Table.find(BasicBlock.Start); + for (const auto &BasicBlock : Function.ControlFlowGraph()) { + auto NodeIterator = Table.find(BasicBlock.Start()); revng_assert(NodeIterator != Table.end()); auto &CurrentNode = *NodeIterator->second; - CurrentNode.NextAddress = BasicBlock.End; + CurrentNode.NextAddress = BasicBlock.End(); - if (BasicBlock.Successors.size() == 2) { + if (BasicBlock.Successors().size() == 2) { revng_assert(CurrentNode.successorCount() <= 2); if (CurrentNode.successorCount() == 2) { auto Front = *CurrentNode.successor_edges_begin(); auto Back = *std::next(CurrentNode.successor_edges_begin()); - if (Front.Neighbor->Address == BasicBlock.End) { + if (Front.Neighbor->Address == BasicBlock.End()) { Front.Label->Type = yield::Graph::EdgeType::Refused; Back.Label->Type = yield::Graph::EdgeType::Taken; - } else if (Back.Neighbor->Address == BasicBlock.End) { + } else if (Back.Neighbor->Address == BasicBlock.End()) { Front.Label->Type = yield::Graph::EdgeType::Taken; Back.Label->Type = yield::Graph::EdgeType::Refused; } } else if (CurrentNode.successorCount() == 1) { - for (const auto &Successor : BasicBlock.Successors) - if (FunctionEdgeType::isCall(Successor->Type)) + for (const auto &Successor : BasicBlock.Successors()) + if (FunctionEdgeType::isCall(Successor->Type())) continue; auto Edge = *CurrentNode.successor_edges_begin(); - if (Edge.Neighbor->Address == BasicBlock.End) + if (Edge.Neighbor->Address == BasicBlock.End()) Edge.Label->Type = yield::Graph::EdgeType::Refused; } } diff --git a/lib/Yield/ControlFlow/FallthroughDetection.cpp b/lib/Yield/ControlFlow/FallthroughDetection.cpp index e05b3b7e3..f1a84cddc 100644 --- a/lib/Yield/ControlFlow/FallthroughDetection.cpp +++ b/lib/Yield/ControlFlow/FallthroughDetection.cpp @@ -17,12 +17,13 @@ yield::cfg::detectFallthrough(const yield::BasicBlock &BasicBlock, const model::Binary &Binary) { const yield::BasicBlock *Result = nullptr; - for (const auto &Edge : BasicBlock.Successors) { - auto [NextAddress, _] = efa::parseSuccessor(*Edge, BasicBlock.End, Binary); - if (NextAddress.isValid() && NextAddress == BasicBlock.End) { - if (auto Iterator = Function.ControlFlowGraph.find(NextAddress); - Iterator != Function.ControlFlowGraph.end()) { - if (Iterator->IsLabelAlwaysRequired == false) { + for (const auto &Edge : BasicBlock.Successors()) { + auto [NextAddress, + _] = efa::parseSuccessor(*Edge, BasicBlock.End(), Binary); + if (NextAddress.isValid() && NextAddress == BasicBlock.End()) { + if (auto Iterator = Function.ControlFlowGraph().find(NextAddress); + Iterator != Function.ControlFlowGraph().end()) { + if (Iterator->IsLabelAlwaysRequired() == false) { revng_assert(Result == nullptr, "Multiple targets with the same address"); Result = &*Iterator; @@ -39,7 +40,7 @@ yield::cfg::labeledBlock(const yield::BasicBlock &BasicBlock, const yield::Function &Function, const model::Binary &Binary) { // Blocks that are a part of another labeled block cannot start a new one. - if (BasicBlock.IsLabelAlwaysRequired == false) + if (BasicBlock.IsLabelAlwaysRequired() == false) return {}; llvm::SmallVector Result = { &BasicBlock }; diff --git a/lib/Yield/ControlFlow/NodeSizeCalculation.cpp b/lib/Yield/ControlFlow/NodeSizeCalculation.cpp index 963326a24..b0eb908d1 100644 --- a/lib/Yield/ControlFlow/NodeSizeCalculation.cpp +++ b/lib/Yield/ControlFlow/NodeSizeCalculation.cpp @@ -93,13 +93,13 @@ linkSize(const MetaAddress &Address, if (Address.isInvalid()) return Indicator + textSize("an unknown location"); - if (auto Iterator = Binary.Functions.find(Address); - Iterator != Binary.Functions.end()) { + if (auto Iterator = Binary.Functions().find(Address); + Iterator != Binary.Functions().end()) { return Indicator + textSize(Iterator->name().str().str()); } else if (NextAddress == Address) { return Indicator + textSize("the next instruction"); - } else if (auto Iterator = Function.ControlFlowGraph.find(Address); - Iterator != Function.ControlFlowGraph.end()) { + } else if (auto Iterator = Function.ControlFlowGraph().find(Address); + Iterator != Function.ControlFlowGraph().end()) { return Indicator + textSize("basic_block_at_" + Address.toString()); } else { return Indicator + textSize("instruction_at_" + Address.toString()); @@ -121,14 +121,14 @@ instructionSize(const yield::Instruction &Instruction, size_t CommentIndicatorSize, bool IsInDelayedSlot = false) { // Instruction body. - yield::Graph::Size Result = fontSize(textSize(Instruction.Disassembled), + yield::Graph::Size Result = fontSize(textSize(Instruction.Disassembled()), Configuration.InstructionFontSize, Configuration); // Comment and delayed slot notice. yield::Graph::Size CommentSize; - if (!Instruction.Comment.empty()) { - CommentSize = textSize(Instruction.Comment); + if (!Instruction.Comment().empty()) { + CommentSize = textSize(Instruction.Comment()); revng_assert(CommentSize.H == 1, "Multi line comments are not supported."); CommentSize.W += CommentIndicatorSize + 1; } @@ -143,7 +143,7 @@ instructionSize(const yield::Instruction &Instruction, Configuration.InstructionFontSize, Configuration); if (CommentSize.H > 1) { - Result.W = std::max(firstLineSize(Instruction.Comment) + Result.W + Result.W = std::max(firstLineSize(Instruction.Comment()) + Result.W + CommentIndicatorSize + 1, CommentBlockSize.W); auto OneLine = fontSize(yield::Graph::Size(1, 1), @@ -156,19 +156,19 @@ instructionSize(const yield::Instruction &Instruction, } // Error. - if (!Instruction.Error.empty()) + if (!Instruction.Error().empty()) appendSize(Result, - fontSize(textSize(Instruction.Error) + fontSize(textSize(Instruction.Error()) + yield::Graph::Size(CommentIndicatorSize + 1, 0), Configuration.CommentFontSize, Configuration)); // Annotation. yield::Graph::Size RawBytesLengthWithOffsets{ 0, 0 }; - RawBytesLengthWithOffsets.W += Instruction.RawBytes.size() * 3; + RawBytesLengthWithOffsets.W += Instruction.RawBytes().size() * 3; RawBytesLengthWithOffsets.W += CommentIndicatorSize + 5; appendSize(Result, - fontSize(textSize(Instruction.Address.toString()) + fontSize(textSize(Instruction.Address().toString()) + RawBytesLengthWithOffsets, Configuration.AnnotationFontSize, Configuration)); @@ -187,8 +187,8 @@ basicBlockSize(const yield::BasicBlock &BasicBlock, const yield::cfg::Configuration &Configuration) { // Account for the size of the label namespace A = model::Architecture; - auto LabelIndicator = A::getAssemblyLabelIndicator(Binary.Architecture); - yield::Graph::Size Result = fontSize(linkSize(BasicBlock.Start, + auto LabelIndicator = A::getAssemblyLabelIndicator(Binary.Architecture()); + yield::Graph::Size Result = fontSize(linkSize(BasicBlock.Start(), Function, Binary, LabelIndicator.size()), @@ -196,11 +196,11 @@ basicBlockSize(const yield::BasicBlock &BasicBlock, Configuration); namespace A = model::Architecture; - auto CommentIndicator = A::getAssemblyCommentIndicator(Binary.Architecture); + auto CommentIndicator = A::getAssemblyCommentIndicator(Binary.Architecture()); // Account for the sizes of each instruction. - auto FromIterator = BasicBlock.Instructions.begin(); - auto ToIterator = std::prev(BasicBlock.Instructions.end()); + auto FromIterator = BasicBlock.Instructions().begin(); + auto ToIterator = std::prev(BasicBlock.Instructions().end()); for (auto Iterator = FromIterator; Iterator != ToIterator; ++Iterator) { appendSize(Result, instructionSize(*Iterator, @@ -211,8 +211,8 @@ basicBlockSize(const yield::BasicBlock &BasicBlock, instructionSize(*ToIterator++, Configuration, CommentIndicator.size(), - BasicBlock.HasDelaySlot)); - revng_assert(ToIterator == BasicBlock.Instructions.end()); + BasicBlock.HasDelaySlot())); + revng_assert(ToIterator == BasicBlock.Instructions().end()); return Result; } @@ -226,11 +226,11 @@ void yield::cfg::calculateNodeSizes(Graph &Graph, if (Node->Address.isValid()) { // A normal node. - if (auto Iterator = Function.ControlFlowGraph.find(Node->Address); - Iterator != Function.ControlFlowGraph.end()) { + if (auto Iterator = Function.ControlFlowGraph().find(Node->Address); + Iterator != Function.ControlFlowGraph().end()) { Node->Size = basicBlockSize(*Iterator, Function, Binary, Configuration); - } else if (auto Iterator = Binary.Functions.find(Node->Address); - Iterator != Binary.Functions.end()) { + } else if (auto Iterator = Binary.Functions().find(Node->Address); + Iterator != Binary.Functions().end()) { Node->Size = singleLineSize(Iterator->name().str(), Configuration.InstructionFontSize, Configuration); diff --git a/lib/Yield/ControlFlow/SVG.cpp b/lib/Yield/ControlFlow/SVG.cpp index 68ad18272..b7f3fb8e4 100644 --- a/lib/Yield/ControlFlow/SVG.cpp +++ b/lib/Yield/ControlFlow/SVG.cpp @@ -347,8 +347,8 @@ struct LabelNodeHelper { for (auto *Node : Graph.nodes()) { if (Node->Address.isValid()) { // A normal node - auto FunctionIterator = Binary.Functions.find(Node->Address); - revng_assert(FunctionIterator != Binary.Functions.end()); + auto FunctionIterator = Binary.Functions().find(Node->Address); + revng_assert(FunctionIterator != Binary.Functions().end()); size_t NameLength = FunctionIterator->name().size(); revng_assert(NameLength != 0); diff --git a/lib/Yield/CrossRelations.cpp b/lib/Yield/CrossRelations.cpp index 21b1b4728..47a85261e 100644 --- a/lib/Yield/CrossRelations.cpp +++ b/lib/Yield/CrossRelations.cpp @@ -16,13 +16,13 @@ using CR = yield::CrossRelations; CR::CrossRelations(const SortedVector &Metadata, const model::Binary &Binary) { - revng_assert(Metadata.size() == Binary.Functions.size()); + revng_assert(Metadata.size() == Binary.Functions().size()); namespace ranks = revng::ranks; - for (auto Inserter = Relations.batch_insert(); - const auto &Function : Binary.Functions) { - const auto Location = pipeline::location(ranks::Function, Function.Entry); + for (auto Inserter = Relations().batch_insert(); + const auto &Function : Binary.Functions()) { + const auto Location = pipeline::location(ranks::Function, Function.Entry()); Inserter.insert(yield::RelationDescription(Location.toString(), {})); } @@ -33,17 +33,17 @@ CR::CrossRelations(const SortedVector &Metadata, MetaAddress::invalid()); for (const auto &BasicBlock : ControlFlowGraph) { - for (const auto &Edge : BasicBlock.Successors) { - if (efa::FunctionEdgeType::isCall(Edge->Type)) { - if (const auto &Callee = Edge->Destination; Callee.isValid()) { + for (const auto &Edge : BasicBlock.Successors()) { + if (efa::FunctionEdgeType::isCall(Edge->Type())) { + if (const auto &Callee = Edge->Destination(); Callee.isValid()) { // TODO: embed information about the call instruction into // `CallLocation` after efa starts providing it. auto L = pipeline::location(ranks::Function, Callee).toString(); - if (auto It = Relations.find(L); It != Relations.end()) { + if (auto It = Relations().find(L); It != Relations().end()) { yield::RelationTarget T(yield::RelationType::IsCalledFrom, CallLocation.toString()); - It->Related.insert(std::move(T)); + It->Related().insert(std::move(T)); } } } @@ -56,10 +56,10 @@ template static void conversionHelper(const yield::CrossRelations &Input, const AddNodeCallable &AddNode, const AddEdgeCallable &AddEdge) { - for (const auto &[LocationString, Related] : Input.Relations) + for (const auto &[LocationString, Related] : Input.Relations()) AddNode(LocationString); - for (const auto &[LocationString, Related] : Input.Relations) { + for (const auto &[LocationString, Related] : Input.Relations()) { for (const auto &[RelationKind, TargetString] : Related) { switch (RelationKind) { case yield::RelationType::IsCalledFrom: diff --git a/lib/Yield/PTML.cpp b/lib/Yield/PTML.cpp index 818912cc2..b4d3d9b6f 100644 --- a/lib/Yield/PTML.cpp +++ b/lib/Yield/PTML.cpp @@ -65,19 +65,19 @@ static std::string label(const yield::BasicBlock &BasicBlock, std::string LabelName; std::string FunctionPath; std::string Location; - if (auto Iterator = Binary.Functions.find(BasicBlock.Start); - Iterator != Binary.Functions.end()) { + if (auto Iterator = Binary.Functions().find(BasicBlock.Start()); + Iterator != Binary.Functions().end()) { LabelName = Iterator->name().str().str(); FunctionPath = "/Functions/" + str(Iterator->key()) + "/CustomName"; Location = serializedLocation(ranks::Function, Iterator->key()); } else { - LabelName = "basic_block_at_" + labelAddress(BasicBlock.Start); + LabelName = "basic_block_at_" + labelAddress(BasicBlock.Start()); Location = serializedLocation(ranks::BasicBlock, - model::Function(Function.Entry).key(), - BasicBlock.Start); + model::Function(Function.Entry()).key(), + BasicBlock.Start()); } using model::Architecture::getAssemblyLabelIndicator; - auto LabelIndicator = getAssemblyLabelIndicator(Binary.Architecture); + auto LabelIndicator = getAssemblyLabelIndicator(Binary.Architecture()); Tag LabelTag(tags::Span, LabelName); LabelTag.addAttribute(attributes::Token, tokenTypes::Label) .addAttribute(attributes::LocationDefinition, Location); @@ -99,23 +99,23 @@ static std::string indent() { static std::string targetPath(const MetaAddress &Target, const yield::Function &Function, const model::Binary &Binary) { - if (auto Iterator = Binary.Functions.find(Target); - Iterator != Binary.Functions.end()) { + if (auto Iterator = Binary.Functions().find(Target); + Iterator != Binary.Functions().end()) { // The target is a function - return serializedLocation(ranks::Function, Iterator->Entry); - } else if (auto Iterator = Function.ControlFlowGraph.find(Target); - Iterator != Function.ControlFlowGraph.end()) { + return serializedLocation(ranks::Function, Iterator->Entry()); + } else if (auto Iterator = Function.ControlFlowGraph().find(Target); + Iterator != Function.ControlFlowGraph().end()) { // The target is a basic block return serializedLocation(ranks::BasicBlock, - Function.Entry, - Iterator->Start); + Function.Entry(), + Iterator->Start()); } else if (Target.isValid()) { - for (const auto &Block : Function.ControlFlowGraph) { - if (Block.Instructions.find(Target) != Block.Instructions.end()) { + for (const auto &Block : Function.ControlFlowGraph()) { + if (Block.Instructions().find(Target) != Block.Instructions().end()) { // The target is an instruction return serializedLocation(ranks::Instruction, - Function.Entry, - Block.Start, + Function.Entry(), + Block.Start(), Target); } } @@ -135,8 +135,8 @@ static std::set targets(const yield::BasicBlock &BasicBlock, }; std::set Result; - for (const auto &Edge : BasicBlock.Successors) { - auto TargetPair = efa::parseSuccessor(*Edge, BasicBlock.End, Binary); + for (const auto &Edge : BasicBlock.Successors()) { + auto TargetPair = efa::parseSuccessor(*Edge, BasicBlock.End(), Binary); if (TargetPair.NextInstructionAddress.isValid()) { std::string Path = targetPath(TargetPair.NextInstructionAddress, Function, @@ -193,30 +193,31 @@ tokenTag(llvm::StringRef Buffer, const yield::TagType::Values &Tag) { } static std::string taggedText(const yield::Instruction &Instruction) { - revng_assert(!Instruction.Tags.empty(), + revng_assert(!Instruction.Tags().empty(), "Tagless instructions are not supported"); - revng_assert(!Instruction.Disassembled.empty(), + revng_assert(!Instruction.Disassembled().empty(), "Empty disassembled instructions are not supported"); - std::vector TagMap(Instruction.Disassembled.size(), yield::TagType::Invalid); - for (yield::Tag Tag : Instruction.Tags) { - revng_assert(Tag.Type != yield::TagType::Invalid, + std::vector TagMap(Instruction.Disassembled().size(), + yield::TagType::Invalid); + for (yield::Tag Tag : Instruction.Tags()) { + revng_assert(Tag.Type() != yield::TagType::Invalid, "\"Invalid\" TagType encountered"); - for (size_t Index = Tag.From; Index < Tag.To; Index++) { - TagMap[Index] = Tag.Type; + for (size_t Index = Tag.From(); Index < Tag.To(); Index++) { + TagMap[Index] = Tag.Type(); } } std::string Result; std::string Buffer; yield::TagType::Values Tag = yield::TagType::Invalid; - for (size_t Index = 0; Index < Instruction.Disassembled.size(); Index++) { + for (size_t Index = 0; Index < Instruction.Disassembled().size(); Index++) { if (Tag != TagMap[Index]) { Result += tokenTag(Buffer, Tag); Tag = TagMap[Index]; Buffer.clear(); } - Buffer += Instruction.Disassembled[Index]; + Buffer += Instruction.Disassembled()[Index]; } Result += tokenTag(Buffer, Tag); @@ -231,14 +232,14 @@ static std::string instruction(const yield::Instruction &Instruction, // Tagged instruction body. std::string Result = taggedText(Instruction); - size_t Tail = Instruction.Disassembled.size() + 1; + size_t Tail = Instruction.Disassembled().size() + 1; Tag Location = Tag(tags::Span) .addAttribute(attributes::LocationDefinition, serializedLocation(ranks::Instruction, - Function.Entry, - BasicBlock.Start, - Instruction.Address)); + Function.Entry(), + BasicBlock.Start(), + Instruction.Address())); Tag Out = Tag(tags::Div, std::move(Result)) .addAttribute(attributes::Scope, scopes::Instruction); @@ -254,11 +255,11 @@ static std::string basicBlock(const yield::BasicBlock &BasicBlock, const yield::Function &Function, const model::Binary &Binary, std::string Label) { - revng_assert(!BasicBlock.Instructions.empty()); - auto FromIterator = BasicBlock.Instructions.begin(); - auto ToIterator = std::prev(BasicBlock.Instructions.end()); - if (BasicBlock.HasDelaySlot) { - revng_assert(BasicBlock.Instructions.size() > 1); + revng_assert(!BasicBlock.Instructions().empty()); + auto FromIterator = BasicBlock.Instructions().begin(); + auto ToIterator = std::prev(BasicBlock.Instructions().end()); + if (BasicBlock.HasDelaySlot()) { + revng_assert(BasicBlock.Instructions().size() > 1); --ToIterator; } @@ -276,9 +277,9 @@ static std::string basicBlock(const yield::BasicBlock &BasicBlock, LabelString = Label + "\n"; } else { std::string Location = serializedLocation(ranks::BasicBlock, - model::Function(Function.Entry) + model::Function(Function.Entry()) .key(), - BasicBlock.Start); + BasicBlock.Start()); LabelString = Tag(tags::Span) .addAttribute(attributes::LocationDefinition, Location) .serialize(); @@ -318,7 +319,7 @@ std::string yield::ptml::functionAssembly(const yield::Function &Function, const model::Binary &Binary) { std::string Result; - for (const auto &BasicBlock : Function.ControlFlowGraph) { + for (const auto &BasicBlock : Function.ControlFlowGraph()) { Result += labeledBlock(BasicBlock, Function, Binary); } @@ -332,8 +333,8 @@ std::string yield::ptml::functionAssembly(const yield::Function &Function, std::string yield::ptml::controlFlowNode(const MetaAddress &Address, const yield::Function &Function, const model::Binary &Binary) { - auto Iterator = Function.ControlFlowGraph.find(Address); - revng_assert(Iterator != Function.ControlFlowGraph.end()); + auto Iterator = Function.ControlFlowGraph().find(Address); + revng_assert(Iterator != Function.ControlFlowGraph().end()); auto Result = labeledBlock(*Iterator, Function, Binary); revng_assert(!Result.empty()); @@ -364,7 +365,7 @@ yield::ptml::functionNameDefinition(const MetaAddress &FunctionEntryPoint, if (FunctionEntryPoint.isInvalid()) return ""; - return functionLinkHelper(Binary.Functions.at(FunctionEntryPoint), + return functionLinkHelper(Binary.Functions().at(FunctionEntryPoint), callGraphTokens::NodeLabel) .addAttribute(attributes::LocationDefinition, serializedLocation(revng::ranks::Function, @@ -377,7 +378,7 @@ std::string yield::ptml::functionLink(const MetaAddress &FunctionEntryPoint, if (FunctionEntryPoint.isInvalid()) return ""; - return functionLinkHelper(Binary.Functions.at(FunctionEntryPoint), + return functionLinkHelper(Binary.Functions().at(FunctionEntryPoint), callGraphTokens::NodeLabel) .addListAttribute(attributes::LocationReferences, serializedLocation(revng::ranks::Function, @@ -391,7 +392,7 @@ yield::ptml::shallowFunctionLink(const MetaAddress &FunctionEntryPoint, if (FunctionEntryPoint.isInvalid()) return ""; - return functionLinkHelper(Binary.Functions.at(FunctionEntryPoint), + return functionLinkHelper(Binary.Functions().at(FunctionEntryPoint), callGraphTokens::ShallowNodeLabel) .addListAttribute(attributes::LocationReferences, serializedLocation(revng::ranks::Function, diff --git a/lib/Yield/Pipes/AssemblyPipes.cpp b/lib/Yield/Pipes/AssemblyPipes.cpp index 90a89620a..0a87fffc4 100644 --- a/lib/Yield/Pipes/AssemblyPipes.cpp +++ b/lib/Yield/Pipes/AssemblyPipes.cpp @@ -45,12 +45,12 @@ void ProcessAssembly::run(pipeline::Context &Context, FunctionMetadataCache Cache; for (const auto &LLVMFunction : FunctionTags::Isolated.functions(&Module)) { const auto &Metadata = Cache.getFunctionMetadata(&LLVMFunction); - auto ModelFunctionIterator = Model->Functions.find(Metadata.Entry); - revng_assert(ModelFunctionIterator != Model->Functions.end()); + auto ModelFunctionIterator = Model->Functions().find(Metadata.Entry()); + revng_assert(ModelFunctionIterator != Model->Functions().end()); const auto &Func = *ModelFunctionIterator; auto Disassembled = Helper.disassemble(Func, Metadata, BinaryView, *Model); - Output.insert_or_assign(Func.Entry, serializeToString(Disassembled)); + Output.insert_or_assign(Func.Entry(), serializeToString(Disassembled)); } } @@ -69,9 +69,9 @@ void YieldAssembly::run(pipeline::Context &Context, for (auto [Address, S] : Input) { auto MaybeFunction = TupleTree::deserialize(S); revng_assert(MaybeFunction && MaybeFunction->verify()); - revng_assert((*MaybeFunction)->Entry == Address); + revng_assert((*MaybeFunction)->Entry() == Address); - Output.insert_or_assign((*MaybeFunction)->Entry, + Output.insert_or_assign((*MaybeFunction)->Entry(), yield::ptml::functionAssembly(**MaybeFunction, *Model)); } diff --git a/lib/Yield/Pipes/CFGPipes.cpp b/lib/Yield/Pipes/CFGPipes.cpp index b5f20a2a5..746924cef 100644 --- a/lib/Yield/Pipes/CFGPipes.cpp +++ b/lib/Yield/Pipes/CFGPipes.cpp @@ -23,9 +23,9 @@ void YieldControlFlow::run(pipeline::Context &Context, for (auto [Address, S] : Input) { auto MaybeFunction = TupleTree::deserialize(S); revng_assert(MaybeFunction && MaybeFunction->verify()); - revng_assert((*MaybeFunction)->Entry == Address); + revng_assert((*MaybeFunction)->Entry() == Address); - Output.insert_or_assign((*MaybeFunction)->Entry, + Output.insert_or_assign((*MaybeFunction)->Entry(), yield::svg::controlFlowGraph(**MaybeFunction, *Model)); } diff --git a/lib/Yield/Pipes/CallGraphPipes.cpp b/lib/Yield/Pipes/CallGraphPipes.cpp index 8b1c7d53b..e00194b16 100644 --- a/lib/Yield/Pipes/CallGraphPipes.cpp +++ b/lib/Yield/Pipes/CallGraphPipes.cpp @@ -33,7 +33,7 @@ void ProcessCallGraph::run(pipeline::Context &Context, SortedVector Metadata; for (const auto &LLVMFunction : FunctionTags::Isolated.functions(&Module)) Metadata.insert(*::detail::extractFunctionMetadata(&LLVMFunction)); - revng_assert(Metadata.size() == Model->Functions.size()); + revng_assert(Metadata.size() == Model->Functions().size()); // Gather the relations yield::CrossRelations Relations(Metadata, *Model); @@ -111,12 +111,12 @@ void YieldCallGraphSlice::run(pipeline::Context &Context, FunctionMetadataCache Cache; for (const auto &LLVMFunction : FunctionTags::Isolated.functions(&Module)) { auto &Metadata = Cache.getFunctionMetadata(&LLVMFunction); - auto ModelFunctionIterator = Model->Functions.find(Metadata.Entry); - revng_assert(ModelFunctionIterator != Model->Functions.end()); + auto ModelFunctionIterator = Model->Functions().find(Metadata.Entry()); + revng_assert(ModelFunctionIterator != Model->Functions().end()); // Slice the graph for the current function and convert it to SVG - Output.insert_or_assign(Metadata.Entry, - yield::svg::callGraphSlice(Metadata.Entry, + Output.insert_or_assign(Metadata.Entry(), + yield::svg::callGraphSlice(Metadata.Entry(), Relations, *Model)); } diff --git a/lib/Yield/Plain.cpp b/lib/Yield/Plain.cpp index 756d82d46..430f661ff 100644 --- a/lib/Yield/Plain.cpp +++ b/lib/Yield/Plain.cpp @@ -29,12 +29,12 @@ static std::string linkAddress(const MetaAddress &Address) { static std::string deduceName(const MetaAddress &Target, const yield::Function &Function, const model::Binary &Binary) { - if (auto Iterator = Binary.Functions.find(Target); - Iterator != Binary.Functions.end()) { + if (auto Iterator = Binary.Functions().find(Target); + Iterator != Binary.Functions().end()) { // The target is a function return Iterator->name().str().str(); - } else if (auto Iterator = Function.ControlFlowGraph.find(Target); - Iterator != Function.ControlFlowGraph.end()) { + } else if (auto Iterator = Function.ControlFlowGraph().find(Target); + Iterator != Function.ControlFlowGraph().end()) { // The target is a basic block // TODO: maybe there's something better than the address to put here. @@ -51,31 +51,31 @@ static std::string deduceName(const MetaAddress &Target, static std::string label(const yield::BasicBlock &BasicBlock, const yield::Function &Function, const model::Binary &Binary) { - std::string Result = deduceName(BasicBlock.Start, Function, Binary); + std::string Result = deduceName(BasicBlock.Start(), Function, Binary); namespace Arch = model::Architecture; - auto LabelIndicator = Arch::getAssemblyLabelIndicator(Binary.Architecture); + auto LabelIndicator = Arch::getAssemblyLabelIndicator(Binary.Architecture()); return (Result += LabelIndicator) += "\n"; } static std::string instruction(const yield::Instruction &Instruction, const yield::BasicBlock &BasicBlock, const model::Binary &Binary) { - std::string Result = Instruction.Disassembled; + std::string Result = Instruction.Disassembled(); namespace A = model::Architecture; - auto CommentIndicator = A::getAssemblyCommentIndicator(Binary.Architecture); + auto CommentIndicator = A::getAssemblyCommentIndicator(Binary.Architecture()); - if (!Instruction.Error.empty()) { + if (!Instruction.Error().empty()) { Result += ' '; Result += CommentIndicator; Result += " Error: "; - Result += Instruction.Error; - } else if (!Instruction.Comment.empty()) { + Result += Instruction.Error(); + } else if (!Instruction.Comment().empty()) { Result += ' '; Result += CommentIndicator; Result += ' '; - Result += Instruction.Comment; + Result += Instruction.Comment(); } return Result; @@ -86,7 +86,7 @@ static std::string basicBlock(const yield::BasicBlock &BasicBlock, const model::Binary &Binary) { std::string Result; - for (const auto &Instruction : BasicBlock.Instructions) + for (const auto &Instruction : BasicBlock.Instructions()) Result += instruction(Instruction, BasicBlock, Binary); return Result; @@ -117,7 +117,7 @@ std::string yield::plain::functionAssembly(const yield::Function &Function, const model::Binary &Binary) { std::string Result; - for (const auto &BasicBlock : Function.ControlFlowGraph) + for (const auto &BasicBlock : Function.ControlFlowGraph()) Result += labeledBlock(BasicBlock, Function, Binary); return Result; @@ -126,8 +126,8 @@ std::string yield::plain::functionAssembly(const yield::Function &Function, std::string yield::plain::controlFlowNode(const MetaAddress &Address, const yield::Function &Function, const model::Binary &Binary) { - auto Iterator = Function.ControlFlowGraph.find(Address); - revng_assert(Iterator != Function.ControlFlowGraph.end()); + auto Iterator = Function.ControlFlowGraph().find(Address); + revng_assert(Iterator != Function.ControlFlowGraph().end()); auto Result = labeledBlock(*Iterator, Function, Binary); revng_assert(!Result.empty()); diff --git a/lib/Yield/Verify.cpp b/lib/Yield/Verify.cpp index d27b13f06..6a29ac7c0 100644 --- a/lib/Yield/Verify.cpp +++ b/lib/Yield/Verify.cpp @@ -12,31 +12,32 @@ #include "revng/Yield/Tag.h" bool yield::Tag::verify(model::VerifyHelper &VH) const { - if (Type == TagType::Invalid) + if (Type() == TagType::Invalid) return VH.fail("The type of this tag is not valid."); - if (From == std::string::npos) + if (From() == std::string::npos) return VH.fail("This tag doesn't have a starting point."); - if (To == std::string::npos) + if (To() == std::string::npos) return VH.fail("This tag doesn't have an ending point."); - if (From >= To) + if (From() >= To()) return VH.fail("This tag doesn't have a positive length."); return true; } bool yield::Instruction::verify(model::VerifyHelper &VH) const { - if (Address.isInvalid()) + if (Address().isInvalid()) return VH.fail("An instruction has to have a valid address."); - if (Disassembled.empty()) + if (Disassembled().empty()) return VH.fail("The disassembled view of an instruction cannot be empty."); - if (RawBytes.empty()) + if (RawBytes().empty()) return VH.fail("An instruction has to be at least one byte big."); - for (const auto &Tag : Tags) { + for (const auto &Tag : Tags()) { if (!Tag.verify(VH)) return VH.fail("Tag verification failed"); - if (Tag.From >= Disassembled.size() || Tag.To >= Disassembled.size()) + if (Tag.From() >= Disassembled().size() + || Tag.To() >= Disassembled().size()) return VH.fail("Tag boundaries must not exceed the size of the text."); } @@ -44,31 +45,31 @@ bool yield::Instruction::verify(model::VerifyHelper &VH) const { } bool yield::BasicBlock::verify(model::VerifyHelper &VH) const { - if (Start.isInvalid()) + if (Start().isInvalid()) return VH.fail("A basic block has to have a valid start address."); - if (End.isInvalid()) + if (End().isInvalid()) return VH.fail("A basic block has to have a valid end address."); - if (Instructions.empty()) + if (Instructions().empty()) return VH.fail("A basic block has to store at least a single instruction."); MetaAddress PreviousAddress = MetaAddress::invalid(); - for (const auto &Instruction : Instructions) { + for (const auto &Instruction : Instructions()) { if (!Instruction.verify(VH)) return VH.fail("Instuction verification failed."); - if (PreviousAddress.isValid() && Instruction.Address >= PreviousAddress) { + 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; + PreviousAddress = Instruction.Address(); } - if (PreviousAddress.isInvalid() || PreviousAddress >= End) { + if (PreviousAddress.isInvalid() || PreviousAddress >= End()) { return VH.fail("The size of the last instruction must be bigger than " "zero."); } - if (HasDelaySlot && Instructions.size() < 2) { + if (HasDelaySlot() && Instructions().size() < 2) { return VH.fail("A basic block with a delay slot must contain at least two " "instructions."); } @@ -77,13 +78,13 @@ bool yield::BasicBlock::verify(model::VerifyHelper &VH) const { } bool yield::Function::verify(model::VerifyHelper &VH) const { - if (Entry.isInvalid()) + if (Entry().isInvalid()) return VH.fail("A function has to have a valid entry point."); - if (ControlFlowGraph.empty()) + if (ControlFlowGraph().empty()) return VH.fail("A function has to store at least a single basic block."); - for (const auto &BasicBlock : ControlFlowGraph) + for (const auto &BasicBlock : ControlFlowGraph()) if (!BasicBlock.verify(VH)) return VH.fail("Basic block verification failed."); diff --git a/scripts/tuple_tree_generator/tuple_tree_generator/templates/struct.h.tpl b/scripts/tuple_tree_generator/tuple_tree_generator/templates/struct.h.tpl index 2d87f6c8f..945b0ccf6 100644 --- a/scripts/tuple_tree_generator/tuple_tree_generator/templates/struct.h.tpl +++ b/scripts/tuple_tree_generator/tuple_tree_generator/templates/struct.h.tpl @@ -31,8 +31,21 @@ struct /*= struct | fullname =*/ /**- for field in struct.fields **/ /*= field.doc | docstring =*/ /**- if field.const **/const /** endif -**/ - /*= field | field_type =*/ /*= field.name =*/ = /*= field | field_type =*/{}; +private: + /*= field | field_type =*/ The/*= field.name =*/ = /*= field | field_type =*/{}; static_assert(Yamlizable); + +public: + using /*= field.name =*/Type = /*= field | field_type =*/; + +public: + const /*= field | field_type =*/ & /*= field.name =*/() const { + return The/*= field.name =*/; + } + + /*= field | field_type =*/ & /*= field.name =*/() { + return The/*= field.name =*/; + } /**- endfor **/ /*# --- Default constructor --- #*/ @@ -40,10 +53,10 @@ struct /*= struct | fullname =*/ /*= struct.name =*/() : /**- if struct.inherits **//*= struct.inherits.name =*/()/** endif **/ /**- for field in struct.fields **/ - /**- if not loop.first or struct.inherits **/, /** endif **//*= field.name =*/() + /**- if not loop.first or struct.inherits **/, /** endif **/The/*= field.name =*/() /**- endfor **/ { /**- if struct.inherits -**/ - Kind = AssociatedKind; + Kind() = AssociatedKind; /**- endif -**/ } @@ -63,11 +76,11 @@ struct /*= struct | fullname =*/ ) /**- else **/ /**- for field in struct.key_fields **/ - /*=- field.name =*/(/*= field.name =*/)/** if not loop.last **/, /** endif **/ + The/*=- field.name =*/(/*= field.name =*/)/** if not loop.last **/, /** endif **/ /**- endfor **/ /**- endif **/ { /**- if struct.inherits and not 'Kind' in struct.key_fields | map(attribute='name') -**/ - Kind = AssociatedKind; + Kind() = AssociatedKind; /**- endif -**/ } /** endif **/ @@ -99,7 +112,7 @@ struct /*= struct | fullname =*/ /*#- Initialize own fields #*/ /**- for field in struct.fields **/ - /*=- field.name =*/(/*= field.name =*/)/** if not loop.last **/, /** endif **/ + The/*=- field.name =*/(/*= field.name =*/)/** if not loop.last **/, /** endif **/ /**- endfor **/ {} /** endif **/ @@ -120,7 +133,7 @@ struct /*= struct | fullname =*/ Key key() const { return Key { /**- for key_field in struct.key_fields -**/ - /*= key_field.name =*//** if not loop.last **/, /** endif **/ + /*= key_field.name =*/()/** if not loop.last **/, /** endif **/ /**- endfor -**/ }; } diff --git a/scripts/tuple_tree_generator/tuple_tree_generator/templates/struct_impl.cpp.tpl b/scripts/tuple_tree_generator/tuple_tree_generator/templates/struct_impl.cpp.tpl index 2b1f49cb5..742f28d71 100644 --- a/scripts/tuple_tree_generator/tuple_tree_generator/templates/struct_impl.cpp.tpl +++ b/scripts/tuple_tree_generator/tuple_tree_generator/templates/struct_impl.cpp.tpl @@ -26,7 +26,7 @@ Key KeyedObjectTraits>::key( return { /**- for key_field in struct.key_fields **/ - Obj->/*= key_field.name =*//** if not loop.last **/, /** endif **/ + Obj->/*= key_field.name =*/()/** if not loop.last **/, /** endif **/ /**- endfor **/ }; } @@ -84,19 +84,19 @@ bool /*= struct | fullname =*/::localCompare(const /*= struct | user_fullname =* /**- if field.__class__.__name__ == "SimpleStructField" **/ /**- if schema.get_definition_for(field.type).__class__.__name__ == "StructDefinition" -**/ - if (not this->/*= field.name =*/.localCompare(Other./*= field.name =*/)) + if (not this->/*= field.name =*/().localCompare(Other./*= field.name =*/())) return false; /**- else -**/ - if (this->/*= field.name =*/ != Other./*= field.name =*/) + if (this->/*= field.name =*/() != Other./*= field.name =*/()) return false; /**- endif -**/ /**- elif field.__class__.__name__ == "SequenceStructField" -**/ - if (this->/*= field.name =*/.size() != Other./*= field.name =*/.size()) + if (this->/*= field.name =*/().size() != Other./*= field.name =*/().size()) return false; /**- if schema.get_definition_for(field.element_type).__class__.__name__ == "StructDefinition" -**/ - for (const auto &[L, R] : llvm::zip(this->/*= field.name =*/, Other./*= field.name =*/)) { + for (const auto &[L, R] : llvm::zip(this->/*= field.name =*/(), Other./*= field.name =*/())) { /** if field.upcastable **/ if (not L->localCompare(*R)) return false; @@ -107,7 +107,7 @@ bool /*= struct | fullname =*/::localCompare(const /*= struct | user_fullname =* } /**- else -**/ - if (this->/*= field.name =*/ != Other./*= field.name =*/) + if (this->/*= field.name =*/() != Other./*= field.name =*/()) return false; /**- endif -**/ diff --git a/scripts/tuple_tree_generator/tuple_tree_generator/templates/struct_late.h.tpl b/scripts/tuple_tree_generator/tuple_tree_generator/templates/struct_late.h.tpl index 787396c70..b29b38a89 100644 --- a/scripts/tuple_tree_generator/tuple_tree_generator/templates/struct_late.h.tpl +++ b/scripts/tuple_tree_generator/tuple_tree_generator/templates/struct_late.h.tpl @@ -29,7 +29,7 @@ template <> struct TupleLikeTraits { static constexpr const llvm::StringRef FullName = "/*=- struct | user_fullname =*/"; using tuple = std::tuple< /**- for field in struct.all_fields -**/ - decltype(/*=- struct | user_fullname =*/::/*=- field.name =*/)/** if not loop.last **/, /** endif -**/ + /*=- struct | user_fullname =*/::/*=- field.name =*/Type/** if not loop.last **/, /** endif -**/ /**- endfor **/>; static constexpr std::array> FieldNames = { @@ -51,7 +51,7 @@ template auto &get(/*= struct.name =*/ &&x) { return __null; /**- for field in struct.all_fields **/ else if constexpr (I == /*= loop.index0 =*/) - return x./*= field.name =*/; + return x./*= field.name =*/(); /**- endfor **/ } @@ -60,7 +60,7 @@ template const auto &get(const /*= struct.name =*/ &x) { return __null; /**- for field in struct.all_fields **/ else if constexpr (I == /*= loop.index0 =*/) - return x./*= field.name =*/; + return x./*= field.name =*/(); /**- endfor **/ } @@ -69,7 +69,7 @@ template auto &get(/*= struct.name =*/ &x) { return __null; /**- for field in struct.all_fields **/ else if constexpr (I == /*= loop.index0 =*/) - return x./*= field.name =*/; + return x./*= field.name =*/(); /**- endfor **/ } } @@ -94,7 +94,7 @@ struct llvm::yaml::ScalarTraits /** if struct.keytype == "simple" **/ template<> struct KeyedObjectTraits { - static /*= struct.key_fields[0] | field_type =*/ key(const /*= struct | user_fullname =*/ &Obj) { return Obj./*= struct.key_fields[0].name =*/; } + static /*= struct.key_fields[0] | field_type =*/ key(const /*= struct | user_fullname =*/ &Obj) { return Obj./*= struct.key_fields[0].name =*/(); } static /*= struct | user_fullname =*/ fromKey(const /*= struct.key_fields[0] | field_type =*/ &Key) { return /*= struct | user_fullname =*/(Key); } @@ -106,7 +106,7 @@ struct KeyedObjectTraits { static Key key(const /*= struct | user_fullname =*/ &Obj) { return { /** for key_field in struct.key_fields -**/ - Obj./*= key_field.name =*/ + Obj./*= key_field.name =*/() /**- if not loop.last **/, /** endif **/ /**- endfor **/ diff --git a/tests/abi/tools/revng-abi-verify/Verify.cpp b/tests/abi/tools/revng-abi-verify/Verify.cpp index 0507fa456..c8d73b058 100644 --- a/tests/abi/tools/revng-abi-verify/Verify.cpp +++ b/tests/abi/tools/revng-abi-verify/Verify.cpp @@ -223,7 +223,7 @@ llvm::Error verifyABI(const TupleTree &Binary, revng_assert(ArchitectureName == ParsedArtifact.Architecture); VerificationHelper Helper{ Architecture, ABI, ParsedArtifact.IsLittleEndian }; - for (auto &Type : Binary->Types) { + for (auto &Type : Binary->Types()) { revng_assert(Type.get() != nullptr); auto CurrentFunction = ParsedArtifact.Functions.find(Type->name()); diff --git a/tests/abi/tools/revng-ensure-rft-equivalence/Main.cpp b/tests/abi/tools/revng-ensure-rft-equivalence/Main.cpp index 45b30524d..4e4573496 100644 --- a/tests/abi/tools/revng-ensure-rft-equivalence/Main.cpp +++ b/tests/abi/tools/revng-ensure-rft-equivalence/Main.cpp @@ -79,13 +79,13 @@ int main(int Argc, char *Argv[]) { model::RawFunctionType *Left; model::RawFunctionType *Right; }; - std::map Functions; - for (model::UpcastableType &LeftType : LeftModel->Model->Types) + std::map Functions; + for (model::UpcastableType &LeftType : LeftModel->Model->Types()) if (auto *Left = llvm::dyn_cast(LeftType.get())) - Functions[Left->ID].Left = Left; - for (model::UpcastableType &RightType : RightModel->Model->Types) + Functions[Left->ID()].Left = Left; + for (model::UpcastableType &RightType : RightModel->Model->Types()) if (auto *Right = llvm::dyn_cast(RightType.get())) - Functions[Right->ID].Right = Right; + Functions[Right->ID()].Right = Right; // Ensure their stack arguments have the same ID. // @@ -96,12 +96,12 @@ int main(int Argc, char *Argv[]) { auto [Left, Right] = Pair; // Try and access the argument struct. - revng_check(Left->StackArgumentsType.Qualifiers.empty()); - revng_check(Right->StackArgumentsType.Qualifiers.empty()); - model::Type *LeftStackArguments = Left->StackArgumentsType.UnqualifiedType - .get(); - model::Type *RightStackArguments = Right->StackArgumentsType.UnqualifiedType - .get(); + revng_check(Left->StackArgumentsType().Qualifiers().empty()); + revng_check(Right->StackArgumentsType().Qualifiers().empty()); + model::Type + *LeftStackArguments = Left->StackArgumentsType().UnqualifiedType().get(); + model::Type * + RightStackArguments = Right->StackArgumentsType().UnqualifiedType().get(); // XOR the `bool`eans - make sure that either both functions have stack // argument or neither one does. @@ -112,14 +112,14 @@ int main(int Argc, char *Argv[]) { continue; // If IDs differ - replace the ID. - if (LeftStackArguments->ID != RightStackArguments->ID) { - model::TypePath FromPath = Right->StackArgumentsType.UnqualifiedType; + if (LeftStackArguments->ID() != RightStackArguments->ID()) { + model::TypePath FromPath = Right->StackArgumentsType().UnqualifiedType(); - RightModel->Model->Types.erase(LeftStackArguments->key()); + RightModel->Model->Types().erase(LeftStackArguments->key()); auto *Struct = llvm::dyn_cast(RightStackArguments); revng_check(Struct != nullptr); auto Copy = model::UpcastableType::make(*Struct); - Copy->ID = LeftStackArguments->ID; + Copy->ID() = LeftStackArguments->ID(); auto ToPath = RightModel->Model->recordNewType(std::move(Copy)); Replacements.emplace(FromPath, ToPath); diff --git a/tests/unit/DiffInvalidationEvent.cpp b/tests/unit/DiffInvalidationEvent.cpp index 539cb0091..ca5427860 100644 --- a/tests/unit/DiffInvalidationEvent.cpp +++ b/tests/unit/DiffInvalidationEvent.cpp @@ -26,7 +26,7 @@ BOOST_AUTO_TEST_CASE(RootInvalidationTest) { Context Ctx; MetaAddress Address(0x1000, MetaAddressType::Code_aarch64); - New.ExtraCodeAddresses.insert(Address); + New.ExtraCodeAddresses().insert(Address); TargetsList ToRemove; GlobalTupleTreeDiff Event(diff(Empty, New)); diff --git a/tests/unit/Location.cpp b/tests/unit/Location.cpp index 9b973138d..ff4f173f4 100644 --- a/tests/unit/Location.cpp +++ b/tests/unit/Location.cpp @@ -51,9 +51,9 @@ BOOST_AUTO_TEST_CASE(MetaAddressAsTheKey) { static model::TypePath makeFunction(model::Binary &Model) { model::CABIFunctionType Function; - Function.CustomName = "my_cool_func"; - Function.OriginalName = "Function_at_0x40012f:Code_x86_64"; - Function.ABI = model::ABI::SystemV_x86_64; + Function.CustomName() = "my_cool_func"; + Function.OriginalName() = "Function_at_0x40012f:Code_x86_64"; + Function.ABI() = model::ABI::SystemV_x86_64; using UT = model::UpcastableType; auto Ptr = UT::make(std::move(Function)); diff --git a/tests/unit/Model.cpp b/tests/unit/Model.cpp index e7442cd9a..a59db91fc 100644 --- a/tests/unit/Model.cpp +++ b/tests/unit/Model.cpp @@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(TestIntrospection) { Function TheFunction(MetaAddress::invalid()); // Use get - TheFunction.CustomName = "FunctionName"; + TheFunction.CustomName() = "FunctionName"; revng_check(get<1>(TheFunction) == "FunctionName"); // Test std::tuple_size @@ -41,8 +41,8 @@ BOOST_AUTO_TEST_CASE(TestIntrospection) { // Test TupleLikeTraits static_assert(TraitedTupleLike); using TLT = TupleLikeTraits; - static_assert(std::is_same_v, - decltype(TheFunction.CustomName)>); + static_assert(std::is_same_v &, + decltype(TheFunction.CustomName())>); revng_check(StringRef(TLT::Name) == "Function"); revng_check(StringRef(TLT::FullName) == "model::Function"); revng_check(StringRef(TLT::FieldNames[1]) == "CustomName"); @@ -50,14 +50,14 @@ BOOST_AUTO_TEST_CASE(TestIntrospection) { BOOST_AUTO_TEST_CASE(TestPathAccess) { Binary TheBinary; - using FunctionsType = decltype(TheBinary.Functions); + using FunctionsType = std::decay_t; TupleTreePath Zero; Zero.push_back(size_t(0)); auto *FirstField = getByPath(Zero, TheBinary); - revng_check(FirstField == &TheBinary.Functions); + revng_check(FirstField == &TheBinary.Functions()); auto *FunctionsField = getByPath("/Functions", TheBinary); - revng_check(FunctionsField == &TheBinary.Functions); + revng_check(FunctionsField == &TheBinary.Functions()); // Test non existing field revng_check(getByPath("/Function", TheBinary) == nullptr); @@ -66,7 +66,7 @@ BOOST_AUTO_TEST_CASE(TestPathAccess) { revng_check(getByPath("/Functions/:Invalid", TheBinary) == nullptr); // Test existing entry in container - Function &F = TheBinary.Functions[MetaAddress::invalid()]; + Function &F = TheBinary.Functions()[MetaAddress::invalid()]; revng_check(getByPath("/Functions/:Invalid", TheBinary) == &F); } @@ -135,9 +135,9 @@ static T *createType(model::Binary &Model) { BOOST_AUTO_TEST_CASE(TestModelDeduplication) { TupleTree Model; auto Dedup = [&Model]() { - int64_t OldTypesCount = Model->Types.size(); + int64_t OldTypesCount = Model->Types().size(); deduplicateEquivalentTypes(Model); - int64_t NewTypesCount = Model->Types.size(); + int64_t NewTypesCount = Model->Types().size(); return OldTypesCount - NewTypesCount; }; @@ -147,15 +147,15 @@ BOOST_AUTO_TEST_CASE(TestModelDeduplication) { // Two typedefs { auto *Typedef1 = createType(*Model); - Typedef1->UnderlyingType = { UInt8, {} }; + Typedef1->UnderlyingType() = { UInt8, {} }; auto *Typedef2 = createType(*Model); - Typedef2->UnderlyingType = { UInt8, {} }; + Typedef2->UnderlyingType() = { UInt8, {} }; revng_check(Dedup() == 0); - Typedef1->OriginalName = "MyUInt8"; - Typedef2->OriginalName = "MyUInt8"; + Typedef1->OriginalName() = "MyUInt8"; + Typedef2->OriginalName() = "MyUInt8"; revng_check(Dedup() == 1); } @@ -163,18 +163,18 @@ BOOST_AUTO_TEST_CASE(TestModelDeduplication) { // Two structs { auto *Struct1 = createType(*Model); - Struct1->Fields[0].CustomName = "FirstField"; - Struct1->Fields[0].Type = { UInt8, {} }; - Struct1->OriginalName = "MyStruct"; + Struct1->Fields()[0].CustomName() = "FirstField"; + Struct1->Fields()[0].Type() = { UInt8, {} }; + Struct1->OriginalName() = "MyStruct"; auto *Struct2 = createType(*Model); - Struct2->Fields[0].CustomName = "DifferentName"; - Struct2->Fields[0].Type = { UInt8, {} }; - Struct2->OriginalName = "MyStruct"; + Struct2->Fields()[0].CustomName() = "DifferentName"; + Struct2->Fields()[0].Type() = { UInt8, {} }; + Struct2->OriginalName() = "MyStruct"; revng_check(Dedup() == 0); - Struct1->Fields[0].CustomName = Struct2->Fields[0].CustomName; + Struct1->Fields()[0].CustomName() = Struct2->Fields()[0].CustomName(); revng_check(Dedup() == 1); } @@ -186,27 +186,29 @@ BOOST_AUTO_TEST_CASE(TestModelDeduplication) { auto *Left1 = createType(*Model); auto *Left2 = createType(*Model); - Left1->Fields[0].Type = { Model->getTypePath(Left2), { PointerQualifier } }; - Left2->Fields[0].Type = { Model->getTypePath(Left1), { PointerQualifier } }; + Left1->Fields()[0].Type() = { Model->getTypePath(Left2), + { PointerQualifier } }; + Left2->Fields()[0].Type() = { Model->getTypePath(Left1), + { PointerQualifier } }; - Left1->OriginalName = "LoopingStructs1"; - Left2->OriginalName = "LoopingStructs2"; + Left1->OriginalName() = "LoopingStructs1"; + Left2->OriginalName() = "LoopingStructs2"; auto *Right1 = createType(*Model); auto *Right2 = createType(*Model); - Right1->Fields[0].Type = { Model->getTypePath(Right2), - { PointerQualifier } }; - Right2->Fields[0].Type = { Model->getTypePath(Right1), - { PointerQualifier, PointerQualifier } }; + Right1->Fields()[0].Type() = { Model->getTypePath(Right2), + { PointerQualifier } }; + Right2->Fields()[0].Type() = { Model->getTypePath(Right1), + { PointerQualifier, PointerQualifier } }; - Right1->OriginalName = "LoopingStructs1"; - Right2->OriginalName = "LoopingStructs2"; + Right1->OriginalName() = "LoopingStructs1"; + Right2->OriginalName() = "LoopingStructs2"; revng_check(Dedup() == 0); - Right2->Fields[0].Type = { Model->getTypePath(Right1), - { PointerQualifier } }; + Right2->Fields()[0].Type() = { Model->getTypePath(Right1), + { PointerQualifier } }; revng_check(Dedup() == 2); } @@ -233,7 +235,7 @@ BOOST_AUTO_TEST_CASE(TestTupleTreeDiffDeserialization) { model::Binary New; MetaAddress Address(0x1000, MetaAddressType::Code_aarch64); - New.ExtraCodeAddresses.insert(Address); + New.ExtraCodeAddresses().insert(Address); auto Diff = diff(Empty, New); diff --git a/tests/unit/ModelType.cpp b/tests/unit/ModelType.cpp index c37b5602b..dc6a2b8a7 100644 --- a/tests/unit/ModelType.cpp +++ b/tests/unit/ModelType.cpp @@ -40,7 +40,7 @@ static bool checkSerialization(const TupleTree &T) { revng_check(T->verify(true)); auto Deserialized = serializeDeserialize(T); revng_check(Deserialized->verify(true)); - return T->Types == Deserialized->Types; + return T->Types() == Deserialized->Types(); } BOOST_AUTO_TEST_CASE(PrimitiveTypes) { @@ -140,60 +140,60 @@ BOOST_AUTO_TEST_CASE(EnumTypes) { TypePath EnumPath = T->recordNewType(makeType()); auto *Enum = cast(EnumPath.get()); - revng_check(T->Types.size() == 2); + revng_check(T->Types().size() == 2); // The enum does not verify if we don't define a valid underlying type and // at least one enum entry auto Int32QT = model::QualifiedType(Int32, {}); - Enum->UnderlyingType = Int32QT; + Enum->UnderlyingType() = Int32QT; revng_check(not Enum->verify(false)); revng_check(not T->verify(false)); // With a valid underlying type and at least one entry we're good, but we // have to initialize all the cross references in the tree. EnumEntry Entry = EnumEntry{ 0 }; - Entry.CustomName = "value0"; + Entry.CustomName() = "value0"; revng_check(Entry.verify(true)); - revng_check(Enum->Entries.insert(Entry).second); + revng_check(Enum->Entries().insert(Entry).second); revng_check(Enum->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // We cannot insert other entries with the same value, but we can insert new // entries with different values. - revng_check(Enum->Entries.size() == 1); - revng_check(not Enum->Entries.insert(EnumEntry{ 0 }).second); - revng_check(Enum->Entries.size() == 1); + revng_check(Enum->Entries().size() == 1); + revng_check(not Enum->Entries().insert(EnumEntry{ 0 }).second); + revng_check(Enum->Entries().size() == 1); revng_check(Enum->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); revng_check(Enum->verify(true)); revng_check(T->verify(true)); - revng_check(Enum->Entries.insert(EnumEntry{ 1 }).second); - revng_check(Enum->Entries.size() == 2); + revng_check(Enum->Entries().insert(EnumEntry{ 1 }).second); + revng_check(Enum->Entries().size() == 2); revng_check(Enum->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // Inserting two entries with the same name succceds but it's bad. EnumEntry Entry1{ 5 }; - Entry1.CustomName = "some_value"; - revng_check(Enum->Entries.insert(Entry1).second); - revng_check(Enum->Entries.size() == 3); + Entry1.CustomName() = "some_value"; + revng_check(Enum->Entries().insert(Entry1).second); + revng_check(Enum->Entries().size() == 3); revng_check(Enum->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); EnumEntry Entry2{ 7 }; - Entry2.CustomName = "some_value"; - revng_check(Enum->Entries.insert(Entry2).second); - revng_check(Enum->Entries.size() == 4); + Entry2.CustomName() = "some_value"; + revng_check(Enum->Entries().insert(Entry2).second); + revng_check(Enum->Entries().size() == 4); revng_check(not Enum->verify(false)); revng_check(not T->verify(false)); // But if we remove the dupicated entry we're good again - revng_check(Enum->Entries.erase(7)); - revng_check(Enum->Entries.size() == 3); + revng_check(Enum->Entries().erase(7)); + revng_check(Enum->Entries().size() == 3); revng_check(Enum->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); @@ -201,25 +201,25 @@ BOOST_AUTO_TEST_CASE(EnumTypes) { // But if we break the underlying, making it point to a type that does not // exist, we're not good anymore auto BrokenPath = TypePath::fromString(T.get(), "/Types/TypedefType-42"); - Enum->UnderlyingType = { BrokenPath, {} }; + Enum->UnderlyingType() = { BrokenPath, {} }; revng_check(not Enum->verify(false)); revng_check(not T->verify(false)); // Also we set the underlying type to a valid type, but that is not a // primitive integer type, we are not good auto PathToNonInt = T->getTypePath(Enum); - Enum->UnderlyingType = { PathToNonInt, {} }; + Enum->UnderlyingType() = { PathToNonInt, {} }; revng_check(not Enum->verify(false)); revng_check(not T->verify(false)); // If we put back the proper underlying type it verifies. - Enum->UnderlyingType = Int32QT; + Enum->UnderlyingType() = Int32QT; revng_check(Enum->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // But if we clear the entries it does not verify anymore - Enum->Entries.clear(); + Enum->Entries().clear(); revng_check(not Enum->verify(false)); revng_check(not T->verify(false)); } @@ -233,34 +233,34 @@ BOOST_AUTO_TEST_CASE(TypedefTypes) { TypePath TypedefPath = T->recordNewType(makeType()); auto *Typedef = cast(TypedefPath.get()); - revng_check(T->Types.size() == 2); + revng_check(T->Types().size() == 2); // The pid_t typedef refers to the int32_t - Typedef->UnderlyingType = { Int32, {} }; + Typedef->UnderlyingType() = { Int32, {} }; revng_check(Typedef->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // Adding qualifiers the typedef still verifies - Typedef->UnderlyingType.Qualifiers.push_back(Qualifier::createConst()); + Typedef->UnderlyingType().Qualifiers().push_back(Qualifier::createConst()); revng_check(Typedef->verify(true)); revng_check(T->verify(true)); - Typedef->UnderlyingType.Qualifiers.push_back(Qualifier::createArray(42)); + Typedef->UnderlyingType().Qualifiers().push_back(Qualifier::createArray(42)); revng_check(Typedef->verify(true)); revng_check(T->verify(true)); - Typedef->UnderlyingType.Qualifiers.push_back(Qualifier::createPointer(8)); + Typedef->UnderlyingType().Qualifiers().push_back(Qualifier::createPointer(8)); revng_check(Typedef->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // Removing qualifiers, the typedef still verifies - Typedef->UnderlyingType.Qualifiers.clear(); + Typedef->UnderlyingType().Qualifiers().clear(); revng_check(Typedef->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // If the underlying type is the type itself something is broken - Typedef->UnderlyingType.UnqualifiedType = T->getTypePath(Typedef); + Typedef->UnderlyingType().UnqualifiedType() = T->getTypePath(Typedef); revng_check(not Typedef->verify(false)); revng_check(not T->verify(false)); } @@ -276,118 +276,118 @@ BOOST_AUTO_TEST_CASE(StructTypes) { // Insert the struct TypePath StructPath = T->recordNewType(makeType()); auto *Struct = cast(StructPath.get()); - revng_check(T->Types.size() == 3); + revng_check(T->Types().size() == 3); // Let's make it large, so that we can play around with fields. - Struct->Size = 1024; + Struct->Size() = 1024; // Insert field in the struct StructField Field0 = StructField{ 0 }; - Field0.Type = { Int32, {} }; - revng_check(Struct->Fields.insert(Field0).second); + Field0.Type() = { Int32, {} }; + revng_check(Struct->Fields().insert(Field0).second); revng_check(Struct->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // Adding a new field is valid StructField Field1 = StructField{ 4 }; - Field1.Type = { Int32, {} }; - revng_check(Struct->Fields.insert(Field1).second); + Field1.Type() = { Int32, {} }; + revng_check(Struct->Fields().insert(Field1).second); revng_check(Struct->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // Inserting fails if the index is already present StructField Field1Bis = StructField{ 4 }; - Field1Bis.Type = { Int32, {} }; - revng_check(not Struct->Fields.insert(Field1Bis).second); + Field1Bis.Type() = { Int32, {} }; + revng_check(not Struct->Fields().insert(Field1Bis).second); revng_check(Struct->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // Assigning succeeds if even if an index is already present StructField Field1Ter = StructField{ 4 }; - Field1Ter.Type = { Int32, {} }; - Field1Ter.CustomName = "fld1ter"; - revng_check(not Struct->Fields.insert_or_assign(Field1Ter).second); + Field1Ter.Type() = { Int32, {} }; + Field1Ter.CustomName() = "fld1ter"; + revng_check(not Struct->Fields().insert_or_assign(Field1Ter).second); revng_check(Struct->verify(true)); - revng_check(Struct->Fields.at(4).CustomName == "fld1ter"); + revng_check(Struct->Fields().at(4).CustomName() == "fld1ter"); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // Adding a new field whose position is not consecutive to others builds a // struct that is valid StructField AnotherField = StructField{ 128 }; - AnotherField.Type = { Int32, {} }; - revng_check(Struct->Fields.insert(AnotherField).second); + AnotherField.Type() = { Int32, {} }; + revng_check(Struct->Fields().insert(AnotherField).second); revng_check(Struct->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // Adding a new field that overlaps with another is not valid StructField Overlap = StructField{ 129 }; - Overlap.Type = { Int32, {} }; - revng_check(Struct->Fields.insert(Overlap).second); + Overlap.Type() = { Int32, {} }; + revng_check(Struct->Fields().insert(Overlap).second); revng_check(not Struct->verify(false)); revng_check(not T->verify(false)); // Removing the overlapping field fixes the struct - revng_check(Struct->Fields.erase(129)); + revng_check(Struct->Fields().erase(129)); revng_check(Struct->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // Erasing a field that's not there fails - revng_check(not Struct->Fields.erase(129)); + revng_check(not Struct->Fields().erase(129)); revng_check(Struct->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // Shrinking the size does not break the struct - Struct->Size = 132; + Struct->Size() = 132; revng_check(Struct->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); for (int I = 0; I < 132; ++I) { // But shrinking too much breaks it again - Struct->Size = I; + Struct->Size() = I; revng_check(not Struct->verify(false)); revng_check(not T->verify(false)); } // Fixing the size fixes the struct - Struct->Size = 132; + Struct->Size() = 132; revng_check(Struct->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // Struct without fields are valid as long as their size is not zero - Struct->Fields.clear(); + Struct->Fields().clear(); revng_check(Struct->verify(false)); revng_check(T->verify(false)); - Struct->Size = 0; + Struct->Size() = 0; revng_check(not Struct->verify(false)); revng_check(not T->verify(false)); // Put the size back to a large value for the other tests. - Struct->Size = 100; + Struct->Size() = 100; revng_check(Struct->verify(false)); revng_check(T->verify(false)); // Struct x cannot have a field with type x - Struct->Fields.clear(); + Struct->Fields().clear(); StructField Same = StructField{ 0 }; - Same.Type = { T->getTypePath(Struct), {} }; - revng_check(Struct->Fields.insert(Same).second); + Same.Type() = { T->getTypePath(Struct), {} }; + revng_check(Struct->Fields().insert(Same).second); revng_check(not Struct->verify(false)); revng_check(not T->verify(false)); // Adding a void field is not valid - Struct->Fields.clear(); + Struct->Fields().clear(); StructField VoidField = StructField{ 0 }; - VoidField.Type = { VoidT, {} }; - revng_check(Struct->Fields.insert(VoidField).second); + VoidField.Type() = { VoidT, {} }; + revng_check(Struct->Fields().insert(VoidField).second); revng_check(not Struct->verify(false)); revng_check(not T->verify(false)); } @@ -404,12 +404,12 @@ BOOST_AUTO_TEST_CASE(UnionTypes) { // Insert the union TypePath UnionPath = T->recordNewType(makeType()); auto *Union = cast(UnionPath.get()); - revng_check(T->Types.size() == 4); + revng_check(T->Types().size() == 4); // Insert field in the struct UnionField Field0(0); - Field0.Type = { Int32, {} }; - revng_check(Union->Fields.insert(Field0).second); + Field0.Type() = { Int32, {} }; + revng_check(Union->Fields().insert(Field0).second); revng_check(Union->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); @@ -417,9 +417,9 @@ BOOST_AUTO_TEST_CASE(UnionTypes) { // Adding a new field is valid { UnionField Field1(1); - Field1.Type = { Int64, {} }; - Field1.CustomName = "fld1"; - const auto [It, New] = Union->Fields.insert(std::move(Field1)); + Field1.Type() = { Int64, {} }; + Field1.CustomName() = "fld1"; + const auto [It, New] = Union->Fields().insert(std::move(Field1)); revng_check(New); } revng_check(Union->verify(true)); @@ -430,39 +430,39 @@ BOOST_AUTO_TEST_CASE(UnionTypes) { // Assigning another field in a different position with a duplicated name // succeeds, but verification fails. UnionField Field1(2); - Field1.Type = { Int32, {} }; - Field1.CustomName = "fld1"; - const auto [It, New] = Union->Fields.insert(std::move(Field1)); + Field1.Type() = { Int32, {} }; + Field1.CustomName() = "fld1"; + const auto [It, New] = Union->Fields().insert(std::move(Field1)); revng_check(New); - revng_check(Union->Fields.at(It->Index).CustomName == "fld1"); + revng_check(Union->Fields().at(It->Index()).CustomName() == "fld1"); revng_check(not Union->verify(false)); revng_check(not T->verify(false)); // But removing goes back to good again - revng_check(Union->Fields.erase(It->Index)); + revng_check(Union->Fields().erase(It->Index())); revng_check(Union->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); } // Union without fields are invalid - Union->Fields.clear(); + Union->Fields().clear(); revng_check(not Union->verify(false)); revng_check(not T->verify(false)); // Union x cannot have a field with type x - Union->Fields.clear(); + Union->Fields().clear(); UnionField Same; - Same.Type = { T->getTypePath(Union), {} }; - revng_check(Union->Fields.insert(Same).second); + Same.Type() = { T->getTypePath(Union), {} }; + revng_check(Union->Fields().insert(Same).second); revng_check(not Union->verify(false)); revng_check(not T->verify(false)); // Adding a void field is not valid - Union->Fields.clear(); + Union->Fields().clear(); UnionField VoidField; - VoidField.Type = { VoidT, {} }; - revng_check(Union->Fields.insert(VoidField).second); + VoidField.Type() = { VoidT, {} }; + revng_check(Union->Fields().insert(VoidField).second); revng_check(not Union->verify(false)); revng_check(not T->verify(false)); } @@ -476,16 +476,16 @@ BOOST_AUTO_TEST_CASE(CABIFunctionTypes) { // Create a C-like function type TypePath FunctionPath = T->recordNewType(makeType()); auto *FunctionType = cast(FunctionPath.get()); - FunctionType->ABI = model::ABI::SystemV_x86_64; - revng_check(T->Types.size() == 3); + FunctionType->ABI() = model::ABI::SystemV_x86_64; + revng_check(T->Types().size() == 3); revng_check(not FunctionType->size().has_value()); // Insert argument in the function type Argument Arg0{ 0 }; - Arg0.Type = { Int32, {} }; - const auto &[InsertedArgIt, New] = FunctionType->Arguments.insert(Arg0); - revng_check(InsertedArgIt != FunctionType->Arguments.end()); + Arg0.Type() = { Int32, {} }; + const auto &[InsertedArgIt, New] = FunctionType->Arguments().insert(Arg0); + revng_check(InsertedArgIt != FunctionType->Arguments().end()); revng_check(New); // Verification fails due to missing return type @@ -493,7 +493,7 @@ BOOST_AUTO_TEST_CASE(CABIFunctionTypes) { revng_check(not T->verify(false)); QualifiedType RetTy{ Int32, {} }; - FunctionType->ReturnType = RetTy; + FunctionType->ReturnType() = RetTy; revng_check(FunctionType->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); @@ -501,29 +501,29 @@ BOOST_AUTO_TEST_CASE(CABIFunctionTypes) { // Adding a new field is valid, and we can have a function type with an // argument of the same type of itself. Argument Arg1{ 1 }; - Arg1.Type = { Int32, {} }; - revng_check(FunctionType->Arguments.insert(Arg1).second); + Arg1.Type() = { Int32, {} }; + revng_check(FunctionType->Arguments().insert(Arg1).second); revng_check(FunctionType->verify(true)); revng_check(checkSerialization(T)); // Inserting an ArgumentType in a position that is already taken fails Argument Arg1Bis{ 1 }; - Arg1Bis.Type = { Int32, {} }; - revng_check(not FunctionType->Arguments.insert(Arg1Bis).second); + Arg1Bis.Type() = { Int32, {} }; + revng_check(not FunctionType->Arguments().insert(Arg1Bis).second); revng_check(FunctionType->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // Assigning an ArgumentType in a position that is already taken succeeds - revng_check(not FunctionType->Arguments.insert_or_assign(Arg1Bis).second); + revng_check(not FunctionType->Arguments().insert_or_assign(Arg1Bis).second); revng_check(FunctionType->verify(true)); - auto &ArgT = FunctionType->Arguments.at(1); - revng_check(ArgT.Type.UnqualifiedType == Int32); + auto &ArgT = FunctionType->Arguments().at(1); + revng_check(ArgT.Type().UnqualifiedType() == Int32); revng_check(T->verify(true)); revng_check(checkSerialization(T)); // FunctionType without argument are valid - FunctionType->Arguments.clear(); + FunctionType->Arguments().clear(); revng_check(FunctionType->verify(true)); revng_check(T->verify(true)); revng_check(checkSerialization(T)); @@ -545,7 +545,7 @@ BOOST_AUTO_TEST_CASE(RawFunctionTypes) { // { model::TypedRegister RAXArgument(model::Register::rax_x86_64); - RAXArgument.Type = { Primitive64, { { QualifierKind::Array, 10 } } }; + RAXArgument.Type() = { Primitive64, { { QualifierKind::Array, 10 } } }; revng_check(not RAXArgument.verify(false)); } @@ -554,25 +554,25 @@ BOOST_AUTO_TEST_CASE(RawFunctionTypes) { // { model::NamedTypedRegister RDIArgument(model::Register::rdi_x86_64); - RDIArgument.Type = Generic64; + RDIArgument.Type() = Generic64; revng_check(RDIArgument.verify(true)); - RAF->Arguments.insert(RDIArgument); + RAF->Arguments().insert(RDIArgument); revng_check(RAF->verify(true)); model::NamedTypedRegister RSIArgument(model::Register::rsi_x86_64); - RSIArgument.Type = Generic64; - RSIArgument.CustomName = "Second"; + RSIArgument.Type() = Generic64; + RSIArgument.CustomName() = "Second"; revng_check(RSIArgument.verify(true)); - RAF->Arguments.insert(RSIArgument); + RAF->Arguments().insert(RSIArgument); revng_check(RAF->verify(true)); } // Add a return value { model::TypedRegister RAXReturnValue(model::Register::rax_x86_64); - RAXReturnValue.Type = Generic64; + RAXReturnValue.Type() = Generic64; revng_check(RAXReturnValue.verify(true)); - RAF->ReturnValues.insert(RAXReturnValue); + RAF->ReturnValues().insert(RAXReturnValue); revng_check(RAF->verify(true)); } } diff --git a/tests/unit/TupleTreeGenerator/Test.cpp b/tests/unit/TupleTreeGenerator/Test.cpp index 1295b2b3a..8023dd924 100644 --- a/tests/unit/TupleTreeGenerator/Test.cpp +++ b/tests/unit/TupleTreeGenerator/Test.cpp @@ -19,16 +19,16 @@ bool init_unit_test(); BOOST_AUTO_TEST_CASE(YAMLSerializationRoundTripTest) { using namespace ttgtest; TestClass ReferenceInstance; - ReferenceInstance.RequiredField = 1; - ReferenceInstance.OptionalField = 2; - ReferenceInstance.EnumField = ttgtest::TestEnum::MemberOne; - ReferenceInstance.SequenceField = { 1, 2, 3, 4, 5 }; + ReferenceInstance.RequiredField() = 1; + ReferenceInstance.OptionalField() = 2; + ReferenceInstance.EnumField() = ttgtest::TestEnum::MemberOne; + ReferenceInstance.SequenceField() = { 1, 2, 3, 4, 5 }; using RefType = TupleTreeReference; - ReferenceInstance.ReferenceField = RefType::fromString(&ReferenceInstance, - "/SequenceField/1"); + ReferenceInstance.ReferenceField() = RefType::fromString(&ReferenceInstance, + "/SequenceField/1"); - revng_assert(ReferenceInstance.ReferenceField.isValid()); - revng_assert(ReferenceInstance.ReferenceField.get()); + revng_assert(ReferenceInstance.ReferenceField().isValid()); + revng_assert(ReferenceInstance.ReferenceField().get()); std::string Buffer; llvm::raw_string_ostream OutputStream(Buffer); diff --git a/tools/efa/extractcfg/Main.cpp b/tools/efa/extractcfg/Main.cpp index dc90952af..785679f82 100644 --- a/tools/efa/extractcfg/Main.cpp +++ b/tools/efa/extractcfg/Main.cpp @@ -63,11 +63,11 @@ int main(int argc, const char **argv) { continue; const efa::FunctionMetadata &FM = Cache.getFunctionMetadata(&BB); - auto &Function = Model->Functions.at(FM.Entry); - revng::DecoratedFunction NewFunction(FM.Entry, - Function.OriginalName, + auto &Function = Model->Functions().at(FM.Entry()); + revng::DecoratedFunction NewFunction(FM.Entry(), + Function.OriginalName(), FM, - Function.Attributes); + Function.Attributes()); DecoratedFunctions.insert(std::move(NewFunction)); } } @@ -75,14 +75,14 @@ int main(int argc, const char **argv) { for (Function &F : FunctionTags::Isolated.functions(Module.get())) { auto *FMMDNode = F.getMetadata(FunctionMetadataMDName); const efa::FunctionMetadata &FM = Cache.getFunctionMetadata(&F); - if (not FMMDNode or DecoratedFunctions.count(FM.Entry) != 0) + if (not FMMDNode or DecoratedFunctions.count(FM.Entry()) != 0) continue; - auto &Function = Model->Functions.at(FM.Entry); - revng::DecoratedFunction NewFunction(FM.Entry, - Function.OriginalName, + auto &Function = Model->Functions().at(FM.Entry()); + revng::DecoratedFunction NewFunction(FM.Entry(), + Function.OriginalName(), FM, - Function.Attributes); + Function.Attributes()); DecoratedFunctions.insert(std::move(NewFunction)); }