[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