[llvm] Add adjustVMA option (PR #72870)

via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 20 05:52:16 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-binary-utilities

Author: None (pwprzybyla)

<details>
<summary>Changes</summary>

Add option to adjust section vma

---
Full diff: https://github.com/llvm/llvm-project/pull/72870.diff


4 Files Affected:

- (modified) llvm/include/llvm/ObjCopy/CommonConfig.h (+5) 
- (modified) llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp (+14-1) 
- (modified) llvm/tools/llvm-objcopy/ObjcopyOptions.cpp (+52) 
- (modified) llvm/tools/llvm-objcopy/ObjcopyOpts.td (+11) 


``````````diff
diff --git a/llvm/include/llvm/ObjCopy/CommonConfig.h b/llvm/include/llvm/ObjCopy/CommonConfig.h
index e7ce1e6f2c54d75..1dd9dbb29dc372b 100644
--- a/llvm/include/llvm/ObjCopy/CommonConfig.h
+++ b/llvm/include/llvm/ObjCopy/CommonConfig.h
@@ -245,6 +245,11 @@ struct CommonConfig {
   StringMap<uint64_t> SetSectionType;
   StringMap<StringRef> SymbolsToRename;
 
+  // Adjust section VMA and LMA
+  int64_t SectionVMA = 0;
+  StringRef SectionName;
+  bool SectionSet = false;
+
   // Symbol info specified by --add-symbol option.
   std::vector<NewSymbolInfo> SymbolsToAdd;
 
diff --git a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
index 9d02ba051a0a84b..245c11457db6c90 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
@@ -652,7 +652,20 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
         Sec.Align = I->second;
     }
   }
-
+  if (Config.SectionVMA != 0) {
+    for (SectionBase &Sec : Obj.sections()) {
+      bool AdjustThisSection = false;
+      if (Config.SectionName.empty() ||
+          Config.SectionName.contains(Sec.Name)){
+        AdjustThisSection = true;
+      }
+      if ((Sec.Flags & ELF::SHF_ALLOC) && AdjustThisSection){
+        if (Config.SectionSet)
+          Sec.Addr = 0;
+        Sec.Addr += Config.SectionVMA;
+      }
+    }
+  }
   if (Config.OnlyKeepDebug)
     for (auto &Sec : Obj.sections())
       if (Sec.Flags & SHF_ALLOC && Sec.Type != SHT_NOTE)
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index d33adb0b6a3e478..e2973c9171a408b 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -533,6 +533,45 @@ static Error loadNewSectionData(StringRef ArgValue, StringRef OptionName,
   return Error::success();
 }
 
+// readChangeSectionVMA reads the command line arguments and sets
+// sectionName and adjustValue of VMA and LMA addresses.
+static Error readChangeSectionVMA(StringRef ArgValue, StringRef OptionName,
+                                StringRef& SectionName, int64_t& AdjustValue, bool& setValue) {
+  SectionName = "";
+  AdjustValue = 0;
+  std::pair<StringRef, StringRef> SecPair;
+  if (ArgValue.contains("=")){
+    setValue = true;
+    SecPair = ArgValue.split("=");
+  }
+  else if (ArgValue.contains("+")){
+    setValue = false;
+    SecPair = ArgValue.split("+");
+  }
+  else if (ArgValue.contains("-")){
+    setValue = false;
+    SecPair = ArgValue.split("-");
+  }
+  else{
+    return createStringError(errc::invalid_argument,
+                            "bad format for " + OptionName + ": missing '='");
+  }
+  if (SecPair.second.empty())
+    return createStringError(errc::invalid_argument, "bad format for " +
+                                                         OptionName +
+                                                         ": missing offset of VMA");
+  SectionName = SecPair.first;
+  auto ChangeValue = getAsInteger<int64_t>(SecPair.second);
+  if (!ChangeValue)
+    return createStringError(ChangeValue.getError(),
+                              "Unable to parse adjustment value");
+  AdjustValue = *ChangeValue;
+  if (ArgValue.contains("-"))
+    AdjustValue *= -1;
+  return Error::success();
+}
+
+
 // parseObjcopyOptions returns the config and sets the input arguments. If a
 // help flag is set then parseObjcopyOptions will print the help messege and
 // exit.
@@ -828,6 +867,11 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
                                        Config.UpdateSection))
       return std::move(Err);
   }
+  for (auto *Arg : InputArgs.filtered(OBJCOPY_adjust_section_vma)) {
+    if (Error Err = readChangeSectionVMA(Arg->getValue(), "--adjust-section-vma",
+                                       Config.SectionName, Config.SectionVMA, Config.SectionSet))
+      return std::move(Err);
+  }
   for (auto *Arg : InputArgs.filtered(OBJCOPY_dump_section)) {
     StringRef Value(Arg->getValue());
     if (Value.split('=').second.empty())
@@ -967,6 +1011,14 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
       ELFConfig.EntryExpr = [Expr, EIncr](uint64_t EAddr) {
         return Expr(EAddr) + *EIncr;
       };
+    } else if(Arg->getOption().matches(OBJCOPY_adjust_vma)){
+      auto EIncr = getAsInteger<int64_t>(Arg->getValue());
+      if (!EIncr)
+        return createStringError(EIncr.getError(),
+                                 "bad entry point VMA increment: '%s'",
+                                 Arg->getValue());
+      Config.SectionName = "";
+      Config.SectionVMA = *EIncr;
     }
 
   if (Config.DecompressDebugSections &&
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOpts.td b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
index ea8828637222ac6..c8adb26fb100d32 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOpts.td
+++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
@@ -230,3 +230,14 @@ defm add_symbol
 defm update_section
     : Eq<"update-section", "Replace the contents of section <name> with contents from a file <file>">,
       MetaVarName<"name=file">;
+
+defm adjust_section_vma
+    : Eq<"adjust-section-vma", "Adjust VMA and LMA of section <section> by <value>"
+        ""
+        "">,
+      MetaVarName<".section{=|+|-}value">;
+defm adjust_vma
+    : Eq<"adjust-vma", "Add <incr> to the vma and lma address."
+        ""
+        "">,
+      MetaVarName<"incr">;

``````````

</details>


https://github.com/llvm/llvm-project/pull/72870


More information about the llvm-commits mailing list