]> granicus.if.org Git - llvm/commitdiff
[llvm-objcopy] Add --prefix-alloc-sections
authorJames Henderson <jh7370@my.bristol.ac.uk>
Wed, 8 May 2019 09:49:35 +0000 (09:49 +0000)
committerJames Henderson <jh7370@my.bristol.ac.uk>
Wed, 8 May 2019 09:49:35 +0000 (09:49 +0000)
This patch adds support for --prefix-alloc-sections, which adds a prefix
to every allocated section names.

It adds a prefix after renaming section names by --rename-section as GNU
objcopy does.

Fixes PR41266: https://bugs.llvm.org/show_bug.cgi?id=41266

Differential Revision: https://reviews.llvm.org/D60042

Patch by Seiya Nuta.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360233 91177308-0d34-0410-b5e6-96231b3b80d8

test/tools/llvm-objcopy/ELF/prefix-alloc-sections-dynrelocsec.test [new file with mode: 0644]
test/tools/llvm-objcopy/ELF/prefix-alloc-sections.test [new file with mode: 0644]
test/tools/llvm-objcopy/ELF/rename-section-and-prefix-alloc-sections.test [new file with mode: 0644]
tools/llvm-objcopy/COFF/COFFObjcopy.cpp
tools/llvm-objcopy/CopyConfig.cpp
tools/llvm-objcopy/CopyConfig.h
tools/llvm-objcopy/ELF/ELFObjcopy.cpp
tools/llvm-objcopy/ObjcopyOpts.td

diff --git a/test/tools/llvm-objcopy/ELF/prefix-alloc-sections-dynrelocsec.test b/test/tools/llvm-objcopy/ELF/prefix-alloc-sections-dynrelocsec.test
new file mode 100644 (file)
index 0000000..9e267f6
--- /dev/null
@@ -0,0 +1,5 @@
+# RUN: llvm-objcopy --prefix-alloc-sections=.prefix %p/Inputs/dynrel.elf %t
+# RUN: llvm-readobj --sections %t | FileCheck %s
+
+# CHECK: Name: .prefix.rela.plt
+# CHECK: Name: .prefix.plt
diff --git a/test/tools/llvm-objcopy/ELF/prefix-alloc-sections.test b/test/tools/llvm-objcopy/ELF/prefix-alloc-sections.test
new file mode 100644 (file)
index 0000000..4cb9df5
--- /dev/null
@@ -0,0 +1,36 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy --prefix-alloc-sections=.prefix %t %t2
+# RUN: llvm-readobj --sections %t2 | FileCheck %s
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .foo
+    Type:            SHT_PROGBITS
+    Flags:           [  ]
+  - Name:            .prefix.already_prefixed
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Info:            .text
+  - Name:            .rela.data
+    Type:            SHT_RELA
+    Info:            .data
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+
+# CHECK: Name: .foo
+# CHECK: Name: .prefix.prefix.already_prefixed
+# CHECK: Name: .prefix.text
+# CHECK: Name: .rel.prefix.text
+# CHECK: Name: .rela.prefix.data
+# CHECK: Name: .prefix.data
diff --git a/test/tools/llvm-objcopy/ELF/rename-section-and-prefix-alloc-sections.test b/test/tools/llvm-objcopy/ELF/rename-section-and-prefix-alloc-sections.test
new file mode 100644 (file)
index 0000000..fd642b6
--- /dev/null
@@ -0,0 +1,32 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy --rename-section=.text=.text2 --rename-section=.data=.data2 --prefix-alloc-sections=.prefix %t %t2
+# RUN: llvm-readobj --sections %t2 | FileCheck %s
+
+# .text/.rel.text and .data/.rela.data are the cases when the relocation section
+# comes after/before its target section respectively. We handle them in different
+# ways to perform both --rename-section and --prefix-alloc-sections in one pass.
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Info:            .text
+  - Name:            .rela.data
+    Type:            SHT_RELA
+    Info:            .data
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+
+# CHECK: Name: .prefix.text2
+# CHECK: Name: .rel.prefix.text2
+# CHECK: Name: .rela.prefix.data2
+# CHECK: Name: .prefix.data2
index ace4ebd13ca842574472b5e1c0f381bd2241b4d4..1f5509e03c2ebf09872827500bd26508754b33a7 100644 (file)
@@ -177,15 +177,15 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
   if (Config.AllowBrokenLinks || !Config.BuildIdLinkDir.empty() ||
       Config.BuildIdLinkInput || Config.BuildIdLinkOutput ||
       !Config.SplitDWO.empty() || !Config.SymbolsPrefix.empty() ||
-      !Config.AddSection.empty() || !Config.DumpSection.empty() ||
-      !Config.KeepSection.empty() || !Config.SymbolsToGlobalize.empty() ||
-      !Config.SymbolsToKeep.empty() || !Config.SymbolsToLocalize.empty() ||
-      !Config.SymbolsToWeaken.empty() || !Config.SymbolsToKeepGlobal.empty() ||
-      !Config.SectionsToRename.empty() || !Config.SetSectionFlags.empty() ||
-      !Config.SymbolsToRename.empty() || Config.ExtractDWO ||
-      Config.KeepFileSymbols || Config.LocalizeHidden || Config.PreserveDates ||
-      Config.StripDWO || Config.StripNonAlloc || Config.StripSections ||
-      Config.Weaken || Config.DecompressDebugSections ||
+      !Config.AllocSectionsPrefix.empty() || !Config.AddSection.empty() ||
+      !Config.DumpSection.empty() || !Config.KeepSection.empty() ||
+      !Config.SymbolsToGlobalize.empty() || !Config.SymbolsToKeep.empty() ||
+      !Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() ||
+      !Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() ||
+      !Config.SetSectionFlags.empty() || !Config.SymbolsToRename.empty() ||
+      Config.ExtractDWO || Config.KeepFileSymbols || Config.LocalizeHidden ||
+      Config.PreserveDates || Config.StripDWO || Config.StripNonAlloc ||
+      Config.StripSections || Config.Weaken || Config.DecompressDebugSections ||
       Config.DiscardMode == DiscardType::Locals ||
       !Config.SymbolsToAdd.empty() || Config.EntryExpr) {
     return createStringError(llvm::errc::invalid_argument,
index 3ea4a95096280651ad507bfc537500f5f872f2cb..94c0a5bc6316b8ae4efe0c0be5395682b52b0427 100644 (file)
@@ -499,6 +499,8 @@ Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
         InputArgs.getLastArgValue(OBJCOPY_build_id_link_output);
   Config.SplitDWO = InputArgs.getLastArgValue(OBJCOPY_split_dwo);
   Config.SymbolsPrefix = InputArgs.getLastArgValue(OBJCOPY_prefix_symbols);
+  Config.AllocSectionsPrefix =
+      InputArgs.getLastArgValue(OBJCOPY_prefix_alloc_sections);
 
   for (auto Arg : InputArgs.filtered(OBJCOPY_redefine_symbol)) {
     if (!StringRef(Arg->getValue()).contains('='))
index fd548cc76e3152585ef17cf451bcd9ef76394bc5..65d1d27e841c9b31b4f99d7f282a5fefee810f81 100644 (file)
@@ -120,6 +120,7 @@ struct CopyConfig {
   Optional<StringRef> BuildIdLinkOutput;
   StringRef SplitDWO;
   StringRef SymbolsPrefix;
+  StringRef AllocSectionsPrefix;
   DiscardType DiscardMode = DiscardType::None;
 
   // Repeated options
index 9b21190000e2070cb1ff9bcdce331f7295750956..bed2414559f797120924b2546e996fba1ca0ee22 100644 (file)
@@ -13,6 +13,7 @@
 #include "llvm-objcopy.h"
 
 #include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
@@ -580,7 +581,8 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj,
   if (Error E = updateAndRemoveSymbols(Config, Obj))
     return E;
 
-  if (!Config.SectionsToRename.empty()) {
+  if (!Config.SectionsToRename.empty() || !Config.AllocSectionsPrefix.empty()) {
+    DenseSet<SectionBase *> PrefixedSections;
     for (auto &Sec : Obj.sections()) {
       const auto Iter = Config.SectionsToRename.find(Sec.Name);
       if (Iter != Config.SectionsToRename.end()) {
@@ -589,6 +591,60 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj,
         if (SR.NewFlags.hasValue())
           setSectionFlagsAndType(Sec, SR.NewFlags.getValue());
       }
+
+      // Add a prefix to allocated sections and their relocation sections. This
+      // should be done after renaming the section by Config.SectionToRename to
+      // imitate the GNU objcopy behavior.
+      if (!Config.AllocSectionsPrefix.empty()) {
+        if (Sec.Flags & SHF_ALLOC) {
+          Sec.Name = (Config.AllocSectionsPrefix + Sec.Name).str();
+          PrefixedSections.insert(&Sec);
+
+        // Rename relocation sections associated to the allocated sections.
+        // For example, if we rename .text to .prefix.text, we also rename
+        // .rel.text to .rel.prefix.text.
+        //
+        // Dynamic relocation sections (SHT_REL[A] with SHF_ALLOC) are handled
+        // above, e.g., .rela.plt is renamed to .prefix.rela.plt, not
+        // .rela.prefix.plt since GNU objcopy does so.
+        } else if (auto *RelocSec = dyn_cast<RelocationSectionBase>(&Sec)) {
+          auto *TargetSec = RelocSec->getSection();
+          if (TargetSec && (TargetSec->Flags & SHF_ALLOC)) {
+            StringRef prefix;
+            switch (Sec.Type) {
+            case SHT_REL:
+              prefix = ".rel";
+              break;
+            case SHT_RELA:
+              prefix = ".rela";
+              break;
+            default:
+              continue;
+            }
+
+            // If the relocation section comes *after* the target section, we
+            // don't add Config.AllocSectionsPrefix because we've already added
+            // the prefix to TargetSec->Name. Otherwise, if the relocation
+            // section comes *before* the target section, we add the prefix.
+            if (PrefixedSections.count(TargetSec)) {
+              Sec.Name = (prefix + TargetSec->Name).str();
+            } else {
+              const auto Iter = Config.SectionsToRename.find(TargetSec->Name);
+              if (Iter != Config.SectionsToRename.end()) {
+                // Both `--rename-section` and `--prefix-alloc-sections` are
+                // given but the target section is not yet renamed.
+                Sec.Name =
+                    (prefix + Config.AllocSectionsPrefix + Iter->second.NewName)
+                        .str();
+              } else {
+                Sec.Name =
+                    (prefix + Config.AllocSectionsPrefix + TargetSec->Name)
+                        .str();
+              }
+            }
+          }
+        }
+      }
     }
   }
 
index 326a459ba355fdbe4c6cd4da92bcc335a57c0a60..33545a521db5a96bbfd11719ef13b1e4eb7bac79 100644 (file)
@@ -238,6 +238,10 @@ defm prefix_symbols
     : Eq<"prefix-symbols", "Add <prefix> to the start of every symbol name">,
       MetaVarName<"prefix">;
 
+defm prefix_alloc_sections
+    : Eq<"prefix-alloc-sections", "Add <prefix> to the start of every allocated section name">,
+      MetaVarName<"prefix">;
+
 def version : Flag<["--"], "version">,
               HelpText<"Print the version and exit.">;
 def V : Flag<["-"], "V">, Alias<version>;