mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:29:58 +00:00
[llvm-objcopy] Add --prefix-alloc-sections
This patch adds support for --prefix-alloc-sections, which adds a prefix to every allocated section names. It adds a prefix after renaming section names by --rename-section as GNU objcopy does. Fixes PR41266: https://bugs.llvm.org/show_bug.cgi?id=41266 Differential Revision: https://reviews.llvm.org/D60042 Patch by Seiya Nuta. llvm-svn: 360233
This commit is contained in:
parent
cf5cd7dbe8
commit
5f4b241a54
@ -0,0 +1,5 @@
|
||||
# RUN: llvm-objcopy --prefix-alloc-sections=.prefix %p/Inputs/dynrel.elf %t
|
||||
# RUN: llvm-readobj --sections %t | FileCheck %s
|
||||
|
||||
# CHECK: Name: .prefix.rela.plt
|
||||
# CHECK: Name: .prefix.plt
|
36
test/tools/llvm-objcopy/ELF/prefix-alloc-sections.test
Normal file
36
test/tools/llvm-objcopy/ELF/prefix-alloc-sections.test
Normal file
@ -0,0 +1,36 @@
|
||||
# RUN: yaml2obj %s > %t
|
||||
# RUN: llvm-objcopy --prefix-alloc-sections=.prefix %t %t2
|
||||
# RUN: llvm-readobj --sections %t2 | FileCheck %s
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .foo
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ ]
|
||||
- Name: .prefix.already_prefixed
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC ]
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC ]
|
||||
- Name: .rel.text
|
||||
Type: SHT_REL
|
||||
Info: .text
|
||||
- Name: .rela.data
|
||||
Type: SHT_RELA
|
||||
Info: .data
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC ]
|
||||
|
||||
# CHECK: Name: .foo
|
||||
# CHECK: Name: .prefix.prefix.already_prefixed
|
||||
# CHECK: Name: .prefix.text
|
||||
# CHECK: Name: .rel.prefix.text
|
||||
# CHECK: Name: .rela.prefix.data
|
||||
# CHECK: Name: .prefix.data
|
@ -0,0 +1,32 @@
|
||||
# RUN: yaml2obj %s > %t
|
||||
# RUN: llvm-objcopy --rename-section=.text=.text2 --rename-section=.data=.data2 --prefix-alloc-sections=.prefix %t %t2
|
||||
# RUN: llvm-readobj --sections %t2 | FileCheck %s
|
||||
|
||||
# .text/.rel.text and .data/.rela.data are the cases when the relocation section
|
||||
# comes after/before its target section respectively. We handle them in different
|
||||
# ways to perform both --rename-section and --prefix-alloc-sections in one pass.
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC ]
|
||||
- Name: .rel.text
|
||||
Type: SHT_REL
|
||||
Info: .text
|
||||
- Name: .rela.data
|
||||
Type: SHT_RELA
|
||||
Info: .data
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC ]
|
||||
|
||||
# CHECK: Name: .prefix.text2
|
||||
# CHECK: Name: .rel.prefix.text2
|
||||
# CHECK: Name: .rela.prefix.data2
|
||||
# CHECK: Name: .prefix.data2
|
@ -177,15 +177,15 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
|
||||
if (Config.AllowBrokenLinks || !Config.BuildIdLinkDir.empty() ||
|
||||
Config.BuildIdLinkInput || Config.BuildIdLinkOutput ||
|
||||
!Config.SplitDWO.empty() || !Config.SymbolsPrefix.empty() ||
|
||||
!Config.AddSection.empty() || !Config.DumpSection.empty() ||
|
||||
!Config.KeepSection.empty() || !Config.SymbolsToGlobalize.empty() ||
|
||||
!Config.SymbolsToKeep.empty() || !Config.SymbolsToLocalize.empty() ||
|
||||
!Config.SymbolsToWeaken.empty() || !Config.SymbolsToKeepGlobal.empty() ||
|
||||
!Config.SectionsToRename.empty() || !Config.SetSectionFlags.empty() ||
|
||||
!Config.SymbolsToRename.empty() || Config.ExtractDWO ||
|
||||
Config.KeepFileSymbols || Config.LocalizeHidden || Config.PreserveDates ||
|
||||
Config.StripDWO || Config.StripNonAlloc || Config.StripSections ||
|
||||
Config.Weaken || Config.DecompressDebugSections ||
|
||||
!Config.AllocSectionsPrefix.empty() || !Config.AddSection.empty() ||
|
||||
!Config.DumpSection.empty() || !Config.KeepSection.empty() ||
|
||||
!Config.SymbolsToGlobalize.empty() || !Config.SymbolsToKeep.empty() ||
|
||||
!Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() ||
|
||||
!Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() ||
|
||||
!Config.SetSectionFlags.empty() || !Config.SymbolsToRename.empty() ||
|
||||
Config.ExtractDWO || Config.KeepFileSymbols || Config.LocalizeHidden ||
|
||||
Config.PreserveDates || Config.StripDWO || Config.StripNonAlloc ||
|
||||
Config.StripSections || Config.Weaken || Config.DecompressDebugSections ||
|
||||
Config.DiscardMode == DiscardType::Locals ||
|
||||
!Config.SymbolsToAdd.empty() || Config.EntryExpr) {
|
||||
return createStringError(llvm::errc::invalid_argument,
|
||||
|
@ -499,6 +499,8 @@ Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
|
||||
InputArgs.getLastArgValue(OBJCOPY_build_id_link_output);
|
||||
Config.SplitDWO = InputArgs.getLastArgValue(OBJCOPY_split_dwo);
|
||||
Config.SymbolsPrefix = InputArgs.getLastArgValue(OBJCOPY_prefix_symbols);
|
||||
Config.AllocSectionsPrefix =
|
||||
InputArgs.getLastArgValue(OBJCOPY_prefix_alloc_sections);
|
||||
|
||||
for (auto Arg : InputArgs.filtered(OBJCOPY_redefine_symbol)) {
|
||||
if (!StringRef(Arg->getValue()).contains('='))
|
||||
|
@ -120,6 +120,7 @@ struct CopyConfig {
|
||||
Optional<StringRef> BuildIdLinkOutput;
|
||||
StringRef SplitDWO;
|
||||
StringRef SymbolsPrefix;
|
||||
StringRef AllocSectionsPrefix;
|
||||
DiscardType DiscardMode = DiscardType::None;
|
||||
|
||||
// Repeated options
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "llvm-objcopy.h"
|
||||
|
||||
#include "llvm/ADT/BitmaskEnum.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
@ -580,7 +581,8 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj,
|
||||
if (Error E = updateAndRemoveSymbols(Config, Obj))
|
||||
return E;
|
||||
|
||||
if (!Config.SectionsToRename.empty()) {
|
||||
if (!Config.SectionsToRename.empty() || !Config.AllocSectionsPrefix.empty()) {
|
||||
DenseSet<SectionBase *> PrefixedSections;
|
||||
for (auto &Sec : Obj.sections()) {
|
||||
const auto Iter = Config.SectionsToRename.find(Sec.Name);
|
||||
if (Iter != Config.SectionsToRename.end()) {
|
||||
@ -589,6 +591,60 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj,
|
||||
if (SR.NewFlags.hasValue())
|
||||
setSectionFlagsAndType(Sec, SR.NewFlags.getValue());
|
||||
}
|
||||
|
||||
// Add a prefix to allocated sections and their relocation sections. This
|
||||
// should be done after renaming the section by Config.SectionToRename to
|
||||
// imitate the GNU objcopy behavior.
|
||||
if (!Config.AllocSectionsPrefix.empty()) {
|
||||
if (Sec.Flags & SHF_ALLOC) {
|
||||
Sec.Name = (Config.AllocSectionsPrefix + Sec.Name).str();
|
||||
PrefixedSections.insert(&Sec);
|
||||
|
||||
// Rename relocation sections associated to the allocated sections.
|
||||
// For example, if we rename .text to .prefix.text, we also rename
|
||||
// .rel.text to .rel.prefix.text.
|
||||
//
|
||||
// Dynamic relocation sections (SHT_REL[A] with SHF_ALLOC) are handled
|
||||
// above, e.g., .rela.plt is renamed to .prefix.rela.plt, not
|
||||
// .rela.prefix.plt since GNU objcopy does so.
|
||||
} else if (auto *RelocSec = dyn_cast<RelocationSectionBase>(&Sec)) {
|
||||
auto *TargetSec = RelocSec->getSection();
|
||||
if (TargetSec && (TargetSec->Flags & SHF_ALLOC)) {
|
||||
StringRef prefix;
|
||||
switch (Sec.Type) {
|
||||
case SHT_REL:
|
||||
prefix = ".rel";
|
||||
break;
|
||||
case SHT_RELA:
|
||||
prefix = ".rela";
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the relocation section comes *after* the target section, we
|
||||
// don't add Config.AllocSectionsPrefix because we've already added
|
||||
// the prefix to TargetSec->Name. Otherwise, if the relocation
|
||||
// section comes *before* the target section, we add the prefix.
|
||||
if (PrefixedSections.count(TargetSec)) {
|
||||
Sec.Name = (prefix + TargetSec->Name).str();
|
||||
} else {
|
||||
const auto Iter = Config.SectionsToRename.find(TargetSec->Name);
|
||||
if (Iter != Config.SectionsToRename.end()) {
|
||||
// Both `--rename-section` and `--prefix-alloc-sections` are
|
||||
// given but the target section is not yet renamed.
|
||||
Sec.Name =
|
||||
(prefix + Config.AllocSectionsPrefix + Iter->second.NewName)
|
||||
.str();
|
||||
} else {
|
||||
Sec.Name =
|
||||
(prefix + Config.AllocSectionsPrefix + TargetSec->Name)
|
||||
.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,6 +238,10 @@ defm prefix_symbols
|
||||
: Eq<"prefix-symbols", "Add <prefix> to the start of every symbol name">,
|
||||
MetaVarName<"prefix">;
|
||||
|
||||
defm prefix_alloc_sections
|
||||
: Eq<"prefix-alloc-sections", "Add <prefix> to the start of every allocated section name">,
|
||||
MetaVarName<"prefix">;
|
||||
|
||||
def version : Flag<["--"], "version">,
|
||||
HelpText<"Print the version and exit.">;
|
||||
def V : Flag<["-"], "V">, Alias<version>;
|
||||
|
Loading…
Reference in New Issue
Block a user