diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index cf1b6465eac3..34fda2d2cc23 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -39,12 +39,14 @@ private: void readAsNeeded(); void readEntry(); void readGroup(); + void readInclude(); void readOutput(); void readOutputFormat(); void readSearchDir(); std::vector Tokens; size_t Pos = 0; + static std::vector> OwningMBs; }; } @@ -55,6 +57,8 @@ void LinkerScript::run() { readEntry(); } else if (Tok == "GROUP") { readGroup(); + } else if (Tok == "INCLUDE") { + readInclude(); } else if (Tok == "OUTPUT") { readOutput(); } else if (Tok == "OUTPUT_FORMAT") { @@ -160,6 +164,16 @@ void LinkerScript::readGroup() { } } +void LinkerScript::readInclude() { + StringRef Tok = next(); + auto MBOrErr = MemoryBuffer::getFile(Tok); + error(MBOrErr, Twine("cannot open ") + Tok); + std::unique_ptr &MB = *MBOrErr; + std::vector V = tokenize(MB->getMemBufferRef().getBuffer()); + Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end()); + OwningMBs.push_back(std::move(MB)); // keep ownership of MB +} + void LinkerScript::readOutput() { // -o takes predecence over OUTPUT(). expect("("); @@ -182,6 +196,8 @@ void LinkerScript::readSearchDir() { expect(")"); } +std::vector> LinkerScript::OwningMBs; + // Entry point. The other functions or classes are private to this file. void lld::elf2::readLinkerScript(MemoryBufferRef MB) { LinkerScript(MB.getBuffer()).run(); diff --git a/lld/test/elf2/linkerscript.s b/lld/test/elf2/linkerscript.s index d45143f212ff..a280ed9e3992 100644 --- a/lld/test/elf2/linkerscript.s +++ b/lld/test/elf2/linkerscript.s @@ -47,6 +47,11 @@ # RUN: ld.lld2 %t.script %t # RUN: llvm-readobj %t.out > /dev/null +# RUN: echo "INCLUDE " %t.script2 "OUTPUT(" %t.out ")" > %t.script1 +# RUN: echo "GROUP(" %t ")" > %t.script2 +# RUN: ld.lld2 %t.script1 +# RUN: llvm-readobj %t2 > /dev/null + # RUN: echo "FOO(BAR)" > %t.script # RUN: not ld.lld2 -o foo %t.script > %t.log 2>&1 # RUN: FileCheck -check-prefix=ERR1 %s < %t.log