Importing rustc-1.70.0
Test: ./build.py --lto=thin
Change-Id: I34045ec5a79462afe9900f38a66f9783d4055a18
diff --git a/src/llvm-project/llvm/tools/llvm-dwarfutil/CMakeLists.txt b/src/llvm-project/llvm/tools/llvm-dwarfutil/CMakeLists.txt
index d932ff1..4210250 100644
--- a/src/llvm-project/llvm/tools/llvm-dwarfutil/CMakeLists.txt
+++ b/src/llvm-project/llvm/tools/llvm-dwarfutil/CMakeLists.txt
@@ -3,15 +3,16 @@
add_public_tablegen_target(DwarfutilTableGen)
set(LLVM_LINK_COMPONENTS
- ${LLVM_TARGETS_TO_BUILD}
DebugInfoDWARF
DWARFLinker
+ DWARFLinkerParallel
MC
ObjCopy
Object
Option
Support
Target
+ TargetParser
AllTargetsCodeGens
AllTargetsDescs
AllTargetsInfos
diff --git a/src/llvm-project/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp b/src/llvm-project/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
index 3e70f46..ef222f8c 100644
--- a/src/llvm-project/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
+++ b/src/llvm-project/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
@@ -14,6 +14,7 @@
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Endian.h"
#include <memory>
#include <vector>
@@ -40,7 +41,7 @@
public:
ObjFileAddressMap(DWARFContext &Context, const Options &Options,
object::ObjectFile &ObjFile)
- : Opts(Options) {
+ : Opts(Options), Context(Context) {
// Remember addresses of existing text sections.
for (const object::SectionRef &Sect : ObjFile.sections()) {
if (!Sect.isText())
@@ -75,7 +76,7 @@
DIE.getTag() == dwarf::DW_TAG_label) &&
"Wrong type of input die");
- if (Optional<uint64_t> LowPC =
+ if (std::optional<uint64_t> LowPC =
dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc))) {
if (!isDeadAddress(*LowPC, DIE.getDwarfUnit()->getVersion(),
Opts.Tombstone,
@@ -137,17 +138,36 @@
void clear() override { DWARFAddressRanges.clear(); }
- llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t, uint64_t) override {
- // should not be called.
- return object::createError("no relocations in linked binary");
+ llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t StartOffset,
+ uint64_t EndOffset) override {
+ // No relocations in linked binary. Return just address value.
+
+ const char *AddrPtr =
+ Context.getDWARFObj().getAddrSection().Data.data() + StartOffset;
+ support::endianness Endianess =
+ Context.getDWARFObj().isLittleEndian() ? support::little : support::big;
+
+ assert(EndOffset > StartOffset);
+ switch (EndOffset - StartOffset) {
+ case 1:
+ return *AddrPtr;
+ case 2:
+ return support::endian::read16(AddrPtr, Endianess);
+ case 4:
+ return support::endian::read32(AddrPtr, Endianess);
+ case 8:
+ return support::endian::read64(AddrPtr, Endianess);
+ }
+
+ llvm_unreachable("relocateIndexedAddr unhandled case!");
}
protected:
// returns true if specified address range is inside address ranges
// of executable sections.
bool isInsideExecutableSectionsAddressRange(uint64_t LowPC,
- Optional<uint64_t> HighPC) {
- Optional<AddressRange> Range =
+ std::optional<uint64_t> HighPC) {
+ std::optional<AddressRange> Range =
TextAddressRanges.getRangeThatContains(LowPC);
if (HighPC)
@@ -156,7 +176,7 @@
return Range.has_value();
}
- uint64_t isBFDDeadAddressRange(uint64_t LowPC, Optional<uint64_t> HighPC,
+ uint64_t isBFDDeadAddressRange(uint64_t LowPC, std::optional<uint64_t> HighPC,
uint16_t Version) {
if (LowPC == 0)
return true;
@@ -167,7 +187,8 @@
return !isInsideExecutableSectionsAddressRange(LowPC, HighPC);
}
- uint64_t isMAXPCDeadAddressRange(uint64_t LowPC, Optional<uint64_t> HighPC,
+ uint64_t isMAXPCDeadAddressRange(uint64_t LowPC,
+ std::optional<uint64_t> HighPC,
uint16_t Version, uint8_t AddressByteSize) {
if (Version <= 4 && HighPC) {
if (LowPC == (dwarf::computeTombstoneAddress(AddressByteSize) - 1))
@@ -182,7 +203,7 @@
return false;
}
- bool isDeadAddressRange(uint64_t LowPC, Optional<uint64_t> HighPC,
+ bool isDeadAddressRange(uint64_t LowPC, std::optional<uint64_t> HighPC,
uint16_t Version, TombstoneKind Tombstone,
uint8_t AddressByteSize) {
switch (Tombstone) {
@@ -202,13 +223,15 @@
bool isDeadAddress(uint64_t LowPC, uint16_t Version, TombstoneKind Tombstone,
uint8_t AddressByteSize) {
- return isDeadAddressRange(LowPC, None, Version, Tombstone, AddressByteSize);
+ return isDeadAddressRange(LowPC, std::nullopt, Version, Tombstone,
+ AddressByteSize);
}
private:
RangesTy DWARFAddressRanges;
AddressRanges TextAddressRanges;
const Options &Opts;
+ DWARFContext &Context;
};
static bool knownByDWARFUtil(StringRef SecName) {
@@ -229,9 +252,63 @@
.Case(".debug_macinfo", true)
.Case(".debug_str", true)
.Case(".debug_str_offsets", true)
+ .Case(".debug_pubnames", true)
+ .Case(".debug_pubtypes", true)
+ .Case(".debug_names", true)
.Default(false);
}
+static std::optional<DwarfLinkerAccelTableKind>
+getAcceleratorTableKind(StringRef SecName) {
+ return llvm::StringSwitch<std::optional<DwarfLinkerAccelTableKind>>(SecName)
+ .Case(".debug_pubnames", DwarfLinkerAccelTableKind::Pub)
+ .Case(".debug_pubtypes", DwarfLinkerAccelTableKind::Pub)
+ .Case(".debug_names", DwarfLinkerAccelTableKind::DebugNames)
+ .Default(std::nullopt);
+}
+
+static std::string getMessageForReplacedAcceleratorTables(
+ SmallVector<StringRef> &AccelTableNamesToReplace,
+ DwarfUtilAccelKind TargetTable) {
+ std::string Message;
+
+ Message += "'";
+ for (StringRef Name : AccelTableNamesToReplace) {
+ if (Message.size() > 1)
+ Message += ", ";
+ Message += Name;
+ }
+
+ Message += "' will be replaced with requested ";
+
+ switch (TargetTable) {
+ case DwarfUtilAccelKind::DWARF:
+ Message += ".debug_names table";
+ break;
+
+ default:
+ assert(false);
+ }
+
+ return Message;
+}
+
+static std::string getMessageForDeletedAcceleratorTables(
+ SmallVector<StringRef> &AccelTableNamesToReplace) {
+ std::string Message;
+
+ Message += "'";
+ for (StringRef Name : AccelTableNamesToReplace) {
+ if (Message.size() > 1)
+ Message += ", ";
+ Message += Name;
+ }
+
+ Message += "' will be deleted as no accelerator tables are requested";
+
+ return Message;
+}
+
Error linkDebugInfo(object::ObjectFile &File, const Options &Options,
raw_pwrite_stream &OutStream) {
@@ -263,11 +340,12 @@
.str()))
return createStringError(std::errc::invalid_argument, "");
+ std::unique_ptr<DWARFContext> Context = DWARFContext::create(File);
+
// Create DWARF linker.
DWARFLinker DebugInfoLinker(&OutStreamer, DwarfLinkerClient::LLD);
DebugInfoLinker.setEstimatedObjfilesAmount(1);
- DebugInfoLinker.setAccelTableKind(DwarfLinkerAccelTableKind::None);
DebugInfoLinker.setErrorHandler(ReportErr);
DebugInfoLinker.setWarningHandler(ReportWarn);
DebugInfoLinker.setNumThreads(Options.NumThreads);
@@ -279,18 +357,6 @@
std::vector<std::unique_ptr<AddressesMap>> AddresssMapForLinking(1);
std::vector<std::string> EmptyWarnings;
- std::unique_ptr<DWARFContext> Context = DWARFContext::create(File);
-
- // Unknown debug sections would be removed. Display warning
- // for such sections.
- for (SectionName Sec : Context->getDWARFObj().getSectionNames()) {
- if (isDebugSection(Sec.Name) && !knownByDWARFUtil(Sec.Name))
- warning(
- formatv("'{0}' is not currently supported: section will be skipped",
- Sec.Name),
- Options.InputFileName);
- }
-
// Add object files to the DWARFLinker.
AddresssMapForLinking[0] =
std::make_unique<ObjFileAddressMap>(*Context, Options, File);
@@ -299,8 +365,77 @@
File.getFileName(), &*Context, AddresssMapForLinking[0].get(),
EmptyWarnings);
+ uint16_t MaxDWARFVersion = 0;
+ std::function<void(const DWARFUnit &Unit)> OnCUDieLoaded =
+ [&MaxDWARFVersion](const DWARFUnit &Unit) {
+ MaxDWARFVersion = std::max(Unit.getVersion(), MaxDWARFVersion);
+ };
+
for (size_t I = 0; I < ObjectsForLinking.size(); I++)
- DebugInfoLinker.addObjectFile(*ObjectsForLinking[I]);
+ DebugInfoLinker.addObjectFile(*ObjectsForLinking[I], nullptr,
+ OnCUDieLoaded);
+
+ // If we haven't seen any CUs, pick an arbitrary valid Dwarf version anyway.
+ if (MaxDWARFVersion == 0)
+ MaxDWARFVersion = 3;
+
+ if (Error Err = DebugInfoLinker.setTargetDWARFVersion(MaxDWARFVersion))
+ return Err;
+
+ SmallVector<DwarfLinkerAccelTableKind> AccelTables;
+
+ switch (Options.AccelTableKind) {
+ case DwarfUtilAccelKind::None:
+ // Nothing to do.
+ break;
+ case DwarfUtilAccelKind::DWARF:
+ // use .debug_names for all DWARF versions.
+ AccelTables.push_back(DwarfLinkerAccelTableKind::DebugNames);
+ break;
+ }
+
+ // Add accelerator tables to DWARFLinker.
+ for (DwarfLinkerAccelTableKind Table : AccelTables)
+ DebugInfoLinker.addAccelTableKind(Table);
+
+ SmallVector<StringRef> AccelTableNamesToReplace;
+ SmallVector<StringRef> AccelTableNamesToDelete;
+
+ // Unknown debug sections or non-requested accelerator sections would be
+ // removed. Display warning for such sections.
+ for (SectionName Sec : Context->getDWARFObj().getSectionNames()) {
+ if (isDebugSection(Sec.Name)) {
+ std::optional<DwarfLinkerAccelTableKind> SrcAccelTableKind =
+ getAcceleratorTableKind(Sec.Name);
+
+ if (SrcAccelTableKind) {
+ assert(knownByDWARFUtil(Sec.Name));
+
+ if (Options.AccelTableKind == DwarfUtilAccelKind::None)
+ AccelTableNamesToDelete.push_back(Sec.Name);
+ else if (std::find(AccelTables.begin(), AccelTables.end(),
+ *SrcAccelTableKind) == AccelTables.end())
+ AccelTableNamesToReplace.push_back(Sec.Name);
+ } else if (!knownByDWARFUtil(Sec.Name)) {
+ assert(!SrcAccelTableKind);
+ warning(
+ formatv("'{0}' is not currently supported: section will be skipped",
+ Sec.Name),
+ Options.InputFileName);
+ }
+ }
+ }
+
+ // Display message for the replaced accelerator tables.
+ if (!AccelTableNamesToReplace.empty())
+ warning(getMessageForReplacedAcceleratorTables(AccelTableNamesToReplace,
+ Options.AccelTableKind),
+ Options.InputFileName);
+
+ // Display message for the removed accelerator tables.
+ if (!AccelTableNamesToDelete.empty())
+ warning(getMessageForDeletedAcceleratorTables(AccelTableNamesToDelete),
+ Options.InputFileName);
// Link debug info.
if (Error Err = DebugInfoLinker.link())
diff --git a/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.h b/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.h
index c993200..38fa2b9 100644
--- a/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.h
+++ b/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.h
@@ -24,6 +24,12 @@
Exec, /// match with address range of executable sections.
};
+/// The kind of accelerator table.
+enum class DwarfUtilAccelKind : uint8_t {
+ None,
+ DWARF // DWARFv5: .debug_names
+};
+
struct Options {
std::string InputFileName;
std::string OutputFileName;
@@ -34,6 +40,7 @@
bool Verbose = false;
int NumThreads = 0;
bool Verify = false;
+ DwarfUtilAccelKind AccelTableKind = DwarfUtilAccelKind::None;
std::string getSeparateDebugFileName() const {
return OutputFileName + ".debug";
diff --git a/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.td b/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.td
index 4ab1b51..d454118 100644
--- a/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.td
+++ b/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.td
@@ -5,6 +5,14 @@
def no_ # NAME: Flag<["--"], "no-" # name>, HelpText<help2>;
}
+def build_accelerator: Separate<["--", "-"], "build-accelerator">,
+ MetaVarName<"[none,DWARF]">,
+ HelpText<"Build accelerator tables(default: none)\n"
+ " =none - Do not build accelerators\n"
+ " =DWARF - .debug_names are generated for all DWARF versions\n"
+ >;
+def: Joined<["--", "-"], "build-accelerator=">, Alias<build_accelerator>;
+
def help : Flag<["--"], "help">,
HelpText<"Prints this help output">;
diff --git a/src/llvm-project/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp b/src/llvm-project/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
index a6466be..74b6104 100644
--- a/src/llvm-project/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
+++ b/src/llvm-project/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
@@ -40,11 +40,14 @@
#undef OPTION
};
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
+#define PREFIX(NAME, VALUE) \
+ static constexpr StringLiteral NAME##_init[] = VALUE; \
+ static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
+ std::size(NAME##_init) - 1);
#include "Options.inc"
#undef PREFIX
-const opt::OptTable::Info InfoTable[] = {
+static constexpr opt::OptTable::Info InfoTable[] = {
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR, VALUES) \
{ \
@@ -56,9 +59,9 @@
#undef OPTION
};
-class DwarfutilOptTable : public opt::OptTable {
+class DwarfutilOptTable : public opt::GenericOptTable {
public:
- DwarfutilOptTable() : OptTable(InfoTable) {}
+ DwarfutilOptTable() : opt::GenericOptTable(InfoTable) {}
};
} // namespace
@@ -120,6 +123,19 @@
formatv("unknown tombstone value: '{0}'", S).str().c_str());
}
+ if (opt::Arg *BuildAccelerator = Args.getLastArg(OPT_build_accelerator)) {
+ StringRef S = BuildAccelerator->getValue();
+
+ if (S == "none")
+ Options.AccelTableKind = DwarfUtilAccelKind::None;
+ else if (S == "DWARF")
+ Options.AccelTableKind = DwarfUtilAccelKind::DWARF;
+ else
+ return createStringError(
+ std::errc::invalid_argument,
+ formatv("unknown build-accelerator value: '{0}'", S).str().c_str());
+ }
+
if (Options.Verbose) {
if (Options.NumThreads != 1 && Args.hasArg(OPT_threads))
warning("--num-threads set to 1 because verbose mode is specified");
@@ -420,8 +436,9 @@
}
static Error applyCLOptions(const struct Options &Opts, ObjectFile &InputFile) {
- if (Opts.DoGarbageCollection) {
- verbose("Do garbage collection for debug info ...", Opts.Verbose);
+ if (Opts.DoGarbageCollection ||
+ Opts.AccelTableKind != DwarfUtilAccelKind::None) {
+ verbose("Do debug info linking...", Opts.Verbose);
DebugInfoBits LinkedDebugInfo;
raw_svector_ostream OutStream(LinkedDebugInfo);
@@ -458,7 +475,7 @@
DwarfutilOptTable T;
unsigned MAI;
unsigned MAC;
- ArrayRef<const char *> ArgsArr = makeArrayRef(Argv + 1, Argc - 1);
+ ArrayRef<const char *> ArgsArr = ArrayRef(Argv + 1, Argc - 1);
opt::InputArgList Args = T.ParseArgs(ArgsArr, MAI, MAC);
if (Args.hasArg(OPT_help) || Args.size() == 0) {
@@ -481,7 +498,6 @@
InitializeAllTargetMCs();
InitializeAllTargetInfos();
InitializeAllAsmPrinters();
- InitializeAllAsmParsers();
ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr =
MemoryBuffer::getFileOrSTDIN(Opts.InputFileName);