ELF: Make .note.GNU-stack more compatible with traditional linkers.

With this patch, lld creates PT_GNU_STACK segments only when all input
files have .note.GNU-stack sections. This is in line with other linkers
with a minor difference (we don't care about .note.GNU-stack rwx bits as
you can always remove .note.GNU-stack sections instead of setting x bit.)

At least, NetBSD loader does not understand PT_GNU_STACK segments and
reject any executables that have the section. This patch makes lld
compatible with such operating systems.

llvm-svn: 253797
This commit is contained in:
Rui Ueyama
2015-11-21 22:19:32 +00:00
parent 6290dbc0f7
commit e79b09a616
24 changed files with 132 additions and 204 deletions

View File

@@ -174,6 +174,7 @@ void elf2::ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &Comdats) {
uint64_t Size = this->ELFObj.getNumSections();
Sections.resize(Size);
unsigned I = -1;
bool HasGnuStack = false;
const ELFFile<ELFT> &Obj = this->ELFObj;
for (const Elf_Shdr &Sec : Obj.sections()) {
++I;
@@ -224,21 +225,25 @@ void elf2::ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &Comdats) {
}
break;
}
default: {
default:
ErrorOr<StringRef> NameOrErr = this->ELFObj.getSectionName(&Sec);
error(NameOrErr);
if (*NameOrErr == ".note.GNU-stack")
StringRef Name = *NameOrErr;
if (Name == ".note.GNU-stack") {
Sections[I] = &InputSection<ELFT>::Discarded;
else if (*NameOrErr == ".eh_frame")
HasGnuStack = true;
} else if (Name == ".eh_frame") {
Sections[I] = new (this->Alloc) EHInputSection<ELFT>(this, &Sec);
else if (shouldMerge<ELFT>(Sec))
} else if (shouldMerge<ELFT>(Sec)) {
Sections[I] = new (this->Alloc) MergeInputSection<ELFT>(this, &Sec);
else
} else {
Sections[I] = new (this->Alloc) InputSection<ELFT>(this, &Sec);
}
break;
}
}
}
if (!HasGnuStack)
Config->ZExecStack = true;
}
template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() {