[llvm-commits] [lld] r155183 - in /lld/trunk: include/lld/Core/ lib/Core/ test/ test/darwin/ tools/lld-core/
Nick Kledzik
kledzik at apple.com
Thu Apr 19 18:24:37 PDT 2012
Author: kledzik
Date: Thu Apr 19 20:24:37 2012
New Revision: 155183
URL: http://llvm.org/viewvc/llvm-project?rev=155183&view=rev
Log:
Add way to represent static archives in yaml test cases.
Add SharedLibraryFile and ArchiveLibraryFile subclasses of File.
Add command line options to lld-core to set various ResolverOptions settings
and added lots of test cases to verify the options work.
Added:
lld/trunk/include/lld/Core/ArchiveLibraryFile.h
lld/trunk/include/lld/Core/SharedLibraryFile.h
lld/trunk/lib/Core/InputFiles.cpp
lld/trunk/test/archive-basic.objtxt
lld/trunk/test/archive-chain.objtxt
lld/trunk/test/archive-tentdef-search.objtxt
lld/trunk/test/dead-strip-basic.objtxt
lld/trunk/test/dead-strip-globals.objtxt
Modified:
lld/trunk/include/lld/Core/File.h
lld/trunk/include/lld/Core/InputFiles.h
lld/trunk/include/lld/Core/SymbolTable.h
lld/trunk/lib/Core/CMakeLists.txt
lld/trunk/lib/Core/Resolver.cpp
lld/trunk/lib/Core/SymbolTable.cpp
lld/trunk/lib/Core/YamlKeyValues.cpp
lld/trunk/lib/Core/YamlKeyValues.h
lld/trunk/lib/Core/YamlReader.cpp
lld/trunk/test/darwin/hello-world.objtxt
lld/trunk/test/pass-got-basic.objtxt
lld/trunk/test/pass-stubs-basic.objtxt
lld/trunk/test/undef-coalesce-error.objtxt
lld/trunk/tools/lld-core/lld-core.cpp
Added: lld/trunk/include/lld/Core/ArchiveLibraryFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/ArchiveLibraryFile.h?rev=155183&view=auto
==============================================================================
--- lld/trunk/include/lld/Core/ArchiveLibraryFile.h (added)
+++ lld/trunk/include/lld/Core/ArchiveLibraryFile.h Thu Apr 19 20:24:37 2012
@@ -0,0 +1,54 @@
+//===- Core/ArchiveLibraryFile.h - Models static library ------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_CORE_ARCHIVE_LIBRARY_FILE_H_
+#define LLD_CORE_ARCHIVE_LIBRARY_FILE_H_
+
+#include "lld/Core/File.h"
+
+namespace lld {
+
+
+///
+/// The ArchiveLibraryFile subclass of File is used to represent unix
+/// static library archives. These libraries provide no atoms to the
+/// initial set of atoms linked. Instead, when the Resolver will query
+/// ArchiveLibraryFile instances for specific symbols names using the
+/// find() method. If the archive contains an object file which has a
+/// DefinedAtom whose scope is not translationUnit, then that entire
+/// object file File is returned.
+///
+class ArchiveLibraryFile : public File {
+public:
+ ArchiveLibraryFile(StringRef path) : File(path) {
+ }
+
+ virtual ~ArchiveLibraryFile() {
+ }
+
+ virtual Kind kind() const {
+ return kindArchiveLibrary;
+ }
+
+ static inline bool classof(const File *f) {
+ return f->kind() == kindArchiveLibrary;
+ }
+ static inline bool classof(const ArchiveLibraryFile *) {
+ return true;
+ }
+
+ /// Check if any member of the archive contains an Atom with the
+ /// specified name and return the File object for that member, or nullptr.
+ virtual const File *find(StringRef name, bool dataSymbolOnly) const = 0;
+
+};
+
+} // namespace lld
+
+#endif // LLD_CORE_ARCHIVE_LIBRARY_FILE_H_
Modified: lld/trunk/include/lld/Core/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/File.h?rev=155183&r1=155182&r2=155183&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/File.h (original)
+++ lld/trunk/include/lld/Core/File.h Thu Apr 19 20:24:37 2012
@@ -27,8 +27,11 @@
/// object file (.o) to be parsed by some reader and produce a single
/// File object that represents the content of that object file.
///
-/// The File class has *begin() and *end() methods for use iterating through
-/// the Atoms in a File object.
+/// To iterate through the Atoms in a File there are four methods that
+/// return collections. For instance to iterate through all the DefinedAtoms
+/// in a File object use:
+/// for (const DefinedAtoms *atom : file->defined()) {
+/// }
///
/// The Atom objects in a File are owned by the File object. The Atom objects
/// are destroyed when the File object is destroyed.
@@ -37,6 +40,18 @@
public:
virtual ~File();
+ /// Kinds of files that are supported.
+ enum Kind {
+ kindObject, ///< object file (.o)
+ kindSharedLibrary, ///< shared library (.so)
+ kindArchiveLibrary, ///< archive (.a)
+ };
+
+ /// Returns file kind. Need for dyn_cast<> on File objects.
+ virtual Kind kind() const {
+ return kindObject;
+ }
+
/// For error messages and debugging, this returns the path to the file
/// which was used to create this object (e.g. "/tmp/foo.o").
StringRef path() const {
@@ -49,6 +64,11 @@
/// be ascertained, this method returns the empty string.
virtual StringRef translationUnitSource() const;
+
+ static inline bool classof(const File *) {
+ return true;
+ }
+
protected:
template <typename T> class atom_iterator; // forward reference
public:
@@ -144,7 +164,7 @@
/// Must be implemented to return the atom_collection object for
/// all AbsoluteAtoms in this File.
virtual const atom_collection<AbsoluteAtom>& absolute() const = 0;
-
+
protected:
/// This is a convenience class for File subclasses which manage their
/// atoms as a simple std::vector<>.
@@ -152,11 +172,12 @@
class atom_collection_vector : public atom_collection<T> {
public:
virtual atom_iterator<T> begin() const {
- return atom_iterator<T>(*this, reinterpret_cast<const void*>(_atoms.data()));
+ return atom_iterator<T>(*this, reinterpret_cast<const void*>
+ (_atoms.data()));
}
virtual atom_iterator<T> end() const{
return atom_iterator<T>(*this, reinterpret_cast<const void*>
- (_atoms.data() + _atoms.size()));
+ (_atoms.data() + _atoms.size()));
}
virtual const T* deref(const void* it) const {
return *reinterpret_cast<const T* const*>(it);
@@ -169,8 +190,6 @@
std::vector<const T*> _atoms;
};
-
-private:
StringRef _path;
};
Modified: lld/trunk/include/lld/Core/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/InputFiles.h?rev=155183&r1=155182&r2=155183&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/InputFiles.h (original)
+++ lld/trunk/include/lld/Core/InputFiles.h Thu Apr 19 20:24:37 2012
@@ -34,23 +34,30 @@
virtual void doAbsoluteAtom(const class AbsoluteAtom &) = 0;
};
+ InputFiles();
+ virtual ~InputFiles();
/// Used by platforms to insert platform specific files.
- virtual void prependFile(const File&) = 0;
+ virtual void prependFile(const File&);
/// Used by platforms to insert platform specific files.
- virtual void appendFile(const File&) = 0;
+ virtual void appendFile(const File&);
/// @brief iterates all atoms in initial files
- virtual void forEachInitialAtom(Handler &) const = 0;
+ virtual void forEachInitialAtom(Handler &) const;
/// @brief searches libraries for name
virtual bool searchLibraries( StringRef name
- , bool searchDylibs
+ , bool searchSharedLibs
, bool searchArchives
, bool dataSymbolOnly
- , Handler &) const = 0;
+ , Handler &) const;
+
+protected:
+ void handleFile(const File *file, InputFiles::Handler &handler) const;
+
+ std::vector<const File*> _files;
};
} // namespace lld
Added: lld/trunk/include/lld/Core/SharedLibraryFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/SharedLibraryFile.h?rev=155183&view=auto
==============================================================================
--- lld/trunk/include/lld/Core/SharedLibraryFile.h (added)
+++ lld/trunk/include/lld/Core/SharedLibraryFile.h Thu Apr 19 20:24:37 2012
@@ -0,0 +1,52 @@
+//===- Core/SharedLibraryFile.h - Models shared libraries as Atoms --------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_CORE_SHARED_LIBRARY_FILE_H_
+#define LLD_CORE_SHARED_LIBRARY_FILE_H_
+
+#include "lld/Core/File.h"
+#include "lld/Core/SharedLibraryAtom.h"
+
+namespace lld {
+
+
+///
+/// The SharedLibraryFile subclass of File is used to represent dynamic
+/// shared libraries being linked against.
+///
+class SharedLibraryFile : public File {
+public:
+ SharedLibraryFile(StringRef path) : File(path) {
+ }
+ virtual ~SharedLibraryFile() {
+ }
+
+ virtual Kind kind() const {
+ return kindSharedLibrary;
+ }
+
+ static inline bool classof(const File *f) {
+ return f->kind() == kindSharedLibrary;
+ }
+ static inline bool classof(const SharedLibraryFile *) {
+ return true;
+ }
+
+
+ /// Check if the shared library exports a symbol with the specified name.
+ /// If so, return a SharedLibraryAtom which represents that exported
+ /// symbol. Otherwise return nullptr.
+ virtual const SharedLibraryAtom *exports(StringRef name,
+ bool dataSymbolOnly) const;
+
+};
+
+} // namespace lld
+
+#endif // LLD_CORE_SHARED_LIBRARY_FILE_H_
Modified: lld/trunk/include/lld/Core/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/SymbolTable.h?rev=155183&r1=155182&r2=155183&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/SymbolTable.h (original)
+++ lld/trunk/include/lld/Core/SymbolTable.h Thu Apr 19 20:24:37 2012
@@ -59,6 +59,9 @@
/// @brief returns vector of remaining UndefinedAtoms
void undefines(std::vector<const Atom *>&);
+
+ /// returns vector of tentative definitions
+ void tentativeDefinitions(std::vector<StringRef> &);
/// @brief count of by-name entries in symbol table
unsigned int size();
Modified: lld/trunk/lib/Core/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/CMakeLists.txt?rev=155183&r1=155182&r2=155183&view=diff
==============================================================================
--- lld/trunk/lib/Core/CMakeLists.txt (original)
+++ lld/trunk/lib/Core/CMakeLists.txt Thu Apr 19 20:24:37 2012
@@ -1,6 +1,7 @@
add_lld_library(lldCore
Error.cpp
File.cpp
+ InputFiles.cpp
NativeFileFormat.h
NativeReader.cpp
NativeWriter.cpp
Added: lld/trunk/lib/Core/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/InputFiles.cpp?rev=155183&view=auto
==============================================================================
--- lld/trunk/lib/Core/InputFiles.cpp (added)
+++ lld/trunk/lib/Core/InputFiles.cpp Thu Apr 19 20:24:37 2012
@@ -0,0 +1,84 @@
+//===- Core/InputFiles.cpp - Manages list of Files -----------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lld/Core/InputFiles.h"
+#include "lld/Core/SharedLibraryFile.h"
+#include "lld/Core/ArchiveLibraryFile.h"
+#include "lld/Core/LLVM.h"
+
+namespace lld {
+
+InputFiles::InputFiles() {
+}
+
+
+InputFiles::~InputFiles() {
+}
+
+void InputFiles::forEachInitialAtom(InputFiles::Handler &handler) const {
+ for ( const File *file : _files ) {
+ this->handleFile(file, handler);
+ }
+}
+
+void InputFiles::prependFile(const File &file) {
+ _files.insert(_files.begin(), &file);
+}
+
+void InputFiles::appendFile(const File &file) {
+ _files.push_back(&file);
+}
+
+
+bool InputFiles::searchLibraries(StringRef name, bool searchSharedLibs,
+ bool searchArchives, bool dataSymbolOnly,
+ InputFiles::Handler &handler) const {
+
+ for ( const File *file : _files ) {
+ if ( searchSharedLibs ) {
+ if (const SharedLibraryFile *shlib = dyn_cast<SharedLibraryFile>(file)) {
+ if ( const SharedLibraryAtom* shAtom = shlib->exports(name,
+ dataSymbolOnly) ) {
+ handler.doSharedLibraryAtom(*shAtom);
+ return true;
+ }
+ }
+ }
+ if ( searchArchives ) {
+ if (const ArchiveLibraryFile *lib = dyn_cast<ArchiveLibraryFile>(file)) {
+ if ( const File *member = lib->find(name, dataSymbolOnly) ) {
+ this->handleFile(member, handler);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+
+void InputFiles::handleFile(const File *file,
+ InputFiles::Handler &handler) const {
+ handler.doFile(*file);
+ for( const DefinedAtom *atom : file->defined() ) {
+ handler.doDefinedAtom(*atom);
+ }
+ for( const UndefinedAtom *undefAtom : file->undefined() ) {
+ handler.doUndefinedAtom(*undefAtom);
+ }
+ for( const SharedLibraryAtom *shlibAtom : file->sharedLibrary() ) {
+ handler.doSharedLibraryAtom(*shlibAtom);
+ }
+ for( const AbsoluteAtom *absAtom : file->absolute() ) {
+ handler.doAbsoluteAtom(*absAtom);
+ }
+}
+
+
+} // namespace lld
Modified: lld/trunk/lib/Core/Resolver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=155183&r1=155182&r2=155183&view=diff
==============================================================================
--- lld/trunk/lib/Core/Resolver.cpp (original)
+++ lld/trunk/lib/Core/Resolver.cpp Thu Apr 19 20:24:37 2012
@@ -137,7 +137,7 @@
void Resolver::resolveUndefines() {
const bool searchArchives =
_options.searchArchivesToOverrideTentativeDefinitions();
- const bool searchDylibs =
+ const bool searchSharedLibs =
_options.searchSharedLibrariesToOverrideTentativeDefinitions();
// keep looping until no more undefines were added in last loop
@@ -154,24 +154,20 @@
}
}
// search libraries for overrides of common symbols
- if (searchArchives || searchDylibs) {
- std::vector<const Atom *> tents;
- for ( const Atom *tent : tents ) {
- if (const DefinedAtom* defAtom = dyn_cast<DefinedAtom>(tent)) {
- if ( defAtom->merge() == DefinedAtom::mergeAsTentative )
- tents.push_back(defAtom);
- }
- }
- for ( const Atom *tent : tents ) {
- // load for previous tentative may also have loaded
- // this tentative, so check again
- StringRef tentName = tent->name();
- const Atom *curAtom = _symbolTable.findByName(tentName);
+ if (searchArchives || searchSharedLibs) {
+ std::vector<StringRef> tentDefNames;
+ _symbolTable.tentativeDefinitions(tentDefNames);
+ for ( StringRef tentDefName : tentDefNames ) {
+ // Load for previous tentative may also have loaded
+ // something that overrode this tentative, so always check.
+ const Atom *curAtom = _symbolTable.findByName(tentDefName);
assert(curAtom != nullptr);
if (const DefinedAtom* curDefAtom = dyn_cast<DefinedAtom>(curAtom)) {
- if (curDefAtom->merge() == DefinedAtom::mergeAsTentative )
- _inputFiles.searchLibraries(tentName, searchDylibs,
- true, true, *this);
+ if (curDefAtom->merge() == DefinedAtom::mergeAsTentative ) {
+ // Still tentative definition, so look for override.
+ _inputFiles.searchLibraries(tentDefName, searchSharedLibs,
+ searchArchives, true, *this);
+ }
}
}
}
Modified: lld/trunk/lib/Core/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/SymbolTable.cpp?rev=155183&r1=155182&r2=155183&view=diff
==============================================================================
--- lld/trunk/lib/Core/SymbolTable.cpp (original)
+++ lld/trunk/lib/Core/SymbolTable.cpp Thu Apr 19 20:24:37 2012
@@ -330,4 +330,16 @@
}
}
+void SymbolTable::tentativeDefinitions(std::vector<StringRef> &names) {
+ for (auto entry : _nameTable) {
+ const Atom *atom = entry.second;
+ StringRef name = entry.first;
+ assert(atom != nullptr);
+ if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom) ) {
+ if ( defAtom->merge() == DefinedAtom::mergeAsTentative )
+ names.push_back(name);
+ }
+ }
+}
+
} // namespace lld
Modified: lld/trunk/lib/Core/YamlKeyValues.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.cpp?rev=155183&r1=155182&r2=155183&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlKeyValues.cpp (original)
+++ lld/trunk/lib/Core/YamlKeyValues.cpp Thu Apr 19 20:24:37 2012
@@ -10,6 +10,7 @@
#include "YamlKeyValues.h"
#include "llvm/Support/ErrorHandling.h"
+#include "lld/Core/File.h"
#include <cstring>
@@ -40,6 +41,9 @@
const char* const KeyValues::fixupsOffsetKeyword = "offset";
const char* const KeyValues::fixupsTargetKeyword = "target";
const char* const KeyValues::fixupsAddendKeyword = "addend";
+const char* const KeyValues::fileAtomsKeyword = "atoms";
+const char* const KeyValues::fileKindKeyword = "kind";
+const char* const KeyValues::fileMembersKeyword = "members";
@@ -54,9 +58,36 @@
const bool KeyValues::isThumbDefault = false;
const bool KeyValues::isAliasDefault = false;
const UndefinedAtom::CanBeNull KeyValues::canBeNullDefault = UndefinedAtom::canBeNullNever;
+const File::Kind KeyValues::fileKindDefault = File::kindObject;
+struct FileKindMapping {
+ const char* string;
+ File::Kind value;
+};
+
+static const FileKindMapping fileKindMappings[] = {
+ { "object", File::kindObject },
+ { "archive", File::kindArchiveLibrary },
+ { "shared-library", File::kindSharedLibrary },
+ { nullptr, File::kindObject }
+};
+ File::Kind KeyValues::fileKind(const char* str) {
+ for (const FileKindMapping* p = fileKindMappings; p->string != nullptr; ++p) {
+ if ( strcmp(p->string, str) == 0 )
+ return p->value;
+ }
+ llvm::report_fatal_error("bad file kind value");
+}
+
+const char* KeyValues::fileKind(File::Kind k) {
+ for (const FileKindMapping* p = fileKindMappings; p->string != nullptr; ++p) {
+ if ( p->value == k )
+ return p->string;
+ }
+ llvm::report_fatal_error("bad file kind value");
+}
struct DefinitionMapping {
Modified: lld/trunk/lib/Core/YamlKeyValues.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.h?rev=155183&r1=155182&r2=155183&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlKeyValues.h (original)
+++ lld/trunk/lib/Core/YamlKeyValues.h Thu Apr 19 20:24:37 2012
@@ -13,6 +13,7 @@
#include "lld/Core/Atom.h"
#include "lld/Core/DefinedAtom.h"
#include "lld/Core/UndefinedAtom.h"
+#include "lld/Core/File.h"
namespace lld {
@@ -28,6 +29,13 @@
static const char* const loadNameKeyword;
static const char* const valueKeyword;
static const char* const fixupsKeyword;
+ static const char* const fileAtomsKeyword;
+ static const char* const fileMembersKeyword;
+
+ static const char* const fileKindKeyword;
+ static const File::Kind fileKindDefault;
+ static File::Kind fileKind(const char*);
+ static const char* fileKind(File::Kind);
static const char* const definitionKeyword;
static const Atom::Definition definitionDefault;
Modified: lld/trunk/lib/Core/YamlReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlReader.cpp?rev=155183&r1=155182&r2=155183&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlReader.cpp (original)
+++ lld/trunk/lib/Core/YamlReader.cpp Thu Apr 19 20:24:37 2012
@@ -13,6 +13,7 @@
#include "lld/Core/AbsoluteAtom.h"
#include "lld/Core/Error.h"
#include "lld/Core/File.h"
+#include "lld/Core/ArchiveLibraryFile.h"
#include "lld/Core/LLVM.h"
#include "lld/Core/Platform.h"
#include "lld/Core/Reference.h"
@@ -30,6 +31,7 @@
#include <cstring>
#include <vector>
+#include <set>
@@ -300,36 +302,47 @@
class YAMLDefinedAtom;
-class YAMLFile : public File {
+class YAMLFile : public ArchiveLibraryFile {
public:
YAMLFile()
- : File("path")
- , _lastRefIndex(0) {}
+ : ArchiveLibraryFile("<anonymous>")
+ , _lastRefIndex(0)
+ , _kind(File::kindObject)
+ , _inArchive(false) {
+ }
+
+ virtual File::Kind kind() const {
+ return _kind;
+ }
virtual const atom_collection<DefinedAtom>& defined() const {
return _definedAtoms;
}
virtual const atom_collection<UndefinedAtom>& undefined() const {
- return _undefinedAtoms;
+ return _undefinedAtoms;
}
virtual const atom_collection<SharedLibraryAtom>& sharedLibrary() const {
- return _sharedLibraryAtoms;
+ return _sharedLibraryAtoms;
}
virtual const atom_collection<AbsoluteAtom>& absolute() const {
- return _absoluteAtoms;
+ return _absoluteAtoms;
}
virtual void addAtom(const Atom&) {
assert(0 && "cannot add atoms to YAML files");
}
+ virtual const File *find(StringRef name, bool dataSymbolOnly) const;
+
void bindTargetReferences();
void addDefinedAtom(YAMLDefinedAtom* atom, const char* refName);
void addUndefinedAtom(UndefinedAtom* atom);
void addSharedLibraryAtom(SharedLibraryAtom* atom);
void addAbsoluteAtom(AbsoluteAtom* atom);
Atom* findAtom(const char* name);
-
+ void addMember(const char*);
+ void setName(const char*);
+
struct NameAtomPair {
NameAtomPair(const char* n, Atom* a) : name(n), atom(a) {}
const char* name;
@@ -342,7 +355,11 @@
atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
std::vector<YAMLReference> _references;
std::vector<NameAtomPair> _nameToAtomMapping;
+ std::vector<const char*> _memberNames;
+ std::vector<YAMLFile*> _memberFiles;
unsigned int _lastRefIndex;
+ File::Kind _kind;
+ bool _inArchive;
};
@@ -643,6 +660,25 @@
_nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
}
+void YAMLFile::addMember(const char* name) {
+ _memberNames.push_back(name);
+}
+
+void YAMLFile::setName(const char* name) {
+ _path = StringRef(name);
+}
+
+const File *YAMLFile::find(StringRef name, bool dataSymbolOnly) const {
+ for (YAMLFile *file : _memberFiles) {
+ for (const DefinedAtom *atom : file->defined() ) {
+ if ( name.equals(atom->name()) )
+ return file;
+ }
+ }
+ return NULL;
+}
+
+
class YAMLAtomState {
public:
@@ -810,17 +846,21 @@
, Platform& platform
, std::vector<const File *> &result) {
std::vector<const YAML::Entry *> entries;
+ std::vector<YAMLFile*> allFiles;
YAML::parse(mb, entries);
YAMLFile *file = nullptr;
YAMLAtomState atomState(platform);
bool inAtoms = false;
bool inFixups = false;
+ bool inMembers = false;
int depthForAtoms = -1;
int depthForFixups = -1;
+ int depthForMembers= -1;
int lastDepth = -1;
bool haveAtom = false;
bool haveFixup = false;
+ bool hasArchives = false;
for (std::vector<const YAML::Entry *>::iterator it = entries.begin();
it != entries.end(); ++it) {
@@ -833,7 +873,7 @@
haveAtom = false;
}
file->bindTargetReferences();
- result.push_back(file);
+ allFiles.push_back(file);
}
file = new YAMLFile();
inAtoms = false;
@@ -853,9 +893,24 @@
if (inFixups && (depthForFixups == -1)) {
depthForFixups = entry->depth;
}
- if (strcmp(entry->key, "atoms") == 0) {
+ if (inMembers && (depthForMembers == -1)) {
+ depthForMembers = entry->depth;
+ }
+ if ( !inFixups && (strcmp(entry->key, KeyValues::fileKindKeyword) == 0) ) {
+ file->_kind = KeyValues::fileKind(entry->value);
+ if ( file->_kind == File::kindArchiveLibrary )
+ hasArchives = true;
+ }
+ else if (strcmp(entry->key, KeyValues::fileMembersKeyword) == 0) {
+ inMembers = true;
+ }
+ else if (strcmp(entry->key, KeyValues::fileAtomsKeyword) == 0) {
inAtoms = true;
}
+ else if ( !inAtoms && !inMembers
+ && (strcmp(entry->key, KeyValues::nameKeyword) == 0) ) {
+ file->setName(entry->value);
+ }
if (inAtoms) {
if (depthForAtoms == entry->depth) {
if (entry->beginSequence) {
@@ -980,6 +1035,15 @@
}
}
}
+ else if (inMembers) {
+ if (depthForMembers == entry->depth) {
+ if (entry->beginSequence) {
+ if (strcmp(entry->key, KeyValues::nameKeyword) == 0) {
+ file->addMember(entry->value);
+ }
+ }
+ }
+ }
lastDepth = entry->depth;
}
if (haveAtom) {
@@ -987,8 +1051,31 @@
}
if (file != nullptr) {
file->bindTargetReferences();
- result.push_back(file);
+ allFiles.push_back(file);
+ }
+
+ // If yaml contained archive files, push members down into archives
+ if ( hasArchives ) {
+ for (YAMLFile *f : allFiles) {
+ if ( f->kind() == File::kindArchiveLibrary ) {
+ for (const char *memberName : f->_memberNames ) {
+ for (YAMLFile *f2 : allFiles) {
+ if ( f2->path().equals(memberName) ) {
+ f2->_inArchive = true;
+ f->_memberFiles.push_back(f2);
+ }
+ }
+ }
+ }
+ }
+ }
+ // Copy files that have not been pushed into archives to result.
+ for (YAMLFile *f : allFiles) {
+ if ( ! f->_inArchive ) {
+ result.push_back(f);
+ }
}
+
return make_error_code(yaml_reader_error::success);
}
Added: lld/trunk/test/archive-basic.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/archive-basic.objtxt?rev=155183&view=auto
==============================================================================
--- lld/trunk/test/archive-basic.objtxt (added)
+++ lld/trunk/test/archive-basic.objtxt Thu Apr 19 20:24:37 2012
@@ -0,0 +1,47 @@
+# RUN: lld-core %s | FileCheck %s
+
+#
+# Tests archives in YAML. Tests that an undefined in a regular file will load
+# all atoms in select archive members.
+#
+
+---
+atoms:
+ - name: foo
+ type: code
+
+ - name: bar
+ definition: undefined
+
+---
+name: bar.o
+atoms:
+ - name: bar
+ scope: global
+ type: code
+
+ - name: bar2
+ type: code
+
+---
+name: baz.o
+atoms:
+ - name: baz
+ scope: global
+ type: code
+
+ - name: baz2
+ type: code
+---
+kind: archive
+members:
+ - name: bar.o
+ - name: baz.o
+...
+
+# CHECK: name: foo
+# CHECK: name: bar
+# CHECK-NOT: definition: undefined
+# CHECK: name: bar2
+# CHECK-NOT: name: baz
+# CHECK: ...
Added: lld/trunk/test/archive-chain.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/archive-chain.objtxt?rev=155183&view=auto
==============================================================================
--- lld/trunk/test/archive-chain.objtxt (added)
+++ lld/trunk/test/archive-chain.objtxt Thu Apr 19 20:24:37 2012
@@ -0,0 +1,74 @@
+# RUN: lld-core %s | FileCheck %s
+
+#
+# Tests that an undefine in one archive can force a load from another archive.
+#
+
+---
+atoms:
+ - name: foo
+ type: code
+
+ - name: bar1
+ definition: undefined
+
+---
+name: bar1.o
+atoms:
+ - name: bar1
+ scope: global
+ type: code
+
+ - name: bar1b
+ type: code
+
+ - name: baz1
+ definition: undefined
+---
+name: bar2.o
+atoms:
+ - name: bar2
+ scope: global
+ type: code
+
+ - name: bar2b
+ type: code
+
+---
+name: baz1.o
+atoms:
+ - name: baz1
+ scope: global
+ type: code
+
+ - name: baz1b
+ type: code
+---
+name: baz2.o
+atoms:
+ - name: baz2
+ scope: global
+ type: code
+
+ - name: baz2b
+ type: code
+---
+kind: archive
+members:
+ - name: bar1.o
+ - name: bar2.o
+---
+kind: archive
+members:
+ - name: baz1.o
+ - name: baz2.o
+...
+
+# CHECK: name: foo
+# CHECK: name: bar1
+# CHECK: name: bar1b
+# CHECK-NOT: name: bar2
+# CHECK: name: baz1
+# CHECK: name: baz1b
+# CHECK-NOT: name: baz2
+# CHECK: ...
Added: lld/trunk/test/archive-tentdef-search.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/archive-tentdef-search.objtxt?rev=155183&view=auto
==============================================================================
--- lld/trunk/test/archive-tentdef-search.objtxt (added)
+++ lld/trunk/test/archive-tentdef-search.objtxt Thu Apr 19 20:24:37 2012
@@ -0,0 +1,45 @@
+# RUN: lld-core -commons-search-archives=false %s | FileCheck -check-prefix=CHK1 %s
+# RUN: lld-core -commons-search-archives=true %s | FileCheck -check-prefix=CHK2 %s
+
+#
+# Tests that -commons_search_archives cause core linker to look for overrides
+# of tentative definition in archives, and that not using that option
+# does not search.
+#
+
+---
+atoms:
+ - name: foo
+ type: code
+
+ - name: bar
+ scope: global
+ content: zero-fill
+ merge: asTentative
+
+---
+name: bar.o
+atoms:
+ - name: bar
+ scope: global
+ type: data
+
+ - name: bar2
+ type: data
+
+---
+kind: archive
+members:
+ - name: bar.o
+...
+
+# CHK1: name: foo
+# CHK1: name: bar
+# CHK1: merge: asTentative
+# CHK1: ...
+
+# CHK2: name: foo
+# CHK2: name: bar
+# CHK2-NOT: merge: asTentative
+# CHK2: name: bar2
+# CHK2: ...
Modified: lld/trunk/test/darwin/hello-world.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/darwin/hello-world.objtxt?rev=155183&r1=155182&r2=155183&view=diff
==============================================================================
--- lld/trunk/test/darwin/hello-world.objtxt (original)
+++ lld/trunk/test/darwin/hello-world.objtxt Thu Apr 19 20:24:37 2012
@@ -1,4 +1,4 @@
-# RUN: lld-core -platform darwin -stubs_pass %s -o %t && llvm-nm %t | FileCheck %s
+# RUN: lld-core -platform darwin -stubs-pass %s -o %t && llvm-nm %t | FileCheck %s
#
# Test that hello-world can be linked into a mach-o executable
Added: lld/trunk/test/dead-strip-basic.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/dead-strip-basic.objtxt?rev=155183&view=auto
==============================================================================
--- lld/trunk/test/dead-strip-basic.objtxt (added)
+++ lld/trunk/test/dead-strip-basic.objtxt Thu Apr 19 20:24:37 2012
@@ -0,0 +1,63 @@
+# RUN: lld-core -dead-strip=true %s | FileCheck -check-prefix=CHK1 %s
+# RUN: lld-core -dead-strip=false %s | FileCheck -check-prefix=CHK2 %s
+
+#
+# Test that -dead-strip removes unreachable code and data
+# and that not using that option leaves them.
+#
+
+---
+atoms:
+ - name: entry
+ dead-strip: never
+ fixups:
+ - offset: 1
+ kind: pcrel32
+ target: bar
+ - offset: 6
+ kind: pcrel32
+ target: baz
+
+ - name: mydead1
+ scope: global
+
+ - name: bar
+ definition: undefined
+
+ - name: baz
+ definition: undefined
+---
+atoms:
+ - name: mydead2
+ scope: global
+ type: data
+
+ - name: bar
+ scope: global
+ type: data
+---
+atoms:
+ - name: baz
+ scope: global
+ type: code
+
+ - name: mydead3
+ type: code
+...
+
+
+# CHK1: name: entry
+# CHK1-NOT: name: mydead1
+# CHK1: name: bar
+# CHK1-NOT: name: mydead2
+# CHK1: name: baz
+# CHK1-NOT: name: mydead3
+# CHK1: ...
+
+# CHK2: name: entry
+# CHK2: name: mydead1
+# CHK2: name: mydead2
+# CHK2: name: bar
+# CHK2: name: baz
+# CHK2: name: mydead3
+# CHK2: ...
Added: lld/trunk/test/dead-strip-globals.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/dead-strip-globals.objtxt?rev=155183&view=auto
==============================================================================
--- lld/trunk/test/dead-strip-globals.objtxt (added)
+++ lld/trunk/test/dead-strip-globals.objtxt Thu Apr 19 20:24:37 2012
@@ -0,0 +1,62 @@
+# RUN: lld-core -dead-strip -keep-globals=true %s | FileCheck -check-prefix=CHK1 %s
+# RUN: lld-core -dead-strip -keep-globals=false %s | FileCheck -check-prefix=CHK2 %s
+
+#
+# Test that -keep-globals prevents -dead-strip from removing globals.
+#
+
+---
+atoms:
+ - name: entry
+ dead-strip: never
+ fixups:
+ - offset: 1
+ kind: pcrel32
+ target: bar
+ - offset: 6
+ kind: pcrel32
+ target: baz
+
+ - name: myglobal1
+ scope: global
+
+ - name: bar
+ definition: undefined
+
+ - name: baz
+ definition: undefined
+---
+atoms:
+ - name: myglobal2
+ scope: global
+ type: data
+
+ - name: bar
+ scope: hidden
+ type: data
+---
+atoms:
+ - name: baz
+ scope: hidden
+ type: code
+
+ - name: mydead
+ type: code
+...
+
+
+# CHK1: name: entry
+# CHK1: name: myglobal1
+# CHK1: name: myglobal2
+# CHK1: name: bar
+# CHK1: name: baz
+# CHK1-NOT: name: mydead
+# CHK1: ...
+
+# CHK2: name: entry
+# CHK2-NOT: name: myglobal1
+# CHK2-NOT: name: myglobal2
+# CHK2: name: bar
+# CHK2: name: baz
+# CHK2-NOT: name: mydead
+# CHK2: ...
Modified: lld/trunk/test/pass-got-basic.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pass-got-basic.objtxt?rev=155183&r1=155182&r2=155183&view=diff
==============================================================================
--- lld/trunk/test/pass-got-basic.objtxt (original)
+++ lld/trunk/test/pass-got-basic.objtxt Thu Apr 19 20:24:37 2012
@@ -1,4 +1,4 @@
-# RUN: lld-core %s -got_pass | FileCheck %s
+# RUN: lld-core %s -got-pass | FileCheck %s
#
# Test that GOT pass instantiates GOT entires and alters references
Modified: lld/trunk/test/pass-stubs-basic.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pass-stubs-basic.objtxt?rev=155183&r1=155182&r2=155183&view=diff
==============================================================================
--- lld/trunk/test/pass-stubs-basic.objtxt (original)
+++ lld/trunk/test/pass-stubs-basic.objtxt Thu Apr 19 20:24:37 2012
@@ -1,4 +1,4 @@
-# RUN: lld-core %s -stubs_pass | FileCheck %s
+# RUN: lld-core %s -stubs-pass | FileCheck %s
#
# Test that stubs pass adds stubs and rebinds call sites to the stub
Modified: lld/trunk/test/undef-coalesce-error.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/undef-coalesce-error.objtxt?rev=155183&r1=155182&r2=155183&view=diff
==============================================================================
--- lld/trunk/test/undef-coalesce-error.objtxt (original)
+++ lld/trunk/test/undef-coalesce-error.objtxt Thu Apr 19 20:24:37 2012
@@ -1,8 +1,10 @@
-# RUN: not lld-core -undefines_are_errors %s 2> %t.err
-# RUN: FileCheck < %t.err %s
+# RUN: not lld-core -undefines-are-errors %s 2> %t.err
+# RUN: FileCheck -check-prefix=CHECKERR < %t.err %s
+# RUN: lld-core -undefines-are-errors=false %s | FileCheck %s
#
-# Test that any remaining undefined symbols cause an error
+# Test that -undefines-are-errors triggers and error
+# and that not using that option results in undefined atoms.
#
---
@@ -35,6 +37,15 @@
definition: undefined
...
-# CHECK: free
-# CHECK: malloc
-# CHECK: symbol(s) not found
+# CHECKERR: free
+# CHECKERR: malloc
+# CHECKERR: symbol(s) not found
+
+# CHECK: name: foo
+# CHECK: name: bar
+# CHECK: name: myfunc
+# CHECK: name: malloc
+# CHECK: definition: undefined
+# CHECK: name: free
+# CHECK: definition: undefined
+# CHECK: ...
Modified: lld/trunk/tools/lld-core/lld-core.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/tools/lld-core/lld-core.cpp?rev=155183&r1=155182&r2=155183&view=diff
==============================================================================
--- lld/trunk/tools/lld-core/lld-core.cpp (original)
+++ lld/trunk/tools/lld-core/lld-core.cpp Thu Apr 19 20:24:37 2012
@@ -345,78 +345,43 @@
};
-
-//
-// A simple input files wrapper for testing.
-//
-class TestingInputFiles : public InputFiles {
-public:
- TestingInputFiles(std::vector<const File*>& f) : _files(f) { }
-
- // InputFiles interface
- virtual void forEachInitialAtom(InputFiles::Handler& handler) const {
- for ( const File *file : _files ) {
- handler.doFile(*file);
- for( const DefinedAtom *atom : file->defined() ) {
- handler.doDefinedAtom(*atom);
- }
- for( const UndefinedAtom *undefAtom : file->undefined() ) {
- handler.doUndefinedAtom(*undefAtom);
- }
- for( const SharedLibraryAtom *shlibAtom : file->sharedLibrary() ) {
- handler.doSharedLibraryAtom(*shlibAtom);
- }
- for( const AbsoluteAtom *absAtom : file->absolute() ) {
- handler.doAbsoluteAtom(*absAtom);
- }
- }
- }
-
- virtual void prependFile(const File &file) {
- _files.insert(_files.begin(), &file);
- }
-
- virtual void appendFile(const File &file) {
- _files.push_back(&file);
- }
-
- virtual bool searchLibraries(StringRef name, bool searchDylibs,
- bool searchArchives, bool dataSymbolOnly,
- InputFiles::Handler &) const {
- return false;
- }
-
-
-private:
- std::vector<const File*>& _files;
-};
-}
-
-
+} // anon namespace
llvm::cl::opt<std::string>
-gInputFilePath(llvm::cl::Positional,
+cmdLineInputFilePath(llvm::cl::Positional,
llvm::cl::desc("<input file>"),
llvm::cl::init("-"));
llvm::cl::opt<std::string>
-gOutputFilePath("o",
+cmdLineOutputFilePath("o",
llvm::cl::desc("Specify output filename"),
llvm::cl::value_desc("filename"));
llvm::cl::opt<bool>
-gDoStubsPass("stubs_pass",
+cmdLineDoStubsPass("stubs-pass",
llvm::cl::desc("Run pass to create stub atoms"));
llvm::cl::opt<bool>
-gDoGotPass("got_pass",
+cmdLineDoGotPass("got-pass",
llvm::cl::desc("Run pass to create GOT atoms"));
llvm::cl::opt<bool>
-gUndefinesIsError("undefines_are_errors",
+cmdLineUndefinesIsError("undefines-are-errors",
llvm::cl::desc("Any undefined symbols at end is an error"));
+llvm::cl::opt<bool>
+cmdLineCommonsSearchArchives("commons-search-archives",
+ llvm::cl::desc("Tentative definitions trigger archive search"));
+
+llvm::cl::opt<bool>
+cmdLineDeadStrip("dead-strip",
+ llvm::cl::desc("Remove unreachable code and data"));
+
+llvm::cl::opt<bool>
+cmdLineGlobalsNotDeadStrip("keep-globals",
+ llvm::cl::desc("All global symbols are roots for dead-strip"));
+
enum PlatformChoice {
platformTesting, platformDarwin
@@ -435,7 +400,10 @@
class TestingResolverOptions : public ResolverOptions {
public:
TestingResolverOptions() {
- _undefinesAreErrors = gUndefinesIsError;
+ _undefinesAreErrors = cmdLineUndefinesIsError;
+ _searchArchivesToOverrideTentativeDefinitions = cmdLineCommonsSearchArchives;
+ _deadCodeStrip = cmdLineDeadStrip;
+ _globalsAreDeadStripRoots = cmdLineGlobalsNotDeadStrip;
}
};
@@ -466,7 +434,7 @@
// read input YAML doc into object file(s)
std::vector<const File *> files;
- if (error(yaml::parseObjectTextFileOrSTDIN(gInputFilePath,
+ if (error(yaml::parseObjectTextFileOrSTDIN(cmdLineInputFilePath,
*platform, files))) {
return 1;
}
@@ -475,7 +443,10 @@
TestingResolverOptions options;
// create object to mange input files
- TestingInputFiles inputFiles(files);
+ InputFiles inputFiles;
+ for (const File *file : files) {
+ inputFiles.appendFile(*file);
+ }
platform->addFiles(inputFiles);
@@ -484,11 +455,11 @@
resolver.resolve();
// run passes
- if ( gDoGotPass ) {
+ if ( cmdLineDoGotPass ) {
GOTPass addGot(resolver.resultFile(), *platform);
addGot.perform();
}
- if ( gDoStubsPass ) {
+ if ( cmdLineDoStubsPass ) {
StubsPass addStubs(resolver.resultFile(), *platform);
addStubs.perform();
}
@@ -515,7 +486,8 @@
// write new atom graph
std::string errorInfo;
- const char* outPath = gOutputFilePath.empty() ? "-" : gOutputFilePath.c_str();
+ const char* outPath = (cmdLineOutputFilePath.empty() ? "-"
+ : cmdLineOutputFilePath.c_str());
llvm::raw_fd_ostream out(outPath, errorInfo);
if ( platformSelected == platformTesting) {
// write atom graph out as YAML doc
More information about the llvm-commits
mailing list