[llvm] Add adjustVMA option (PR #72870)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 20 06:10:40 PST 2023
https://github.com/pwprzybyla updated https://github.com/llvm/llvm-project/pull/72870
>From 306d9ea7b709dcb3ae046e456763da0cd3d9cc8e Mon Sep 17 00:00:00 2001
From: Piotr Przybyla <piotr.przybyla at arm.com>
Date: Mon, 20 Nov 2023 13:50:21 +0000
Subject: [PATCH] Add adjustVMA option
Add option to adjust section vma
---
llvm/include/llvm/ObjCopy/CommonConfig.h | 5 ++
llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp | 14 ++++-
llvm/tools/llvm-objcopy/ObjcopyOptions.cpp | 58 ++++++++++++++++--
llvm/tools/llvm-objcopy/ObjcopyOpts.td | 68 +++++++++++++---------
4 files changed, 114 insertions(+), 31 deletions(-)
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..ac84ec21a3f400e 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
@@ -652,7 +652,19 @@ 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..c88450a833fb7b6 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -533,6 +533,42 @@ 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.
@@ -606,8 +642,8 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
MatchStyle SectionMatchStyle = InputArgs.hasArg(OBJCOPY_regex)
? MatchStyle::Regex
: MatchStyle::Wildcard;
- MatchStyle SymbolMatchStyle
- = InputArgs.hasArg(OBJCOPY_regex) ? MatchStyle::Regex
+ MatchStyle SymbolMatchStyle =
+ InputArgs.hasArg(OBJCOPY_regex) ? MatchStyle::Regex
: InputArgs.hasArg(OBJCOPY_wildcard) ? MatchStyle::Wildcard
: MatchStyle::Literal;
StringRef InputFormat, OutputFormat;
@@ -828,6 +864,12 @@ 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 +1009,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 &&
@@ -1251,8 +1301,8 @@ objcopy::parseStripOptions(ArrayRef<const char *> RawArgsArr,
"--regex and --wildcard are incompatible");
MatchStyle SectionMatchStyle =
InputArgs.hasArg(STRIP_regex) ? MatchStyle::Regex : MatchStyle::Wildcard;
- MatchStyle SymbolMatchStyle
- = InputArgs.hasArg(STRIP_regex) ? MatchStyle::Regex
+ MatchStyle SymbolMatchStyle =
+ InputArgs.hasArg(STRIP_regex) ? MatchStyle::Regex
: InputArgs.hasArg(STRIP_wildcard) ? MatchStyle::Wildcard
: MatchStyle::Literal;
ELFConfig.AllowBrokenLinks = InputArgs.hasArg(STRIP_allow_broken_links);
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOpts.td b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
index ea8828637222ac6..a5c94ab90bba7a4 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOpts.td
+++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
@@ -24,17 +24,20 @@ def O : JoinedOrSeparate<["-"], "O">,
Alias<output_target>,
HelpText<"Alias for --output-target">;
-defm new_symbol_visibility : Eq<"new-symbol-visibility", "Visibility of "
- "symbols generated for binary input or added"
- " with --add-symbol unless otherwise"
- " specified. The default value is 'default'">;
+defm new_symbol_visibility
+ : Eq<"new-symbol-visibility", "Visibility of "
+ "symbols generated for binary input or added"
+ " with --add-symbol unless otherwise"
+ " specified. The default value is 'default'">;
def compress_debug_sections
: Joined<["--"], "compress-debug-sections=">,
MetaVarName<"format">,
- HelpText<"Compress DWARF debug sections using specified format. Supported "
- "formats: zlib, zstd. Select zlib if <format> is omitted">;
-def : Flag<["--"], "compress-debug-sections">, Alias<compress_debug_sections>,
+ HelpText<
+ "Compress DWARF debug sections using specified format. Supported "
+ "formats: zlib, zstd. Select zlib if <format> is omitted">;
+def : Flag<["--"], "compress-debug-sections">,
+ Alias<compress_debug_sections>,
AliasArgs<["zlib"]>;
def decompress_debug_sections : Flag<["--"], "decompress-debug-sections">,
HelpText<"Decompress DWARF debug sections">;
@@ -64,7 +67,7 @@ defm redefine_symbols
"contains two symbols per line separated with whitespace and may "
"contain comments beginning with '#'. Leading and trailing "
"whitespace is stripped from each line. May be repeated to read "
- "symbols from many files">,
+ "symbols from many files">,
MetaVarName<"filename">;
defm only_section : Eq<"only-section", "Remove all but <section>">,
@@ -93,9 +96,7 @@ defm set_section_type
"Set the type of section <section> to the integer <type>">,
MetaVarName<"section=type">;
-def S : Flag<["-"], "S">,
- Alias<strip_all>,
- HelpText<"Alias for --strip-all">;
+def S : Flag<["-"], "S">, Alias<strip_all>, HelpText<"Alias for --strip-all">;
def strip_dwo : Flag<["--"], "strip-dwo">,
HelpText<"Remove all DWARF .dwo sections from file">;
def strip_non_alloc
@@ -111,10 +112,8 @@ defm strip_unneeded_symbols
"if they are not needed by relocations">,
MetaVarName<"filename">;
-defm subsystem
- : Eq<"subsystem",
- "Set PE subsystem and version">,
- MetaVarName<"name[:version]">;
+defm subsystem : Eq<"subsystem", "Set PE subsystem and version">,
+ MetaVarName<"name[:version]">;
def extract_dwo
: Flag<["--"], "extract-dwo">,
@@ -205,28 +204,45 @@ defm prefix_symbols
MetaVarName<"prefix">;
defm prefix_alloc_sections
- : Eq<"prefix-alloc-sections", "Add <prefix> to the start of every allocated section name">,
+ : Eq<"prefix-alloc-sections",
+ "Add <prefix> to the start of every allocated section name">,
MetaVarName<"prefix">;
-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">;
+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>,
HelpText<"Alias for --change-start">;
defm add_symbol
- : Eq<"add-symbol", "Add new symbol <name> to .symtab. Accepted flags: "
- "global, local, weak, default, hidden, protected, file, section, object, "
+ : Eq<"add-symbol",
+ "Add new symbol <name> to .symtab. Accepted flags: "
+ "global, local, weak, default, hidden, protected, file, section, "
+ "object, "
"function, indirect-function. Accepted but ignored for "
"compatibility: debug, constructor, warning, indirect, synthetic, "
"unique-object, before">,
MetaVarName<"name=[section:]value[,flags]">;
defm update_section
- : Eq<"update-section", "Replace the contents of section <name> with contents from a file <file>">,
+ : 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">;
More information about the llvm-commits
mailing list