Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions lld/ELF/LinkerScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,18 +411,35 @@ void LinkerScript::assignSymbol(SymbolAssignment *cmd, bool inSec) {
cmd->sym->type = v.type;
}

bool InputSectionDescription::matchesFile(const InputFile &file) const {
// Convert an absolute address to a filename
static inline StringRef getExtractFilename(StringRef filename) {
size_t pos = filename.rfind("/");
if (pos != std::string::npos) {
return filename.substr(pos + 1);
}
return filename;
}

bool InputSectionDescription::matchesFile(const InputFile &file,
bool ExtractFlag) const {
if (filePat.isTrivialMatchAll())
return true;

if (!matchesFileCache || matchesFileCache->first != &file) {
if (matchType == MatchType::WholeArchive) {
matchesFileCache.emplace(&file, filePat.match(file.archiveName));
} else {
if (matchType == MatchType::ArchivesExcluded && !file.archiveName.empty())
if (matchType == MatchType::ArchivesExcluded && !file.archiveName.empty()){
matchesFileCache.emplace(&file, false);
else
matchesFileCache.emplace(&file, filePat.match(file.getNameForScript()));
} else {
bool MatchFilename = filePat.match(file.getNameForScript());
StringRef ExtractFilename = getExtractFilename(file.getNameForScript());
// only use for computeInputSections
if (ExtractFlag) {
MatchFilename = MatchFilename || filePat.match(ExtractFilename);
}
matchesFileCache.emplace(&file, MatchFilename);
}
}
}

Expand All @@ -442,7 +459,7 @@ bool SectionPattern::excludesFile(const InputFile &file) const {

bool LinkerScript::shouldKeep(InputSectionBase *s) {
for (InputSectionDescription *id : keptSections)
if (id->matchesFile(*s->file))
if (id->matchesFile(*s->file, false))
for (SectionPattern &p : id->sectionPatterns)
if (p.sectionPat.match(s->name) &&
(s->flags & id->withFlags) == id->withFlags &&
Expand Down Expand Up @@ -571,8 +588,8 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
if (!pat.sectionPat.match(sec->name))
continue;

if (!cmd->matchesFile(*sec->file) || pat.excludesFile(*sec->file) ||
!flagsMatch(sec))
if (!cmd->matchesFile(*sec->file, true) ||
pat.excludesFile(*sec->file) || !flagsMatch(sec))
continue;

if (sec->parent) {
Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/LinkerScript.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ class InputSectionDescription : public SectionCommand {
return c->kind == InputSectionKind;
}

bool matchesFile(const InputFile &file) const;
bool matchesFile(const InputFile &file, bool ExtractFilename) const;

// Input sections that matches at least one of SectionPatterns
// will be associated with this InputSectionDescription.
Expand Down
56 changes: 56 additions & 0 deletions lld/test/ELF/linkerscript/abs-path-match.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# REQUIRES: x86
# RUN: rm -rf %t && mkdir -p %t
# RUN: split-file %s %t && cd %t

# RUN: llvm-mc -filetype=obj -triple=x86_64 main.s -o main.o

# RUN: llvm-mc -filetype=obj -triple=x86_64 foo.s -o foo.o
# RUN: llvm-objcopy --rename-section .text=.text_foo foo.o foo.o

# RUN: llvm-mc -filetype=obj -triple=x86_64 bar.s -o bar.o
# RUN: llvm-objcopy --rename-section .text=.text_bar bar.o bar.o

# RUN: ld.lld -r main.o %t/foo.o %t/bar.o -T script.ld -o main_abs.o

# RUN: llvm-objdump -S main_abs.o > main_abs
# RUN: llvm-objdump -S main_abs.o | FileCheck %s
# CHECK: Disassembly of section .goo:


#--- foo.s
.text
.globl foo
.p2align 4
.type foo,@function
foo:
nop


#--- bar.s
.text
.globl bar
.p2align 4
.type bar,@function
bar:
nop


#--- main.s
.text
.globl main
.p2align 4
.type main,@function
main:
callq foo@PLT
callq bar@PLT
retq


#--- script.ld
SECTIONS {
.text : { *(.text) }
.goo : {
bar.o(.text_bar);
foo.o(.text_foo);
}
}