Index: llvm/include/llvm/ObjCopy/CommonConfig.h =================================================================== --- llvm/include/llvm/ObjCopy/CommonConfig.h +++ llvm/include/llvm/ObjCopy/CommonConfig.h @@ -69,7 +69,8 @@ SecContents = 1 << 10, SecShare = 1 << 11, SecExclude = 1 << 12, - LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/SecExclude) + SecLarge = 1 << 13, + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/SecLarge) }; struct SectionRename { Index: llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp =================================================================== --- llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp +++ llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp @@ -68,8 +68,9 @@ return !isDWOSection(Sec); } -static uint64_t getNewShfFlags(SectionFlag AllFlags) { - uint64_t NewFlags = 0; +static Error getNewShfFlags(SectionFlag AllFlags, uint64_t &NewFlags, + uint16_t EM) { + NewFlags = 0; if (AllFlags & SectionFlag::SecAlloc) NewFlags |= ELF::SHF_ALLOC; if (!(AllFlags & SectionFlag::SecReadonly)) @@ -82,7 +83,15 @@ NewFlags |= ELF::SHF_STRINGS; if (AllFlags & SectionFlag::SecExclude) NewFlags |= ELF::SHF_EXCLUDE; - return NewFlags; + if (AllFlags & SectionFlag::SecLarge) { + if (EM != EM_X86_64) + return createStringError( + object_error::invalid_file_type, + "section flag 'large' can only be used with x86_64 architecture"); + NewFlags |= ELF::SHF_X86_64_LARGE; + } + + return Error::success(); } static uint64_t getSectionFlagsPreserveMask(uint64_t OldFlags, @@ -105,8 +114,12 @@ Sec.Type = Type; } -static void setSectionFlagsAndType(SectionBase &Sec, SectionFlag Flags) { - Sec.Flags = getSectionFlagsPreserveMask(Sec.Flags, getNewShfFlags(Flags)); +static Error setSectionFlagsAndType(SectionBase &Sec, SectionFlag Flags, + uint16_t EM) { + if (uint64_t NewFlags; Error E = getNewShfFlags(Flags, NewFlags, EM)) + return E; + else + Sec.Flags = getSectionFlagsPreserveMask(Sec.Flags, NewFlags); // In GNU objcopy, certain flags promote SHT_NOBITS to SHT_PROGBITS. This rule // may promote more non-ALLOC sections than GNU objcopy, but it is fine as @@ -115,6 +128,8 @@ (!(Sec.Flags & ELF::SHF_ALLOC) || Flags & (SectionFlag::SecContents | SectionFlag::SecLoad))) setSectionType(Sec, ELF::SHT_PROGBITS); + + return Error::success(); } static ElfType getOutputElfType(const Binary &Bin) { @@ -688,7 +703,9 @@ const auto Iter = Config.SetSectionFlags.find(Sec.Name); if (Iter != Config.SetSectionFlags.end()) { const SectionFlagsUpdate &SFU = Iter->second; - setSectionFlagsAndType(Sec, SFU.NewFlags); + uint16_t Arch = Config.OutputArch.value_or(MachineInfo()); + if (Error E = setSectionFlagsAndType(Sec, SFU.NewFlags, Arch.EMachine)) + return E; } auto It2 = Config.SetSectionType.find(Sec.Name); if (It2 != Config.SetSectionType.end()) @@ -705,8 +722,12 @@ if (Iter != Config.SectionsToRename.end()) { const SectionRename &SR = Iter->second; Sec.Name = std::string(SR.NewName); - if (SR.NewFlags) - setSectionFlagsAndType(Sec, *SR.NewFlags); + if (SR.NewFlags) { + uint16_t Arch = Config.OutputArch.value_or(MachineInfo()); + if (Error E = + setSectionFlagsAndType(Sec, *SR.NewFlags, Arch.EMachine)) + return E; + } RenamedSections.insert(&Sec); } else if (RelocSec && !(Sec.Flags & SHF_ALLOC)) // Postpone processing relocation sections which are not specified in Index: llvm/tools/llvm-objcopy/ObjcopyOptions.cpp =================================================================== --- llvm/tools/llvm-objcopy/ObjcopyOptions.cpp +++ llvm/tools/llvm-objcopy/ObjcopyOptions.cpp @@ -204,6 +204,7 @@ .CaseLower("contents", SectionFlag::SecContents) .CaseLower("share", SectionFlag::SecShare) .CaseLower("exclude", SectionFlag::SecExclude) + .CaseLower("large", SectionFlag::SecLarge) .Default(SectionFlag::SecNone); } @@ -217,7 +218,7 @@ errc::invalid_argument, "unrecognized section flag '%s'. Flags supported for GNU " "compatibility: alloc, load, noload, readonly, exclude, debug, " - "code, data, rom, share, contents, merge, strings", + "code, data, rom, share, contents, merge, strings, large", Flag.str().c_str()); ParsedFlags |= ParsedFlag; }