Index: llvm/test/tools/llvm-objcopy/ELF/prefix-alloc-sections.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-objcopy/ELF/prefix-alloc-sections.test @@ -0,0 +1,55 @@ +# RUN: yaml2obj %s > %t +# RUN: llvm-objcopy --prefix-alloc-sections=.alloc_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: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + - Name: .rela.data + Type: SHT_RELA + Info: .data + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + - Name: .rel.text + Type: SHT_REL + Info: .text + - Name: .plt + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + - Name: .got.plt + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + - Name: .rela.plt + Type: SHT_RELA + Flags: [ SHF_ALLOC ] + Info: .got.plt + Link: .dynsym + - Name: .dynsym + Type: SHT_DYNSYM + Flags: [ SHF_ALLOC ] + Link: .dynstr + - Name: .dynstr + Type: SHT_STRTAB + Flags: [ SHF_ALLOC ] + Content: "00" + +# CHECK: Sections [ +# CHECK: Name: .foo +# CHECK: Name: .alloc_prefix.text +# CHECK: Name: .rela.alloc_prefix.data +# CHECK: Name: .alloc_prefix.data +# CHECK: Name: .rel.alloc_prefix.text +# CHECK: Name: .alloc_prefix.plt +# CHECK: Name: .alloc_prefix.rela.plt +# CHECK: ] Index: llvm/test/tools/llvm-objcopy/ELF/rename-section-and-prefix-alloc-sections.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-objcopy/ELF/rename-section-and-prefix-alloc-sections.test @@ -0,0 +1,28 @@ +# RUN: yaml2obj %s > %t +# RUN: llvm-objcopy --rename-section=.text=.text2 --prefix-alloc-sections=.alloc_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: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + - Name: .rel.text + Type: SHT_REL + Info: .text + - Name: .bar + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + +# CHECK: Name: .foo +# CHECK: Name: .alloc_prefix.text2 +# CHECK: Name: .rel.alloc_prefix.text2 +# CHECK: Name: .alloc_prefix.bar Index: llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp =================================================================== --- llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp +++ llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp @@ -176,15 +176,16 @@ if (!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.SymbolsPrefix.empty() || !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, Index: llvm/tools/llvm-objcopy/CopyConfig.h =================================================================== --- llvm/tools/llvm-objcopy/CopyConfig.h +++ llvm/tools/llvm-objcopy/CopyConfig.h @@ -113,6 +113,7 @@ Optional BuildIdLinkOutput; StringRef SplitDWO; StringRef SymbolsPrefix; + StringRef AllocSectionsPrefix; DiscardType DiscardMode = DiscardType::None; // Repeated options Index: llvm/tools/llvm-objcopy/CopyConfig.cpp =================================================================== --- llvm/tools/llvm-objcopy/CopyConfig.cpp +++ llvm/tools/llvm-objcopy/CopyConfig.cpp @@ -473,6 +473,8 @@ 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('=')) Index: llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp =================================================================== --- llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp +++ llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp @@ -620,6 +620,47 @@ NewSection.Type = SHT_NOTE; } + if (!Config.AllocSectionsPrefix.empty()) { + for (auto &Sec : Obj.sections()) { + if ((Sec.Flags & SHF_ALLOC) != 0) { + Sec.Name = (Config.AllocSectionsPrefix + Sec.Name).str(); + + // 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 (isa(&Sec)) { + auto *TargetSec = dyn_cast(&Sec)->getSection(); + if (TargetSec && (TargetSec->Flags & SHF_ALLOC) != 0) { + 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 (TargetSec->Name.find(Config.AllocSectionsPrefix) == 0) + Sec.Name = (prefix + TargetSec->Name).str(); + else + Sec.Name = + (prefix + Config.AllocSectionsPrefix + TargetSec->Name).str(); + } + } + } + } + for (const auto &Flag : Config.DumpSection) { std::pair SecPair = Flag.split("="); StringRef SecName = SecPair.first; Index: llvm/tools/llvm-objcopy/ObjcopyOpts.td =================================================================== --- llvm/tools/llvm-objcopy/ObjcopyOpts.td +++ llvm/tools/llvm-objcopy/ObjcopyOpts.td @@ -231,6 +231,10 @@ : Eq<"prefix-symbols", "Add to the start of every symbol name">, MetaVarName<"prefix">; +defm prefix_alloc_sections + : Eq<"prefix-alloc-sections", "Add 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;