summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-objcopy/llvm-objcopy.cpp')
-rw-r--r--llvm/tools/llvm-objcopy/llvm-objcopy.cpp51
1 files changed, 38 insertions, 13 deletions
diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
index ce2a1f1f259..345a11d8ba7 100644
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -178,6 +178,7 @@ struct CopyConfig {
bool StripSections = false;
bool StripUnneeded = false;
bool Weaken = false;
+ bool DecompressDebugSections = false;
DebugCompressionType CompressionType = DebugCompressionType::None;
};
@@ -430,33 +431,34 @@ static bool isCompressable(const SectionBase &Section) {
Section.Name != ".gdb_index";
}
-static void compressSections(const CopyConfig &Config, Object &Obj,
- SectionPred &RemovePred) {
- SmallVector<SectionBase *, 13> ToCompress;
+static void replaceDebugSections(
+ const CopyConfig &Config, Object &Obj, SectionPred &RemovePred,
+ function_ref<bool(const SectionBase &)> shouldReplace,
+ function_ref<SectionBase *(const SectionBase *)> addSection) {
+ SmallVector<SectionBase *, 13> ToReplace;
SmallVector<RelocationSection *, 13> RelocationSections;
for (auto &Sec : Obj.sections()) {
if (RelocationSection *R = dyn_cast<RelocationSection>(&Sec)) {
- if (isCompressable(*R->getSection()))
+ if (shouldReplace(*R->getSection()))
RelocationSections.push_back(R);
continue;
}
- if (isCompressable(Sec))
- ToCompress.push_back(&Sec);
+ if (shouldReplace(Sec))
+ ToReplace.push_back(&Sec);
}
- for (SectionBase *S : ToCompress) {
- CompressedSection &CS =
- Obj.addSection<CompressedSection>(*S, Config.CompressionType);
+ for (SectionBase *S : ToReplace) {
+ SectionBase *NewSection = addSection(S);
for (RelocationSection *RS : RelocationSections) {
if (RS->getSection() == S)
- RS->setSection(&CS);
+ RS->setSection(NewSection);
}
}
- RemovePred = [RemovePred](const SectionBase &Sec) {
- return isCompressable(Sec) || RemovePred(Sec);
+ RemovePred = [shouldReplace, RemovePred](const SectionBase &Sec) {
+ return shouldReplace(Sec) || RemovePred(Sec);
};
}
@@ -672,7 +674,19 @@ static void handleArgs(const CopyConfig &Config, Object &Obj,
}
if (Config.CompressionType != DebugCompressionType::None)
- compressSections(Config, Obj, RemovePred);
+ replaceDebugSections(Config, Obj, RemovePred, isCompressable,
+ [&Config, &Obj](const SectionBase *S) {
+ return &Obj.addSection<CompressedSection>(
+ *S, Config.CompressionType);
+ });
+ else if (Config.DecompressDebugSections)
+ replaceDebugSections(
+ Config, Obj, RemovePred,
+ [](const SectionBase &S) { return isa<CompressedSection>(&S); },
+ [&Obj](const SectionBase *S) {
+ auto CS = cast<CompressedSection>(S);
+ return &Obj.addSection<DecompressedSection>(*CS);
+ });
Obj.removeSections(RemovePred);
@@ -983,6 +997,8 @@ static DriverConfig parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
Config.DiscardAll = InputArgs.hasArg(OBJCOPY_discard_all);
Config.OnlyKeepDebug = InputArgs.hasArg(OBJCOPY_only_keep_debug);
Config.KeepFileSymbols = InputArgs.hasArg(OBJCOPY_keep_file_symbols);
+ Config.DecompressDebugSections =
+ InputArgs.hasArg(OBJCOPY_decompress_debug_sections);
for (auto Arg : InputArgs.filtered(OBJCOPY_localize_symbol))
Config.SymbolsToLocalize.push_back(Arg->getValue());
for (auto Arg : InputArgs.filtered(OBJCOPY_keep_global_symbol))
@@ -1002,6 +1018,15 @@ static DriverConfig parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
DriverConfig DC;
DC.CopyConfigs.push_back(std::move(Config));
+ if (Config.DecompressDebugSections &&
+ Config.CompressionType != DebugCompressionType::None) {
+ error("Cannot specify --compress-debug-sections at the same time as "
+ "--decompress-debug-sections at the same time");
+ }
+
+ if (Config.DecompressDebugSections && !zlib::isAvailable())
+ error("LLVM was not compiled with LLVM_ENABLE_ZLIB: cannot decompress.");
+
return DC;
}
OpenPOWER on IntegriCloud