forked from OSchip/llvm-project
Reapply "[dsymutil] Gather function ranges during DIE selection."
This reverts commit r231967 which reinstates r231957. Now that IntervalMap uses explicitely aligned storage, it should be safe. llvm-svn: 232080
This commit is contained in:
parent
af06e7562b
commit
1af75f7624
|
@ -10,6 +10,7 @@
|
|||
#include "BinaryHolder.h"
|
||||
#include "DebugMap.h"
|
||||
#include "dsymutil.h"
|
||||
#include "llvm/ADT/IntervalMap.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
|
@ -49,6 +50,11 @@ bool error(const Twine &Error, const Twine &Context) {
|
|||
return false;
|
||||
}
|
||||
|
||||
template <typename KeyT, typename ValT>
|
||||
using HalfOpenIntervalMap =
|
||||
IntervalMap<KeyT, ValT, IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
|
||||
IntervalMapHalfOpenInfo<KeyT>>;
|
||||
|
||||
/// \brief Stores all information relating to a compile unit, be it in
|
||||
/// its original instance in the object file to its brand new cloned
|
||||
/// and linked DIE tree.
|
||||
|
@ -63,15 +69,19 @@ public:
|
|||
bool InDebugMap; ///< Was this DIE's entity found in the map?
|
||||
};
|
||||
|
||||
CompileUnit(DWARFUnit &OrigUnit) : OrigUnit(OrigUnit) {
|
||||
CompileUnit(DWARFUnit &OrigUnit)
|
||||
: OrigUnit(OrigUnit), RangeAlloc(), Ranges(RangeAlloc) {
|
||||
Info.resize(OrigUnit.getNumDIEs());
|
||||
}
|
||||
|
||||
// Workaround MSVC not supporting implicit move ops
|
||||
CompileUnit(CompileUnit &&RHS)
|
||||
: OrigUnit(RHS.OrigUnit), Info(std::move(RHS.Info)),
|
||||
CUDie(std::move(RHS.CUDie)), StartOffset(RHS.StartOffset),
|
||||
NextUnitOffset(RHS.NextUnitOffset) {}
|
||||
NextUnitOffset(RHS.NextUnitOffset), RangeAlloc(), Ranges(RangeAlloc) {
|
||||
// The CompileUnit container has been 'reserve()'d with the right
|
||||
// size. We cannot move the IntervalMap anyway.
|
||||
llvm_unreachable("CompileUnits should not be moved.");
|
||||
}
|
||||
|
||||
DWARFUnit &getOrigUnit() const { return OrigUnit; }
|
||||
|
||||
|
@ -100,6 +110,10 @@ public:
|
|||
/// \brief Apply all fixups recored by noteForwardReference().
|
||||
void fixupForwardReferences();
|
||||
|
||||
/// \brief Add a function range [\p LowPC, \p HighPC) that is
|
||||
/// relocatad by applying offset \p PCOffset.
|
||||
void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset);
|
||||
|
||||
private:
|
||||
DWARFUnit &OrigUnit;
|
||||
std::vector<DIEInfo> Info; ///< DIE info indexed by DIE index.
|
||||
|
@ -115,6 +129,12 @@ private:
|
|||
/// cloning because for forward refences the target DIE's offset isn't
|
||||
/// known you emit the reference attribute.
|
||||
std::vector<std::pair<DIE *, DIEInteger *>> ForwardDIEReferences;
|
||||
|
||||
HalfOpenIntervalMap<uint64_t, int64_t>::Allocator RangeAlloc;
|
||||
/// \brief The ranges in that interval map are the PC ranges for
|
||||
/// functions in this unit, associated with the PC offset to apply
|
||||
/// to the addresses to get the linked address.
|
||||
HalfOpenIntervalMap<uint64_t, int64_t> Ranges;
|
||||
};
|
||||
|
||||
uint64_t CompileUnit::computeNextUnitOffset() {
|
||||
|
@ -138,6 +158,11 @@ void CompileUnit::fixupForwardReferences() {
|
|||
Ref.second->setValue(Ref.first->getOffset() + getStartOffset());
|
||||
}
|
||||
|
||||
void CompileUnit::addFunctionRange(uint64_t LowPC, uint64_t HighPC,
|
||||
int64_t PCOffset) {
|
||||
Ranges.insert(LowPC, HighPC, PCOffset);
|
||||
}
|
||||
|
||||
/// \brief A string table that doesn't need relocations.
|
||||
///
|
||||
/// We are doing a final link, no need for a string table that
|
||||
|
@ -944,7 +969,25 @@ unsigned DwarfLinker::shouldKeepSubprogramDIE(
|
|||
if (Options.Verbose)
|
||||
DIE.dump(outs(), const_cast<DWARFUnit *>(&OrigUnit), 0, 8 /* Indent */);
|
||||
|
||||
return Flags | TF_Keep;
|
||||
Flags |= TF_Keep;
|
||||
|
||||
DWARFFormValue HighPcValue;
|
||||
if (!DIE.getAttributeValue(&OrigUnit, dwarf::DW_AT_high_pc, HighPcValue)) {
|
||||
reportWarning("Function without high_pc. Range will be discarded.\n",
|
||||
&OrigUnit, &DIE);
|
||||
return Flags;
|
||||
}
|
||||
|
||||
uint64_t HighPc;
|
||||
if (HighPcValue.isFormClass(DWARFFormValue::FC_Address)) {
|
||||
HighPc = *HighPcValue.getAsAddress(&OrigUnit);
|
||||
} else {
|
||||
assert(HighPcValue.isFormClass(DWARFFormValue::FC_Constant));
|
||||
HighPc = LowPc + *HighPcValue.getAsUnsignedConstant();
|
||||
}
|
||||
|
||||
Unit.addFunctionRange(LowPc, HighPc, MyInfo.AddrAdjust);
|
||||
return Flags;
|
||||
}
|
||||
|
||||
/// \brief Check if a DIE should be kept.
|
||||
|
|
Loading…
Reference in New Issue