[llvm] 536f35e - [DWARFLinker][DWARFv5] Support debug_loclists.
Alexey Lapshin via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 15 03:51:21 PDT 2023
Author: Alexey Lapshin
Date: 2023-03-15T11:36:59+01:00
New Revision: 536f35ea62c62d9b28444b33d173d5f556945c90
URL: https://github.com/llvm/llvm-project/commit/536f35ea62c62d9b28444b33d173d5f556945c90
DIFF: https://github.com/llvm/llvm-project/commit/536f35ea62c62d9b28444b33d173d5f556945c90.diff
LOG: [DWARFLinker][DWARFv5] Support debug_loclists.
This patch adds support of DWARFv5 .debug_loclists table.
As DWARFLinker resolves relocations, it is able to always
use DW_FORM_addr instead of DW_FORM_addrx. DW_FORM_addrx
helps to minimize number of relocations, it is also used for
split DWARF. Both of these cases are not relevant for the
DWARFLinker. Thus, this patch converts all DW_FORM_addrx
forms into the DW_FORM_addr. And, as the result, it converts
location lists of DW_FORM_loclistx form into the DW_FORM_sec_offset.
For the --update case all DW_FORM_addrx, DW_FORM_loclistx
are preserved as is.
Depends On D145499
Differential Revision: https://reviews.llvm.org/D145680
Added:
llvm/test/tools/dsymutil/Inputs/dwarf5-loclists.o
llvm/test/tools/dsymutil/X86/dwarf5-loclists.test
llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-loclists.test
Modified:
llvm/include/llvm/DWARFLinker/DWARFLinker.h
llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
llvm/include/llvm/DWARFLinker/DWARFStreamer.h
llvm/lib/DWARFLinker/DWARFLinker.cpp
llvm/lib/DWARFLinker/DWARFStreamer.cpp
llvm/test/tools/dsymutil/X86/debug-loc-base-addr.test
Removed:
llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-loclists.test
################################################################################
diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/DWARFLinker.h
index ebfac89d4e670..f58bb3f6ec32b 100644
--- a/llvm/include/llvm/DWARFLinker/DWARFLinker.h
+++ b/llvm/include/llvm/DWARFLinker/DWARFLinker.h
@@ -117,19 +117,32 @@ class DwarfEmitter {
virtual void
emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) = 0;
- /// Emit debug ranges(.debug_ranges, .debug_rnglists) header.
+ /// Emit debug ranges (.debug_ranges, .debug_rnglists) header.
virtual MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) = 0;
- /// Emit debug ranges(.debug_ranges, .debug_rnglists) fragment.
+ /// Emit debug ranges (.debug_ranges, .debug_rnglists) fragment.
virtual void
emitDwarfDebugRangeListFragment(const CompileUnit &Unit,
const AddressRanges &LinkedRanges,
PatchLocation Patch) = 0;
- /// Emit debug ranges(.debug_ranges, .debug_rnglists) footer.
+ /// Emit debug ranges (.debug_ranges, .debug_rnglists) footer.
virtual void emitDwarfDebugRangeListFooter(const CompileUnit &Unit,
MCSymbol *EndLabel) = 0;
+ /// Emit debug locations (.debug_loc, .debug_loclists) header.
+ virtual MCSymbol *emitDwarfDebugLocListHeader(const CompileUnit &Unit) = 0;
+
+ /// Emit debug locations (.debug_loc, .debug_loclists) fragment.
+ virtual void emitDwarfDebugLocListFragment(
+ const CompileUnit &Unit,
+ const DWARFLocationExpressionsVector &LinkedLocationExpression,
+ PatchLocation Patch) = 0;
+
+ /// Emit debug locations (.debug_loc, .debug_loclists) footer.
+ virtual void emitDwarfDebugLocListFooter(const CompileUnit &Unit,
+ MCSymbol *EndLabel) = 0;
+
/// Emit .debug_aranges entries for \p Unit
virtual void
emitDwarfDebugArangesTable(const CompileUnit &Unit,
@@ -159,14 +172,6 @@ class DwarfEmitter {
virtual void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint64_t Address,
StringRef Bytes) = 0;
- /// Emit the .debug_loc contribution for \p Unit by copying the entries from
- /// \p Dwarf and offsetting them. Update the location attributes to point to
- /// the new entries.
- virtual void emitLocationsForUnit(
- const CompileUnit &Unit, DWARFContext &Dwarf,
- std::function<void(StringRef, SmallVectorImpl<uint8_t> &)>
- ProcessExpr) = 0;
-
/// Emit the compilation unit header for \p Unit in the
/// .debug_info section.
///
@@ -207,6 +212,9 @@ class DwarfEmitter {
/// Returns size of generated .debug_macro section.
virtual uint64_t getDebugMacroSectionSize() const = 0;
+
+ /// Returns size of generated .debug_loclists section.
+ virtual uint64_t getLocListsSectionSize() const = 0;
};
using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
@@ -738,6 +746,14 @@ class DWARFLinker {
/// .debug_rnglists) for \p Unit, patch the attributes referencing it.
void generateUnitRanges(CompileUnit &Unit, const DWARFFile &File) const;
+ using ExpressionHandlerRef = function_ref<void(SmallVectorImpl<uint8_t> &,
+ SmallVectorImpl<uint8_t> &)>;
+
+ /// Compute and emit debug locations (.debug_loc, .debug_loclists)
+ /// for \p Unit, patch the attributes referencing it.
+ void generateUnitLocations(CompileUnit &Unit, const DWARFFile &File,
+ ExpressionHandlerRef ExprHandler) const;
+
/// Extract the line tables from the original dwarf, extract the relevant
/// parts according to the linked function ranges and emit the result in the
/// .debug_line section.
diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h b/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
index 39305a3de8680..cfbd13414f703 100644
--- a/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
+++ b/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
@@ -44,6 +44,7 @@ struct PatchLocation {
};
using RngListAttributesTy = SmallVector<PatchLocation>;
+using LocListAttributesTy = SmallVector<std::pair<PatchLocation, int64_t>>;
/// Stores all information relating to a compile unit, be it in its original
/// instance in the object file to its brand new cloned and generated DIE tree.
@@ -153,8 +154,7 @@ class CompileUnit {
return UnitRangeAttribute;
}
- const std::vector<std::pair<PatchLocation, int64_t>> &
- getLocationAttributes() const {
+ const LocListAttributesTy &getLocationAttributes() const {
return LocationAttributes;
}
@@ -289,7 +289,7 @@ class CompileUnit {
/// original debug_loc section to the liked one. They are stored
/// along with the PC offset that is to be applied to their
/// function's address.
- std::vector<std::pair<PatchLocation, int64_t>> LocationAttributes;
+ LocListAttributesTy LocationAttributes;
/// Accelerator entries for the unit, both for the pub*
/// sections and the apple* ones.
diff --git a/llvm/include/llvm/DWARFLinker/DWARFStreamer.h b/llvm/include/llvm/DWARFLinker/DWARFStreamer.h
index 69d1f9348449a..c96dd4007c23f 100644
--- a/llvm/include/llvm/DWARFLinker/DWARFStreamer.h
+++ b/llvm/include/llvm/DWARFLinker/DWARFStreamer.h
@@ -105,6 +105,19 @@ class DwarfStreamer : public DwarfEmitter {
void emitDwarfDebugRangeListFooter(const CompileUnit &Unit,
MCSymbol *EndLabel) override;
+ /// Emit debug locations(.debug_loc, .debug_loclists) header.
+ MCSymbol *emitDwarfDebugLocListHeader(const CompileUnit &Unit) override;
+
+ /// Emit debug ranges(.debug_loc, .debug_loclists) fragment.
+ void emitDwarfDebugLocListFragment(
+ const CompileUnit &Unit,
+ const DWARFLocationExpressionsVector &LinkedLocationExpression,
+ PatchLocation Patch) override;
+
+ /// Emit debug ranges(.debug_loc, .debug_loclists) footer.
+ void emitDwarfDebugLocListFooter(const CompileUnit &Unit,
+ MCSymbol *EndLabel) override;
+
/// Emit .debug_aranges entries for \p Unit
void emitDwarfDebugArangesTable(const CompileUnit &Unit,
const AddressRanges &LinkedRanges) override;
@@ -115,14 +128,6 @@ class DwarfStreamer : public DwarfEmitter {
return RngListsSectionSize;
}
- /// Emit the debug_loc contribution for \p Unit by copying the entries from
- /// \p Dwarf and offsetting them. Update the location attributes to point to
- /// the new entries.
- void emitLocationsForUnit(
- const CompileUnit &Unit, DWARFContext &Dwarf,
- std::function<void(StringRef, SmallVectorImpl<uint8_t> &)> ProcessExpr)
- override;
-
/// Emit the line table described in \p Rows into the debug_line section.
void emitLineTableForUnit(MCDwarfLineTableParams Params,
StringRef PrologueBytes, unsigned MinInstLength,
@@ -181,6 +186,10 @@ class DwarfStreamer : public DwarfEmitter {
return MacroSectionSize;
}
+ uint64_t getLocListsSectionSize() const override {
+ return LocListsSectionSize;
+ }
+
void emitMacroTables(DWARFContext *Context,
const Offset2UnitMap &UnitMacroMap,
OffsetsStringPool &StringPool) override;
@@ -210,6 +219,18 @@ class DwarfStreamer : public DwarfEmitter {
const AddressRanges &LinkedRanges,
PatchLocation Patch);
+ /// Emit piece of .debug_loc for \p LinkedRanges.
+ void emitDwarfDebugLocTableFragment(
+ const CompileUnit &Unit,
+ const DWARFLocationExpressionsVector &LinkedLocationExpression,
+ PatchLocation Patch);
+
+ /// Emit piece of .debug_loclists for \p LinkedRanges.
+ void emitDwarfDebugLocListsTableFragment(
+ const CompileUnit &Unit,
+ const DWARFLocationExpressionsVector &LinkedLocationExpression,
+ PatchLocation Patch);
+
/// \defgroup MCObjects MC layer objects constructed by the streamer
/// @{
std::unique_ptr<MCRegisterInfo> MRI;
@@ -234,6 +255,7 @@ class DwarfStreamer : public DwarfEmitter {
uint64_t RangesSectionSize = 0;
uint64_t RngListsSectionSize = 0;
uint64_t LocSectionSize = 0;
+ uint64_t LocListsSectionSize = 0;
uint64_t LineSectionSize = 0;
uint64_t FrameSectionSize = 0;
uint64_t DebugInfoSectionSize = 0;
diff --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp
index ae9fb16907356..980b7f9da86b5 100644
--- a/llvm/lib/DWARFLinker/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp
@@ -1261,8 +1261,13 @@ unsigned DWARFLinker::DIECloner::cloneScalarAttribute(
}
if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
Info.IsDeclaration = true;
- Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
- dwarf::Form(AttrSpec.Form), DIEInteger(Value));
+
+ if (AttrSpec.Form == dwarf::DW_FORM_loclistx)
+ Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
+ dwarf::Form(AttrSpec.Form), DIELocList(Value));
+ else
+ Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
+ dwarf::Form(AttrSpec.Form), DIEInteger(Value));
return AttrSize;
}
@@ -1285,6 +1290,27 @@ unsigned DWARFLinker::DIECloner::cloneScalarAttribute(
return 0;
}
+ Value = *Offset;
+ AttrSpec.Form = dwarf::DW_FORM_sec_offset;
+ AttrSize = Unit.getOrigUnit().getFormParams().getDwarfOffsetByteSize();
+ } else if (AttrSpec.Form == dwarf::DW_FORM_loclistx) {
+ // DWARFLinker does not generate .debug_addr table. Thus we need to change
+ // all "addrx" related forms to "addr" version. Change DW_FORM_loclistx
+ // to DW_FORM_sec_offset here.
+ std::optional<uint64_t> Index = Val.getAsSectionOffset();
+ if (!Index) {
+ Linker.reportWarning("Cannot read the attribute. Dropping.", File,
+ &InputDIE);
+ return 0;
+ }
+ std::optional<uint64_t> Offset =
+ Unit.getOrigUnit().getLoclistOffset(*Index);
+ if (!Offset) {
+ Linker.reportWarning("Cannot read the attribute. Dropping.", File,
+ &InputDIE);
+ return 0;
+ }
+
Value = *Offset;
AttrSpec.Form = dwarf::DW_FORM_sec_offset;
AttrSize = Unit.getOrigUnit().getFormParams().getDwarfOffsetByteSize();
@@ -1307,6 +1333,7 @@ unsigned DWARFLinker::DIECloner::cloneScalarAttribute(
&InputDIE);
return 0;
}
+
PatchLocation Patch =
Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
dwarf::Form(AttrSpec.Form), DIEInteger(Value));
@@ -1314,13 +1341,10 @@ unsigned DWARFLinker::DIECloner::cloneScalarAttribute(
AttrSpec.Attr == dwarf::DW_AT_start_scope) {
Unit.noteRangeAttribute(Die, Patch);
Info.HasRanges = true;
- }
- // A more generic way to check for location attributes would be
- // nice, but it's very unlikely that any other attribute needs a
- // location list.
- // FIXME: use DWARFAttribute::mayHaveLocationDescription().
- else if (AttrSpec.Attr == dwarf::DW_AT_location ||
- AttrSpec.Attr == dwarf::DW_AT_frame_base) {
+ } else if (DWARFAttribute::mayHaveLocationList(AttrSpec.Attr) &&
+ dwarf::doesFormBelongToClass(AttrSpec.Form,
+ DWARFFormValue::FC_SectionOffset,
+ Unit.getOrigUnit().getVersion())) {
Unit.noteLocationAttribute(Patch, Info.PCOffset);
} else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
Info.IsDeclaration = true;
@@ -1383,6 +1407,7 @@ unsigned DWARFLinker::DIECloner::cloneAttribute(
case dwarf::DW_FORM_flag:
case dwarf::DW_FORM_flag_present:
case dwarf::DW_FORM_rnglistx:
+ case dwarf::DW_FORM_loclistx:
return cloneScalarAttribute(Die, InputDIE, File, Unit, AttrSpec, Val,
AttrSize, Info);
default:
@@ -1464,6 +1489,12 @@ static bool shouldSkipAttribute(
case dwarf::DW_AT_str_offsets_base:
// FIXME: Use the string offset table with Dwarf 5.
return true;
+ case dwarf::DW_AT_loclists_base:
+ // In case !Update the .debug_addr table is not generated/preserved.
+ // Thus instead of DW_FORM_loclistx the DW_FORM_sec_offset is used.
+ // Since DW_AT_loclists_base is used for only DW_FORM_loclistx the
+ // DW_AT_loclists_base is removed.
+ return !Update;
case dwarf::DW_AT_location:
case dwarf::DW_AT_frame_base:
// FIXME: for some reason dsymutil-classic keeps the location attributes
@@ -1732,6 +1763,61 @@ void DWARFLinker::generateUnitRanges(CompileUnit &Unit,
}
}
+void DWARFLinker::generateUnitLocations(
+ CompileUnit &Unit, const DWARFFile &File,
+ ExpressionHandlerRef ExprHandler) const {
+ if (LLVM_UNLIKELY(Options.Update))
+ return;
+
+ const LocListAttributesTy &AllLocListAttributes =
+ Unit.getLocationAttributes();
+
+ if (AllLocListAttributes.empty())
+ return;
+
+ // Emit locations list table header.
+ MCSymbol *EndLabel = TheDwarfEmitter->emitDwarfDebugLocListHeader(Unit);
+
+ for (auto &CurLocAttr : AllLocListAttributes) {
+ // Get location expressions vector corresponding to the current attribute
+ // from the source DWARF.
+ Expected<DWARFLocationExpressionsVector> OriginalLocations =
+ Unit.getOrigUnit().findLoclistFromOffset((CurLocAttr.first).get());
+
+ if (!OriginalLocations) {
+ llvm::consumeError(OriginalLocations.takeError());
+ reportWarning("Invalid location attribute ignored.", File);
+ continue;
+ }
+
+ DWARFLocationExpressionsVector LinkedLocationExpressions;
+ for (DWARFLocationExpression &CurExpression : *OriginalLocations) {
+
+ DWARFLocationExpression LinkedExpression;
+
+ if (CurExpression.Range) {
+ // Relocate address range.
+ LinkedExpression.Range = {
+ CurExpression.Range->LowPC + CurLocAttr.second,
+ CurExpression.Range->HighPC + CurLocAttr.second};
+ }
+
+ // Clone expression.
+ LinkedExpression.Expr.reserve(CurExpression.Expr.size());
+ ExprHandler(CurExpression.Expr, LinkedExpression.Expr);
+
+ LinkedLocationExpressions.push_back(LinkedExpression);
+ }
+
+ // Emit locations list table fragment corresponding to the CurLocAttr.
+ TheDwarfEmitter->emitDwarfDebugLocListFragment(
+ Unit, LinkedLocationExpressions, CurLocAttr.first);
+ }
+
+ // Emit locations list table footer.
+ TheDwarfEmitter->emitDwarfDebugLocListFooter(Unit, EndLabel);
+}
+
/// Insert the new line info sequence \p Seq into the current
/// set of already linked line info \p Rows.
static void insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
@@ -2314,17 +2400,17 @@ uint64_t DWARFLinker::DIECloner::cloneAllCompileUnits(
Linker.generateUnitRanges(*CurrentUnit, File);
- auto ProcessExpr = [&](StringRef Bytes,
- SmallVectorImpl<uint8_t> &Buffer) {
+ auto ProcessExpr = [&](SmallVectorImpl<uint8_t> &SrcBytes,
+ SmallVectorImpl<uint8_t> &OutBytes) {
DWARFUnit &OrigUnit = CurrentUnit->getOrigUnit();
- DataExtractor Data(Bytes, IsLittleEndian,
+ DataExtractor Data(SrcBytes, IsLittleEndian,
OrigUnit.getAddressByteSize());
cloneExpression(Data,
DWARFExpression(Data, OrigUnit.getAddressByteSize(),
OrigUnit.getFormParams().Format),
- File, *CurrentUnit, Buffer);
+ File, *CurrentUnit, OutBytes);
};
- Emitter->emitLocationsForUnit(*CurrentUnit, DwarfContext, ProcessExpr);
+ Linker.generateUnitLocations(*CurrentUnit, File, ProcessExpr);
}
}
@@ -2433,6 +2519,8 @@ void DWARFLinker::copyInvariantDebugSection(DWARFContext &Dwarf) {
Dwarf.getDWARFObj().getAddrSection().Data, "debug_addr");
TheDwarfEmitter->emitSectionContents(
Dwarf.getDWARFObj().getRnglistsSection().Data, "debug_rnglists");
+ TheDwarfEmitter->emitSectionContents(
+ Dwarf.getDWARFObj().getLoclistsSection().Data, "debug_loclists");
}
void DWARFLinker::addObjectFile(DWARFFile &File, objFileLoader Loader,
@@ -2518,20 +2606,6 @@ Error DWARFLinker::link() {
continue;
}
- // Check for unsupported sections. Following sections can be referenced
- // from .debug_info section. Current DWARFLinker implementation does not
- // support or update references to these tables. Thus we report warning
- // and skip corresponding object file.
- if (!OptContext.File.Dwarf->getDWARFObj()
- .getLoclistsSection()
- .Data.empty()) {
- reportWarning("'.debug_loclists' is not currently supported: file "
- "will be skipped",
- OptContext.File);
- OptContext.Skip = true;
- continue;
- }
-
// In a first phase, just read in the debug info and load all clang modules.
OptContext.CompileUnits.reserve(
OptContext.File.Dwarf->getNumCompileUnits());
diff --git a/llvm/lib/DWARFLinker/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/DWARFStreamer.cpp
index 3af7cde52509d..1593ea65065d5 100644
--- a/llvm/lib/DWARFLinker/DWARFStreamer.cpp
+++ b/llvm/lib/DWARFLinker/DWARFStreamer.cpp
@@ -110,6 +110,7 @@ bool DwarfStreamer::init(Triple TheTriple,
RangesSectionSize = 0;
RngListsSectionSize = 0;
LocSectionSize = 0;
+ LocListsSectionSize = 0;
LineSectionSize = 0;
FrameSectionSize = 0;
DebugInfoSectionSize = 0;
@@ -206,6 +207,8 @@ void DwarfStreamer::emitSectionContents(StringRef SecData, StringRef SecName) {
.Case("debug_addr", MC->getObjectFileInfo()->getDwarfAddrSection())
.Case("debug_rnglists",
MC->getObjectFileInfo()->getDwarfRnglistsSection())
+ .Case("debug_loclists",
+ MC->getObjectFileInfo()->getDwarfLoclistsSection())
.Default(nullptr);
if (Section) {
@@ -483,73 +486,149 @@ void DwarfStreamer::emitDwarfDebugRngListsTableFragment(
RngListsSectionSize += 1;
}
-/// Emit location lists for \p Unit and update attributes to point to the new
-/// entries.
-void DwarfStreamer::emitLocationsForUnit(
- const CompileUnit &Unit, DWARFContext &Dwarf,
- std::function<void(StringRef, SmallVectorImpl<uint8_t> &)> ProcessExpr) {
- const auto &Attributes = Unit.getLocationAttributes();
+/// Emit debug locations(.debug_loc, .debug_loclists) header.
+MCSymbol *DwarfStreamer::emitDwarfDebugLocListHeader(const CompileUnit &Unit) {
+ if (Unit.getOrigUnit().getVersion() < 5)
+ return nullptr;
+
+ // Make .debug_loclists the current section.
+ MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
+
+ MCSymbol *BeginLabel = Asm->createTempSymbol("Bloclists");
+ MCSymbol *EndLabel = Asm->createTempSymbol("Eloclists");
+ unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
+
+ // Length
+ Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t));
+ Asm->OutStreamer->emitLabel(BeginLabel);
+ LocListsSectionSize += sizeof(uint32_t);
+
+ // Version.
+ MS->emitInt16(5);
+ LocListsSectionSize += sizeof(uint16_t);
+
+ // Address size.
+ MS->emitInt8(AddressSize);
+ LocListsSectionSize++;
+
+ // Seg_size
+ MS->emitInt8(0);
+ LocListsSectionSize++;
- if (Attributes.empty())
+ // Offset entry count
+ MS->emitInt32(0);
+ LocListsSectionSize += sizeof(uint32_t);
+
+ return EndLabel;
+}
+
+/// Emit debug locations(.debug_loc, .debug_loclists) fragment.
+void DwarfStreamer::emitDwarfDebugLocListFragment(
+ const CompileUnit &Unit,
+ const DWARFLocationExpressionsVector &LinkedLocationExpression,
+ PatchLocation Patch) {
+ if (Unit.getOrigUnit().getVersion() < 5) {
+ emitDwarfDebugLocTableFragment(Unit, LinkedLocationExpression, Patch);
return;
+ }
- MS->switchSection(MC->getObjectFileInfo()->getDwarfLocSection());
+ emitDwarfDebugLocListsTableFragment(Unit, LinkedLocationExpression, Patch);
+}
+
+/// Emit debug locations(.debug_loc, .debug_loclists) footer.
+void DwarfStreamer::emitDwarfDebugLocListFooter(const CompileUnit &Unit,
+ MCSymbol *EndLabel) {
+ if (Unit.getOrigUnit().getVersion() < 5)
+ return;
+
+ // Make .debug_loclists the current section.
+ MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
+
+ if (EndLabel != nullptr)
+ Asm->OutStreamer->emitLabel(EndLabel);
+}
+/// Emit piece of .debug_loc for \p LinkedLocationExpression.
+void DwarfStreamer::emitDwarfDebugLocTableFragment(
+ const CompileUnit &Unit,
+ const DWARFLocationExpressionsVector &LinkedLocationExpression,
+ PatchLocation Patch) {
+ Patch.set(LocSectionSize);
+
+ // Make .debug_loc to be current section.
+ MS->switchSection(MC->getObjectFileInfo()->getDwarfLocSection());
unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
- uint64_t BaseAddressMarker = (AddressSize == 8)
- ? std::numeric_limits<uint64_t>::max()
- : std::numeric_limits<uint32_t>::max();
- const DWARFSection &InputSec = Dwarf.getDWARFObj().getLocSection();
- DataExtractor Data(InputSec.Data, Dwarf.isLittleEndian(), AddressSize);
- DWARFUnit &OrigUnit = Unit.getOrigUnit();
- auto OrigUnitDie = OrigUnit.getUnitDIE(false);
- int64_t UnitPcOffset = 0;
- if (auto OrigLowPc =
- dwarf::toAddress(OrigUnitDie.find(dwarf::DW_AT_low_pc))) {
- assert(Unit.getLowPc());
- UnitPcOffset = int64_t(*OrigLowPc) - *Unit.getLowPc();
+
+ // Emit ranges.
+ uint64_t BaseAddress = 0;
+ if (std::optional<uint64_t> LowPC = Unit.getLowPc())
+ BaseAddress = *LowPC;
+
+ for (const DWARFLocationExpression &LocExpression :
+ LinkedLocationExpression) {
+ if (LocExpression.Range) {
+ MS->emitIntValue(LocExpression.Range->LowPC - BaseAddress, AddressSize);
+ MS->emitIntValue(LocExpression.Range->HighPC - BaseAddress, AddressSize);
+
+ LocSectionSize += AddressSize;
+ LocSectionSize += AddressSize;
+ }
+
+ Asm->OutStreamer->emitIntValue(LocExpression.Expr.size(), 2);
+ Asm->OutStreamer->emitBytes(StringRef(
+ (const char *)LocExpression.Expr.data(), LocExpression.Expr.size()));
+ LocSectionSize += LocExpression.Expr.size() + 2;
}
- SmallVector<uint8_t, 32> Buffer;
- for (const auto &Attr : Attributes) {
- uint64_t Offset = Attr.first.get();
- Attr.first.set(LocSectionSize);
- // This is the quantity to add to the old location address to get
- // the correct address for the new one.
- int64_t LocPcOffset = Attr.second + UnitPcOffset;
- while (Data.isValidOffset(Offset)) {
- uint64_t Low = Data.getUnsigned(&Offset, AddressSize);
- uint64_t High = Data.getUnsigned(&Offset, AddressSize);
- LocSectionSize += 2 * AddressSize;
- // End of list entry.
- if (Low == 0 && High == 0) {
- Asm->OutStreamer->emitIntValue(0, AddressSize);
- Asm->OutStreamer->emitIntValue(0, AddressSize);
- break;
- }
- // Base address selection entry.
- if (Low == BaseAddressMarker) {
- Asm->OutStreamer->emitIntValue(BaseAddressMarker, AddressSize);
- Asm->OutStreamer->emitIntValue(High + Attr.second, AddressSize);
- LocPcOffset = 0;
- continue;
- }
- // Location list entry.
- Asm->OutStreamer->emitIntValue(Low + LocPcOffset, AddressSize);
- Asm->OutStreamer->emitIntValue(High + LocPcOffset, AddressSize);
- uint64_t Length = Data.getU16(&Offset);
- Asm->OutStreamer->emitIntValue(Length, 2);
- // Copy the bytes into to the buffer, process them, emit them.
- Buffer.reserve(Length);
- Buffer.resize(0);
- StringRef Input = InputSec.Data.substr(Offset, Length);
- ProcessExpr(Input, Buffer);
- Asm->OutStreamer->emitBytes(
- StringRef((const char *)Buffer.data(), Length));
- Offset += Length;
- LocSectionSize += Length + 2;
+ // Add the terminator entry.
+ MS->emitIntValue(0, AddressSize);
+ MS->emitIntValue(0, AddressSize);
+
+ LocSectionSize += AddressSize;
+ LocSectionSize += AddressSize;
+}
+
+/// Emit piece of .debug_loclists for \p LinkedLocationExpression.
+void DwarfStreamer::emitDwarfDebugLocListsTableFragment(
+ const CompileUnit &Unit,
+ const DWARFLocationExpressionsVector &LinkedLocationExpression,
+ PatchLocation Patch) {
+ Patch.set(LocListsSectionSize);
+
+ // Make .debug_loclists the current section.
+ MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
+
+ unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
+
+ for (const DWARFLocationExpression &LocExpression :
+ LinkedLocationExpression) {
+ if (LocExpression.Range) {
+ // Emit type of entry.
+ MS->emitInt8(dwarf::DW_LLE_start_length);
+ LocListsSectionSize += 1;
+
+ // Emit start address.
+ MS->emitIntValue(LocExpression.Range->LowPC, AddressSize);
+ LocListsSectionSize += AddressSize;
+
+ // Emit length of the range.
+ LocListsSectionSize += MS->emitSLEB128IntValue(
+ LocExpression.Range->HighPC - LocExpression.Range->LowPC);
+ } else {
+ // Emit type of entry.
+ MS->emitInt8(dwarf::DW_LLE_default_location);
+ LocListsSectionSize += 1;
}
+
+ LocListsSectionSize += MS->emitULEB128IntValue(LocExpression.Expr.size());
+ Asm->OutStreamer->emitBytes(StringRef(
+ (const char *)LocExpression.Expr.data(), LocExpression.Expr.size()));
+ LocListsSectionSize += LocExpression.Expr.size();
}
+
+ // Emit the terminator entry.
+ MS->emitInt8(dwarf::DW_LLE_end_of_list);
+ LocListsSectionSize += 1;
}
void DwarfStreamer::emitLineTableForUnit(MCDwarfLineTableParams Params,
diff --git a/llvm/test/tools/dsymutil/Inputs/dwarf5-loclists.o b/llvm/test/tools/dsymutil/Inputs/dwarf5-loclists.o
new file mode 100644
index 0000000000000..694346426c8c4
Binary files /dev/null and b/llvm/test/tools/dsymutil/Inputs/dwarf5-loclists.o
diff er
diff --git a/llvm/test/tools/dsymutil/X86/debug-loc-base-addr.test b/llvm/test/tools/dsymutil/X86/debug-loc-base-addr.test
index 07244c288a13b..a36e9139bcf0b 100644
--- a/llvm/test/tools/dsymutil/X86/debug-loc-base-addr.test
+++ b/llvm/test/tools/dsymutil/X86/debug-loc-base-addr.test
@@ -1,4 +1,4 @@
-RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/baseaddr/loc1.x86_64 -f -o - | llvm-dwarfdump -debug-loc - | FileCheck %s
+RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/baseaddr/loc1.x86_64 -f -o - | llvm-dwarfdump --debug-info - | FileCheck %s
The test was compiled from a single source:
$ cat loc1.cpp
@@ -17,10 +17,14 @@ int main() {
return 0;
}
-CHECK: .debug_loc contents:
-CHECK: [0x0000000100000f94, 0x0000000100000f97): DW_OP_consts +3, DW_OP_stack_value
-CHECK: [0x0000000100000f97, 0x0000000100000f99): DW_OP_consts +4, DW_OP_stack_value
-
-CHECK: [0x0000000100000f94, 0x0000000100000f97): DW_OP_consts +5, DW_OP_stack_value
-
-CHECK: [0x0000000100000f97, 0x0000000100000f99): DW_OP_reg0 RAX
+CHECK: DW_TAG_compile_unit
+CHECK: DW_TAG_variable
+CHECK: DW_AT_location
+CHECK: [0x0000000100000f94, 0x0000000100000f97): DW_OP_consts +3, DW_OP_stack_value
+CHECK: [0x0000000100000f97, 0x0000000100000f99): DW_OP_consts +4, DW_OP_stack_value
+CHECK: DW_TAG_variable
+CHECK: DW_AT_location
+CHECK: [0x0000000100000f94, 0x0000000100000f97): DW_OP_consts +5, DW_OP_stack_value
+CHECK: DW_TAG_variable
+CHECK: DW_AT_location
+CHECK: [0x0000000100000f97, 0x0000000100000f99): DW_OP_reg0 RAX
diff --git a/llvm/test/tools/dsymutil/X86/dwarf5-loclists.test b/llvm/test/tools/dsymutil/X86/dwarf5-loclists.test
new file mode 100644
index 0000000000000..d393cda76af52
--- /dev/null
+++ b/llvm/test/tools/dsymutil/X86/dwarf5-loclists.test
@@ -0,0 +1,107 @@
+## This test checks that .debug_loclists table is correclty handled
+## and transformed into the DW_FORM_sec_offset form in case
+## --no-update. Or correctly preserved in --update case.
+
+## cat dwarf5-loclists.c
+## #include <stdio.h>
+##
+## int main ( int argv, char** argc ) {
+## printf ("\n argv %d", argv );
+## argv++;
+## printf ("\n argv %d", argv );
+## argv++;
+## printf ("\n argv %d", &argv );
+## return 0;
+## }
+
+## $ clang -gdwarf-5 dwarf5-loclists.c -c -O2 -o dwarf5-rnglists.o
+
+#RUN: dsymutil -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM
+#RUN: llvm-dwarfdump --verify %t.dSYM | FileCheck %s
+#RUN: llvm-dwarfdump -a --verbose %t.dSYM | FileCheck %s --check-prefix DWARF-CHECK
+
+#RUN: dsymutil --update -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM
+#RUN: llvm-dwarfdump --verify %t.dSYM | FileCheck %s
+#RUN: llvm-dwarfdump -a --verbose %t.dSYM | FileCheck %s --check-prefix UPD-DWARF-CHECK
+
+#CHECK: No errors.
+
+#DWARF-CHECK: DW_TAG_formal_parameter
+#DWARF-CHECK: DW_AT_name {{.*}} "dwarf5-loclists.c"
+#DWARF-CHECK-NOT: DW_AT_loclists_base
+#DWARF-CHECK: DW_TAG_formal_parameter
+#DWARF-CHECK: DW_AT_location [DW_FORM_sec_offset] (0x0000000c:
+#DWARF-CHECK: [0x0000000100000f70, 0x0000000100000f87): DW_OP_reg5 RDI
+#DWARF-CHECK: [0x0000000100000f87, 0x0000000100000f93): DW_OP_reg3 RBX
+#DWARF-CHECK: [0x0000000100000f93, 0x0000000100000f9d): DW_OP_reg4 RSI
+#DWARF-CHECK: [0x0000000100000fa0, 0x0000000100000fa3): DW_OP_reg3 RBX
+#DWARF-CHECK: [0x0000000100000fa3, 0x0000000100000fbc): DW_OP_breg6 RBP-20)
+#DWARF-CHECK: DW_AT_name {{.*}} "argv"
+#DWARF-CHECK: DW_TAG_formal_parameter
+#DWARF-CHECK: DW_AT_location [DW_FORM_sec_offset] (0x0000004a:
+#DWARF-CHECK: [0x0000000100000f70, 0x0000000100000f89): DW_OP_reg4 RSI
+#DWARF-CHECK: [0x0000000100000f89, 0x0000000100000fbc): DW_OP_entry_value(DW_OP_reg4 RSI), DW_OP_stack_value)
+#DWARF-CHECK: DW_AT_name {{.*}} "argc"
+#DWARF-CHECK: .debug_loclists contents:
+#DWARF-CHECK: 0x00000000: locations list header: length = 0x00000062, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
+#DWARF-CHECK: 0x0000000c:
+#DWARF-CHECK: DW_LLE_start_length (0x0000000100000f70, 0x0000000000000017)
+#DWARF-CHECK: => [0x0000000100000f70, 0x0000000100000f87): DW_OP_reg5 RDI
+#DWARF-CHECK: DW_LLE_start_length (0x0000000100000f87, 0x000000000000000c)
+#DWARF-CHECK: => [0x0000000100000f87, 0x0000000100000f93): DW_OP_reg3 RBX
+#DWARF-CHECK: DW_LLE_start_length (0x0000000100000f93, 0x000000000000000a)
+#DWARF-CHECK: => [0x0000000100000f93, 0x0000000100000f9d): DW_OP_reg4 RSI
+#DWARF-CHECK: DW_LLE_start_length (0x0000000100000fa0, 0x0000000000000003)
+#DWARF-CHECK: => [0x0000000100000fa0, 0x0000000100000fa3): DW_OP_reg3 RBX
+#DWARF-CHECK: DW_LLE_start_length (0x0000000100000fa3, 0x0000000000000019)
+#DWARF-CHECK: => [0x0000000100000fa3, 0x0000000100000fbc): DW_OP_breg6 RBP-20
+#DWARF-CHECK: DW_LLE_end_of_list ()
+#DWARF-CHECK: 0x0000004a:
+#DWARF-CHECK: DW_LLE_start_length (0x0000000100000f70, 0x0000000000000019)
+#DWARF-CHECK: => [0x0000000100000f70, 0x0000000100000f89): DW_OP_reg4 RSI
+#DWARF-CHECK: DW_LLE_start_length (0x0000000100000f89, 0x0000000000000033)
+#DWARF-CHECK: => [0x0000000100000f89, 0x0000000100000fbc): DW_OP_entry_value(DW_OP_reg4 RSI), DW_OP_stack_value
+#DWARF-CHECK: DW_LLE_end_of_list ()
+
+#UPD-DWARF-CHECK: DW_TAG_compile_unit
+#UPD-DWARF-CHECK: DW_AT_name {{.*}} "dwarf5-loclists.c"
+#UPD-DWARF-CHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x0000000c)
+#UPD-DWARF-CHECK: DW_TAG_formal_parameter [8] (0x00000058)
+#UPD-DWARF-CHECK: DW_AT_location [DW_FORM_loclistx] (indexed (0x0) loclist = 0x00000014:
+#UPD-DWARF-CHECK: [0x0000000000000000, 0x0000000000000017): DW_OP_reg5 RDI
+#UPD-DWARF-CHECK: [0x0000000000000017, 0x0000000000000023): DW_OP_reg3 RBX
+#UPD-DWARF-CHECK: [0x0000000000000023, 0x000000000000002d): DW_OP_reg4 RSI
+#UPD-DWARF-CHECK: [0x0000000000000030, 0x0000000000000033): DW_OP_reg3 RBX
+#UPD-DWARF-CHECK: [0x0000000000000033, 0x000000000000004c): DW_OP_breg6 RBP-20)
+#UPD-DWARF-CHECK: DW_AT_name {{.*}} "argv"
+#UPD-DWARF-CHECK: DW_TAG_formal_parameter [8] (0x00000058)
+#UPD-DWARF-CHECK: DW_AT_location [DW_FORM_loclistx] (indexed (0x1) loclist = 0x0000002f:
+#UPD-DWARF-CHECK: [0x0000000000000000, 0x0000000000000019): DW_OP_reg4 RSI
+#UPD-DWARF-CHECK: [0x0000000000000019, 0x000000000000004c): DW_OP_entry_value(DW_OP_reg4 RSI), DW_OP_stack_value)
+#UPD-DWARF-CHECK: DW_AT_name {{.*}} "argc"
+#UPD-DWARF-CHECK: .debug_loclists contents:
+#UPD-DWARF-CHECK: 0x00000000: locations list header: length = 0x00000039, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000002
+#UPD-DWARF-CHECK: offsets: [
+#UPD-DWARF-CHECK: 0x00000008 => 0x00000014
+#UPD-DWARF-CHECK: 0x00000023 => 0x0000002f
+#UPD-DWARF-CHECK: ]
+#UPD-DWARF-CHECK: 0x00000014:
+#UPD-DWARF-CHECK: DW_LLE_offset_pair (0x0000000000000000, 0x0000000000000017): DW_OP_reg5 RDI
+#UPD-DWARF-CHECK: DW_LLE_offset_pair (0x0000000000000017, 0x0000000000000023): DW_OP_reg3 RBX
+#UPD-DWARF-CHECK: DW_LLE_offset_pair (0x0000000000000023, 0x000000000000002d): DW_OP_reg4 RSI
+#UPD-DWARF-CHECK: DW_LLE_offset_pair (0x0000000000000030, 0x0000000000000033): DW_OP_reg3 RBX
+#UPD-DWARF-CHECK: DW_LLE_offset_pair (0x0000000000000033, 0x000000000000004c): DW_OP_breg6 RBP-20
+#UPD-DWARF-CHECK: DW_LLE_end_of_list ()
+#UPD-DWARF-CHECK: 0x0000002f:
+#UPD-DWARF-CHECK: DW_LLE_offset_pair (0x0000000000000000, 0x0000000000000019): DW_OP_reg4 RSI
+#UPD-DWARF-CHECK: DW_LLE_offset_pair (0x0000000000000019, 0x000000000000004c): DW_OP_entry_value(DW_OP_reg4 RSI), DW_OP_stack_value
+#UPD-DWARF-CHECK: DW_LLE_end_of_list ()
+
+---
+triple: 'x86_64-apple-darwin'
+objects:
+ - filename: 'dwarf5-loclists.o'
+ timestamp: 1676048242
+ symbols:
+ - { sym: _main, objAddr: 0x0, binAddr: 0x100000F70, size: 0x48 }
+ - { sym: _g1, binAddr: 0x100001000, size: 0x0 }
diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-loclists.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-loclists.test
new file mode 100644
index 0000000000000..89b01c565aa0a
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-loclists.test
@@ -0,0 +1,201 @@
+## Test that DWARFv5 .debug_loclists is correctly recognized
+## and converted into the DW_FORM_sec_offset form in --garbage-collection
+## case or correctly preserved in --no-garbage-collection case.
+
+# RUN: yaml2obj %s -o %t.o
+
+# RUN: llvm-dwarfutil %t.o %t1
+# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
+# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix DWARF-CHECK
+
+# RUN: llvm-dwarfutil --no-garbage-collection %t.o %t1
+# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
+# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK
+
+# RUN: llvm-dwarfutil --no-garbage-collection --build-accelerator=DWARF %t.o %t1
+# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
+# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK
+
+#CHECK: No errors.
+
+#DWARF-CHECK: DW_TAG_compile_unit
+#DWARF-CHECK: DW_AT_name {{.*}}"CU1"
+#DWARF-CHECK-NOT: DW_AT_loclists_base
+#DWARF-CHECK: DW_TAG_variable
+#DWARF-CHECK: DW_AT_name {{.*}}"var1"
+#DWARF-CHECK: DW_AT_location [DW_FORM_sec_offset] (0x0000000c:
+#DWARF-CHECK: [0x0000000000001130, 0x0000000000001140): DW_OP_reg5 RDI)
+#DWARF-CHECK: DW_AT_name {{.*}}"var2"
+#DWARF-CHECK: DW_AT_location [DW_FORM_sec_offset] (0x00000019:
+#DWARF-CHECK: <default>: DW_OP_reg5 RDI)
+#DWARF-CHECK: DW_TAG_variable
+#DWARF-CHECK: DW_AT_name {{.*}}"var3"
+#DWARF-CHECK: DW_AT_location [DW_FORM_sec_offset] (0x0000001d:
+#DWARF-CHECK: [0x0000000000001140, 0x0000000000001150): DW_OP_reg5 RDI
+#DWARF-CHECK: [0x0000000000001160, 0x0000000000001170): DW_OP_reg6 RBP)
+
+#UPD-DWARF-CHECK: DW_TAG_compile_unit
+#UPD-DWARF-CHECK: DW_AT_name {{.*}}"CU1"
+#UPD-DWARF-CHECK: DW_AT_loclists_base [DW_FORM_sec_offset] (0x0000000c)
+#UPD-DWARF-CHECK: DW_TAG_variable
+#UPD-DWARF-CHECK: DW_AT_name {{.*}}"var1"
+#UPD-DWARF-CHECK: DW_AT_location [DW_FORM_loclistx] (indexed (0x0) loclist = 0x00000018:
+#UPD-DWARF-CHECK: [0x0000000000001130, 0x0000000000001140): DW_OP_reg5 RDI)
+#UPD-DWARF-CHECK: DW_TAG_variable
+#UPD-DWARF-CHECK: DW_AT_name {{.*}}"var2"
+#UPD-DWARF-CHECK: DW_AT_location [DW_FORM_loclistx] (indexed (0x1) loclist = 0x0000001e:
+#UPD-DWARF-CHECK: <default>: DW_OP_reg5 RDI)
+#UPD-DWARF-CHECK: DW_TAG_variable
+#UPD-DWARF-CHECK: DW_AT_name {{.*}}"var3"
+#UPD-DWARF-CHECK: DW_AT_location [DW_FORM_loclistx] (indexed (0x2) loclist = 0x00000022:
+#UPD-DWARF-CHECK: [0x0000000000001140, 0x0000000000001150): DW_OP_reg5 RDI
+#UPD-DWARF-CHECK: [0x0000000000001160, 0x0000000000001170): DW_OP_reg6 RBP)
+
+## Following yaml description has Content of the .debug_rnglists exactly like following data vvvvvvvvvvv
+## .debug_rnglists contents:
+## 0x00000000: range list header: length = 0x0000003e, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000005
+## offsets: [
+## 0x00000014 => 0x00000020
+## 0x00000018 => 0x00000024
+## 0x0000001c => 0x00000028
+## 0x00000027 => 0x00000033
+## 0x00000032 => 0x0000003e
+## ]
+## ranges:
+## 0x00000020: [DW_RLE_startx_length]: 0x0000000000000000, 0x0000000000000010 => [0x0000000000001130, 0x0000000000001140)
+## 0x00000023: [DW_RLE_end_of_list ]
+## 0x00000024: [DW_RLE_startx_length]: 0x0000000000000001, 0x0000000000000010 => [0x0000000000001140, 0x0000000000001150)
+## 0x00000027: [DW_RLE_end_of_list ]
+## 0x00000028: [DW_RLE_start_length ]: 0x0000000000001150, 0x0000000000000010 => [0x0000000000001150, 0x0000000000001160)
+## 0x00000032: [DW_RLE_end_of_list ]
+## 0x00000033: [DW_RLE_start_length ]: 0x0000000000001160, 0x0000000000000010 => [0x0000000000001160, 0x0000000000001170)
+## 0x0000003d: [DW_RLE_end_of_list ]
+## 0x0000003e: [DW_RLE_startx_length]: 0x0000000000000000, 0x0000000000000040 => [0x0000000000001130, 0x0000000000001170)
+## 0x00000041: [DW_RLE_end_of_list ]
+
+
+## Following yaml description has Content of the .debug_loclists exactly like following data vvvvvvvvvvv
+## .debug_loclists contents:
+## 0x00000000: locations list header: length = 0x00000029, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000003
+## offsets: [
+## 0x0000000c => 0x00000018
+## 0x00000012 => 0x0000001e
+## 0x00000016 => 0x00000022
+## ]
+## 0x00000018:
+## DW_LLE_startx_length (0x0000000000000000, 0x0000000000000010): DW_OP_reg5 RDI
+## DW_LLE_end_of_list ()
+##
+## 0x0000001e:
+## DW_LLE_default_location()
+## => <default>: DW_OP_reg5 RDI
+## DW_LLE_end_of_list ()
+##
+## 0x00000022:
+## DW_LLE_startx_length (0x0000000000000001, 0x0000000000000010): DW_OP_reg5 RDI
+## DW_LLE_startx_length (0x0000000000000003, 0x0000000000000010): DW_OP_reg6 RBP
+## DW_LLE_end_of_list ()
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1130
+ Size: 0x70
+ - Name: .debug_rnglists
+ Type: SHT_PROGBITS
+ Flags: [ ]
+ Content: "3e000000050008000500000014000000180000001c000000270000003200000003001000030110000750110000000000001000076011000000000000100003004000"
+ - Name: .debug_loclists
+ Type: SHT_PROGBITS
+ Flags: [ ]
+ Content: "2900000005000800030000000c0000001200000016000000030010015500050155000301100155030310015600"
+DWARF:
+ debug_abbrev:
+ - Table:
+ - Tag: DW_TAG_compile_unit
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_producer
+ Form: DW_FORM_string
+ - Attribute: DW_AT_language
+ Form: DW_FORM_data2
+ - Attribute: DW_AT_name
+ Form: DW_FORM_string
+ - Attribute: DW_AT_low_pc
+ Form: DW_FORM_addrx
+ - Attribute: DW_AT_ranges
+ Form: DW_FORM_rnglistx
+ - Attribute: DW_AT_rnglists_base
+ Form: DW_FORM_sec_offset
+ - Attribute: DW_AT_loclists_base
+ Form: DW_FORM_sec_offset
+ - Attribute: DW_AT_addr_base
+ Form: DW_FORM_sec_offset
+ - Tag: DW_TAG_base_type
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_string
+ - Tag: DW_TAG_variable
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_string
+ - Attribute: DW_AT_const_value
+ Form: DW_FORM_data4
+ - Attribute: DW_AT_type
+ Form: DW_FORM_ref_addr
+ - Attribute: DW_AT_location
+ Form: DW_FORM_loclistx
+ debug_info:
+ - Version: 5
+ UnitType: DW_UT_compile
+ Entries:
+ - AbbrCode: 1
+ Values:
+ - CStr: by_hand
+ - Value: 0x04
+ - CStr: CU1
+ - Value: 0x0
+ - Value: 0x4
+ - Value: 0xc
+ - Value: 0xc
+ - Value: 0x8
+ - AbbrCode: 2
+ Values:
+ - CStr: int
+ - AbbrCode: 3
+ Values:
+ - CStr: var1
+ - Value: 0x00000000
+ - Value: 0x00000029
+ - Value: 0x0
+ - AbbrCode: 3
+ Values:
+ - CStr: var2
+ - Value: 0x00000000
+ - Value: 0x00000029
+ - Value: 0x1
+ - AbbrCode: 3
+ Values:
+ - CStr: var3
+ - Value: 0x00000000
+ - Value: 0x00000029
+ - Value: 0x2
+ - AbbrCode: 0
+ debug_addr:
+ - Version: 5
+ AddressSize: 0x08
+ Entries:
+ - Address: 0x1130
+ - Address: 0x1140
+ - Address: 0x1150
+ - Address: 0x1160
+...
diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-loclists.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-loclists.test
deleted file mode 100644
index 09e2cea4993da..0000000000000
--- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-loclists.test
+++ /dev/null
@@ -1,54 +0,0 @@
-## This test checks the warning message displayed if input file
-## contains .debug_loclists section.
-
-# RUN: yaml2obj %s -o %t.o
-
-# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o
-
-# CHECK: [[FILE]]: warning: '.debug_loclists' is not currently supported: file will be skipped
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- Address: 0x1000
- AddressAlign: 0x0000000000000010
- Content: "FFFFFFFF"
- - Name: .debug_loclists
- Type: SHT_PROGBITS
- Flags: [ ]
- Content: "0000000000000000000000"
-DWARF:
- debug_abbrev:
- - Table:
- - Tag: DW_TAG_compile_unit
- Children: DW_CHILDREN_yes
- Attributes:
- - Attribute: DW_AT_producer
- Form: DW_FORM_string
- - Attribute: DW_AT_language
- Form: DW_FORM_data2
- - Attribute: DW_AT_name
- Form: DW_FORM_string
- - Attribute: DW_AT_low_pc
- Form: DW_FORM_addr
- - Attribute: DW_AT_high_pc
- Form: DW_FORM_data8
- debug_info:
- - Version: 4
- Entries:
- - AbbrCode: 1
- Values:
- - CStr: by_hand
- - Value: 0x04
- - CStr: CU1
- - Value: 0x1000
- - Value: 0x4
- - AbbrCode: 0
-...
More information about the llvm-commits
mailing list