llvm-project/bolt/lib/Core/AddressMap.cpp
Rafael Auler b5ac1697c8 [BOLT] Give precedence to first AddressMap entries
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
2023-08-24 11:59:43 -07:00

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