[llvm] Add adjustVMA option (PR #72870)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 14 04:40:01 PST 2024
https://github.com/pwprzybyla updated https://github.com/llvm/llvm-project/pull/72870
>From 8b4fbe07ebbe14e0f7e5a242dcaf53c1965338f0 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/docs/CommandGuide/llvm-objcopy.rst | 7 +
llvm/include/llvm/ObjCopy/CommonConfig.h | 9 ++
llvm/lib/ObjCopy/ConfigManager.cpp | 11 +-
llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp | 28 ++++
.../llvm-objcopy/ELF/adjust-section-vma.test | 130 ++++++++++++++++
.../tools/llvm-objcopy/ELF/adjust-vma.test | 146 ++++++++++++++++++
llvm/tools/llvm-objcopy/ObjcopyOptions.cpp | 71 ++++++++-
llvm/tools/llvm-objcopy/ObjcopyOpts.td | 8 +
8 files changed, 402 insertions(+), 8 deletions(-)
create mode 100644 llvm/test/tools/llvm-objcopy/ELF/adjust-section-vma.test
create mode 100644 llvm/test/tools/llvm-objcopy/ELF/adjust-vma.test
diff --git a/llvm/docs/CommandGuide/llvm-objcopy.rst b/llvm/docs/CommandGuide/llvm-objcopy.rst
index 0233a4f7b2f045..4a6b97443c23c2 100644
--- a/llvm/docs/CommandGuide/llvm-objcopy.rst
+++ b/llvm/docs/CommandGuide/llvm-objcopy.rst
@@ -483,6 +483,13 @@ them.
Mark all defined global symbols as weak in the output.
+.. option:: --adjust-vma <value>
+ Add ``<value>`` to start address and VMA and LMA addresses of sections.
+
+.. option:: --adjust-section-vma <name>{+|-|=}<value>
+ Adjust section ``<name>`` VMA and LMA address by ``<value>``.
+ Address can be either increased (+), decreased (-) or set (=) to ``<value>``.
+
MACH-O-SPECIFIC OPTIONS
-----------------------
diff --git a/llvm/include/llvm/ObjCopy/CommonConfig.h b/llvm/include/llvm/ObjCopy/CommonConfig.h
index e7ce1e6f2c54d7..0dcfee805170ac 100644
--- a/llvm/include/llvm/ObjCopy/CommonConfig.h
+++ b/llvm/include/llvm/ObjCopy/CommonConfig.h
@@ -84,6 +84,14 @@ struct SectionFlagsUpdate {
SectionFlag NewFlags;
};
+enum class SectionUpdateType { Increase, Decrease, Set };
+
+struct SectionVMAUpdate {
+ int64_t UpdateValue;
+ StringRef UpdateSection;
+ SectionUpdateType UpdateAs;
+};
+
enum class DiscardType {
None, // Default
All, // --discard-all (-x)
@@ -244,6 +252,7 @@ struct CommonConfig {
StringMap<SectionFlagsUpdate> SetSectionFlags;
StringMap<uint64_t> SetSectionType;
StringMap<StringRef> SymbolsToRename;
+ StringMap<SectionVMAUpdate> AdjustSectionVMA;
// Symbol info specified by --add-symbol option.
std::vector<NewSymbolInfo> SymbolsToAdd;
diff --git a/llvm/lib/ObjCopy/ConfigManager.cpp b/llvm/lib/ObjCopy/ConfigManager.cpp
index bccb2903e62aeb..7e29bf2872290b 100644
--- a/llvm/lib/ObjCopy/ConfigManager.cpp
+++ b/llvm/lib/ObjCopy/ConfigManager.cpp
@@ -23,7 +23,8 @@ Expected<const COFFConfig &> ConfigManager::getCOFFConfig() const {
Common.ExtractDWO || Common.PreserveDates || Common.StripDWO ||
Common.StripNonAlloc || Common.StripSections || Common.Weaken ||
Common.DecompressDebugSections ||
- Common.DiscardMode == DiscardType::Locals || !Common.SymbolsToAdd.empty())
+ Common.DiscardMode == DiscardType::Locals ||
+ !Common.SymbolsToAdd.empty() || !Common.AdjustSectionVMA.empty())
return createStringError(llvm::errc::invalid_argument,
"option is not supported for COFF");
@@ -42,7 +43,8 @@ Expected<const MachOConfig &> ConfigManager::getMachOConfig() const {
Common.PreserveDates || Common.StripAllGNU || Common.StripDWO ||
Common.StripNonAlloc || Common.StripSections ||
Common.DecompressDebugSections || Common.StripUnneeded ||
- Common.DiscardMode == DiscardType::Locals || !Common.SymbolsToAdd.empty())
+ Common.DiscardMode == DiscardType::Locals ||
+ !Common.SymbolsToAdd.empty() || !Common.AdjustSectionVMA.empty())
return createStringError(llvm::errc::invalid_argument,
"option is not supported for MachO");
@@ -60,7 +62,7 @@ Expected<const WasmConfig &> ConfigManager::getWasmConfig() const {
!Common.SymbolsToWeaken.empty() || !Common.SymbolsToKeepGlobal.empty() ||
!Common.SectionsToRename.empty() || !Common.SetSectionAlignment.empty() ||
!Common.SetSectionFlags.empty() || !Common.SetSectionType.empty() ||
- !Common.SymbolsToRename.empty())
+ !Common.SymbolsToRename.empty() || !Common.AdjustSectionVMA.empty())
return createStringError(llvm::errc::invalid_argument,
"only flags for section dumping, removal, and "
"addition are supported");
@@ -86,7 +88,8 @@ Expected<const XCOFFConfig &> ConfigManager::getXCOFFConfig() const {
Common.ExtractMainPartition || Common.OnlyKeepDebug ||
Common.PreserveDates || Common.StripAllGNU || Common.StripDWO ||
Common.StripDebug || Common.StripNonAlloc || Common.StripSections ||
- Common.Weaken || Common.StripUnneeded || Common.DecompressDebugSections) {
+ Common.Weaken || Common.StripUnneeded || Common.DecompressDebugSections ||
+ !Common.AdjustSectionVMA.empty()) {
return createStringError(
llvm::errc::invalid_argument,
"no flags are supported yet, only basic copying is allowed");
diff --git a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
index 9d02ba051a0a84..4fd5b42209a7d6 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
@@ -653,6 +653,34 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
}
}
+ // Handle VMA adjustment
+ for (SectionBase &Sec : Obj.sections()) {
+ SectionVMAUpdate SectionUpdate;
+ bool AdjustThisSection = false;
+ if (auto It = Config.AdjustSectionVMA.find(Sec.Name);
+ It != Config.AdjustSectionVMA.end()) {
+ AdjustThisSection = true;
+ SectionUpdate = It->second;
+ } else if (auto It = Config.AdjustSectionVMA.find("*");
+ It != Config.AdjustSectionVMA.end()) {
+ AdjustThisSection = true;
+ SectionUpdate = It->second;
+ }
+ if (AdjustThisSection) {
+ switch (SectionUpdate.UpdateAs) {
+ case SectionUpdateType::Increase:
+ Sec.Addr += SectionUpdate.UpdateValue;
+ break;
+ case SectionUpdateType::Decrease:
+ Sec.Addr -= SectionUpdate.UpdateValue;
+ break;
+ case SectionUpdateType::Set:
+ Sec.Addr = SectionUpdate.UpdateValue;
+ break;
+ }
+ }
+ }
+
if (Config.OnlyKeepDebug)
for (auto &Sec : Obj.sections())
if (Sec.Flags & SHF_ALLOC && Sec.Type != SHT_NOTE)
diff --git a/llvm/test/tools/llvm-objcopy/ELF/adjust-section-vma.test b/llvm/test/tools/llvm-objcopy/ELF/adjust-section-vma.test
new file mode 100644
index 00000000000000..99eaab46708217
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/adjust-section-vma.test
@@ -0,0 +1,130 @@
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-objdump --all-headers -D -z %t | FileCheck %s --check-prefixes=COMMON,NOADJUST
+# RUN: llvm-objcopy --adjust-section-vma .text+0x123000 %t
+# RUN: llvm-objdump --all-headers -D -z %t | FileCheck %s --check-prefixes=COMMON,ADJUST
+# RUN: llvm-objcopy --adjust-section-vma .text-0x123000 %t
+# RUN: llvm-objdump --all-headers -D -z %t | FileCheck %s --check-prefixes=COMMON,NOADJUST
+# RUN: llvm-objcopy --adjust-section-vma .text=0x123000 %t
+# RUN: llvm-objdump --all-headers -D -z %t | FileCheck %s --check-prefixes=COMMON,ADJUST
+
+# NOADJUST: Sections:
+# NOADJUST-NEXT: Idx Name Size VMA Type
+# NOADJUST-NEXT: 0 00000000 0000000000000000
+# NOADJUST-NEXT: 1 .text 00000002 0000000000000000 TEXT
+# NOADJUST-NEXT: 2 .debug_str 00000004 0000000000000000
+# NOADJUST-NEXT: 3 .rela.debug_str 00000018 0000000000000000
+# NOADJUST-NEXT: 4 .data 00000004 0000000000000000 DATA
+# NOADJUST-NEXT: 5 .rela.data 00000018 0000000000000000
+# NOADJUST-NEXT: 6 .symtab {{.*}} 0000000000000000
+# NOADJUST-NEXT: 7 .strtab {{.*}} 0000000000000000
+# NOADJUST-NEXT: 8 .shstrtab 0000003c 0000000000000000
+
+# ADJUST: Sections:
+# ADJUST-NEXT: Idx Name Size VMA Type
+# ADJUST-NEXT: 0 00000000 0000000000000000
+# ADJUST-NEXT: 1 .text 00000002 0000000000123000 TEXT
+# ADJUST-NEXT: 2 .debug_str 00000004 0000000000000000
+# ADJUST-NEXT: 3 .rela.debug_str 00000018 0000000000000000
+# ADJUST-NEXT: 4 .data 00000004 0000000000000000 DATA
+# ADJUST-NEXT: 5 .rela.data 00000018 0000000000000000
+# ADJUST-NEXT: 6 .symtab {{.*}} 0000000000000000
+# ADJUST-NEXT: 7 .strtab {{.*}} 0000000000000000
+# ADJUST-NEXT: 8 .shstrtab 0000003c 0000000000000000
+
+# NOADJUST: SYMBOL TABLE:
+# NOADJUST-NEXT: 0000000000000001 l F .text 0000000000000000 func
+# NOADJUST-NEXT: 0000000000000000 l .text 0000000000000000 sym
+# NOADJUST-NEXT: 0000000000000000 l d .text 0000000000000000 .text
+# NOADJUST-NEXT: 0000000000003333 l *ABS* 0000000000000000 abs
+# NOADJUST-NEXT: 0000000000000000 l .debug_str 0000000000000000 debug_str_sym
+
+# ADJUST: SYMBOL TABLE:
+# ADJUST-NEXT: 0000000000123001 l F .text 0000000000000000 func
+# ADJUST-NEXT: 0000000000123000 l .text 0000000000000000 sym
+# ADJUST-NEXT: 0000000000123000 l d .text 0000000000000000 .text
+# ADJUST-NEXT: 0000000000003333 l *ABS* 0000000000000000 abs
+# ADJUST-NEXT: 0000000000000000 l .debug_str 0000000000000000 debug_str_sym
+
+# NOADJUST: 0000000000000000 <sym>:
+# NOADJUST-NEXT: 0: {{.*}} nop
+# NOADJUST: 0000000000000001 <func>:
+# NOADJUST-NEXT: 1: {{.*}} retq
+
+# ADJUST: 0000000000123000 <sym>:
+# ADJUST-NEXT: 123000: {{.*}} nop
+# ADJUST: 0000000000123001 <func>:
+# ADJUST-NEXT: 123001: {{.*}} retq
+
+# COMMON: 0000000000000000 <debug_str_sym>:
+# COMMON-NEXT: 0: {{.*}} %al, (%rax)
+# COMMON-NEXT: 0000000000000001: R_X86_64_32 .text
+# COMMON-NEXT: 2: {{.*}} addb %al, (%rax)
+
+# COMMON: 0000000000000000 <.rela.debug_str>:
+# COMMON-NEXT: 0: {{.*}} addl %eax, (%rax)
+## ... There are more lines here. We do not care.
+
+# COMMON: 0000000000000000 <.data>:
+# COMMON-NEXT: 0: {{.*}} addb %al, (%rax)
+# COMMON-NEXT: 0000000000000000: R_X86_64_32 .text
+# COMMON-NEXT: 2: {{.*}} addb %al, (%rax)
+
+# COMMON: 0000000000000000 <.rela.data>:
+# COMMON-NEXT: 0: {{.*}} addb %al, (%rax)
+## ... There are more lines here. We do not care.
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: 90C3
+ - Name: .debug_str
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x0000000000000001
+ Content: '00000000'
+ - Name: .rela.debug_str
+ Type: SHT_RELA
+ Link: .symtab
+ AddressAlign: 0x0000000000000008
+ Info: .debug_str
+ Relocations:
+ - Offset: 0x0000000000000001
+ Symbol: .text
+ Type: R_X86_64_32
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000001
+ Content: '00000000'
+ - Name: .rela.data
+ Type: SHT_RELA
+ Link: .symtab
+ AddressAlign: 0x0000000000000008
+ Info: .data
+ Relocations:
+ - Offset: 0x0000000000000000
+ Symbol: .text
+ Type: R_X86_64_32
+Symbols:
+ - Name: func
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x0000000000000001
+ - Name: sym
+ Section: .text
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: abs
+ Index: SHN_ABS
+ Value: 0x3333
+ - Name: debug_str_sym
+ Section: .debug_str
diff --git a/llvm/test/tools/llvm-objcopy/ELF/adjust-vma.test b/llvm/test/tools/llvm-objcopy/ELF/adjust-vma.test
new file mode 100644
index 00000000000000..93fa534ff3c94f
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/adjust-vma.test
@@ -0,0 +1,146 @@
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-objdump --all-headers -D -z %t | FileCheck %s --check-prefixes=NOADJUST
+# RUN: llvm-objcopy --adjust-vma 0x123000 %t
+# RUN: llvm-objdump --all-headers -D -z %t | FileCheck %s --check-prefixes=ADJUST
+
+# NOADJUST: Sections:
+# NOADJUST-NEXT: Idx Name Size VMA Type
+# NOADJUST-NEXT: 0 00000000 0000000000000000
+# NOADJUST-NEXT: 1 .text 00000002 0000000000000000 TEXT
+# NOADJUST-NEXT: 2 .debug_str 00000004 0000000000000000
+# NOADJUST-NEXT: 3 .rela.debug_str 00000018 0000000000000000
+# NOADJUST-NEXT: 4 .data 00000004 0000000000000000 DATA
+# NOADJUST-NEXT: 5 .rela.data 00000018 0000000000000000
+# NOADJUST-NEXT: 6 .symtab {{.*}} 0000000000000000
+# NOADJUST-NEXT: 7 .strtab {{.*}} 0000000000000000
+# NOADJUST-NEXT: 8 .shstrtab 0000003c 0000000000000000
+
+# ADJUST: Sections:
+# ADJUST-NEXT: Idx Name Size VMA Type
+# ADJUST-NEXT: 0 00000000 0000000000000000
+# ADJUST-NEXT: 1 .text 00000002 0000000000123000 TEXT
+# ADJUST-NEXT: 2 .debug_str 00000004 0000000000123000
+# ADJUST-NEXT: 3 .rela.debug_str 00000018 0000000000123000
+# ADJUST-NEXT: 4 .data 00000004 0000000000123000 DATA
+# ADJUST-NEXT: 5 .rela.data 00000018 0000000000123000
+# ADJUST-NEXT: 6 .symtab {{.*}} 0000000000123000
+# ADJUST-NEXT: 7 .strtab {{.*}} 0000000000123000
+# ADJUST-NEXT: 8 .shstrtab 0000003c 0000000000123000
+
+# NOADJUST: SYMBOL TABLE:
+# NOADJUST-NEXT: 0000000000000001 l F .text 0000000000000000 func
+# NOADJUST-NEXT: 0000000000000000 l .text 0000000000000000 sym
+# NOADJUST-NEXT: 0000000000000000 l d .text 0000000000000000 .text
+# NOADJUST-NEXT: 0000000000003333 l *ABS* 0000000000000000 abs
+# NOADJUST-NEXT: 0000000000000000 l .debug_str 0000000000000000 debug_str_sym
+
+# ADJUST: SYMBOL TABLE:
+# ADJUST-NEXT: 0000000000123001 l F .text 0000000000000000 func
+# ADJUST-NEXT: 0000000000123000 l .text 0000000000000000 sym
+# ADJUST-NEXT: 0000000000123000 l d .text 0000000000000000 .text
+# ADJUST-NEXT: 0000000000003333 l *ABS* 0000000000000000 abs
+# ADJUST-NEXT: 0000000000123000 l .debug_str 0000000000000000 debug_str_sym
+
+# NOADJUST: 0000000000000000 <sym>:
+# NOADJUST-NEXT: 0: {{.*}} nop
+# NOADJUST: 0000000000000001 <func>:
+# NOADJUST-NEXT: 1: {{.*}} retq
+
+# ADJUST: 0000000000123000 <sym>:
+# ADJUST-NEXT: 123000: {{.*}} nop
+# ADJUST: 0000000000123001 <func>:
+# ADJUST-NEXT: 123001: {{.*}} retq
+
+# NOADJUST: 0000000000000000 <debug_str_sym>:
+# NOADJUST-NEXT: 0: {{.*}} %al, (%rax)
+# NOADJUST-NEXT: 0000000000000001: R_X86_64_32 .text
+# NOADJUST-NEXT: 2: {{.*}} addb %al, (%rax)
+
+# ADJUST: 0000000000123000 <debug_str_sym>:
+# ADJUST-NEXT: 123000: {{.*}} %al, (%rax)
+# ADJUST-NEXT: 0000000000123001: R_X86_64_32 .text
+# ADJUST-NEXT: 123002: {{.*}} addb %al, (%rax)
+
+
+# NOADJUST: 0000000000000000 <.rela.debug_str>:
+# NOADJUST-NEXT: 0: {{.*}} addl %eax, (%rax)
+## ... There are more lines here. We do not care.
+
+# ADJUST: 0000000000123000 <.rela.debug_str>:
+# ADJUST-NEXT: 123000: {{.*}} addl %eax, (%rax)
+## ... There are more lines here. We do not care.
+
+
+# NOADJUST: 0000000000000000 <.data>:
+# NOADJUST-NEXT: 0: {{.*}} addb %al, (%rax)
+# NOADJUST-NEXT: 0000000000000000: R_X86_64_32 .text
+# NOADJUST-NEXT: 2: {{.*}} addb %al, (%rax)
+
+# ADJUST: 0000000000123000 <.data>:
+# ADJUST-NEXT: 123000: {{.*}} addb %al, (%rax)
+# ADJUST-NEXT: 0000000000123000: R_X86_64_32 .text
+# ADJUST-NEXT: 123002: {{.*}} addb %al, (%rax)
+
+# NOADJUST: 0000000000000000 <.rela.data>:
+# NOADJUST-NEXT: 0: {{.*}} addb %al, (%rax)
+## ... There are more lines here. We do not care.
+
+# ADJUST: 0000000000123000 <.rela.data>:
+# ADJUST-NEXT: 123000: {{.*}} addb %al, (%rax)
+## ... There are more lines here. We do not care.
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: 90C3
+ - Name: .debug_str
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x0000000000000001
+ Content: '00000000'
+ - Name: .rela.debug_str
+ Type: SHT_RELA
+ Link: .symtab
+ AddressAlign: 0x0000000000000008
+ Info: .debug_str
+ Relocations:
+ - Offset: 0x0000000000000001
+ Symbol: .text
+ Type: R_X86_64_32
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000001
+ Content: '00000000'
+ - Name: .rela.data
+ Type: SHT_RELA
+ Link: .symtab
+ AddressAlign: 0x0000000000000008
+ Info: .data
+ Relocations:
+ - Offset: 0x0000000000000000
+ Symbol: .text
+ Type: R_X86_64_32
+Symbols:
+ - Name: func
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x0000000000000001
+ - Name: sym
+ Section: .text
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: abs
+ Index: SHN_ABS
+ Value: 0x3333
+ - Name: debug_str_sym
+ Section: .debug_str
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index 57129025394437..086a366edb949c 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -532,6 +532,38 @@ 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 Expected<SectionVMAUpdate> parseAdjustSectionVMA(StringRef ArgValue,
+ StringRef OptionName) {
+ SectionVMAUpdate SectionUpdate;
+ std::pair<StringRef, StringRef> SecPair;
+ if (ArgValue.contains("=")) {
+ SectionUpdate.UpdateAs = SectionUpdateType::Set;
+ SecPair = ArgValue.split("=");
+ } else if (ArgValue.contains("+")) {
+ SectionUpdate.UpdateAs = SectionUpdateType::Increase;
+ SecPair = ArgValue.split("+");
+ } else if (ArgValue.contains("-")) {
+ SectionUpdate.UpdateAs = SectionUpdateType::Decrease;
+ 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");
+ SectionUpdate.UpdateSection = SecPair.first;
+ auto ChangeValue = getAsInteger<int64_t>(SecPair.second);
+ if (!ChangeValue)
+ return createStringError(ChangeValue.getError(),
+ "Unable to parse adjustment value");
+ SectionUpdate.UpdateValue = *ChangeValue;
+ return SectionUpdate;
+}
+
// parseObjcopyOptions returns the config and sets the input arguments. If a
// help flag is set then parseObjcopyOptions will print the help messege and
// exit.
@@ -605,8 +637,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;
@@ -827,6 +859,18 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
Config.UpdateSection))
return std::move(Err);
}
+ for (auto *Arg : InputArgs.filtered(OBJCOPY_adjust_section_vma)) {
+ Expected<SectionVMAUpdate> SVMAU =
+ parseAdjustSectionVMA(Arg->getValue(), "--adjust-section-vma");
+ if (!SVMAU)
+ return SVMAU.takeError();
+ if (!Config.AdjustSectionVMA.try_emplace(SVMAU->UpdateSection, *SVMAU)
+ .second)
+ return createStringError(
+ errc::invalid_argument,
+ "--adjust-section-vma set multiple times for section '%s'",
+ SVMAU->UpdateSection.str().c_str());
+ }
for (auto *Arg : InputArgs.filtered(OBJCOPY_dump_section)) {
StringRef Value(Arg->getValue());
if (Value.split('=').second.empty())
@@ -966,6 +1010,25 @@ 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());
+ SectionVMAUpdate SVMAU;
+ SVMAU.UpdateSection = "*";
+ SVMAU.UpdateValue = *EIncr;
+ SVMAU.UpdateAs = SectionUpdateType::Increase;
+ if (!Config.AdjustSectionVMA.try_emplace(SVMAU.UpdateSection, SVMAU)
+ .second)
+ return createStringError(errc::invalid_argument,
+ "--adjust-vma set multiple times");
+ auto Expr = ELFConfig.EntryExpr ? std::move(ELFConfig.EntryExpr)
+ : [](uint64_t A) { return A; };
+ ELFConfig.EntryExpr = [Expr, EIncr](uint64_t EAddr) {
+ return Expr(EAddr) + *EIncr;
+ };
}
if (Config.DecompressDebugSections &&
@@ -1250,8 +1313,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 ea8828637222ac..77d00ac8e7377a 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOpts.td
+++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
@@ -230,3 +230,11 @@ 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 <name> by <value>">,
+ MetaVarName<"name{=|+|-}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