1 //===- bolt/Core/AddressMap.h - Input-output address map --------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the declaration of the AddressMap class used for looking 10 // up addresses in the output object. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef BOLT_CORE_ADDRESS_MAP_H 15 #define BOLT_CORE_ADDRESS_MAP_H 16 17 #include "llvm/MC/MCSymbol.h" 18 19 #include <optional> 20 #include <unordered_map> 21 22 namespace llvm { 23 24 class MCStreamer; 25 26 namespace bolt { 27 28 class BinaryContext; 29 30 /// Helper class to create a mapping from input entities to output addresses 31 /// needed for updating debugging symbols and BAT. We emit a section containing 32 /// <Input entity, Output MCSymbol> pairs to the object file and JITLink will 33 /// transform this in <Input entity, Output address> pairs. The linker output 34 /// can then be parsed and used to establish the mapping. 35 /// 36 /// The entities that can be mapped to output address are input addresses and 37 /// labels (MCSymbol). Input addresses support one-to-many mapping. 38 class AddressMap { 39 static const char *const AddressSectionName; 40 static const char *const LabelSectionName; 41 42 /// Map multiple <input address> to <output address>. 43 using Addr2AddrMapTy = std::unordered_multimap<uint64_t, uint64_t>; 44 Addr2AddrMapTy Address2AddressMap; 45 46 /// Map MCSymbol to its output address. Normally used for temp symbols that 47 /// are not updated by the linker. 48 using Label2AddrMapTy = DenseMap<const MCSymbol *, uint64_t>; 49 Label2AddrMapTy Label2AddrMap; 50 51 public: 52 static void emit(MCStreamer &Streamer, BinaryContext &BC); 53 static std::optional<AddressMap> parse(BinaryContext &BC); 54 lookup(uint64_t InputAddress)55 std::optional<uint64_t> lookup(uint64_t InputAddress) const { 56 auto It = Address2AddressMap.find(InputAddress); 57 if (It != Address2AddressMap.end()) 58 return It->second; 59 return std::nullopt; 60 } 61 lookup(const MCSymbol * Symbol)62 std::optional<uint64_t> lookup(const MCSymbol *Symbol) const { 63 auto It = Label2AddrMap.find(Symbol); 64 if (It != Label2AddrMap.end()) 65 return It->second; 66 return std::nullopt; 67 } 68 69 std::pair<Addr2AddrMapTy::const_iterator, Addr2AddrMapTy::const_iterator> lookupAll(uint64_t InputAddress)70 lookupAll(uint64_t InputAddress) const { 71 return Address2AddressMap.equal_range(InputAddress); 72 } 73 }; 74 75 } // namespace bolt 76 } // namespace llvm 77 78 #endif 79