diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 921128dae2bdb..c325f18616fe3 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -411,7 +411,17 @@ 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; @@ -419,10 +429,17 @@ bool InputSectionDescription::matchesFile(const InputFile &file) const { 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); + } } } @@ -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 && @@ -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) { diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index 80c4f564afabc..452cfbcd9b777 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -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. diff --git a/lld/test/ELF/linkerscript/abs-path-match.s b/lld/test/ELF/linkerscript/abs-path-match.s new file mode 100644 index 0000000000000..cc31dcd1e8031 --- /dev/null +++ b/lld/test/ELF/linkerscript/abs-path-match.s @@ -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); + } +} \ No newline at end of file