10
10
#include " bolt/Core/BinaryFunction.h"
11
11
#include " llvm/Support/DataExtractor.h"
12
12
#include " llvm/Support/Errc.h"
13
+ #include " llvm/Support/Error.h"
14
+ #include " llvm/Support/LEB128.h"
13
15
14
16
#define DEBUG_TYPE " bolt-bat"
15
17
@@ -44,7 +46,7 @@ void BoltAddressTranslation::writeEntriesForBB(MapTy &Map,
44
46
// and this deleted block will both share the same output address (the same
45
47
// key), and we need to map back. We choose here to privilege the successor by
46
48
// allowing it to overwrite the previously inserted key in the map.
47
- Map[BBOutputOffset] = BBInputOffset;
49
+ Map[BBOutputOffset] = BBInputOffset << 1 ;
48
50
49
51
const auto &IOAddressMap =
50
52
BB.getFunction ()->getBinaryContext ().getIOAddressMap ();
@@ -61,8 +63,8 @@ void BoltAddressTranslation::writeEntriesForBB(MapTy &Map,
61
63
62
64
LLVM_DEBUG (dbgs () << " Key: " << Twine::utohexstr (OutputOffset) << " Val: "
63
65
<< Twine::utohexstr (InputOffset) << " (branch)\n " );
64
- Map.insert (
65
- std::pair< uint32_t , uint32_t >(OutputOffset, InputOffset | BRANCHENTRY));
66
+ Map.insert (std::pair< uint32_t , uint32_t >(OutputOffset,
67
+ ( InputOffset << 1 ) | BRANCHENTRY));
66
68
}
67
69
}
68
70
@@ -102,28 +104,28 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) {
102
104
}
103
105
104
106
const uint32_t NumFuncs = Maps.size ();
105
- OS. write ( reinterpret_cast < const char *>(& NumFuncs), 4 );
107
+ encodeULEB128 ( NumFuncs, OS );
106
108
LLVM_DEBUG (dbgs () << " Writing " << NumFuncs << " functions for BAT.\n " );
107
109
for (auto &MapEntry : Maps) {
108
110
const uint64_t Address = MapEntry.first ;
109
111
MapTy &Map = MapEntry.second ;
110
112
const uint32_t NumEntries = Map.size ();
111
113
LLVM_DEBUG (dbgs () << " Writing " << NumEntries << " entries for 0x"
112
114
<< Twine::utohexstr (Address) << " .\n " );
113
- OS. write ( reinterpret_cast < const char *>(& Address), 8 );
114
- OS. write ( reinterpret_cast < const char *>(& NumEntries), 4 );
115
+ encodeULEB128 ( Address, OS );
116
+ encodeULEB128 ( NumEntries, OS );
115
117
for (std::pair<const uint32_t , uint32_t > &KeyVal : Map) {
116
- OS. write ( reinterpret_cast < const char *>(& KeyVal.first ), 4 );
117
- OS. write ( reinterpret_cast < const char *>(& KeyVal.second ), 4 );
118
+ encodeULEB128 ( KeyVal.first , OS );
119
+ encodeULEB128 ( KeyVal.second , OS );
118
120
}
119
121
}
120
122
const uint32_t NumColdEntries = ColdPartSource.size ();
121
123
LLVM_DEBUG (dbgs () << " Writing " << NumColdEntries
122
124
<< " cold part mappings.\n " );
123
- OS. write ( reinterpret_cast < const char *>(& NumColdEntries), 4 );
125
+ encodeULEB128 ( NumColdEntries, OS );
124
126
for (std::pair<const uint64_t , uint64_t > &ColdEntry : ColdPartSource) {
125
- OS. write ( reinterpret_cast < const char *>(& ColdEntry.first ), 8 );
126
- OS. write ( reinterpret_cast < const char *>(& ColdEntry.second ), 8 );
127
+ encodeULEB128 ( ColdEntry.first , OS );
128
+ encodeULEB128 ( ColdEntry.second , OS );
127
129
LLVM_DEBUG (dbgs () << " " << Twine::utohexstr (ColdEntry.first ) << " -> "
128
130
<< Twine::utohexstr (ColdEntry.second ) << " \n " );
129
131
}
@@ -152,43 +154,31 @@ std::error_code BoltAddressTranslation::parse(StringRef Buf) {
152
154
if (Name.substr (0 , 4 ) != " BOLT" )
153
155
return make_error_code (llvm::errc::io_error);
154
156
155
- if (Buf.size () - Offset < 4 )
156
- return make_error_code (llvm::errc::io_error);
157
-
158
- const uint32_t NumFunctions = DE.getU32 (&Offset);
157
+ Error Err (Error::success ());
158
+ const uint32_t NumFunctions = DE.getULEB128 (&Offset, &Err);
159
159
LLVM_DEBUG (dbgs () << " Parsing " << NumFunctions << " functions\n " );
160
160
for (uint32_t I = 0 ; I < NumFunctions; ++I) {
161
- if (Buf.size () - Offset < 12 )
162
- return make_error_code (llvm::errc::io_error);
163
-
164
- const uint64_t Address = DE.getU64 (&Offset);
165
- const uint32_t NumEntries = DE.getU32 (&Offset);
161
+ const uint64_t Address = DE.getULEB128 (&Offset, &Err);
162
+ const uint32_t NumEntries = DE.getULEB128 (&Offset, &Err);
166
163
MapTy Map;
167
164
168
165
LLVM_DEBUG (dbgs () << " Parsing " << NumEntries << " entries for 0x"
169
166
<< Twine::utohexstr (Address) << " \n " );
170
- if (Buf.size () - Offset < 8 * NumEntries)
171
- return make_error_code (llvm::errc::io_error);
172
167
for (uint32_t J = 0 ; J < NumEntries; ++J) {
173
- const uint32_t OutputAddr = DE.getU32 (&Offset);
174
- const uint32_t InputAddr = DE.getU32 (&Offset);
168
+ const uint32_t OutputAddr = DE.getULEB128 (&Offset, &Err );
169
+ const uint32_t InputAddr = DE.getULEB128 (&Offset, &Err );
175
170
Map.insert (std::pair<uint32_t , uint32_t >(OutputAddr, InputAddr));
176
171
LLVM_DEBUG (dbgs () << Twine::utohexstr (OutputAddr) << " -> "
177
172
<< Twine::utohexstr (InputAddr) << " \n " );
178
173
}
179
174
Maps.insert (std::pair<uint64_t , MapTy>(Address, Map));
180
175
}
181
176
182
- if (Buf.size () - Offset < 4 )
183
- return make_error_code (llvm::errc::io_error);
184
-
185
- const uint32_t NumColdEntries = DE.getU32 (&Offset);
177
+ const uint32_t NumColdEntries = DE.getULEB128 (&Offset, &Err);
186
178
LLVM_DEBUG (dbgs () << " Parsing " << NumColdEntries << " cold part mappings\n " );
187
179
for (uint32_t I = 0 ; I < NumColdEntries; ++I) {
188
- if (Buf.size () - Offset < 16 )
189
- return make_error_code (llvm::errc::io_error);
190
- const uint32_t ColdAddress = DE.getU64 (&Offset);
191
- const uint32_t HotAddress = DE.getU64 (&Offset);
180
+ const uint32_t ColdAddress = DE.getULEB128 (&Offset, &Err);
181
+ const uint32_t HotAddress = DE.getULEB128 (&Offset, &Err);
192
182
ColdPartSource.insert (
193
183
std::pair<uint64_t , uint64_t >(ColdAddress, HotAddress));
194
184
LLVM_DEBUG (dbgs () << Twine::utohexstr (ColdAddress) << " -> "
@@ -198,7 +188,7 @@ std::error_code BoltAddressTranslation::parse(StringRef Buf) {
198
188
outs () << " BOLT-INFO: Parsed " << NumColdEntries
199
189
<< " BAT cold-to-hot entries\n " ;
200
190
201
- return std::error_code ( );
191
+ return errorToErrorCode ( std::move (Err) );
202
192
}
203
193
204
194
void BoltAddressTranslation::dump (raw_ostream &OS) {
@@ -209,7 +199,7 @@ void BoltAddressTranslation::dump(raw_ostream &OS) {
209
199
OS << " BB mappings:\n " ;
210
200
for (const auto &Entry : MapEntry.second ) {
211
201
const bool IsBranch = Entry.second & BRANCHENTRY;
212
- const uint32_t Val = Entry.second & ~BRANCHENTRY;
202
+ const uint32_t Val = Entry.second >> 1 ; // dropping BRANCHENTRY bit
213
203
OS << " 0x" << Twine::utohexstr (Entry.first ) << " -> "
214
204
<< " 0x" << Twine::utohexstr (Val);
215
205
if (IsBranch)
@@ -244,7 +234,7 @@ uint64_t BoltAddressTranslation::translate(uint64_t FuncAddress,
244
234
245
235
--KeyVal;
246
236
247
- const uint32_t Val = KeyVal->second & ~BRANCHENTRY;
237
+ const uint32_t Val = KeyVal->second >> 1 ; // dropping BRANCHENTRY bit
248
238
// Branch source addresses are translated to the first instruction of the
249
239
// source BB to avoid accounting for modifications BOLT may have made in the
250
240
// BB regarding deletion/addition of instructions.
0 commit comments