Skip to content

Commit 011c2c1

Browse files
committed
Add a --dwarf64-str-offsets option value.
This option controls if llvm-dwp can promote a .debug_str_offsets table from DWARF32 to DWARF64. Setting this option value to "enabled" allows promotion of a DWARF32 .debug_str_offsets table to DWARF64 only if any string in the .debug_str_offsets table exceeds UINT32_MAX. Setting this option value to "disabled" (the default) will keep pre-existing behavior where all .debug_str_offsets tables will be emitted in the same format as are in each .dwo file. Setting this option value to "always" forces all .debug_str_offsets tables to be emitted as DWARF64 tables. This is used for testing. Removed the previous --force-dwarf64-str-offsets option.
1 parent 604b555 commit 011c2c1

File tree

5 files changed

+64
-20
lines changed

5 files changed

+64
-20
lines changed

llvm/include/llvm/DWP/DWP.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ enum OnCuIndexOverflow {
2222
Continue,
2323
};
2424

25+
enum Dwarf64StrOffsets {
26+
Disabled, ///< Don't do any conversion of .debug_str_offsets tables.
27+
Enabled, ///< Convert any .debug_str_offsets tables to DWARD64 if needed.
28+
Always, ///< Always emit .debug_str_offsets talbes as DWARF64 for testing.
29+
};
30+
2531
struct UnitIndexEntry {
2632
DWARFUnitIndex::Entry::SectionContribution Contributions[8];
2733
std::string Name;
@@ -69,7 +75,7 @@ struct CompileUnitIdentifiers {
6975

7076
LLVM_ABI Error write(MCStreamer &Out, ArrayRef<std::string> Inputs,
7177
OnCuIndexOverflow OverflowOptValue,
72-
bool ForceDwarf64StringOffsets);
78+
Dwarf64StrOffsets StrOffsetsOptValue);
7379

7480
typedef std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLengths;
7581

llvm/lib/DWP/DWP.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ void writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings,
430430
StringRef CurStrSection,
431431
StringRef CurStrOffsetSection, uint16_t Version,
432432
SectionLengths &SectionLength,
433-
const bool ForceDwarf64StringOffsets) {
433+
const Dwarf64StrOffsets StrOffsetsOptValue) {
434434
// Could possibly produce an error or warning if one of these was non-null but
435435
// the other was null.
436436
if (CurStrSection.empty() || CurStrOffsetSection.empty())
@@ -444,15 +444,19 @@ void writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings,
444444

445445
// Keep track if any new string offsets exceed UINT32_MAX. If any do, we can
446446
// emit a DWARF64 .debug_str_offsets table for this compile unit. If the
447-
// \a ForceDwarf64StringOffsets argument is true, then force the emission of
448-
// DWARF64 .debug_str_offsets for testing.
447+
// \a StrOffsetsOptValue argument is Dwarf64StrOffsets::Always, then force
448+
// the emission of DWARF64 .debug_str_offsets for testing.
449449
uint32_t OldOffsetSize = 4;
450-
uint32_t NewOffsetSize = ForceDwarf64StringOffsets ? 8 : 4;
450+
uint32_t NewOffsetSize =
451+
StrOffsetsOptValue == Dwarf64StrOffsets::Always ? 8 : 4;
451452
while (const char *S = Data.getCStr(&LocalOffset)) {
452453
uint64_t NewOffset = Strings.getOffset(S, LocalOffset - PrevOffset);
453454
OffsetRemapping[PrevOffset] = NewOffset;
454-
if (NewOffset > UINT32_MAX)
455+
// Only promote the .debug_str_offsets to DWARF64 if our setting allows it.
456+
if (StrOffsetsOptValue != Dwarf64StrOffsets::Disabled &&
457+
NewOffset > UINT32_MAX) {
455458
NewOffsetSize = 8;
459+
}
456460
PrevOffset = LocalOffset;
457461
}
458462

@@ -670,7 +674,7 @@ Error handleSection(
670674

671675
Error write(MCStreamer &Out, ArrayRef<std::string> Inputs,
672676
OnCuIndexOverflow OverflowOptValue,
673-
bool ForceDwarf64StringOffsets) {
677+
Dwarf64StrOffsets StrOffsetsOptValue) {
674678
const auto &MCOFI = *Out.getContext().getObjectFileInfo();
675679
MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
676680
MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
@@ -764,7 +768,7 @@ Error write(MCStreamer &Out, ArrayRef<std::string> Inputs,
764768

765769
writeStringsAndOffsets(Out, Strings, StrOffsetSection, CurStrSection,
766770
CurStrOffsetSection, Header.Version, SectionLength,
767-
ForceDwarf64StringOffsets);
771+
StrOffsetsOptValue);
768772

769773
for (auto Pair : SectionLength) {
770774
auto Index = getContributionIndex(Pair.first, IndexVersion);

llvm/test/tools/llvm-dwp/X86/dwarf64-str-offsets.test

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,17 @@
66
# 4GB .dwo file.
77

88
# RUN: yaml2obj %s -o %t.dwo
9-
# RUN: llvm-dwp %t.dwo -o %t.32.dwp
10-
# RUN: llvm-dwp %t.dwo -o %t.64.dwp --force-dwarf64-str-offsets
11-
# RUN: llvm-dwarfdump --debug-str-offsets %t.32.dwp | FileCheck --check-prefixes=DWARF32 %s
12-
# RUN: llvm-dwarfdump --debug-str-offsets %t.64.dwp | FileCheck --check-prefixes=DWARF64 %s
9+
# RUN: llvm-dwp %t.dwo -o %t.dwp
10+
# RUN: llvm-dwp %t.dwo -o %t.default.dwp --dwarf64-str-offsets
11+
# RUN: llvm-dwp %t.dwo -o %t.disabled.dwp --dwarf64-str-offsets=disabled
12+
# RUN: llvm-dwp %t.dwo -o %t.enabled.dwp --dwarf64-str-offsets=enabled
13+
# RUN: llvm-dwp %t.dwo -o %t.always.dwp --dwarf64-str-offsets=always
14+
# RUN: not llvm-dwp %t.dwo -o %t.invalid.dwp --dwarf64-str-offsets=invalid 2>&1 | FileCheck --check-prefixes=ERROR %s
15+
# RUN: llvm-dwarfdump --debug-str-offsets %t.dwp | FileCheck --check-prefixes=DWARF32 %s
16+
# RUN: llvm-dwarfdump --debug-str-offsets %t.default.dwp | FileCheck --check-prefixes=DWARF32 %s
17+
# RUN: llvm-dwarfdump --debug-str-offsets %t.disabled.dwp | FileCheck --check-prefixes=DWARF32 %s
18+
# RUN: llvm-dwarfdump --debug-str-offsets %t.enabled.dwp | FileCheck --check-prefixes=DWARF32 %s
19+
# RUN: llvm-dwarfdump --debug-str-offsets %t.always.dwp | FileCheck --check-prefixes=DWARF64 %s
1320

1421
# DWARF32: .debug_str_offsets.dwo contents:
1522
# DWARF32-NEXT: 0x00000000: Contribution size = 36, Format = DWARF32, Version = 5
@@ -33,6 +40,8 @@
3340
# DWARF64-NEXT: 0x00000040: 0000000000000046 "simple.cpp"
3441
# DWARF64-NEXT: 0x00000048: 0000000000000051 "simple.dwo"
3542

43+
# ERROR: invalid value for --dwarf64-str-offsets. Valid values are one of: "enabled", "disabled" or "always".
44+
3645
--- !ELF
3746
FileHeader:
3847
Class: ELFCLASS64

llvm/tools/llvm-dwp/Opts.td

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,13 @@ def continueOnCuIndexOverflow_EQ : Joined<["-", "--"], "continue-on-cu-index-ove
1616
"\t\ttruncated but valid DWP file, discarding any DWO files that would not fit within \n"
1717
"\t\tthe 32 bit/4GB limits of the format.">,
1818
Values<"continue,soft-stop">;
19-
def forceDwarf64StringOffsets : Flag<["-", "--"], "force-dwarf64-str-offsets">,
20-
Flags<[HelpHidden]>,
21-
HelpText<"Force all .debug_str_offsets to be emitted as DWARF64 tables. This "
22-
"option is used for testing.">;
19+
20+
def dwarf64StringOffsets : Flag<["-", "--"], "dwarf64-str-offsets">;
21+
def dwarf64StringOffsets_EQ : Joined<["-", "--"], "dwarf64-str-offsets=">,
22+
HelpText<"default = disabled, This setting doesn't convert DWARF32 .debug_str_offsets\n"
23+
"tables in .dwo files to DWARF64 in the .dwp file. = enabled, This allows .debug_str\n"
24+
"tables to exceed the 4GB limit and have any DWARF32 .debug_str_offsets tables\n"
25+
"converted to DWARF64 only for tables that require 64 bit string offsets.\n"
26+
"= always, This forces all .debug_str_offsets tables to be emitted as DWARF64.\n"
27+
"This is used for testing.">,
28+
Values<"disabled,enabled,always">;

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

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ class DwpOptTable : public opt::GenericOptTable {
7373
static std::vector<std::string> ExecFilenames;
7474
static std::string OutputFilename;
7575
static std::string ContinueOption;
76-
static bool ForceDwarf64StringOffsets = false;
7776

7877
static Expected<SmallVector<std::string, 16>>
7978
getDWOFilenames(StringRef ExecFilename) {
@@ -126,6 +125,8 @@ int llvm_dwp_main(int argc, char **argv, const llvm::ToolContext &) {
126125
llvm::BumpPtrAllocator A;
127126
llvm::StringSaver Saver{A};
128127
OnCuIndexOverflow OverflowOptValue = OnCuIndexOverflow::HardStop;
128+
Dwarf64StrOffsets Dwarf64StrOffsetsValue = Dwarf64StrOffsets::Disabled;
129+
129130
opt::InputArgList Args =
130131
Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
131132
llvm::errs() << Msg << '\n';
@@ -161,8 +162,26 @@ int llvm_dwp_main(int argc, char **argv, const llvm::ToolContext &) {
161162
}
162163
}
163164
}
164-
if (Args.getLastArg(OPT_forceDwarf64StringOffsets))
165-
ForceDwarf64StringOffsets = true;
165+
166+
if (Arg *Arg = Args.getLastArg(OPT_dwarf64StringOffsets,
167+
OPT_dwarf64StringOffsets_EQ)) {
168+
if (Arg->getOption().matches(OPT_dwarf64StringOffsets)) {
169+
Dwarf64StrOffsetsValue = Dwarf64StrOffsets::Enabled;
170+
} else {
171+
std::string OptValue = Arg->getValue();
172+
if (OptValue == "disabled") {
173+
Dwarf64StrOffsetsValue = Dwarf64StrOffsets::Disabled;
174+
} else if (OptValue == "enabled") {
175+
Dwarf64StrOffsetsValue = Dwarf64StrOffsets::Enabled;
176+
} else if (OptValue == "always") {
177+
Dwarf64StrOffsetsValue = Dwarf64StrOffsets::Always;
178+
} else {
179+
llvm::errs() << "invalid value for --dwarf64-str-offsets. Valid values "
180+
"are one of: \"enabled\", \"disabled\" or \"always\".\n";
181+
exit(1);
182+
}
183+
}
184+
}
166185

167186
for (const llvm::opt::Arg *A : Args.filtered(OPT_execFileNames))
168187
ExecFilenames.emplace_back(A->getValue());
@@ -278,7 +297,7 @@ int llvm_dwp_main(int argc, char **argv, const llvm::ToolContext &) {
278297
return error("no object streamer for target " + TripleName, Context);
279298

280299
if (auto Err = write(*MS, DWOFilenames, OverflowOptValue,
281-
ForceDwarf64StringOffsets)) {
300+
Dwarf64StrOffsetsValue)) {
282301
logAllUnhandledErrors(std::move(Err), WithColor::error());
283302
return 1;
284303
}

0 commit comments

Comments
 (0)