Skip to content

Commit 4c44dcf

Browse files
authored
Support soft failure on DWP section overflow, producing a truncated but valid DWP(#71902)
When 'ContinueOnCuIndexOverflow' enables without this modification, the forcibly generated '.dwp' won't be recognized by Debugger(gdb 10.1) correctly. <img width="657" alt="image" src="https://github.com/llvm/llvm-project/assets/150100070/31732775-2548-453a-a47a-fa04c6d05fe9"> it looks like there's a problem with processing the dwarf header, which makes debugging completely impossible. (unless the consumer walks the debug_info section to rebuild that column (if that's the only section that overflowed - if it's another section, there's no recovery)) **About patch:** When llvm-dwp enables option '--continue-on-cu-index-overflow=soft-stop' and recognizes the overflow problem , it will stop packing and generate the '.dwp' file at once, discarding any DWO files that would not fit within the 32 bit/4GB limits of the format. <img width="625" alt="image" src="https://github.com/llvm/llvm-project/assets/150100070/77d6be24-262b-4f4c-afc0-9a6c49e133c7">
1 parent 481e9b3 commit 4c44dcf

File tree

4 files changed

+70
-21
lines changed

4 files changed

+70
-21
lines changed

llvm/include/llvm/DWP/DWP.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
#include <vector>
1616

1717
namespace llvm {
18+
enum OnCuIndexOverflow {
19+
HardStop,
20+
SoftStop,
21+
Continue,
22+
};
23+
1824
struct UnitIndexEntry {
1925
DWARFUnitIndex::Entry::SectionContribution Contributions[8];
2026
std::string Name;
@@ -61,7 +67,7 @@ struct CompileUnitIdentifiers {
6167
};
6268

6369
Error write(MCStreamer &Out, ArrayRef<std::string> Inputs,
64-
bool ContinueOnCuIndexOverflow);
70+
OnCuIndexOverflow OverflowOptValue);
6571

6672
unsigned getContributionIndex(DWARFSectionKind Kind, uint32_t IndexVersion);
6773

llvm/lib/DWP/DWP.cpp

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,19 @@ static StringRef getSubsection(StringRef Section,
183183
static Error sectionOverflowErrorOrWarning(uint32_t PrevOffset,
184184
uint32_t OverflowedOffset,
185185
StringRef SectionName,
186-
bool ContinueOnCuIndexOverflow) {
186+
OnCuIndexOverflow OverflowOptValue,
187+
bool &AnySectionOverflow) {
187188
std::string Msg =
188189
(SectionName +
189190
Twine(" Section Contribution Offset overflow 4G. Previous Offset ") +
190191
Twine(PrevOffset) + Twine(", After overflow offset ") +
191192
Twine(OverflowedOffset) + Twine("."))
192193
.str();
193-
if (ContinueOnCuIndexOverflow) {
194+
if (OverflowOptValue == OnCuIndexOverflow::Continue) {
195+
WithColor::defaultWarningHandler(make_error<DWPError>(Msg));
196+
return Error::success();
197+
} else if (OverflowOptValue == OnCuIndexOverflow::SoftStop) {
198+
AnySectionOverflow = true;
194199
WithColor::defaultWarningHandler(make_error<DWPError>(Msg));
195200
return Error::success();
196201
}
@@ -201,7 +206,8 @@ static Error addAllTypesFromDWP(
201206
MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
202207
const DWARFUnitIndex &TUIndex, MCSection *OutputTypes, StringRef Types,
203208
const UnitIndexEntry &TUEntry, uint32_t &TypesOffset,
204-
unsigned TypesContributionIndex, bool ContinueOnCuIndexOverflow) {
209+
unsigned TypesContributionIndex, OnCuIndexOverflow OverflowOptValue,
210+
bool &AnySectionOverflow) {
205211
Out.switchSection(OutputTypes);
206212
for (const DWARFUnitIndex::Entry &E : TUIndex.getRows()) {
207213
auto *I = E.getContributions();
@@ -232,9 +238,14 @@ static Error addAllTypesFromDWP(
232238
static_assert(sizeof(OldOffset) == sizeof(TypesOffset));
233239
TypesOffset += C.getLength();
234240
if (OldOffset > TypesOffset) {
235-
if (Error Err = sectionOverflowErrorOrWarning(
236-
OldOffset, TypesOffset, "Types", ContinueOnCuIndexOverflow))
241+
if (Error Err = sectionOverflowErrorOrWarning(OldOffset, TypesOffset,
242+
"Types", OverflowOptValue,
243+
AnySectionOverflow))
237244
return Err;
245+
if (AnySectionOverflow) {
246+
TypesOffset = OldOffset;
247+
return Error::success();
248+
}
238249
}
239250
}
240251
return Error::success();
@@ -244,7 +255,7 @@ static Error addAllTypesFromTypesSection(
244255
MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
245256
MCSection *OutputTypes, const std::vector<StringRef> &TypesSections,
246257
const UnitIndexEntry &CUEntry, uint32_t &TypesOffset,
247-
bool ContinueOnCuIndexOverflow) {
258+
OnCuIndexOverflow OverflowOptValue, bool &AnySectionOverflow) {
248259
for (StringRef Types : TypesSections) {
249260
Out.switchSection(OutputTypes);
250261
uint64_t Offset = 0;
@@ -273,9 +284,14 @@ static Error addAllTypesFromTypesSection(
273284
uint32_t OldOffset = TypesOffset;
274285
TypesOffset += C.getLength32();
275286
if (OldOffset > TypesOffset) {
276-
if (Error Err = sectionOverflowErrorOrWarning(
277-
OldOffset, TypesOffset, "types", ContinueOnCuIndexOverflow))
287+
if (Error Err = sectionOverflowErrorOrWarning(OldOffset, TypesOffset,
288+
"Types", OverflowOptValue,
289+
AnySectionOverflow))
278290
return Err;
291+
if (AnySectionOverflow) {
292+
TypesOffset = OldOffset;
293+
return Error::success();
294+
}
279295
}
280296
}
281297
}
@@ -583,7 +599,7 @@ Error handleSection(
583599
}
584600

585601
Error write(MCStreamer &Out, ArrayRef<std::string> Inputs,
586-
bool ContinueOnCuIndexOverflow) {
602+
OnCuIndexOverflow OverflowOptValue) {
587603
const auto &MCOFI = *Out.getContext().getObjectFileInfo();
588604
MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
589605
MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
@@ -613,6 +629,7 @@ Error write(MCStreamer &Out, ArrayRef<std::string> Inputs,
613629
uint32_t ContributionOffsets[8] = {};
614630
uint16_t Version = 0;
615631
uint32_t IndexVersion = 0;
632+
bool AnySectionOverflow = false;
616633

617634
DWPStringPool Strings(Out, StrSection);
618635

@@ -687,12 +704,15 @@ Error write(MCStreamer &Out, ArrayRef<std::string> Inputs,
687704
uint32_t SectionIndex = 0;
688705
for (auto &Section : Obj.sections()) {
689706
if (SectionIndex == Index) {
690-
return sectionOverflowErrorOrWarning(
691-
OldOffset, ContributionOffsets[Index], *Section.getName(),
692-
ContinueOnCuIndexOverflow);
707+
if (Error Err = sectionOverflowErrorOrWarning(
708+
OldOffset, ContributionOffsets[Index], *Section.getName(),
709+
OverflowOptValue, AnySectionOverflow))
710+
return Err;
693711
}
694712
++SectionIndex;
695713
}
714+
if (AnySectionOverflow)
715+
break;
696716
}
697717
}
698718

@@ -720,8 +740,14 @@ Error write(MCStreamer &Out, ArrayRef<std::string> Inputs,
720740
C.getLength32()) {
721741
if (Error Err = sectionOverflowErrorOrWarning(
722742
InfoSectionOffset, InfoSectionOffset + C.getLength32(),
723-
"debug_info", ContinueOnCuIndexOverflow))
743+
"debug_info", OverflowOptValue, AnySectionOverflow))
724744
return Err;
745+
if (AnySectionOverflow) {
746+
if (Header.Version < 5 ||
747+
Header.UnitType == dwarf::DW_UT_split_compile)
748+
FoundCUUnit = true;
749+
break;
750+
}
725751
}
726752

727753
UnitOffset += C.getLength32();
@@ -752,6 +778,8 @@ Error write(MCStreamer &Out, ArrayRef<std::string> Inputs,
752778
Info.substr(UnitOffset - C.getLength32(), C.getLength32()));
753779
InfoSectionOffset += C.getLength32();
754780
}
781+
if (AnySectionOverflow)
782+
break;
755783
}
756784

757785
if (!FoundCUUnit)
@@ -762,9 +790,11 @@ Error write(MCStreamer &Out, ArrayRef<std::string> Inputs,
762790
if (Error Err = addAllTypesFromTypesSection(
763791
Out, TypeIndexEntries, TypesSection, CurTypesSection, CurEntry,
764792
ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)],
765-
ContinueOnCuIndexOverflow))
793+
OverflowOptValue, AnySectionOverflow))
766794
return Err;
767795
}
796+
if (AnySectionOverflow)
797+
break;
768798
continue;
769799
}
770800

@@ -860,9 +890,11 @@ Error write(MCStreamer &Out, ArrayRef<std::string> Inputs,
860890
if (Error Err = addAllTypesFromDWP(
861891
Out, TypeIndexEntries, TUIndex, OutSection, TypeInputSection,
862892
CurEntry, ContributionOffsets[TypesContributionIndex],
863-
TypesContributionIndex, ContinueOnCuIndexOverflow))
893+
TypesContributionIndex, OverflowOptValue, AnySectionOverflow))
864894
return Err;
865895
}
896+
if (AnySectionOverflow)
897+
break;
866898
}
867899

868900
if (Version < 5) {

llvm/tools/llvm-dwp/Opts.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@ def version : F<"version", "Display the version of this program">;
99

1010
def execFileNames : S<"e", "Specify the executable/library files to get the list of *.dwo from.">, MetaVarName<"<filename>">;
1111
def outputFileName : S<"o", "Specify the output file.">, MetaVarName<"<filename>">;
12-
def continueOnCuIndexOverflow: F<"continue-on-cu-index-overflow", "This turns an error when offset for .debug_*.dwo sections "
13-
"overfolws into a warning.">, MetaVarName<"<filename>">;
12+
def continueOnCuIndexOverflow : S<"continue-on-cu-index-overflow", "default = continue, This turns an error when offset "
13+
"for .debug_*.dwo sections overfolws into a warning. = soft-stop, This produces a "
14+
"truncated but valid DWP file, discarding any DWO files that would not fit within "
15+
"the 32 bit/4GB limits of the format.">, MetaVarName<"<filename>">;

llvm/tools/llvm-dwp/llvm-dwp.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class DwpOptTable : public opt::GenericOptTable {
7171
// Options
7272
static std::vector<std::string> ExecFilenames;
7373
static std::string OutputFilename;
74-
static bool ContinueOnCuIndexOverflow;
74+
static std::string ContinueOption;
7575

7676
static Expected<SmallVector<std::string, 16>>
7777
getDWOFilenames(StringRef ExecFilename) {
@@ -125,6 +125,7 @@ int llvm_dwp_main(int argc, char **argv, const llvm::ToolContext &) {
125125
DwpOptTable Tbl;
126126
llvm::BumpPtrAllocator A;
127127
llvm::StringSaver Saver{A};
128+
OnCuIndexOverflow OverflowOptValue = OnCuIndexOverflow::HardStop;
128129
opt::InputArgList Args =
129130
Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
130131
llvm::errs() << Msg << '\n';
@@ -143,7 +144,15 @@ int llvm_dwp_main(int argc, char **argv, const llvm::ToolContext &) {
143144
}
144145

145146
OutputFilename = Args.getLastArgValue(OPT_outputFileName, "");
146-
ContinueOnCuIndexOverflow = Args.hasArg(OPT_continueOnCuIndexOverflow);
147+
if (Args.hasArg(OPT_continueOnCuIndexOverflow)) {
148+
ContinueOption =
149+
Args.getLastArgValue(OPT_continueOnCuIndexOverflow, "continue");
150+
if (ContinueOption == "soft-stop") {
151+
OverflowOptValue = OnCuIndexOverflow::SoftStop;
152+
} else {
153+
OverflowOptValue = OnCuIndexOverflow::Continue;
154+
}
155+
}
147156

148157
for (const llvm::opt::Arg *A : Args.filtered(OPT_execFileNames))
149158
ExecFilenames.emplace_back(A->getValue());
@@ -255,7 +264,7 @@ int llvm_dwp_main(int argc, char **argv, const llvm::ToolContext &) {
255264
if (!MS)
256265
return error("no object streamer for target " + TripleName, Context);
257266

258-
if (auto Err = write(*MS, DWOFilenames, ContinueOnCuIndexOverflow)) {
267+
if (auto Err = write(*MS, DWOFilenames, OverflowOptValue)) {
259268
logAllUnhandledErrors(std::move(Err), WithColor::error());
260269
return 1;
261270
}

0 commit comments

Comments
 (0)