[lld] r192269 - [inputGraph] Associate Resolve state with appropriate nodes
Shankar Easwaran
shankare at codeaurora.org
Tue Oct 8 20:40:30 PDT 2013
Author: shankare
Date: Tue Oct 8 22:40:29 2013
New Revision: 192269
URL: http://llvm.org/viewvc/llvm-project?rev=192269&view=rev
Log:
[inputGraph] Associate Resolve state with appropriate nodes
This associates resolveState to FileNodes. The control node derive
their resolution state from the inputElements that are contained in
it.
This makes --start-group/--end-group to work with ELF linking.
Added:
lld/trunk/test/elf/X86_64/Inputs/group/
lld/trunk/test/elf/X86_64/Inputs/group/1.c
lld/trunk/test/elf/X86_64/Inputs/group/1.o
lld/trunk/test/elf/X86_64/Inputs/group/fn.c
lld/trunk/test/elf/X86_64/Inputs/group/fn.o
lld/trunk/test/elf/X86_64/Inputs/group/fn1.c
lld/trunk/test/elf/X86_64/Inputs/group/fn1.o
lld/trunk/test/elf/X86_64/Inputs/group/fn2.c
lld/trunk/test/elf/X86_64/Inputs/group/fn2.o
lld/trunk/test/elf/X86_64/Inputs/group/group.sh
lld/trunk/test/elf/X86_64/Inputs/group/libfn.a
lld/trunk/test/elf/X86_64/Inputs/group/libfn1.a
lld/trunk/test/elf/X86_64/startGroupEndGroup.test
Modified:
lld/trunk/include/lld/Driver/GnuLdInputGraph.h
lld/trunk/include/lld/Driver/InputGraph.h
lld/trunk/lib/Core/LinkingContext.cpp
lld/trunk/lib/Core/Resolver.cpp
lld/trunk/lib/Driver/GnuLdDriver.cpp
lld/trunk/lib/Driver/InputGraph.cpp
Modified: lld/trunk/include/lld/Driver/GnuLdInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/GnuLdInputGraph.h?rev=192269&r1=192268&r2=192269&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/GnuLdInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/GnuLdInputGraph.h Tue Oct 8 22:40:29 2013
@@ -114,10 +114,11 @@ public:
/// to start processing files as part of the inputelement from beginning.
/// reset the next file index to 0 only if the node is an archive library or
/// a shared library
- virtual void resetNextFileIndex() {
+ virtual void resetNextIndex() {
if ((!_isWholeArchive && (_files[0]->kind() == File::kindArchiveLibrary)) ||
(_files[0]->kind() == File::kindSharedLibrary))
_nextFileIndex = 0;
+ setResolveState(Resolver::StateNoChange);
return;
}
@@ -144,7 +145,8 @@ private:
/// \brief Represents a ELF control node
class ELFGroup : public Group {
public:
- ELFGroup(ELFLinkingContext &ctx) : Group(), _elfLinkingContext(ctx) {}
+ ELFGroup(ELFLinkingContext &ctx, int64_t ordinal)
+ : Group(ordinal), _elfLinkingContext(ctx) {}
static inline bool classof(const InputElement *a) {
return a->kind() == InputElement::Kind::Control;
@@ -167,42 +169,6 @@ public:
return error_code::success();
}
- /// \brief Return the file that has to be processed by the resolver
- /// to resolve atoms. This iterates over all the elements thats part
- /// of this node.
- virtual ErrorOr<File &> getNextFile() {
- // Does the linker need to process the elements again ?
- bool again = false;
- // If there are no elements, move on to the next input element
- if (_elements.size() == 0)
- return make_error_code(InputGraphError::no_more_files);
- // If we have processed all the elements as part of this node
- // check the resolver status for each input element and if the status
- // has not changed, move onto the next file.
- if (_nextElementIndex == _elements.size()) {
- for (auto &elem : _elements) {
- if (elem->getResolverState() == Resolver::StateNoChange) {
- again = true;
- break;
- }
- }
- if (!again)
- return make_error_code(InputGraphError::no_more_files);
- _nextElementIndex = 0;
- // Reset the next file to be processed as part of each element
- for (auto &elem : _elements)
- elem->resetNextFileIndex();
- }
- auto file = _elements[_nextElementIndex]->getNextFile();
- // Move on to the next element if we have finished processing all
- // the files in the input element
- if (error_code(file) == InputGraphError::no_more_files)
- _nextElementIndex++;
- else
- return *file;
- return getNextFile();
- }
-
private:
const ELFLinkingContext &_elfLinkingContext;
};
Modified: lld/trunk/include/lld/Driver/InputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/InputGraph.h?rev=192269&r1=192268&r2=192269&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/InputGraph.h (original)
+++ lld/trunk/include/lld/Driver/InputGraph.h Tue Oct 8 22:40:29 2013
@@ -173,21 +173,19 @@ public:
/// Get the next file to be processed by the resolver
virtual ErrorOr<File &> getNextFile() = 0;
- /// \brief Set the resolver state for the element
- virtual void setResolverState(int32_t state) { _resolveState = state; }
+ /// \brief Set the resolve state for the element
+ virtual void setResolveState(uint32_t state) = 0;
- /// \brief Get the resolver state for the element
- virtual int32_t getResolverState() const { return _resolveState; }
+ /// \brief Get the resolve state for the element
+ virtual uint32_t getResolveState() const = 0;
- /// Process files again.
- virtual void resetNextFileIndex() { _nextFileIndex = 0; }
+ /// \brief Reset the next index
+ virtual void resetNextIndex() = 0;
protected:
Kind _kind; // The type of the Element
int64_t _ordinal; // The ordinal value
int64_t _weight; // Weight of the file
- int32_t _resolveState; // The resolve state
- uint32_t _nextFileIndex; // The file that would be processed by the resolver
};
/// \brief The Control class represents a control node in the InputGraph
@@ -204,7 +202,8 @@ public:
ControlNode::ControlKind::Simple,
int64_t _ordinal = -1)
: InputElement(InputElement::Kind::Control, _ordinal),
- _controlKind(controlKind), _nextElementIndex(0) {}
+ _controlKind(controlKind), _currentElementIndex(0),
+ _nextElementIndex(0) {}
virtual ~ControlNode() {}
@@ -233,9 +232,20 @@ public:
/// in the InputElement
virtual void assignFileOrdinals(uint64_t &startOrdinal);
+ virtual void resetNextIndex() {
+ _currentElementIndex = _nextElementIndex = 0;
+ for (auto &elem : _elements)
+ elem->resetNextIndex();
+ }
+
+ virtual uint32_t getResolveState() const;
+
+ virtual void setResolveState(uint32_t);
+
protected:
ControlKind _controlKind;
InputGraph::InputElementVectorT _elements;
+ uint32_t _currentElementIndex;
uint32_t _nextElementIndex;
};
@@ -246,8 +256,7 @@ protected:
/// directly.
class FileNode : public InputElement {
public:
- FileNode(StringRef path, int64_t ordinal = -1)
- : InputElement(InputElement::Kind::File, ordinal), _path(path) {}
+ FileNode(StringRef path, int64_t ordinal = -1);
virtual ErrorOr<StringRef> getPath(const LinkingContext &) const {
return _path;
@@ -301,13 +310,29 @@ public:
/// in the InputElement
virtual void assignFileOrdinals(uint64_t &startOrdinal);
+ /// \brief Reset the file index if the resolver needs to process
+ /// the node again.
+ virtual void resetNextIndex();
+
+ /// \brief Set the resolve state for the FileNode.
+ virtual void setResolveState(uint32_t resolveState) {
+ _resolveState = resolveState;
+ }
+
+ /// \brief Retrieve the resolve state of the FileNode.
+ virtual uint32_t getResolveState() const { return _resolveState; }
+
protected:
/// \brief Read the file into _buffer.
error_code readFile(const LinkingContext &ctx, raw_ostream &diagnostics);
- StringRef _path;
- InputGraph::FileVectorT _files;
- std::unique_ptr<llvm::MemoryBuffer> _buffer;
+ StringRef _path; // The path of the Input file
+ InputGraph::FileVectorT _files; // A vector of lld File objects
+ std::unique_ptr<llvm::MemoryBuffer> _buffer; // Memory buffer to actual
+ // contents
+ uint32_t _resolveState; // The resolve state of the file
+ uint32_t _nextFileIndex; // The next file that would be processed by the
+ // resolver
};
/// \brief A Control node which contains a group of InputElements
@@ -316,23 +341,26 @@ protected:
/// follow the group
class Group : public ControlNode {
public:
- Group() : ControlNode(ControlNode::ControlKind::Group) {}
+ Group(int64_t ordinal)
+ : ControlNode(ControlNode::ControlKind::Group, ordinal) {}
static inline bool classof(const InputElement *a) {
return a->kind() == InputElement::Kind::Control;
}
+ /// \brief Process input element and add it to the group
virtual bool processInputElement(std::unique_ptr<InputElement> element) {
_elements.push_back(std::move(element));
return true;
}
+
+ virtual ErrorOr<File &> getNextFile();
};
/// \brief Represents Internal Input files
class SimpleFileNode : public InputElement {
public:
- SimpleFileNode(StringRef path, int64_t ordinal = -1)
- : InputElement(InputElement::Kind::SimpleFile, ordinal), _path(path) {}
+ SimpleFileNode(StringRef path, int64_t ordinal = -1);
virtual llvm::ErrorOr<StringRef> path(const LinkingContext &) const {
return _path;
@@ -379,22 +407,35 @@ public:
return error_code::success();
}
+ /// \brief Return the next File thats part of this node to the
+ /// resolver.
virtual ErrorOr<File &> getNextFile() {
if (_nextFileIndex == _files.size())
return make_error_code(InputGraphError::no_more_files);
return *_files[_nextFileIndex++];
}
+ /// \brief Set the resolver state.
+ virtual void setResolveState(uint32_t resolveState) {
+ _resolveState = resolveState;
+ }
+
+ /// \brief Retrieve the resolve state.
+ virtual uint32_t getResolveState() const { return _resolveState; }
+
// Do nothing here.
- virtual void resetNextFileIndex() {}
+ virtual void resetNextIndex() {}
/// \brief Assign File ordinals for files contained
/// in the InputElement
virtual void assignFileOrdinals(uint64_t &startOrdinal);
protected:
- StringRef _path;
- InputGraph::FileVectorT _files;
+ StringRef _path; // A string associated with this file.
+ InputGraph::FileVectorT _files; // Vector of lld::File objects
+ uint32_t _nextFileIndex; // The next file that would be processed by the
+ // resolver
+ uint32_t _resolveState; // The resolve state associated with this Node
};
} // namespace lld
Modified: lld/trunk/lib/Core/LinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/LinkingContext.cpp?rev=192269&r1=192268&r2=192269&view=diff
==============================================================================
--- lld/trunk/lib/Core/LinkingContext.cpp (original)
+++ lld/trunk/lib/Core/LinkingContext.cpp Tue Oct 8 22:40:29 2013
@@ -77,7 +77,7 @@ bool LinkingContext::createInternalFiles
}
void LinkingContext::setResolverState(uint32_t state) {
- _currentInputElement->setResolverState(state);
+ _currentInputElement->setResolveState(state);
}
ErrorOr<File &> LinkingContext::nextFile() {
Modified: lld/trunk/lib/Core/Resolver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=192269&r1=192268&r2=192269&view=diff
==============================================================================
--- lld/trunk/lib/Core/Resolver.cpp (original)
+++ lld/trunk/lib/Core/Resolver.cpp Tue Oct 8 22:40:29 2013
@@ -292,6 +292,7 @@ void Resolver::resolveUndefines() {
ScopedTask task(getDefaultDomain(), "resolveUndefines");
while (ErrorOr<File &> nextFile = _context.nextFile()) {
+ _context.setResolverState(Resolver::StateNoChange);
if (error_code(nextFile) == InputGraphError::no_more_files)
break;
if (nextFile->kind() == File::kindObject)
Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=192269&r1=192268&r2=192269&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Tue Oct 8 22:40:29 2013
@@ -254,7 +254,7 @@ bool GnuLdDriver::parse(int argc, const
break;
case OPT_start_group: {
- std::unique_ptr<InputElement> controlStart(new ELFGroup(*ctx));
+ std::unique_ptr<InputElement> controlStart(new ELFGroup(*ctx, index++));
controlNodeStack.push(controlStart.get());
(llvm::dyn_cast<ControlNode>)(controlNodeStack.top())
->processControlEnter();
@@ -266,13 +266,13 @@ bool GnuLdDriver::parse(int argc, const
(llvm::dyn_cast<ControlNode>)(controlNodeStack.top())
->processControlExit();
controlNodeStack.pop();
- return true;
+ break;
case OPT_INPUT:
case OPT_l: {
std::unique_ptr<InputElement> inputFile =
std::move(std::unique_ptr<InputElement>(new ELFFileNode(
- *ctx, inputArg->getValue(), searchPath, index, isWholeArchive,
+ *ctx, inputArg->getValue(), searchPath, index++, isWholeArchive,
asNeeded, inputArg->getOption().getID() == OPT_l)));
if (controlNodeStack.empty())
inputGraph->addInputElement(std::move(inputFile));
Modified: lld/trunk/lib/Driver/InputGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/InputGraph.cpp?rev=192269&r1=192268&r2=192269&view=diff
==============================================================================
--- lld/trunk/lib/Driver/InputGraph.cpp (original)
+++ lld/trunk/lib/Driver/InputGraph.cpp Tue Oct 8 22:40:29 2013
@@ -53,6 +53,7 @@ bool InputGraph::dump(raw_ostream &diagn
return true;
}
+/// \brief Insert element at position
void InputGraph::insertElementsAt(
std::vector<std::unique_ptr<InputElement> > inputElements,
Position position, size_t pos) {
@@ -95,7 +96,11 @@ ErrorOr<void> InputGraph::setNextElement
/// is initially set to -1, if the user wants to override its ordinal,
/// let the user do it
InputElement::InputElement(Kind type, int64_t ordinal)
- : _kind(type), _ordinal(ordinal), _weight(0),
+ : _kind(type), _ordinal(ordinal), _weight(0) {}
+
+/// FileNode
+FileNode::FileNode(StringRef path, int64_t ordinal)
+ : InputElement(InputElement::Kind::File, ordinal), _path(path),
_resolveState(Resolver::StateNoChange), _nextFileIndex(0) {}
/// \brief Assign File ordinals for files contained
@@ -133,6 +138,14 @@ FileNode::readFile(const LinkingContext
return error_code::success();
}
+// Reset the next file that would be be processed by the resolver.
+// Reset the resolve state too.
+void FileNode::resetNextIndex() {
+ _nextFileIndex = 0;
+ setResolveState(Resolver::StateNoChange);
+}
+
+/// ControlNode
/// \brief Assign File ordinals for files contained
/// in the InputElement
@@ -141,9 +154,61 @@ void ControlNode::assignFileOrdinals(uin
elem->assignFileOrdinals(startOrdinal);
}
+/// \brief Get the resolver State. The return value of the resolve
+/// state for a control node is the or'ed value of the resolve states
+/// contained in it.
+uint32_t ControlNode::getResolveState() const {
+ uint32_t resolveState = Resolver::StateNoChange;
+ for (auto &elem : _elements)
+ resolveState |= elem->getResolveState();
+ return resolveState;
+}
+
+/// \brief Set the resolve state for the current element
+/// thats processed by the resolver.
+void ControlNode::setResolveState(uint32_t resolveState) {
+ if (_elements.size() == 0)
+ return;
+ _elements[_currentElementIndex]->setResolveState(resolveState);
+}
+
+/// SimpleFileNode
+
+SimpleFileNode::SimpleFileNode(StringRef path, int64_t ordinal)
+ : InputElement(InputElement::Kind::SimpleFile, ordinal), _path(path),
+ _nextFileIndex(0), _resolveState(Resolver::StateNoChange) {}
+
/// \brief Assign File ordinals for files contained
/// in the InputElement
void SimpleFileNode::assignFileOrdinals(uint64_t &startOrdinal) {
for (auto &file : _files)
file->setOrdinalAndIncrement(startOrdinal);
}
+
+/// Group
+
+/// \brief Return the next file that need to be processed by the resolver.
+/// This also processes input elements depending on the resolve status
+/// of the input elements contained in the group.
+ErrorOr<File &> Group::getNextFile() {
+ // If there are no elements, move on to the next input element
+ if (_elements.size() == 0)
+ return make_error_code(InputGraphError::no_more_files);
+ // If we have processed all the elements as part of this node
+ // check the resolver status for each input element and if the status
+ // has not changed, move onto the next file.
+ if (_nextElementIndex == _elements.size()) {
+ if (getResolveState() == Resolver::StateNoChange)
+ return make_error_code(InputGraphError::no_more_files);
+ resetNextIndex();
+ }
+ _currentElementIndex = _nextElementIndex;
+ auto file = _elements[_nextElementIndex]->getNextFile();
+ // Move on to the next element if we have finished processing all
+ // the files in the input element
+ if (error_code(file) == InputGraphError::no_more_files)
+ _nextElementIndex++;
+ else
+ return *file;
+ return getNextFile();
+}
Added: lld/trunk/test/elf/X86_64/Inputs/group/1.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/group/1.c?rev=192269&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/Inputs/group/1.c (added)
+++ lld/trunk/test/elf/X86_64/Inputs/group/1.c Tue Oct 8 22:40:29 2013
@@ -0,0 +1,8 @@
+int _start() {
+ return 0;
+}
+
+int main() {
+fn();
+return 0;
+}
Added: lld/trunk/test/elf/X86_64/Inputs/group/1.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/group/1.o?rev=192269&view=auto
==============================================================================
Binary files lld/trunk/test/elf/X86_64/Inputs/group/1.o (added) and lld/trunk/test/elf/X86_64/Inputs/group/1.o Tue Oct 8 22:40:29 2013 differ
Added: lld/trunk/test/elf/X86_64/Inputs/group/fn.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/group/fn.c?rev=192269&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/Inputs/group/fn.c (added)
+++ lld/trunk/test/elf/X86_64/Inputs/group/fn.c Tue Oct 8 22:40:29 2013
@@ -0,0 +1,4 @@
+int fn() {
+fn1();
+return 0;
+}
Added: lld/trunk/test/elf/X86_64/Inputs/group/fn.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/group/fn.o?rev=192269&view=auto
==============================================================================
Binary files lld/trunk/test/elf/X86_64/Inputs/group/fn.o (added) and lld/trunk/test/elf/X86_64/Inputs/group/fn.o Tue Oct 8 22:40:29 2013 differ
Added: lld/trunk/test/elf/X86_64/Inputs/group/fn1.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/group/fn1.c?rev=192269&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/Inputs/group/fn1.c (added)
+++ lld/trunk/test/elf/X86_64/Inputs/group/fn1.c Tue Oct 8 22:40:29 2013
@@ -0,0 +1,3 @@
+int fn1() {
+fn2();
+}
Added: lld/trunk/test/elf/X86_64/Inputs/group/fn1.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/group/fn1.o?rev=192269&view=auto
==============================================================================
Binary files lld/trunk/test/elf/X86_64/Inputs/group/fn1.o (added) and lld/trunk/test/elf/X86_64/Inputs/group/fn1.o Tue Oct 8 22:40:29 2013 differ
Added: lld/trunk/test/elf/X86_64/Inputs/group/fn2.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/group/fn2.c?rev=192269&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/Inputs/group/fn2.c (added)
+++ lld/trunk/test/elf/X86_64/Inputs/group/fn2.c Tue Oct 8 22:40:29 2013
@@ -0,0 +1,3 @@
+int fn2() {
+return 0;
+}
Added: lld/trunk/test/elf/X86_64/Inputs/group/fn2.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/group/fn2.o?rev=192269&view=auto
==============================================================================
Binary files lld/trunk/test/elf/X86_64/Inputs/group/fn2.o (added) and lld/trunk/test/elf/X86_64/Inputs/group/fn2.o Tue Oct 8 22:40:29 2013 differ
Added: lld/trunk/test/elf/X86_64/Inputs/group/group.sh
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/group/group.sh?rev=192269&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/Inputs/group/group.sh (added)
+++ lld/trunk/test/elf/X86_64/Inputs/group/group.sh Tue Oct 8 22:40:29 2013
@@ -0,0 +1,37 @@
+cat > 1.c << \!
+int _start() {
+ return 0;
+}
+
+int main() {
+fn();
+return 0;
+}
+!
+
+cat > fn.c << \!
+int fn() {
+fn1();
+return 0;
+}
+!
+
+cat > fn2.c << \!
+int fn2() {
+return 0;
+}
+!
+
+cat > fn1.c << \!
+int fn1() {
+fn2();
+}
+!
+
+gcc -c 1.c fn.c fn2.c fn1.c
+ar cr libfn.a fn.o fn2.o
+ar cr libfn1.a fn1.o
+lld -flavor gnu -target x86_64 1.o libfn.a libfn1.a -o x
+lld -flavor gnu -target x86_64 1.o --start-group libfn.a libfn1.a --end-group -o x
+lld -flavor gnu -target x86_64 1.o --start-group fn.o fn2.o fn1.o --end-group -o x
+lld -flavor gnu -target x86_64 1.o --start-group --whole-archive libfn.a --no-whole-archive libfn1.a --end-group -o x
Added: lld/trunk/test/elf/X86_64/Inputs/group/libfn.a
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/group/libfn.a?rev=192269&view=auto
==============================================================================
Binary files lld/trunk/test/elf/X86_64/Inputs/group/libfn.a (added) and lld/trunk/test/elf/X86_64/Inputs/group/libfn.a Tue Oct 8 22:40:29 2013 differ
Added: lld/trunk/test/elf/X86_64/Inputs/group/libfn1.a
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/Inputs/group/libfn1.a?rev=192269&view=auto
==============================================================================
Binary files lld/trunk/test/elf/X86_64/Inputs/group/libfn1.a (added) and lld/trunk/test/elf/X86_64/Inputs/group/libfn1.a Tue Oct 8 22:40:29 2013 differ
Added: lld/trunk/test/elf/X86_64/startGroupEndGroup.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/startGroupEndGroup.test?rev=192269&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/startGroupEndGroup.test (added)
+++ lld/trunk/test/elf/X86_64/startGroupEndGroup.test Tue Oct 8 22:40:29 2013
@@ -0,0 +1,27 @@
+# This tests functionality of --start-group, --end-group
+
+# This link should fail with unresolve symbol
+RUN: not lld -flavor gnu -target x86_64 %p/Inputs/group/1.o %p/Inputs/group/libfn.a \
+RUN: %p/Inputs/group/libfn1.a -o x 2> %t.err
+
+# Test group
+RUN: lld -flavor gnu -target x86_64 %p/Inputs/group/1.o --start-group \
+RUN: %p/Inputs/group/libfn.a %p/Inputs/group/libfn1.a --end-group -o %t1
+
+# Mix object files in group
+RUN: lld -flavor gnu -target x86_64 %p/Inputs/group/1.o --start-group \
+RUN: %p/Inputs/group/fn.o %p/Inputs/group/fn2.o \
+RUN: %p/Inputs/group/fn1.o --end-group -o %t2
+
+# Mix Whole archive input, the group should not iterate the file libfn.a
+RUN: lld -flavor gnu -target x86_64 %p/Inputs/group/1.o --start-group \
+RUN: --whole-archive %p/Inputs/group/libfn.a --no-whole-archive %p/Inputs/group/libfn1.a --end-group -o %t3
+
+RUN: FileCheck --check-prefix=UNRESOLVED %s < %t.err
+RUN: llvm-nm %t1 | FileCheck -check-prefix=RESOLVEDEXTERNAL %s
+RUN: llvm-nm %t2 | FileCheck -check-prefix=RESOLVEDEXTERNAL %s
+RUN: llvm-nm %t3 | FileCheck -check-prefix=RESOLVEDEXTERNAL %s
+
+UNRESOLVED: Undefined Symbol: {{[\/0-9A-Za-z_]+}}libfn1.a(fn1.o) : fn2
+
+RESOLVEDEXTERNAL: {{[0-9a-z]+}} T fn2
More information about the llvm-commits
mailing list