forked from GrammaTech/gtirb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathModule.cpp
101 lines (97 loc) · 3.79 KB
/
Module.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//===- Module.cpp -----------------------------------------------*- C++ -*-===//
//
// Copyright (C) 2020 GrammaTech, Inc.
//
// This code is licensed under the MIT license. See the LICENSE file in the
// project root for license terms.
//
// This project is sponsored by the Office of Naval Research, One Liberty
// Center, 875 N. Randolph Street, Arlington, VA 22203 under contract #
// N68335-17-C-0700. The content of the information does not necessarily
// reflect the position or policy of the Government and no official
// endorsement should be inferred.
//
//===----------------------------------------------------------------------===//
#include "Module.hpp"
#include <gtirb/CFG.hpp>
#include <gtirb/CodeBlock.hpp>
#include <gtirb/Serialization.hpp>
#include <gtirb/SymbolicExpression.hpp>
#include <proto/Module.pb.h>
#include <map>
using namespace gtirb;
void Module::toProtobuf(MessageType* Message) const {
nodeUUIDToBytes(this, *Message->mutable_uuid());
Message->set_binary_path(this->BinaryPath);
Message->set_preferred_addr(static_cast<uint64_t>(this->PreferredAddr));
Message->set_rebase_delta(this->RebaseDelta);
Message->set_file_format(static_cast<proto::FileFormat>(this->FileFormat));
Message->set_isa(static_cast<proto::ISA>(this->Isa));
Message->set_name(this->Name);
*Message->mutable_cfg() = gtirb::toProtobuf(this->Cfg);
sequenceToProtobuf(ProxyBlocks.begin(), ProxyBlocks.end(),
Message->mutable_proxies());
sequenceToProtobuf(sections_begin(), sections_end(),
Message->mutable_sections());
containerToProtobuf(Symbols, Message->mutable_symbols());
if (EntryPoint) {
nodeUUIDToBytes(EntryPoint, *Message->mutable_entry_point());
}
AuxDataContainer::toProtobuf(Message);
}
// FIXME: improve containerFromProtobuf so it can handle a pair where one
// element is a pointer to a Node subclass.
template <class T, class U, class V, class W>
static void nodeMapFromProtobuf(Context& C, std::map<T, U*>& Values,
const google::protobuf::Map<V, W>& Message) {
Values.clear();
std::for_each(Message.begin(), Message.end(), [&Values, &C](const auto& M) {
std::pair<T, U*> Val;
fromProtobuf(C, Val.first, M.first);
Val.second = U::fromProtobuf(C, M.second);
Values.insert(std::move(Val));
});
}
Module* Module::fromProtobuf(Context& C, IR* Parent,
const MessageType& Message) {
Module* M = Module::Create(C);
M->setIR(Parent);
setNodeUUIDFromBytes(M, Message.uuid());
M->BinaryPath = Message.binary_path();
M->PreferredAddr = Addr(Message.preferred_addr());
M->RebaseDelta = Message.rebase_delta();
M->FileFormat = static_cast<gtirb::FileFormat>(Message.file_format());
M->Isa = static_cast<ISA>(Message.isa());
M->Name = Message.name();
for (const auto& Elt : Message.proxies()) {
auto* B = ProxyBlock::fromProtobuf(C, M, Elt);
M->ProxyBlocks.insert(B);
B->setModule(M);
addVertex(B, M->Cfg);
}
for (const auto& Elt : Message.sections()) {
auto* S = Section::fromProtobuf(C, M, Elt);
M->Sections.emplace(S);
S->setModule(M);
S->addToIndices();
}
for (const auto& Elt : Message.symbols()) {
auto* S = Symbol::fromProtobuf(C, M, Elt);
M->Symbols.emplace(S);
S->setModule(M);
}
for (const auto& ProtoS : Message.sections()) {
for (const auto& ProtoBI : ProtoS.byte_intervals()) {
auto* BI =
cast<ByteInterval>(getByUUID(C, uuidFromBytes(ProtoBI.uuid())));
BI->symbolicExpressionsFromProtobuf(C, ProtoBI);
}
}
gtirb::fromProtobuf(C, M->Cfg, Message.cfg());
if (!Message.entry_point().empty()) {
M->EntryPoint = cast<CodeBlock>(
Node::getByUUID(C, uuidFromBytes(Message.entry_point())));
}
static_cast<AuxDataContainer*>(M)->fromProtobuf(C, Message);
return M;
}