summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/tools/llvm-objcopy/CopyConfig.cpp17
-rw-r--r--llvm/tools/llvm-objcopy/CopyConfig.h2
-rw-r--r--llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp3
-rw-r--r--llvm/tools/llvm-objcopy/ELF/Object.cpp23
-rw-r--r--llvm/tools/llvm-objcopy/ELF/Object.h5
5 files changed, 30 insertions, 20 deletions
diff --git a/llvm/tools/llvm-objcopy/CopyConfig.cpp b/llvm/tools/llvm-objcopy/CopyConfig.cpp
index 94c0a5bc631..0b0023f52d8 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.cpp
+++ b/llvm/tools/llvm-objcopy/CopyConfig.cpp
@@ -16,6 +16,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Errc.h"
+#include "llvm/Support/JamCRC.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/StringSaver.h"
#include <memory>
@@ -490,6 +491,22 @@ Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
}
Config.AddGnuDebugLink = InputArgs.getLastArgValue(OBJCOPY_add_gnu_debuglink);
+ // The gnu_debuglink's target is expected to not change or else its CRC would
+ // become invalidated and get rejected. We can avoid recalculating the
+ // checksum for every target file inside an archive by precomputing the CRC
+ // here. This prevents a significant amount of I/O.
+ if (!Config.AddGnuDebugLink.empty()) {
+ auto DebugOrErr = MemoryBuffer::getFile(Config.AddGnuDebugLink);
+ if (!DebugOrErr)
+ return createFileError(Config.AddGnuDebugLink, DebugOrErr.getError());
+ auto Debug = std::move(*DebugOrErr);
+ JamCRC CRC;
+ CRC.update(
+ ArrayRef<char>(Debug->getBuffer().data(), Debug->getBuffer().size()));
+ // The CRC32 value needs to be complemented because the JamCRC doesn't
+ // finalize the CRC32 value.
+ Config.GnuDebugLinkCRC32 = ~CRC.getCRC();
+ }
Config.BuildIdLinkDir = InputArgs.getLastArgValue(OBJCOPY_build_id_link_dir);
if (InputArgs.hasArg(OBJCOPY_build_id_link_input))
Config.BuildIdLinkInput =
diff --git a/llvm/tools/llvm-objcopy/CopyConfig.h b/llvm/tools/llvm-objcopy/CopyConfig.h
index 65d1d27e841..7607d3b34a3 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.h
+++ b/llvm/tools/llvm-objcopy/CopyConfig.h
@@ -115,6 +115,8 @@ struct CopyConfig {
// Advanced options
StringRef AddGnuDebugLink;
+ // Cached gnu_debuglink's target CRC
+ uint32_t GnuDebugLinkCRC32;
StringRef BuildIdLinkDir;
Optional<StringRef> BuildIdLinkInput;
Optional<StringRef> BuildIdLinkOutput;
diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
index bed2414559f..27b56f4622d 100644
--- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
@@ -685,7 +685,8 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj,
}
if (!Config.AddGnuDebugLink.empty())
- Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink);
+ Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink,
+ Config.GnuDebugLinkCRC32);
for (const NewSymbolInfo &SI : Config.SymbolsToAdd) {
SectionBase *Sec = Obj.findSection(SI.SectionName);
diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp
index d66948a0f46..09d6d827465 100644
--- a/llvm/tools/llvm-objcopy/ELF/Object.cpp
+++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp
@@ -755,7 +755,7 @@ void Section::initialize(SectionTableRef SecTable) {
void Section::finalize() { this->Link = LinkSection ? LinkSection->Index : 0; }
-void GnuDebugLinkSection::init(StringRef File, StringRef Data) {
+void GnuDebugLinkSection::init(StringRef File) {
FileName = sys::path::filename(File);
// The format for the .gnu_debuglink starts with the file name and is
// followed by a null terminator and then the CRC32 of the file. The CRC32
@@ -770,21 +770,12 @@ void GnuDebugLinkSection::init(StringRef File, StringRef Data) {
// establish the order that sections should go in. By using the maximum
// possible offset we cause this section to wind up at the end.
OriginalOffset = std::numeric_limits<uint64_t>::max();
- JamCRC CRC;
- CRC.update(ArrayRef<char>(Data.data(), Data.size()));
- // The CRC32 value needs to be complemented because the JamCRC dosn't
- // finalize the CRC32 value. It also dosn't negate the initial CRC32 value
- // but it starts by default at 0xFFFFFFFF which is the complement of zero.
- CRC32 = ~CRC.getCRC();
-}
-
-GnuDebugLinkSection::GnuDebugLinkSection(StringRef File) : FileName(File) {
- // Read in the file to compute the CRC of it.
- auto DebugOrErr = MemoryBuffer::getFile(File);
- if (!DebugOrErr)
- error("'" + File + "': " + DebugOrErr.getError().message());
- auto Debug = std::move(*DebugOrErr);
- init(File, Debug->getBuffer());
+}
+
+GnuDebugLinkSection::GnuDebugLinkSection(StringRef File,
+ uint32_t PrecomputedCRC)
+ : FileName(File), CRC32(PrecomputedCRC) {
+ init(File);
}
template <class ELFT>
diff --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/tools/llvm-objcopy/ELF/Object.h
index 54e72d29aba..9298518bcce 100644
--- a/llvm/tools/llvm-objcopy/ELF/Object.h
+++ b/llvm/tools/llvm-objcopy/ELF/Object.h
@@ -18,7 +18,6 @@
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/FileOutputBuffer.h"
-#include "llvm/Support/JamCRC.h"
#include <cstddef>
#include <cstdint>
#include <functional>
@@ -703,11 +702,11 @@ private:
StringRef FileName;
uint32_t CRC32;
- void init(StringRef File, StringRef Data);
+ void init(StringRef File);
public:
// If we add this section from an external source we can use this ctor.
- explicit GnuDebugLinkSection(StringRef File);
+ explicit GnuDebugLinkSection(StringRef File, uint32_t PrecomputedCRC);
void accept(SectionVisitor &Visitor) const override;
void accept(MutableSectionVisitor &Visitor) override;
};
OpenPOWER on IntegriCloud