[llvm-commits] [lld] r155183 - in /lld/trunk: include/lld/Core/ lib/Core/ test/ test/darwin/ tools/lld-core/
Michael Spencer
bigcheesegs at gmail.com
Fri Apr 20 11:43:29 PDT 2012
On Thu, Apr 19, 2012 at 6:24 PM, Nick Kledzik <kledzik at apple.com> wrote:
> 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: ...
I find this a weird way to represent archives in YAML. Each document
should represent a separate main file
handed to the linker, so all archive members should be in the same
document. I would rather see:
---
archive:
- name: bar.o
atoms:
- blah....
- name: baz.o
- blah....
...
- Michael Spencer
> 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
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list