[llvm] r354854 - [llvm-objcopy] Add --set-start, --change-start and --adjust-start

Eugene Leviant via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 26 01:24:22 PST 2019


Author: evgeny777
Date: Tue Feb 26 01:24:22 2019
New Revision: 354854

URL: http://llvm.org/viewvc/llvm-project?rev=354854&view=rev
Log:
[llvm-objcopy] Add --set-start, --change-start and --adjust-start

Differential revision: https://reviews.llvm.org/D58173

Added:
    llvm/trunk/test/tools/llvm-objcopy/ELF/change-entry-point.test
Modified:
    llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
    llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp
    llvm/trunk/tools/llvm-objcopy/CopyConfig.h
    llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
    llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td

Added: llvm/trunk/test/tools/llvm-objcopy/ELF/change-entry-point.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/change-entry-point.test?rev=354854&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/change-entry-point.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/change-entry-point.test Tue Feb 26 01:24:22 2019
@@ -0,0 +1,57 @@
+# RUN: yaml2obj %s -o %t
+
+# Test --set-start.
+# RUN: llvm-objcopy --set-start 0x1000 %t %t2
+# RUN: llvm-readobj --file-headers %t2 | FileCheck %s --check-prefix=SET
+# RUN: llvm-objcopy --set-start 4096 %t %t3
+# RUN: cmp %t2 %t3
+# RUN: llvm-objcopy --set-start 0x100000000 %t %t4
+# RUN: llvm-readobj --file-headers %t4 | FileCheck %s --check-prefix=SET-LARGE
+# RUN: not llvm-objcopy --set-start -123 %t %t5 2>&1 | FileCheck %s --check-prefix=SET-ERR
+
+# Test --change-start.
+# RUN: llvm-objcopy --change-start 0x50 %t %t6
+# RUN: llvm-readobj --file-headers %t6 | FileCheck %s --check-prefix=ADD
+# RUN: llvm-objcopy --change-start 0x100000000 %t %t7
+# RUN: llvm-readobj --file-headers %t7 | FileCheck %s --check-prefix=ADD-LARGE
+# RUN: llvm-objcopy --change-start -4353 %t %t8
+# RUN: llvm-readobj --file-headers %t8 | FileCheck %s --check-prefix=ADD-UNDERFLOW
+# RUN: llvm-objcopy --change-start -0x1101 %t %t9
+# RUN: cmp %t8 %t9
+# RUN: not llvm-objcopy --change-start -xyz %t %t10 2>&1 | FileCheck %s --check-prefix=ADD-ERR
+
+# Test --change-start after --set-start. Result should be 0x1150.
+# RUN: llvm-objcopy --set-start 0x1000 --change-start 0x100 --change-start 0x50 %t %t11
+# RUN: cmp %t6 %t11
+
+# If --set-start is after --change-start then --change-start has no effect.
+# RUN: llvm-objcopy --change-start 0x150 --set-start 0x1000 %t %t12
+# RUN: cmp %t2 %t12
+
+# --adjust-start is an alias for --change-start.
+# RUN: llvm-objcopy --adjust-start -0x1101 %t %t13
+# RUN: cmp %t9 %t13
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+  Entry:           0x1100
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x1000
+    AddressAlign:    0x0000000000001000
+    Size:            0x200
+
+# SET: Entry: 0x1000
+# ADD: Entry: 0x1150
+# SUB: Entry: 0x1080
+# SET-ERR: error: bad entry point address: '-123'
+# SET-LARGE: Entry: 0x100000000
+# ADD-LARGE: Entry: 0x100001100
+# ADD-ERR: error: bad entry point increment: '-xyz'
+# ADD-UNDERFLOW: Entry: 0xFFFFFFFFFFFFFFFF

Modified: llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp?rev=354854&r1=354853&r2=354854&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp Tue Feb 26 01:24:22 2019
@@ -186,7 +186,7 @@ static Error handleArgs(const CopyConfig
       Config.PreserveDates || Config.StripDWO || Config.StripNonAlloc ||
       Config.StripSections || Config.Weaken || Config.DecompressDebugSections ||
       Config.DiscardMode == DiscardType::Locals ||
-      !Config.SymbolsToAdd.empty()) {
+      !Config.SymbolsToAdd.empty() || Config.EntryExpr) {
     return createStringError(llvm::errc::invalid_argument,
                              "Option not supported by llvm-objcopy for COFF");
   }

Modified: llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp?rev=354854&r1=354853&r2=354854&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp Tue Feb 26 01:24:22 2019
@@ -371,6 +371,14 @@ static Error addSymbolsToRenameFromFile(
   }
   return Error::success();
 }
+
+template <class T> static ErrorOr<T> getAsInteger(StringRef Val) {
+  T Result;
+  if (Val.getAsInteger(0, Result))
+    return errc::invalid_argument;
+  return Result;
+}
+
 // ParseObjcopyOptions returns the config and sets the input arguments. If a
 // help flag is set then ParseObjcopyOptions will print the help messege and
 // exit.
@@ -617,6 +625,27 @@ Expected<DriverConfig> parseObjcopyOptio
 
   Config.PreserveDates = InputArgs.hasArg(OBJCOPY_preserve_dates);
 
+  for (auto Arg : InputArgs)
+    if (Arg->getOption().matches(OBJCOPY_set_start)) {
+      auto EAddr = getAsInteger<uint64_t>(Arg->getValue());
+      if (!EAddr)
+        return createStringError(
+            EAddr.getError(), "bad entry point address: '%s'", Arg->getValue());
+
+      Config.EntryExpr = [EAddr](uint64_t) { return *EAddr; };
+    } else if (Arg->getOption().matches(OBJCOPY_change_start)) {
+      auto EIncr = getAsInteger<int64_t>(Arg->getValue());
+      if (!EIncr)
+        return createStringError(EIncr.getError(),
+                                 "bad entry point increment: '%s'",
+                                 Arg->getValue());
+      auto Expr = Config.EntryExpr ? std::move(Config.EntryExpr)
+                                   : [](uint64_t A) { return A; };
+      Config.EntryExpr = [Expr, EIncr](uint64_t EAddr) {
+        return Expr(EAddr) + *EIncr;
+      };
+    }
+
   if (Config.DecompressDebugSections &&
       Config.CompressionType != DebugCompressionType::None) {
     return createStringError(

Modified: llvm/trunk/tools/llvm-objcopy/CopyConfig.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/CopyConfig.h?rev=354854&r1=354853&r2=354854&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/CopyConfig.h (original)
+++ llvm/trunk/tools/llvm-objcopy/CopyConfig.h Tue Feb 26 01:24:22 2019
@@ -113,6 +113,12 @@ struct CopyConfig {
   StringMap<SectionFlagsUpdate> SetSectionFlags;
   StringMap<StringRef> SymbolsToRename;
 
+  // ELF entry point address expression. The input parameter is an entry point
+  // address in the input ELF file. The entry address in the output file is
+  // calculated with EntryExpr(input_address), when either --set-start or
+  // --change-start is used.
+  std::function<uint64_t(uint64_t)> EntryExpr;
+
   // Boolean options
   bool DeterministicArchives = true;
   bool ExtractDWO = false;

Modified: llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp?rev=354854&r1=354853&r2=354854&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp Tue Feb 26 01:24:22 2019
@@ -574,6 +574,8 @@ static Error handleArgs(const CopyConfig
                                Sec ? SYMBOL_SIMPLE_INDEX : SHN_ABS, 0);
   }
 
+  if (Config.EntryExpr)
+    Obj.Entry = Config.EntryExpr(Obj.Entry);
   return Error::success();
 }
 

Modified: llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td?rev=354854&r1=354853&r2=354854&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td (original)
+++ llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td Tue Feb 26 01:24:22 2019
@@ -238,6 +238,16 @@ def regex
     : Flag<["-", "--"], "regex">,
       HelpText<"Permit regular expressions in name comparison">;
 
+defm set_start : Eq<"set-start", "Set the start address to <addr>. Overrides "
+                    "any previous --change-start or --adjust-start values.">,
+                 MetaVarName<"addr">;
+defm change_start : Eq<"change-start", "Add <incr> to the start address. Can be "                        
+                       "specified multiple times, all values will be applied "
+                       "cumulatively.">,
+                    MetaVarName<"incr">;
+def adjust_start : JoinedOrSeparate<["-", "--"], "adjust-start">,
+                   Alias<change_start>;
+
 defm add_symbol
     : Eq<"add-symbol", "Add new symbol <name> to .symtab. Accepted flags: "
          "global, local, weak, default, hidden, file, section, object, "




More information about the llvm-commits mailing list