mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 01:58:44 +08:00
[ELF] Allow sections after a non-SHF_ALLOC section to be covered by PT_LOAD
GNU ld allows sections after a non-SHF_ALLOC section to be covered by PT_LOAD (PR37607) and assigns addresses to non-SHF_ALLOC output sections (similar to SHF_ALLOC NOBITS sections. The location counter is not advanced). This patch tries to fix PR37607 (remove a special case in `Writer<ELFT>::createPhdrs`). To make the created PT_LOAD meaningful, we cannot reset dot to 0 for a middle non-SHF_ALLOC output section. This results in removal of two special cases in LinkerScript::assignOffsets. Non-SHF_ALLOC non-orphan sections can have non-zero addresses like in GNU ld. The zero address rule for non-SHF_ALLOC sections is weakened to apply to orphan only. This results in a special case in createSection and findOrphanPos, respectively. Reviewed By: jhenderson Differential Revision: https://reviews.llvm.org/D85100
This commit is contained in:
@@ -586,6 +586,8 @@ static OutputSection *findByName(ArrayRef<BaseCommand *> vec,
|
||||
static OutputSection *createSection(InputSectionBase *isec,
|
||||
StringRef outsecName) {
|
||||
OutputSection *sec = script->createOutputSection(outsecName, "<internal>");
|
||||
if (!(isec->flags & SHF_ALLOC))
|
||||
sec->addrExpr = [] { return 0; };
|
||||
sec->recordSection(isec);
|
||||
return sec;
|
||||
}
|
||||
@@ -848,9 +850,6 @@ static OutputSection *findFirstSection(PhdrEntry *load) {
|
||||
// This function assigns offsets to input sections and an output section
|
||||
// for a single sections command (e.g. ".text { *(.text); }").
|
||||
void LinkerScript::assignOffsets(OutputSection *sec) {
|
||||
if (!(sec->flags & SHF_ALLOC))
|
||||
dot = 0;
|
||||
|
||||
const bool sameMemRegion = ctx->memRegion == sec->memRegion;
|
||||
const bool prevLMARegionIsDefault = ctx->lmaRegion == nullptr;
|
||||
ctx->memRegion = sec->memRegion;
|
||||
@@ -858,7 +857,7 @@ void LinkerScript::assignOffsets(OutputSection *sec) {
|
||||
if (ctx->memRegion)
|
||||
dot = ctx->memRegion->curPos;
|
||||
|
||||
if ((sec->flags & SHF_ALLOC) && sec->addrExpr)
|
||||
if (sec->addrExpr)
|
||||
setDot(sec->addrExpr, sec->location, false);
|
||||
|
||||
// If the address of the section has been moved forward by an explicit
|
||||
|
||||
Reference in New Issue
Block a user