diff --git a/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp b/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp index d66e0926ad99ea..a209fa760556f8 100644 --- a/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp +++ b/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp @@ -75,7 +75,7 @@ enum dwarf_regnums { dwarf_pc }; -static const RegisterInfo g_register_infos[] = { +static RegisterInfo g_register_infos[] = { // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME // DWARF GENERIC PROCESS PLUGINS // LLDB NATIVE VALUE REGS INVALIDATE REGS @@ -542,9 +542,24 @@ static const RegisterInfo g_register_infos[] = { static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos); +static bool g_register_info_names_constified = false; const lldb_private::RegisterInfo * ABISysV_mips::GetRegisterInfoArray(uint32_t &count) { + // Make the C-string names and alt_names for the register infos into const + // C-string values by having the ConstString unique the names in the global + // constant C-string pool. + if (!g_register_info_names_constified) { + g_register_info_names_constified = true; + for (uint32_t i = 0; i < k_num_register_infos; ++i) { + if (g_register_infos[i].name) + g_register_infos[i].name = + ConstString(g_register_infos[i].name).GetCString(); + if (g_register_infos[i].alt_name) + g_register_infos[i].alt_name = + ConstString(g_register_infos[i].alt_name).GetCString(); + } + } count = k_num_register_infos; return g_register_infos; } diff --git a/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp b/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp index 751555722daccb..9a07c3398e19c6 100644 --- a/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp +++ b/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp @@ -75,7 +75,7 @@ enum dwarf_regnums { dwarf_pc }; -static const RegisterInfo g_register_infos_mips64[] = { +static RegisterInfo g_register_infos_mips64[] = { // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME // DWARF GENERIC PROCESS PLUGIN // LLDB NATIVE @@ -542,9 +542,24 @@ static const RegisterInfo g_register_infos_mips64[] = { static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos_mips64); +static bool g_register_info_names_constified = false; const lldb_private::RegisterInfo * ABISysV_mips64::GetRegisterInfoArray(uint32_t &count) { + // Make the C-string names and alt_names for the register infos into const + // C-string values by having the ConstString unique the names in the global + // constant C-string pool. + if (!g_register_info_names_constified) { + g_register_info_names_constified = true; + for (uint32_t i = 0; i < k_num_register_infos; ++i) { + if (g_register_infos_mips64[i].name) + g_register_infos_mips64[i].name = + ConstString(g_register_infos_mips64[i].name).GetCString(); + if (g_register_infos_mips64[i].alt_name) + g_register_infos_mips64[i].alt_name = + ConstString(g_register_infos_mips64[i].alt_name).GetCString(); + } + } count = k_num_register_infos; return g_register_infos_mips64; } diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp index 43ec2b1fa82f2d..94325c5f63a27d 100644 --- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp @@ -40,11 +40,12 @@ static uint64_t getNextRVA(const Object &Obj) { Obj.IsPE ? Obj.PeHeader.SectionAlignment : 1); } -static std::vector createGnuDebugLinkSectionContents(StringRef File) { +static Expected> +createGnuDebugLinkSectionContents(StringRef File) { ErrorOr> LinkTargetOrErr = MemoryBuffer::getFile(File); if (!LinkTargetOrErr) - error("'" + File + "': " + LinkTargetOrErr.getError().message()); + return createFileError(File, LinkTargetOrErr.getError()); auto LinkTarget = std::move(*LinkTargetOrErr); uint32_t CRC32 = llvm::crc32(arrayRefFromStringRef(LinkTarget->getBuffer())); @@ -81,12 +82,17 @@ static void addSection(Object &Obj, StringRef Name, ArrayRef Contents, Obj.addSections(Sec); } -static void addGnuDebugLink(Object &Obj, StringRef DebugLinkFile) { - std::vector Contents = +static Error addGnuDebugLink(Object &Obj, StringRef DebugLinkFile) { + Expected> Contents = createGnuDebugLinkSectionContents(DebugLinkFile); - addSection(Obj, ".gnu_debuglink", Contents, + if (!Contents) + return Contents.takeError(); + + addSection(Obj, ".gnu_debuglink", *Contents, IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE); + + return Error::success(); } static void setSectionFlags(Section &Sec, SectionFlag AllFlags) { @@ -174,8 +180,7 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) { Sym.Name = I->getValue(); } - // Actually do removals of symbols. - Obj.removeSymbols([&](const Symbol &Sym) { + auto ToRemove = [&](const Symbol &Sym) -> Expected { // For StripAll, all relocations have been stripped and we remove all // symbols. if (Config.StripAll || Config.StripAllGNU) @@ -184,11 +189,10 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) { if (Config.SymbolsToRemove.matches(Sym.Name)) { // Explicitly removing a referenced symbol is an error. if (Sym.Referenced) - reportError(Config.OutputFilename, - createStringError(llvm::errc::invalid_argument, - "not stripping symbol '%s' because it is " - "named in a relocation", - Sym.Name.str().c_str())); + return createStringError( + llvm::errc::invalid_argument, + "'" + Config.OutputFilename + "': not stripping symbol '" + + Sym.Name.str() + "' because it is named in a relocation"); return true; } @@ -213,7 +217,11 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) { } return false; - }); + }; + + // Actually do removals of symbols. + if (Error Err = Obj.removeSymbols(ToRemove)) + return Err; if (!Config.SetSectionFlags.empty()) for (Section &Sec : Obj.getMutableSections()) { @@ -239,7 +247,8 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) { } if (!Config.AddGnuDebugLink.empty()) - addGnuDebugLink(Obj, Config.AddGnuDebugLink); + if (Error E = addGnuDebugLink(Obj, Config.AddGnuDebugLink)) + return E; if (Config.AllowBrokenLinks || !Config.BuildIdLinkDir.empty() || Config.BuildIdLinkInput || Config.BuildIdLinkOutput || diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp index b07532c1dc3930..2a57f9707055f7 100644 --- a/llvm/tools/llvm-objcopy/COFF/Object.cpp +++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp @@ -37,12 +37,23 @@ const Symbol *Object::findSymbol(size_t UniqueId) const { return It->second; } -void Object::removeSymbols(function_ref ToRemove) { - Symbols.erase( - std::remove_if(std::begin(Symbols), std::end(Symbols), - [ToRemove](const Symbol &Sym) { return ToRemove(Sym); }), - std::end(Symbols)); +Error Object::removeSymbols( + function_ref(const Symbol &)> ToRemove) { + Error Errs = Error::success(); + Symbols.erase(std::remove_if(std::begin(Symbols), std::end(Symbols), + [ToRemove, &Errs](const Symbol &Sym) { + Expected ShouldRemove = ToRemove(Sym); + if (!ShouldRemove) { + Errs = joinErrors(std::move(Errs), + ShouldRemove.takeError()); + return false; + } + return *ShouldRemove; + }), + std::end(Symbols)); + updateSymbols(); + return Errs; } Error Object::markSymbols() { diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h index 78f8da00b8cd4d..31233783a90a0a 100644 --- a/llvm/tools/llvm-objcopy/COFF/Object.h +++ b/llvm/tools/llvm-objcopy/COFF/Object.h @@ -116,7 +116,7 @@ struct Object { const Symbol *findSymbol(size_t UniqueId) const; void addSymbols(ArrayRef NewSymbols); - void removeSymbols(function_ref ToRemove); + Error removeSymbols(function_ref(const Symbol &)> ToRemove); // Set the Referenced field on all Symbols, based on relocations in // all sections.