aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp')
-rw-r--r--llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp35
1 files changed, 27 insertions, 8 deletions
diff --git a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
index dfe843e1d4b7..9d02ba051a0a 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
@@ -68,7 +68,8 @@ static bool onlyKeepDWOPred(const Object &Obj, const SectionBase &Sec) {
return !isDWOSection(Sec);
}
-static uint64_t getNewShfFlags(SectionFlag AllFlags) {
+static Expected<uint64_t> getNewShfFlags(SectionFlag AllFlags,
+ uint16_t EMachine) {
uint64_t NewFlags = 0;
if (AllFlags & SectionFlag::SecAlloc)
NewFlags |= ELF::SHF_ALLOC;
@@ -82,18 +83,27 @@ static uint64_t getNewShfFlags(SectionFlag AllFlags) {
NewFlags |= ELF::SHF_STRINGS;
if (AllFlags & SectionFlag::SecExclude)
NewFlags |= ELF::SHF_EXCLUDE;
+ if (AllFlags & SectionFlag::SecLarge) {
+ if (EMachine != EM_X86_64)
+ return createStringError(errc::invalid_argument,
+ "section flag SHF_X86_64_LARGE can only be used "
+ "with x86_64 architecture");
+ NewFlags |= ELF::SHF_X86_64_LARGE;
+ }
return NewFlags;
}
static uint64_t getSectionFlagsPreserveMask(uint64_t OldFlags,
- uint64_t NewFlags) {
+ uint64_t NewFlags,
+ uint16_t EMachine) {
// Preserve some flags which should not be dropped when setting flags.
// Also, preserve anything OS/processor dependant.
const uint64_t PreserveMask =
(ELF::SHF_COMPRESSED | ELF::SHF_GROUP | ELF::SHF_LINK_ORDER |
ELF::SHF_MASKOS | ELF::SHF_MASKPROC | ELF::SHF_TLS |
ELF::SHF_INFO_LINK) &
- ~ELF::SHF_EXCLUDE;
+ ~ELF::SHF_EXCLUDE &
+ ~(EMachine == EM_X86_64 ? (uint64_t)ELF::SHF_X86_64_LARGE : 0UL);
return (OldFlags & PreserveMask) | (NewFlags & ~PreserveMask);
}
@@ -105,8 +115,12 @@ static void setSectionType(SectionBase &Sec, uint64_t Type) {
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 EMachine) {
+ Expected<uint64_t> NewFlags = getNewShfFlags(Flags, EMachine);
+ if (!NewFlags)
+ return NewFlags.takeError();
+ Sec.Flags = getSectionFlagsPreserveMask(Sec.Flags, *NewFlags, EMachine);
// 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 +129,8 @@ static void setSectionFlagsAndType(SectionBase &Sec, SectionFlag Flags) {
(!(Sec.Flags & ELF::SHF_ALLOC) ||
Flags & (SectionFlag::SecContents | SectionFlag::SecLoad)))
setSectionType(Sec, ELF::SHT_PROGBITS);
+
+ return Error::success();
}
static ElfType getOutputElfType(const Binary &Bin) {
@@ -681,7 +697,8 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
const auto Iter = Config.SetSectionFlags.find(Sec.Name);
if (Iter != Config.SetSectionFlags.end()) {
const SectionFlagsUpdate &SFU = Iter->second;
- setSectionFlagsAndType(Sec, SFU.NewFlags);
+ if (Error E = setSectionFlagsAndType(Sec, SFU.NewFlags, Obj.Machine))
+ return E;
}
auto It2 = Config.SetSectionType.find(Sec.Name);
if (It2 != Config.SetSectionType.end())
@@ -698,8 +715,10 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
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) {
+ if (Error E = setSectionFlagsAndType(Sec, *SR.NewFlags, Obj.Machine))
+ return E;
+ }
RenamedSections.insert(&Sec);
} else if (RelocSec && !(Sec.Flags & SHF_ALLOC))
// Postpone processing relocation sections which are not specified in