forked from OSchip/llvm-project
Create an OutputSection for each non-empty OutputSectionCommand.
We were already pretty close, the one exception was when a name was reused in another SECTIONS directive: SECTIONS { .text : { *(.text) } .data : { *(.data) } } SECTIONS { .data : { *(other) } } In this case we would create a single .data and magically output "other" while looking at the first OutputSectionCommand. We now create two .data sections. This matches what gold does. If we really want to create a single one, we should change the parser so that the above is parsed as if the user had written SECTIONS { .text : { *(.text) } .data : { *(.data) *(other)} } That is, there should be only one OutputSectionCommand for .data and it would have two InputSectionDescriptions. By itself this patch makes the code a bit more complicated, but is an important step in allowing assignAddresses to operate just on the linker script. llvm-svn: 301484
This commit is contained in:
parent
8186cd43e2
commit
4f013bb3b2
|
@ -407,7 +407,7 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) {
|
|||
|
||||
// Add input sections to an output section.
|
||||
for (InputSectionBase *S : V)
|
||||
Factory.addInputSec(S, Cmd->Name);
|
||||
Factory.addInputSec(S, Cmd->Name, Cmd->Sec);
|
||||
}
|
||||
}
|
||||
CurOutSec = nullptr;
|
||||
|
@ -465,9 +465,21 @@ void LinkerScript::fabricateDefaultCommands(bool AllocateHeader) {
|
|||
|
||||
// Add sections that didn't match any sections command.
|
||||
void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
|
||||
for (InputSectionBase *S : InputSections)
|
||||
if (S->Live && !S->OutSec)
|
||||
Factory.addInputSec(S, getOutputSectionName(S->Name));
|
||||
for (InputSectionBase *S : InputSections) {
|
||||
if (!S->Live || S->OutSec)
|
||||
continue;
|
||||
StringRef Name = getOutputSectionName(S->Name);
|
||||
auto I = std::find_if(
|
||||
Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
|
||||
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
|
||||
return Cmd->Name == Name;
|
||||
return false;
|
||||
});
|
||||
if (I == Opt.Commands.end())
|
||||
Factory.addInputSec(S, Name);
|
||||
else
|
||||
Factory.addInputSec(S, Name, cast<OutputSectionCommand>(*I)->Sec);
|
||||
}
|
||||
}
|
||||
|
||||
static bool isTbss(OutputSection *Sec) {
|
||||
|
@ -576,14 +588,6 @@ void LinkerScript::process(BaseCommand &Base) {
|
|||
}
|
||||
}
|
||||
|
||||
static OutputSection *
|
||||
findSection(StringRef Name, const std::vector<OutputSection *> &Sections) {
|
||||
for (OutputSection *Sec : Sections)
|
||||
if (Sec->Name == Name)
|
||||
return Sec;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// This function searches for a memory region to place the given output
|
||||
// section in. If found, a pointer to the appropriate memory region is
|
||||
// returned. Otherwise, a nullptr is returned.
|
||||
|
@ -663,7 +667,8 @@ void LinkerScript::removeEmptyCommands() {
|
|||
auto Pos = std::remove_if(
|
||||
Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
|
||||
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
|
||||
return !Cmd->Sec;
|
||||
return std::find(OutputSections->begin(), OutputSections->end(),
|
||||
Cmd->Sec) == OutputSections->end();
|
||||
return false;
|
||||
});
|
||||
Opt.Commands.erase(Pos, Opt.Commands.end());
|
||||
|
@ -687,8 +692,7 @@ void LinkerScript::adjustSectionsBeforeSorting() {
|
|||
auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
|
||||
if (!Cmd)
|
||||
continue;
|
||||
if (OutputSection *Sec = findSection(Cmd->Name, *OutputSections)) {
|
||||
Cmd->Sec = Sec;
|
||||
if (OutputSection *Sec = Cmd->Sec) {
|
||||
Flags = Sec->Flags;
|
||||
Type = Sec->Type;
|
||||
continue;
|
||||
|
|
|
@ -395,14 +395,20 @@ static void reportDiscarded(InputSectionBase *IS) {
|
|||
|
||||
void OutputSectionFactory::addInputSec(InputSectionBase *IS,
|
||||
StringRef OutsecName) {
|
||||
SectionKey Key = createKey(IS, OutsecName);
|
||||
OutputSection *&Sec = Map[Key];
|
||||
return addInputSec(IS, OutsecName, Sec);
|
||||
}
|
||||
|
||||
void OutputSectionFactory::addInputSec(InputSectionBase *IS,
|
||||
StringRef OutsecName,
|
||||
OutputSection *&Sec) {
|
||||
if (!IS->Live) {
|
||||
reportDiscarded(IS);
|
||||
return;
|
||||
}
|
||||
|
||||
SectionKey Key = createKey(IS, OutsecName);
|
||||
uint64_t Flags = getOutFlags(IS);
|
||||
OutputSection *&Sec = Map[Key];
|
||||
if (Sec) {
|
||||
if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags))
|
||||
error("incompatible section flags for " + Sec->Name +
|
||||
|
@ -418,7 +424,7 @@ void OutputSectionFactory::addInputSec(InputSectionBase *IS,
|
|||
}
|
||||
Sec->Flags |= Flags;
|
||||
} else {
|
||||
Sec = make<OutputSection>(Key.Name, IS->Type, Flags);
|
||||
Sec = make<OutputSection>(OutsecName, IS->Type, Flags);
|
||||
OutputSections.push_back(Sec);
|
||||
}
|
||||
|
||||
|
|
|
@ -141,6 +141,8 @@ public:
|
|||
~OutputSectionFactory();
|
||||
|
||||
void addInputSec(InputSectionBase *IS, StringRef OutsecName);
|
||||
void addInputSec(InputSectionBase *IS, StringRef OutsecName,
|
||||
OutputSection *&Sec);
|
||||
|
||||
private:
|
||||
llvm::SmallDenseMap<SectionKey, OutputSection *> Map;
|
||||
|
|
|
@ -86,7 +86,8 @@
|
|||
|
||||
# Idx Name Size
|
||||
# SEC-MULTI: 1 .text 0000000e {{[0-9a-f]*}} TEXT DATA
|
||||
# SEC-MULTI-NEXT: .data 00000023 {{[0-9a-f]*}} DATA
|
||||
# SEC-MULTI-NEXT: .data 00000020 {{[0-9a-f]*}} DATA
|
||||
# SEC-MULTI-NEXT: .data 00000003 {{[0-9a-f]*}} DATA
|
||||
# SEC-MULTI-NEXT: .bss 00000002 {{[0-9a-f]*}} BSS
|
||||
# SEC-MULTI-NEXT: .comment 00000008 {{[0-9a-f]*}}
|
||||
# SEC-MULTI-NEXT: .symtab 00000030 {{[0-9a-f]*}}
|
||||
|
|
Loading…
Reference in New Issue