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