-
Notifications
You must be signed in to change notification settings - Fork 734
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[BOLT] Calculate input to output address map using BOLTLinker
BOLT uses MCAsmLayout to calculate the output values of basic blocks. This means output values are calculated based on a pre-linking state and any changes to symbol values during linking will cause incorrect values to be used. This issue was first addressed in D154604 by adding all basic block symbols to the symbol table for the linker to resolve them. However, the runtime overhead of handling this huge symbol table turned out to be prohibitively large. This patch solves the issue in a different way. First, a temporary section containing [input address, output symbol] pairs is emitted to the intermediary object file. The linker will resolve all these references so we end up with a section of [input address, output address] pairs. This section is then parsed and used to: - Replace BinaryBasicBlock::OffsetTranslationTable - Replace BinaryFunction::InputOffsetToAddressMap - Update BinaryBasicBlock::OutputAddressRange Note that the reason this is more performant than the previous attempt is that these symbol references do not cause entries to be added to the symbol table. Instead, section-relative references are used for the relocations. Reviewed By: maksfb Differential Revision: https://reviews.llvm.org/D155604
- Loading branch information
Showing
13 changed files
with
183 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
//===- bolt/Core/AddressMap.h - Input-output address map --------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Helper class to create a mapping from input to output addresses needed for | ||
// updating debugging symbols and BAT. We emit an MCSection containing | ||
// <Input address, Output MCSymbol> pairs to the object file and JITLink will | ||
// transform this in <Input address, Output address> pairs. The linker output | ||
// can then be parsed and used to establish the mapping. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
#ifndef BOLT_CORE_ADDRESS_MAP_H | ||
#define BOLT_CORE_ADDRESS_MAP_H | ||
|
||
#include "llvm/ADT/StringRef.h" | ||
|
||
#include <optional> | ||
#include <unordered_map> | ||
|
||
namespace llvm { | ||
|
||
class MCStreamer; | ||
|
||
namespace bolt { | ||
|
||
class BinaryContext; | ||
|
||
class AddressMap { | ||
using MapTy = std::unordered_multimap<uint64_t, uint64_t>; | ||
MapTy Map; | ||
|
||
public: | ||
static const char *const SectionName; | ||
|
||
static void emit(MCStreamer &Streamer, BinaryContext &BC); | ||
static AddressMap parse(StringRef Buffer, const BinaryContext &BC); | ||
|
||
std::optional<uint64_t> lookup(uint64_t InputAddress) const { | ||
auto It = Map.find(InputAddress); | ||
if (It != Map.end()) | ||
return It->second; | ||
return std::nullopt; | ||
} | ||
|
||
std::pair<MapTy::const_iterator, MapTy::const_iterator> | ||
lookupAll(uint64_t InputAddress) const { | ||
return Map.equal_range(InputAddress); | ||
} | ||
}; | ||
|
||
} // namespace bolt | ||
} // namespace llvm | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#include "bolt/Core/AddressMap.h" | ||
#include "bolt/Core/BinaryContext.h" | ||
#include "bolt/Core/BinaryFunction.h" | ||
#include "llvm/MC/MCStreamer.h" | ||
#include "llvm/Support/DataExtractor.h" | ||
|
||
namespace llvm { | ||
namespace bolt { | ||
|
||
const char *const AddressMap::SectionName = ".bolt.address_map"; | ||
|
||
static void emitLabel(MCStreamer &Streamer, uint64_t InputAddress, | ||
const MCSymbol *OutputLabel) { | ||
Streamer.emitIntValue(InputAddress, 8); | ||
Streamer.emitSymbolValue(OutputLabel, 8); | ||
} | ||
|
||
void AddressMap::emit(MCStreamer &Streamer, BinaryContext &BC) { | ||
Streamer.switchSection(BC.getDataSection(SectionName)); | ||
|
||
for (const auto &[BFAddress, BF] : BC.getBinaryFunctions()) { | ||
if (!BF.requiresAddressMap()) | ||
continue; | ||
|
||
for (const auto &BB : BF) { | ||
if (!BB.getLabel()->isDefined()) | ||
continue; | ||
|
||
emitLabel(Streamer, BFAddress + BB.getInputAddressRange().first, | ||
BB.getLabel()); | ||
|
||
if (!BB.hasLocSyms()) | ||
continue; | ||
|
||
for (auto [Offset, Symbol] : BB.getLocSyms()) | ||
emitLabel(Streamer, BFAddress + Offset, Symbol); | ||
} | ||
} | ||
} | ||
|
||
AddressMap AddressMap::parse(StringRef Buffer, const BinaryContext &BC) { | ||
const auto EntrySize = 2 * BC.AsmInfo->getCodePointerSize(); | ||
assert(Buffer.size() % EntrySize == 0 && "Unexpected address map size"); | ||
|
||
DataExtractor DE(Buffer, BC.AsmInfo->isLittleEndian(), | ||
BC.AsmInfo->getCodePointerSize()); | ||
DataExtractor::Cursor Cursor(0); | ||
|
||
AddressMap Parsed; | ||
Parsed.Map.reserve(Buffer.size() / EntrySize); | ||
|
||
while (Cursor && !DE.eof(Cursor)) { | ||
const auto Input = DE.getAddress(Cursor); | ||
const auto Output = DE.getAddress(Cursor); | ||
Parsed.Map.insert({Input, Output}); | ||
} | ||
|
||
assert(Cursor && "Error reading address map section"); | ||
return Parsed; | ||
} | ||
|
||
} // namespace bolt | ||
} // namespace llvm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.