mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-03 02:36:08 +00:00

When parsing AddressMap and there is a conflict in keys, where two entries share the same key, consider the first entry as the correct one, instead of the last. This matches previous behavior in BOLT and covers case such as BOLT creating a new basic block but sharing the same input offset of the previous (or entry) basic block. In this case, instead of translating debuginfo to use the newly created BB, translate using the BB that was originally read from input. This will increase our chances of getting debuginfo right. Tested via binary comparison in tests: X86/dwarf4-df-input-lowpc-ranges.test X86/dwarf5-df-input-lowpc-ranges.test Reviewed By: #bolt, maksfb, jobnoorman Differential Revision: https://reviews.llvm.org/D158686
65 lines
1.8 KiB
C++
65 lines
1.8 KiB
C++
#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);
|
|
if (!Parsed.Map.count(Input))
|
|
Parsed.Map.insert({Input, Output});
|
|
}
|
|
|
|
assert(Cursor && "Error reading address map section");
|
|
return Parsed;
|
|
}
|
|
|
|
} // namespace bolt
|
|
} // namespace llvm
|