xref: /llvm-project/bolt/lib/Core/AddressMap.cpp (revision b5ac1697c88bda324111f1fb61c93e091cefe500)
1 #include "bolt/Core/AddressMap.h"
2 #include "bolt/Core/BinaryContext.h"
3 #include "bolt/Core/BinaryFunction.h"
4 #include "llvm/MC/MCStreamer.h"
5 #include "llvm/Support/DataExtractor.h"
6 
7 namespace llvm {
8 namespace bolt {
9 
10 const char *const AddressMap::SectionName = ".bolt.address_map";
11 
12 static void emitLabel(MCStreamer &Streamer, uint64_t InputAddress,
13                       const MCSymbol *OutputLabel) {
14   Streamer.emitIntValue(InputAddress, 8);
15   Streamer.emitSymbolValue(OutputLabel, 8);
16 }
17 
18 void AddressMap::emit(MCStreamer &Streamer, BinaryContext &BC) {
19   Streamer.switchSection(BC.getDataSection(SectionName));
20 
21   for (const auto &[BFAddress, BF] : BC.getBinaryFunctions()) {
22     if (!BF.requiresAddressMap())
23       continue;
24 
25     for (const auto &BB : BF) {
26       if (!BB.getLabel()->isDefined())
27         continue;
28 
29       emitLabel(Streamer, BFAddress + BB.getInputAddressRange().first,
30                 BB.getLabel());
31 
32       if (!BB.hasLocSyms())
33         continue;
34 
35       for (auto [Offset, Symbol] : BB.getLocSyms())
36         emitLabel(Streamer, BFAddress + Offset, Symbol);
37     }
38   }
39 }
40 
41 AddressMap AddressMap::parse(StringRef Buffer, const BinaryContext &BC) {
42   const auto EntrySize = 2 * BC.AsmInfo->getCodePointerSize();
43   assert(Buffer.size() % EntrySize == 0 && "Unexpected address map size");
44 
45   DataExtractor DE(Buffer, BC.AsmInfo->isLittleEndian(),
46                    BC.AsmInfo->getCodePointerSize());
47   DataExtractor::Cursor Cursor(0);
48 
49   AddressMap Parsed;
50   Parsed.Map.reserve(Buffer.size() / EntrySize);
51 
52   while (Cursor && !DE.eof(Cursor)) {
53     const auto Input = DE.getAddress(Cursor);
54     const auto Output = DE.getAddress(Cursor);
55     if (!Parsed.Map.count(Input))
56       Parsed.Map.insert({Input, Output});
57   }
58 
59   assert(Cursor && "Error reading address map section");
60   return Parsed;
61 }
62 
63 } // namespace bolt
64 } // namespace llvm
65