[llvm-commits] [lld] r147903 - in /lld/trunk: include/lld/Core/ include/lld/Platform/ lib/Core/ test/ tools/lld-core/
Nick Kledzik
kledzik at apple.com
Tue Jan 10 17:06:19 PST 2012
Author: kledzik
Date: Tue Jan 10 19:06:19 2012
New Revision: 147903
URL: http://llvm.org/viewvc/llvm-project?rev=147903&view=rev
Log:
A couple of big refactorings: 1) Move most attributes of Atom down to DefinedAtom, so only atoms representing definitions need to implement them. 2) Remove definitionTentative, definitionWeak, mergeDuplicates, and autoHide. Replace with merge and interposable attributes. 3) Make all methods on Atom be virtual so that future object file readers can lazily generated attributes
Added:
lld/trunk/include/lld/Core/DefinedAtom.h
Removed:
lld/trunk/lib/Core/Atom.cpp
Modified:
lld/trunk/include/lld/Core/Atom.h
lld/trunk/include/lld/Core/File.h
lld/trunk/include/lld/Core/Resolver.h
lld/trunk/include/lld/Core/SymbolTable.h
lld/trunk/include/lld/Core/UndefinedAtom.h
lld/trunk/include/lld/Platform/Platform.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/lib/Core/YamlWriter.cpp
lld/trunk/test/auto-hide-coalesce.objtxt
lld/trunk/test/cstring-coalesce.objtxt
lld/trunk/test/inline-coalesce.objtxt
lld/trunk/test/multiple-def-error.objtxt
lld/trunk/test/tent-merge.objtxt
lld/trunk/test/weak-coalesce.objtxt
lld/trunk/tools/lld-core/lld-core.cpp
Modified: lld/trunk/include/lld/Core/Atom.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Atom.h?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Atom.h (original)
+++ lld/trunk/include/lld/Core/Atom.h Tue Jan 10 19:06:19 2012
@@ -12,173 +12,32 @@
#include <assert.h>
-#include "lld/Core/Reference.h"
-
namespace llvm {
- template <typename T>
- class ArrayRef;
-
class StringRef;
}
namespace lld {
class File;
+class DefinedAtom;
-/// An atom is the fundamental unit of linking. A C function or global variable
-/// is an atom. An atom has content and attributes. The content of a function
-/// atom is the instructions that implement the function. The content of a
-/// global variable atom is its initial bytes.
-///
-/// Here are some example attribute sets for common atoms. If a particular
-/// attribute is not listed, the default values are: definition=regular,
-/// sectionChoice=basedOnContent, scope=translationUnit, mergeDupes=false,
-/// autoHide=false, internalName=false, deadStrip=normal
-///
-/// C function: void foo() {} <br>
-/// name=foo, type=code, perm=r_x, scope=global
-///
-/// C static function: staic void func() {} <br>
-/// name=func, type=code, perm=r_x
-///
-/// C global variable: int count = 1; <br>
-/// name=count, type=data, perm=rw_, scope=global
-///
-/// C tentative definition: int bar; <br>
-/// name=bar, type=data, perm=rw_, scope=global, definition=tentative
-///
-/// Uninitialized C static variable: static int stuff; <br>
-/// name=stuff, type=zerofill, perm=rw_
-///
-/// Weak C function: __attribute__((weak)) void foo() {} <br>
-/// name=foo, type=code, perm=r_x, scope=global, definition=weak
-///
-/// Hidden C function: __attribute__((visibility("hidden"))) void foo() {}<br>
-/// name=foo, type=code, perm=r_x, scope=linkageUnit
-///
-/// No-dead-strip function: __attribute__((used)) void foo() {} <br>
-/// name=foo, type=code, perm=r_x, scope=global, deadStrip=never
-///
-/// Non-inlined C++ inline method: inline void Foo::doit() {} <br>
-/// name=_ZN3Foo4doitEv, type=code, perm=r_x, scope=global,
-/// mergeDupes=true, autoHide=true
-///
-/// Non-inlined C++ inline method whose address is taken:
-/// inline void Foo::doit() {} <br>
-/// name=_ZN3Foo4doitEv, type=code, perm=r_x, scope=global, mergeDupes=true
-///
-/// literal c-string: "hello" <br>
-/// name=L0, internalName=true, type=cstring, perm=r__,
-/// scope=linkageUnit, mergeDupes=true
///
-/// literal double: 1.234 <br>
-/// name=L0, internalName=true, type=literal8, perm=r__,
-/// scope=linkageUnit, mergeDupes=true
-///
-/// constant: { 1,2,3 } <br>
-/// name=L0, internalName=true, type=constant, perm=r__,
-/// scope=linkageUnit, mergeDupes=true
-///
-/// Pointer to initializer function: <br>
-/// name=_init, internalName=true, type=initializer, perm=rw_l,
-/// sectionChoice=customRequired
-///
-/// C function place in custom section: __attribute__((section("__foo")))
-/// void foo() {} <br>
-/// name=foo, type=code, perm=r_x, scope=global,
-/// sectionChoice=customRequired, sectionName=__foo
+/// The linker has a Graph Theory model of linking. An object file is seen
+/// as a set of Atoms with References to other Atoms. Each Atom is a node
+/// and each Reference is an edge. An Atom can be a DefinedAtom which has
+/// content or a UndefinedAtom which is a placeholder and represents an
+/// undefined symbol (extern declaration).
///
class Atom {
public:
- /// The scope in which this atom is acessible to other atoms.
- enum Scope {
- scopeTranslationUnit, ///< Accessible only to atoms in the same translation
- /// unit (e.g. a C static).
- scopeLinkageUnit, ///< Accessible to atoms being linked but not visible
- /// to runtime loader (e.g. visibility=hidden).
- scopeGlobal ///< Accessible to all atoms and visible to runtime
- /// loader (e.g. visibility=default) .
- };
-
/// Whether this atom is defined or a proxy for an undefined symbol
enum Definition {
definitionRegular, ///< Normal C/C++ function or global variable.
- definitionWeak, ///< Can be silently overridden by definitionRegular
- definitionTentative, ///< C-only pre-ANSI support aka common.
definitionAbsolute, ///< Asm-only (foo = 10). Not tied to any content.
definitionUndefined, ///< Only in .o files to model reference to undef.
definitionSharedLibrary ///< Only in shared libraries to model export.
};
- enum ContentType {
- typeUnknown, // for use with definitionUndefined
- typeCode, // executable code
- typeResolver, // function which returns address of target
- typeBranchIsland, // linker created for large binaries
- typeBranchShim, // linker created to switch thumb mode
- typeStub, // linker created for calling external function
- typeStubHelper, // linker created for initial stub binding
- typeConstant, // a read-only constant
- typeCString, // a zero terminated UTF8 C string
- typeUTF16String, // a zero terminated UTF16 string
- typeCFI, // a FDE or CIE from dwarf unwind info
- typeLSDA, // extra unwinding info
- typeLiteral4, // a four-btye read-only constant
- typeLiteral8, // an eight-btye read-only constant
- typeLiteral16, // a sixteen-btye read-only constant
- typeData, // read-write data
- typeZeroFill, // zero-fill data
- typeObjC1Class, // ObjC1 class [Darwin]
- typeLazyPointer, // pointer through which a stub jumps
- typeLazyDylibPointer, // pointer through which a stub jumps [Darwin]
- typeCFString, // NS/CFString object [Darwin]
- typeGOT, // pointer to external symbol
- typeInitializerPtr, // pointer to initializer function
- typeTerminatorPtr, // pointer to terminator function
- typeCStringPtr, // pointer to UTF8 C string [Darwin]
- typeObjCClassPtr, // pointer to ObjC class [Darwin]
- typeObjC2CategoryList, // pointers to ObjC category [Darwin]
- typeDTraceDOF, // runtime data for Dtrace [Darwin]
- typeTempLTO, // temporary atom for bitcode reader
- typeCompactUnwindInfo, // runtime data for unwinder [Darwin]
- typeThunkTLV, // thunk used to access a TLV [Darwin]
- typeTLVInitialData, // initial data for a TLV [Darwin]
- typeTLVInitialZeroFill, // TLV initial zero fill data [Darwin]
- typeTLVInitializerPtr, // pointer to thread local initializer [Darwin]
- typeFirstInSection, // label for boundary of section [Darwin]
- typeLastInSection, // label for boundary of section [Darwin]
- };
-
- enum ContentPermissions {
- perm___ = 0, // mapped as unacessible
- permR__ = 8, // mapped read-only
- permR_X = 8 + 2, // mapped readable and executable
- permRW_ = 8 + 4, // mapped readable and writable
- permRW_L = 8 + 4 + 1, // initially mapped r/w, then made read-only
- // loader writable
- };
-
- enum SectionChoice {
- sectionBasedOnContent, // linker infers final section based on content
- sectionCustomPreferred, // linker may place in specific section
- sectionCustomRequired // linker must place in specific section
- };
-
- enum DeadStripKind {
- deadStripNormal, // linker may dead strip this atom
- deadStripNever, // linker must never dead strip this atom
- deadStripAlways // linker must remove this atom if unused
- };
-
- struct Alignment {
- Alignment(int p2, int m = 0)
- : powerOf2(p2)
- , modulus(m) {}
-
- uint16_t powerOf2;
- uint16_t modulus;
- };
-
/// file - returns the File that produced/owns this Atom
virtual const class File& file() const = 0;
@@ -186,204 +45,23 @@
/// name of the function.
virtual llvm::StringRef name() const = 0;
- /// internalName - If the name is just a temporary label that should
- /// not show up in the final linked image.
- bool internalName() const {
- return _internalName;
- }
-
- /// size - the number of bytes of space this atom's content will occupy
- /// in the final linked image. For a function atom, it is the number
- /// of bytes of code in the function.
- virtual uint64_t size() const = 0;
-
- /// scope - The visibility of this atom to other atoms. C static functions
- /// have scope scopeTranslationUnit. Regular C functions have scope
- /// scopeGlobal. Functions compiled with visibility=hidden have scope
- /// scopeLinkageUnit so they can be see by other atoms being linked but not
- /// by the OS loader.
- Scope scope() const {
- return _scope;
- }
-
/// definition - Whether this atom is a definition or represents an undefined
- /// or tentative symbol.
- Definition definition() const {
- return _definition;
- }
-
- /// mergeDuplicates - For definitionRegular atoms, this means the
- /// atom can be silently coalesced with another atom that has the
- /// same name or content.
- bool mergeDuplicates() const {
- return _mergeDuplicates;
- }
-
- /// contentType - The type of this atom, such as code or data.
- ContentType contentType() const {
- return _contentType;
- }
-
- /// alignment - The alignment constraints on how this atom must be laid out
- /// in the final linked image (e.g. 16-byte aligned).
- Alignment alignment() const {
- return Alignment(_alignmentPowerOf2, _alignmentModulus);
- }
-
- /// sectionChoice - Whether this atom must be in a specially named section
- /// in the final linked image, or if the linker can infer the section
- /// based on the contentType().
- SectionChoice sectionChoice() const {
- return _sectionChoice;
- }
-
- /// customSectionName - If sectionChoice() != sectionBasedOnContent, then
- /// this return the name of the section the atom should be placed into.
- virtual llvm::StringRef customSectionName() const;
-
- /// deadStrip - constraints on whether the linker may dead strip away
- /// this atom.
- DeadStripKind deadStrip() const {
- return _deadStrip;
- }
-
- /// autoHide - Whether it is ok for the linker to change the scope of this
- /// atom to hidden as long as all other duplicates are also autoHide.
- bool autoHide() const {
- return _autoHide;
- }
-
- /// permissions - Returns the OS memory protections required for this atom's
- /// content at runtime. A function atom is R_X, a global variable is RW_,
- /// and a read-only constant is R__.
- virtual ContentPermissions permissions() const;
-
- /// isThumb - only applicable to ARM code. Tells the linker if the code
- /// uses thumb or arm instructions. The linker needs to know this to
- /// set the low bit of pointers to thumb functions.
- bool isThumb() const {
- return _thumb;
- }
-
- /// isAlias - means this is a zero size atom that exists to provide an
- /// alternate name for another atom. Alias atoms must have a special
- /// Reference to the atom they alias which the layout engine recognizes
- /// and forces the alias atom to layout right before the target atom.
- bool isAlias() const {
- return _alias;
- }
-
- /// rawContent - returns a reference to the raw (unrelocated) bytes of
- /// this Atom's content.
- virtual llvm::ArrayRef<uint8_t> rawContent() const;
-
- /// referencesBegin - used to start iterating this Atom's References
- virtual Reference::iterator referencesBegin() const;
-
- /// referencesEnd - used to end iterating this Atom's References
- virtual Reference::iterator referencesEnd() const;
-
- /// setLive - sets or clears the liveness bit. Used by linker to do
- /// dead code stripping.
- void setLive(bool l) { _live = l; }
-
- /// live - returns the liveness bit. Used by linker to do
- /// dead code stripping.
- bool live() const { return _live; }
-
- /// ordinal - returns a value for the order of this Atom within its file.
- /// This is used by the linker to order the layout of Atoms so that
- /// the resulting image is stable and reproducible.
- uint64_t ordinal() const {
- assert(_mode == modeOrdinal);
- return _address;
- }
-
- /// sectionOffset - returns the section offset assigned to this Atom within
- /// its final section.
- uint64_t sectionOffset() const {
- assert(_mode == modeSectionOffset);
- return _address;
- }
-
- /// finalAddress - returns the address assigned to Atom within the final
- /// linked image.
- uint64_t finalAddress() const {
- assert(_mode == modeFinalAddress);
- return _address;
- }
-
- /// setSectionOffset - assigns an offset within a section in the final
- /// linked image.
- void setSectionOffset(uint64_t off) {
- assert(_mode != modeFinalAddress);
- _address = off;
- _mode = modeSectionOffset;
- }
+ /// symbol.
+ virtual Definition definition() const = 0;
- /// setSectionOffset - assigns an offset within a section in the final
- /// linked image.
- void setFinalAddress(uint64_t addr) {
- assert(_mode == modeSectionOffset);
- _address = addr;
- _mode = modeFinalAddress;
- }
+ /// definedAtom - like dynamic_cast, if atom is definitionRegular
+ /// returns atom cast to DefinedAtom*, else returns NULL;
+ virtual const DefinedAtom* definedAtom() const { return NULL; }
- /// constructor
- Atom( uint64_t ord
- , Definition d
- , Scope s
- , ContentType ct
- , SectionChoice sc
- , bool internalName
- , bool mergeDupes
- , bool autoHide
- , DeadStripKind ds
- , bool IsThumb
- , bool IsAlias
- , Alignment a)
- : _address(ord)
- , _alignmentModulus(a.modulus)
- , _alignmentPowerOf2(a.powerOf2)
- , _contentType(ct)
- , _definition(d)
- , _scope(s)
- , _sectionChoice(sc)
- , _internalName(internalName)
- , _deadStrip(ds)
- , _mode(modeOrdinal)
- , _mergeDuplicates(mergeDupes)
- , _thumb(IsThumb)
- , _autoHide(autoHide)
- , _alias(IsAlias)
- {}
-
-
protected:
+ /// Atom is an abstract base class. Only subclasses can access constructor.
+ Atom() {}
+
/// The memory for Atom objects is always managed by the owning File
/// object. Therefore, no one but the owning File object should call
/// delete on an Atom. In fact, some File objects may bulk allocate
/// an array of Atoms, so they cannot be individually deleted by anyone.
- virtual ~Atom();
-
- /// The __address field has different meanings throughout the life of an Atom.
- enum AddressMode { modeOrdinal, modeSectionOffset, modeFinalAddress };
-
- uint64_t _address;
- uint16_t _alignmentModulus;
- uint8_t _alignmentPowerOf2;
- ContentType _contentType : 8;
- Definition _definition : 3;
- Scope _scope : 2;
- SectionChoice _sectionChoice: 2;
- bool _internalName : 1;
- DeadStripKind _deadStrip : 2;
- AddressMode _mode : 2;
- bool _mergeDuplicates : 1;
- bool _thumb : 1;
- bool _autoHide : 1;
- bool _alias : 1;
- bool _live : 1;
+ virtual ~Atom() {}
};
} // namespace lld
Added: lld/trunk/include/lld/Core/DefinedAtom.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/DefinedAtom.h?rev=147903&view=auto
==============================================================================
--- lld/trunk/include/lld/Core/DefinedAtom.h (added)
+++ lld/trunk/include/lld/Core/DefinedAtom.h Tue Jan 10 19:06:19 2012
@@ -0,0 +1,287 @@
+//===- Core/DefinedAtom.h - The Fundimental Unit of Linking ---------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_CORE_DEFINED_ATOM_H_
+#define LLD_CORE_DEFINED_ATOM_H_
+
+#include <assert.h>
+
+#include "lld/Core/Atom.h"
+#include "lld/Core/Reference.h"
+
+namespace llvm {
+ template <typename T>
+ class ArrayRef;
+
+ class StringRef;
+}
+
+namespace lld {
+
+class File;
+
+/// An atom is the fundamental unit of linking. A C function or global variable
+/// is an atom. An atom has content and attributes. The content of a function
+/// atom is the instructions that implement the function. The content of a
+/// global variable atom is its initial bytes.
+///
+/// Here are some example attribute sets for common atoms. If a particular
+/// attribute is not listed, the default values are: definition=regular,
+/// sectionChoice=basedOnContent, scope=translationUnit, merge=no,
+/// internalName=false, deadStrip=normal, interposable=no
+///
+/// C function: void foo() {} <br>
+/// name=foo, type=code, perm=r_x, scope=global
+///
+/// C static function: staic void func() {} <br>
+/// name=func, type=code, perm=r_x
+///
+/// C global variable: int count = 1; <br>
+/// name=count, type=data, perm=rw_, scope=global
+///
+/// C tentative definition: int bar; <br>
+/// name=bar, type=zerofill, perm=rw_, scope=global,
+/// merge=asTentative, interposable=yesAndRuntimeWeak
+///
+/// Uninitialized C static variable: static int stuff; <br>
+/// name=stuff, type=zerofill, perm=rw_
+///
+/// Weak C function: __attribute__((weak)) void foo() {} <br>
+/// name=foo, type=code, perm=r_x, scope=global, merge=asWeak
+///
+/// Hidden C function: __attribute__((visibility("hidden"))) void foo() {}<br>
+/// name=foo, type=code, perm=r_x, scope=linkageUnit
+///
+/// No-dead-strip function: __attribute__((used)) void foo() {} <br>
+/// name=foo, type=code, perm=r_x, scope=global, deadStrip=never
+///
+/// Non-inlined C++ inline method: inline void Foo::doit() {} <br>
+/// name=_ZN3Foo4doitEv, type=code, perm=r_x, scope=global,
+/// mergeDupes=asWeak
+///
+/// Non-inlined C++ inline method whose address is taken:
+/// inline void Foo::doit() {} <br>
+/// name=_ZN3Foo4doitEv, type=code, perm=r_x, scope=global,
+/// mergeDupes=asAddressedWeak
+///
+/// literal c-string: "hello" <br>
+/// name=L0, internalName=true, type=cstring, perm=r__, scope=linkageUnit
+///
+/// literal double: 1.234 <br>
+/// name=L0, internalName=true, type=literal8, perm=r__, scope=linkageUnit
+///
+/// constant: { 1,2,3 } <br>
+/// name=L0, internalName=true, type=constant, perm=r__, scope=linkageUnit
+///
+/// Pointer to initializer function: <br>
+/// name=_init, internalName=true, type=initializer, perm=rw_l,
+/// sectionChoice=customRequired
+///
+/// C function place in custom section: __attribute__((section("__foo")))
+/// void foo() {} <br>
+/// name=foo, type=code, perm=r_x, scope=global,
+/// sectionChoice=customRequired, sectionName=__foo
+///
+class DefinedAtom : public Atom {
+public:
+ /// Whether this atom is defined or a proxy for an undefined symbol
+ virtual Definition definition() const {
+ return Atom::definitionRegular;
+ }
+
+ virtual const DefinedAtom* definedAtom() const {
+ return this;
+ }
+
+ /// The scope in which this atom is acessible to other atoms.
+ enum Scope {
+ scopeTranslationUnit, ///< Accessible only to atoms in the same translation
+ /// unit (e.g. a C static).
+ scopeLinkageUnit, ///< Accessible to atoms being linked but not visible
+ /// to runtime loader (e.g. visibility=hidden).
+ scopeGlobal ///< Accessible to all atoms and visible to runtime
+ /// loader (e.g. visibility=default).
+ };
+
+ enum Interposable {
+ interposeNo, // linker can directly bind uses of this atom
+ interposeYes, // linker must indirect (through GOT) uses
+ interposeYesAndRuntimeWeak // must indirect and mark symbol weak in final
+ // linked image
+ };
+
+ enum Merge {
+ mergeNo, // Another atom with same name is error
+ mergeAsTentative, // Is ANSI C tentative defintion, can be coalesced
+ mergeAsWeak, // is C++ inline definition that was not inlined,
+ // but address was not taken, so atom can be hidden
+ // by linker
+ mergeAsWeakAndAddressUsed // is C++ definition inline definition whose
+ // address was taken.
+ };
+
+ enum ContentType {
+ typeUnknown, // for use with definitionUndefined
+ typeCode, // executable code
+ typeResolver, // function which returns address of target
+ typeBranchIsland, // linker created for large binaries
+ typeBranchShim, // linker created to switch thumb mode
+ typeStub, // linker created for calling external function
+ typeStubHelper, // linker created for initial stub binding
+ typeConstant, // a read-only constant
+ typeCString, // a zero terminated UTF8 C string
+ typeUTF16String, // a zero terminated UTF16 string
+ typeCFI, // a FDE or CIE from dwarf unwind info
+ typeLSDA, // extra unwinding info
+ typeLiteral4, // a four-btye read-only constant
+ typeLiteral8, // an eight-btye read-only constant
+ typeLiteral16, // a sixteen-btye read-only constant
+ typeData, // read-write data
+ typeZeroFill, // zero-fill data
+ typeObjC1Class, // ObjC1 class [Darwin]
+ typeLazyPointer, // pointer through which a stub jumps
+ typeLazyDylibPointer, // pointer through which a stub jumps [Darwin]
+ typeCFString, // NS/CFString object [Darwin]
+ typeGOT, // pointer to external symbol
+ typeInitializerPtr, // pointer to initializer function
+ typeTerminatorPtr, // pointer to terminator function
+ typeCStringPtr, // pointer to UTF8 C string [Darwin]
+ typeObjCClassPtr, // pointer to ObjC class [Darwin]
+ typeObjC2CategoryList, // pointers to ObjC category [Darwin]
+ typeDTraceDOF, // runtime data for Dtrace [Darwin]
+ typeTempLTO, // temporary atom for bitcode reader
+ typeCompactUnwindInfo, // runtime data for unwinder [Darwin]
+ typeThunkTLV, // thunk used to access a TLV [Darwin]
+ typeTLVInitialData, // initial data for a TLV [Darwin]
+ typeTLVInitialZeroFill, // TLV initial zero fill data [Darwin]
+ typeTLVInitializerPtr, // pointer to thread local initializer [Darwin]
+ typeFirstInSection, // label for boundary of section [Darwin]
+ typeLastInSection, // label for boundary of section [Darwin]
+ };
+
+ enum ContentPermissions {
+ perm___ = 0, // mapped as unaccessible
+ permR__ = 8, // mapped read-only
+ permR_X = 8 + 2, // mapped readable and executable
+ permRW_ = 8 + 4, // mapped readable and writable
+ permRW_L = 8 + 4 + 1, // initially mapped r/w, then made read-only
+ // loader writable
+ };
+
+ enum SectionChoice {
+ sectionBasedOnContent, // linker infers final section based on content
+ sectionCustomPreferred, // linker may place in specific section
+ sectionCustomRequired // linker must place in specific section
+ };
+
+ enum DeadStripKind {
+ deadStripNormal, // linker may dead strip this atom
+ deadStripNever, // linker must never dead strip this atom
+ deadStripAlways // linker must remove this atom if unused
+ };
+
+ struct Alignment {
+ Alignment(int p2, int m = 0)
+ : powerOf2(p2)
+ , modulus(m) {}
+
+ uint16_t powerOf2;
+ uint16_t modulus;
+ };
+
+ /// ordinal - returns a value for the order of this Atom within its file.
+ /// This is used by the linker to order the layout of Atoms so that
+ /// the resulting image is stable and reproducible.
+ virtual uint64_t ordinal() const = 0;
+
+ /// internalName - If the name is just a temporary label that should
+ /// not show up in the final linked image.
+ virtual bool internalName() const = 0;
+
+ /// size - the number of bytes of space this atom's content will occupy
+ /// in the final linked image. For a function atom, it is the number
+ /// of bytes of code in the function.
+ virtual uint64_t size() const = 0;
+
+ /// scope - The visibility of this atom to other atoms. C static functions
+ /// have scope scopeTranslationUnit. Regular C functions have scope
+ /// scopeGlobal. Functions compiled with visibility=hidden have scope
+ /// scopeLinkageUnit so they can be see by other atoms being linked but not
+ /// by the OS loader.
+ virtual Scope scope() const = 0;
+
+ /// interposable - Whether the linker should use direct or indirect
+ /// access to this atom.
+ virtual Interposable interposable() const = 0;
+
+ /// merge - how the linker should handle if multiple atoms have
+ /// the same name.
+ virtual Merge merge() const = 0;
+
+ /// contentType - The type of this atom, such as code or data.
+ virtual ContentType contentType() const = 0;
+
+ /// alignment - The alignment constraints on how this atom must be laid out
+ /// in the final linked image (e.g. 16-byte aligned).
+ virtual Alignment alignment() const = 0;
+
+ /// sectionChoice - Whether this atom must be in a specially named section
+ /// in the final linked image, or if the linker can infer the section
+ /// based on the contentType().
+ virtual SectionChoice sectionChoice() const = 0;
+
+ /// customSectionName - If sectionChoice() != sectionBasedOnContent, then
+ /// this return the name of the section the atom should be placed into.
+ virtual llvm::StringRef customSectionName() const = 0;
+
+ /// deadStrip - constraints on whether the linker may dead strip away
+ /// this atom.
+ virtual DeadStripKind deadStrip() const = 0;
+
+ /// permissions - Returns the OS memory protections required for this atom's
+ /// content at runtime. A function atom is R_X, a global variable is RW_,
+ /// and a read-only constant is R__.
+ virtual ContentPermissions permissions() const = 0;
+
+ /// isThumb - only applicable to ARM code. Tells the linker if the code
+ /// uses thumb or arm instructions. The linker needs to know this to
+ /// set the low bit of pointers to thumb functions.
+ virtual bool isThumb() const = 0;
+
+ /// isAlias - means this is a zero size atom that exists to provide an
+ /// alternate name for another atom. Alias atoms must have a special
+ /// Reference to the atom they alias which the layout engine recognizes
+ /// and forces the alias atom to layout right before the target atom.
+ virtual bool isAlias() const = 0;
+
+ /// rawContent - returns a reference to the raw (unrelocated) bytes of
+ /// this Atom's content.
+ virtual llvm::ArrayRef<uint8_t> rawContent() const = 0;
+
+ /// referencesBegin - used to start iterating this Atom's References
+ virtual Reference::iterator referencesBegin() const = 0;
+
+ /// referencesEnd - used to end iterating this Atom's References
+ virtual Reference::iterator referencesEnd() const = 0;
+
+protected:
+ /// DefinedAtom is an abstract base class.
+ /// Only subclasses can access constructor.
+ DefinedAtom() { }
+
+ /// The memory for DefinedAtom objects is always managed by the owning File
+ /// object. Therefore, no one but the owning File object should call
+ /// delete on an Atom. In fact, some File objects may bulk allocate
+ /// an array of Atoms, so they cannot be individually deleted by anyone.
+ virtual ~DefinedAtom() {}
+};
+
+} // namespace lld
+
+#endif // LLD_CORE_DEFINED_ATOM_H_
Modified: lld/trunk/include/lld/Core/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/File.h?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/File.h (original)
+++ lld/trunk/include/lld/Core/File.h Tue Jan 10 19:06:19 2012
@@ -12,6 +12,9 @@
#include "llvm/ADT/StringRef.h"
+#include "lld/Core/DefinedAtom.h"
+#include "lld/Core/UndefinedAtom.h"
+
namespace lld {
class File {
@@ -22,7 +25,8 @@
class AtomHandler {
public:
virtual ~AtomHandler() {}
- virtual void doAtom(const class Atom &) = 0;
+ virtual void doDefinedAtom(const class DefinedAtom &) = 0;
+ virtual void doUndefinedAtom(const class UndefinedAtom &) = 0;
virtual void doFile(const class File &) = 0;
};
Modified: lld/trunk/include/lld/Core/Resolver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Resolver.h?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Resolver.h (original)
+++ lld/trunk/include/lld/Core/Resolver.h Tue Jan 10 19:06:19 2012
@@ -13,6 +13,8 @@
#include "lld/Core/File.h"
#include "lld/Core/SymbolTable.h"
+#include "llvm/ADT/DenseSet.h"
+
#include <vector>
#include <set>
@@ -39,8 +41,9 @@
, _completedInitialObjectFiles(false) {}
// AtomHandler methods
- virtual void doAtom(const Atom &);
- virtual void doFile(const File &);
+ virtual void doDefinedAtom(const class DefinedAtom&);
+ virtual void doUndefinedAtom(const class UndefinedAtom&);
+ virtual void doFile(const File&);
/// @brief do work of merging and resolving and return list
std::vector<const Atom *> &resolve();
@@ -65,7 +68,7 @@
const Atom *entryPoint();
void markLive(const Atom &atom, WhyLiveBackChain *previous);
- void addAtoms(const std::vector<const Atom *>&);
+ void addAtoms(const std::vector<const DefinedAtom *>&);
Platform &_platform;
const InputFiles &_inputFiles;
@@ -73,6 +76,7 @@
std::vector<const Atom *> _atoms;
std::set<const Atom *> _deadStripRoots;
std::vector<const Atom *> _atomsWithUnresolvedReferences;
+ llvm::DenseSet<const Atom *> _liveAtoms;
bool _haveLLVMObjs;
bool _addToFinalSection;
bool _completedInitialObjectFiles;
Modified: lld/trunk/include/lld/Core/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/SymbolTable.h?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/SymbolTable.h (original)
+++ lld/trunk/include/lld/Core/SymbolTable.h Tue Jan 10 19:06:19 2012
@@ -21,6 +21,8 @@
namespace lld {
class Atom;
+class DefinedAtom;
+class UndefinedAtom;
class Platform;
/// The SymbolTable class is responsible for coalescing atoms.
@@ -33,7 +35,10 @@
SymbolTable(Platform& plat);
/// @brief add atom to symbol table
- void add(const Atom &);
+ void add(const DefinedAtom &);
+
+ /// @brief add atom to symbol table
+ void add(const UndefinedAtom &);
/// @brief checks if name is in symbol table and if so atom is not
/// UndefinedAtom
@@ -55,15 +60,16 @@
typedef std::map<llvm::StringRef, const Atom *> NameToAtom;
typedef std::map<const Atom *, const Atom *> AtomToAtom;
struct MyMappingInfo {
- static const Atom * getEmptyKey() { return NULL; }
- static const Atom * getTombstoneKey() { return (Atom*)(-1); }
- static unsigned getHashValue(const Atom * const Val);
- static bool isEqual(const Atom * const LHS, const Atom * const RHS);
+ static const DefinedAtom * getEmptyKey() { return NULL; }
+ static const DefinedAtom * getTombstoneKey() { return (DefinedAtom*)(-1); }
+ static unsigned getHashValue(const DefinedAtom * const Val);
+ static bool isEqual(const DefinedAtom * const LHS,
+ const DefinedAtom * const RHS);
};
- typedef llvm::DenseSet<const Atom*, MyMappingInfo> AtomContentSet;
+ typedef llvm::DenseSet<const DefinedAtom*, MyMappingInfo> AtomContentSet;
void addByName(const Atom &);
- void addByContent(const Atom &);
+ void addByContent(const DefinedAtom &);
Platform& _platform;
AtomToAtom _replacedAtoms;
Modified: lld/trunk/include/lld/Core/UndefinedAtom.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/UndefinedAtom.h?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/UndefinedAtom.h (original)
+++ lld/trunk/include/lld/Core/UndefinedAtom.h Tue Jan 10 19:06:19 2012
@@ -20,22 +20,9 @@
/// It exists as a place holder for a future atom.
class UndefinedAtom : public Atom {
public:
- UndefinedAtom(llvm::StringRef nm, const File& f)
- : Atom( 0,
- Atom::definitionUndefined
- , Atom::scopeLinkageUnit
- , Atom::typeUnknown
- , Atom::sectionBasedOnContent
- , false
- , false
- , false
- , deadStripNormal
- , false
- , false
- , Atom::Alignment(0))
- , _name(nm), _file(f) {}
+ UndefinedAtom(llvm::StringRef nm, bool weakImport, const File& f)
+ : _name(nm), _file(f), _weakImport(weakImport) {}
- // overrides of Atom
virtual const File& file() const {
return _file;
}
@@ -43,21 +30,21 @@
virtual llvm::StringRef name() const {
return _name;
}
- virtual uint64_t size() const {
- return 0;
+
+ virtual Definition definition() const {
+ return Atom::definitionUndefined;
}
- virtual uint64_t objectAddress() const {
- return 0;
+
+ virtual bool weakImport() const {
+ return _weakImport;
}
- virtual void copyRawContent(uint8_t buffer[]) const { }
- virtual void setScope(Scope) { }
- bool weakImport();
protected:
virtual ~UndefinedAtom() {}
llvm::StringRef _name;
const File& _file;
+ bool _weakImport;
};
} // namespace lld
Modified: lld/trunk/include/lld/Platform/Platform.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Platform/Platform.h?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/include/lld/Platform/Platform.h (original)
+++ lld/trunk/include/lld/Platform/Platform.h Tue Jan 10 19:06:19 2012
@@ -14,6 +14,7 @@
namespace lld {
class Atom;
+class DefinedAtom;
/// The Platform class encapsulated plaform specific linking knowledge.
///
@@ -29,15 +30,15 @@
virtual void atomAdded(const Atom &file) = 0;
/// @brief give platform a chance to change each atom's scope
- virtual void adjustScope(const Atom &atom) = 0;
+ virtual void adjustScope(const DefinedAtom &atom) = 0;
/// @brief if specified atom needs alternate names, return AliasAtom(s)
virtual bool getAliasAtoms(const Atom &atom,
- std::vector<const Atom *>&) = 0;
+ std::vector<const DefinedAtom *>&) = 0;
/// @brief give platform a chance to resolve platform-specific undefs
virtual bool getPlatformAtoms(llvm::StringRef undefined,
- std::vector<const Atom *>&) = 0;
+ std::vector<const DefinedAtom *>&) = 0;
/// @brief resolver should remove unreferenced atoms
virtual bool deadCodeStripping() = 0;
@@ -46,7 +47,7 @@
virtual bool isDeadStripRoot(const Atom &atom) = 0;
/// @brief if target must have some atoms, denote here
- virtual bool getImplicitDeadStripRoots(std::vector<const Atom *>&) = 0;
+ virtual bool getImplicitDeadStripRoots(std::vector<const DefinedAtom *>&) = 0;
/// @brief return entry point for output file (e.g. "main") or NULL
virtual llvm::StringRef entryPointName() = 0;
Removed: lld/trunk/lib/Core/Atom.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Atom.cpp?rev=147902&view=auto
==============================================================================
--- lld/trunk/lib/Core/Atom.cpp (original)
+++ lld/trunk/lib/Core/Atom.cpp (removed)
@@ -1,44 +0,0 @@
-//===- Core/Atom.cpp - The Fundimental Unit of Linking --------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lld/Core/Atom.h"
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace lld {
-
- Atom::~Atom() {}
-
- llvm::StringRef Atom::name() const {
- return llvm::StringRef();
- }
-
- llvm::StringRef Atom::customSectionName() const {
- return llvm::StringRef();
- }
-
- llvm::ArrayRef<uint8_t> Atom::rawContent() const {
- return llvm::ArrayRef<uint8_t>();
- }
-
- Atom::ContentPermissions Atom::permissions() const {
- return perm___;
- }
-
- Reference::iterator Atom::referencesBegin() const {
- return 0;
- }
-
- Reference::iterator Atom::referencesEnd() const{
- return 0;
- }
-
-
-} // namespace lld
Modified: lld/trunk/lib/Core/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/CMakeLists.txt?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/lib/Core/CMakeLists.txt (original)
+++ lld/trunk/lib/Core/CMakeLists.txt Tue Jan 10 19:06:19 2012
@@ -1,5 +1,4 @@
add_lld_library(lldCore
- Atom.cpp
File.cpp
Resolver.cpp
SymbolTable.cpp
Modified: lld/trunk/lib/Core/Resolver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/lib/Core/Resolver.cpp (original)
+++ lld/trunk/lib/Core/Resolver.cpp Tue Jan 10 19:06:19 2012
@@ -19,17 +19,35 @@
#include <algorithm>
#include <cassert>
+
#include <vector>
namespace lld {
+/// This is used as a filter function to std::remove_if to dead strip atoms.
class NotLive {
public:
+ NotLive(const llvm::DenseSet<const Atom*>& la) : _liveAtoms(la) { }
+
bool operator()(const Atom *atom) const {
- return !(atom->live() || !atom->deadStrip());
+ // don't remove if live
+ if ( _liveAtoms.count(atom) )
+ return false;
+ // don't remove if marked never-dead-strip
+ if ( const DefinedAtom* defAtom = atom->definedAtom() ) {
+ if ( defAtom->deadStrip() == DefinedAtom::deadStripNever )
+ return false;
+ }
+ // do remove this atom
+ return true;
}
+
+private:
+ const llvm::DenseSet<const Atom*> _liveAtoms;
};
+
+/// This is used as a filter function to std::remove_if to coalesced atoms.
class AtomCoalescedAway {
public:
AtomCoalescedAway(SymbolTable &sym) : _symbolTable(sym) {}
@@ -43,6 +61,9 @@
SymbolTable &_symbolTable;
};
+
+
+
void Resolver::initializeState() {
_platform.initialize();
}
@@ -68,24 +89,34 @@
_platform.fileAdded(file);
}
+
+void Resolver::doUndefinedAtom(const class UndefinedAtom& atom) {
+ // add to list of known atoms
+ _atoms.push_back(&atom);
+
+ // tell symbol table
+ _symbolTable.add(atom);
+}
+
+
// called on each atom when a file is added
-void Resolver::doAtom(const Atom &atom) {
+void Resolver::doDefinedAtom(const DefinedAtom &atom) {
// notify platform
_platform.atomAdded(atom);
// add to list of known atoms
_atoms.push_back(&atom);
-
+
// adjust scope (e.g. force some globals to be hidden)
_platform.adjustScope(atom);
// non-static atoms need extra handling
- if (atom.scope() != Atom::scopeTranslationUnit) {
+ if (atom.scope() != DefinedAtom::scopeTranslationUnit) {
// tell symbol table about non-static atoms
_symbolTable.add(atom);
// platform can add aliases for any symbol
- std::vector<const Atom *> aliases;
+ std::vector<const DefinedAtom *> aliases;
if (_platform.getAliasAtoms(atom, aliases))
this->addAtoms(aliases);
}
@@ -104,10 +135,10 @@
}
// utility to add a vector of atoms
-void Resolver::addAtoms(const std::vector<const Atom *> &newAtoms) {
- for (std::vector<const Atom *>::const_iterator it = newAtoms.begin();
+void Resolver::addAtoms(const std::vector<const DefinedAtom*>& newAtoms) {
+ for (std::vector<const DefinedAtom *>::const_iterator it = newAtoms.begin();
it != newAtoms.end(); ++it) {
- this->doAtom(**it);
+ this->doDefinedAtom(**it);
}
}
@@ -135,7 +166,7 @@
// give platform a chance to instantiate platform
// specific atoms (e.g. section boundary)
if (!_symbolTable.isDefined(undefName)) {
- std::vector<const Atom *> platAtoms;
+ std::vector<const DefinedAtom *> platAtoms;
if (_platform.getPlatformAtoms(undefName, platAtoms))
this->addAtoms(platAtoms);
}
@@ -146,9 +177,10 @@
std::vector<const Atom *> tents;
for (std::vector<const Atom *>::iterator ait = _atoms.begin();
ait != _atoms.end(); ++ait) {
- const Atom *atom = *ait;
- if (atom->definition() == Atom::definitionTentative)
- tents.push_back(atom);
+ if ( const DefinedAtom* defAtom = (*ait)->definedAtom() ) {
+ if ( defAtom->merge() == DefinedAtom::mergeAsTentative )
+ tents.push_back(defAtom);
+ }
}
for (std::vector<const Atom *>::iterator dit = tents.begin();
dit != tents.end(); ++dit) {
@@ -157,9 +189,10 @@
llvm::StringRef tentName = (*dit)->name();
const Atom *curAtom = _symbolTable.findByName(tentName);
assert(curAtom != NULL);
- if (curAtom->definition() == Atom::definitionTentative) {
- _inputFiles.searchLibraries(tentName, searchDylibs, true, true,
- *this);
+ if ( const DefinedAtom* curDefAtom = curAtom->definedAtom() ) {
+ if (curDefAtom->merge() == DefinedAtom::mergeAsTentative )
+ _inputFiles.searchLibraries(tentName, searchDylibs,
+ true, true, *this);
}
}
}
@@ -171,10 +204,11 @@
void Resolver::updateReferences() {
for (std::vector<const Atom *>::iterator it = _atoms.begin();
it != _atoms.end(); ++it) {
- const Atom *atom = *it;
- for (Reference::iterator rit = atom->referencesBegin(),
- end = atom->referencesEnd(); rit != end; ++rit) {
- rit->target = _symbolTable.replacement(rit->target);
+ if ( const DefinedAtom* defAtom = (*it)->definedAtom() ) {
+ for (Reference::iterator rit = defAtom->referencesBegin(),
+ end = defAtom->referencesEnd(); rit != end; ++rit) {
+ rit->target = _symbolTable.replacement(rit->target);
+ }
}
}
}
@@ -195,19 +229,21 @@
}
// if already marked live, then done (stop recursion)
- if (atom.live())
+ if ( _liveAtoms.count(&atom) )
return;
// mark this atom is live
- const_cast<Atom *>(&atom)->setLive(true);
+ _liveAtoms.insert(&atom);
// mark all atoms it references as live
WhyLiveBackChain thisChain;
thisChain.previous = previous;
thisChain.referer = &atom;
- for (Reference::iterator rit = atom.referencesBegin(),
- end = atom.referencesEnd(); rit != end; ++rit) {
- this->markLive(*(rit->target), &thisChain);
+ if ( const DefinedAtom* defAtom = atom.definedAtom() ) {
+ for (Reference::iterator rit = defAtom->referencesBegin(),
+ end = defAtom->referencesEnd(); rit != end; ++rit) {
+ this->markLive(*(rit->target), &thisChain);
+ }
}
}
@@ -218,11 +254,7 @@
return;
// clear liveness on all atoms
- for (std::vector<const Atom *>::iterator it = _atoms.begin();
- it != _atoms.end(); ++it) {
- const Atom *atom = *it;
- const_cast<Atom *>(atom)->setLive(0);
- }
+ _liveAtoms.clear();
// add entry point (main) to live roots
const Atom *entry = this->entryPoint();
@@ -239,7 +271,7 @@
}
// add platform specific helper atoms
- std::vector<const Atom *> platRootAtoms;
+ std::vector<const DefinedAtom *> platRootAtoms;
if (_platform.getImplicitDeadStripRoots(platRootAtoms))
this->addAtoms(platRootAtoms);
@@ -254,7 +286,7 @@
// now remove all non-live atoms from _atoms
_atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(),
- NotLive()), _atoms.end());
+ NotLive(_liveAtoms)), _atoms.end());
}
// error out if some undefines remain
@@ -270,7 +302,7 @@
// when dead code stripping we don't care if dead atoms are undefined
undefinedAtoms.erase(std::remove_if(
undefinedAtoms.begin(), undefinedAtoms.end(),
- NotLive()), undefinedAtoms.end());
+ NotLive(_liveAtoms)), undefinedAtoms.end());
}
// let platform make error message about missing symbols
@@ -289,15 +321,16 @@
void Resolver::checkDylibSymbolCollisions() {
for (std::vector<const Atom *>::const_iterator it = _atoms.begin();
it != _atoms.end(); ++it) {
- const Atom *atom = *it;
- if (atom->scope() == Atom::scopeGlobal) {
- if (atom->definition() == Atom::definitionTentative) {
- // See if any shared library also has symbol which
- // collides with the tentative definition.
- // SymbolTable will warn if needed.
- _inputFiles.searchLibraries(atom->name(), true, false, false, *this);
- }
- }
+ const DefinedAtom* defAtom = (*it)->definedAtom();
+ if ( defAtom == NULL )
+ continue;
+ if ( defAtom->merge() != DefinedAtom::mergeAsTentative )
+ continue;
+ assert(defAtom->scope() != DefinedAtom::scopeTranslationUnit);
+ // See if any shared library also has symbol which
+ // collides with the tentative definition.
+ // SymbolTable will warn if needed.
+ _inputFiles.searchLibraries(defAtom->name(), true, false, false, *this);
}
}
Modified: lld/trunk/lib/Core/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/SymbolTable.cpp?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/lib/Core/SymbolTable.cpp (original)
+++ lld/trunk/lib/Core/SymbolTable.cpp Tue Jan 10 19:06:19 2012
@@ -9,6 +9,8 @@
#include "lld/Core/SymbolTable.h"
#include "lld/Core/Atom.h"
+#include "lld/Core/DefinedAtom.h"
+#include "lld/Core/UndefinedAtom.h"
#include "lld/Core/File.h"
#include "lld/Core/InputFiles.h"
#include "lld/Core/Resolver.h"
@@ -30,12 +32,16 @@
: _platform(plat) {
}
-void SymbolTable::add(const Atom &atom) {
- assert(atom.scope() != Atom::scopeTranslationUnit);
+void SymbolTable::add(const UndefinedAtom &atom) {
+ this->addByName(atom);
+}
+
+void SymbolTable::add(const DefinedAtom &atom) {
+ assert(atom.scope() != DefinedAtom::scopeTranslationUnit);
if ( !atom.internalName() ) {
this->addByName(atom);
}
- else if ( atom.mergeDuplicates() ) {
+ else {
this->addByContent(atom);
}
}
@@ -43,37 +49,27 @@
enum NameCollisionResolution {
NCR_First,
NCR_Second,
- NCR_Weak,
- NCR_Larger,
NCR_Dup,
NCR_Error
};
-static NameCollisionResolution cases[6][6] = {
- //regular weak tentative absolute undef sharedLib
+static NameCollisionResolution cases[4][4] = {
+ //regular absolute undef sharedLib
{
// first is regular
- NCR_Dup, NCR_First, NCR_First, NCR_Error, NCR_First, NCR_First
- },
- {
- // first is weak
- NCR_Second, NCR_Weak, NCR_Larger, NCR_Error, NCR_First, NCR_First
- },
- {
- // first is tentative
- NCR_Second, NCR_Second, NCR_Larger, NCR_Error, NCR_First, NCR_First
+ NCR_Dup, NCR_Error, NCR_First, NCR_First
},
{
// first is absolute
- NCR_Error, NCR_Error, NCR_Error, NCR_Error, NCR_First, NCR_First
+ NCR_Error, NCR_Error, NCR_First, NCR_First
},
{
// first is undef
- NCR_Second, NCR_Second, NCR_Second, NCR_Second, NCR_First, NCR_Second
+ NCR_Second, NCR_Second, NCR_First, NCR_Second
},
{
// first is sharedLib
- NCR_Second, NCR_Second, NCR_Second, NCR_Second, NCR_First, NCR_First
+ NCR_Second, NCR_Second, NCR_First, NCR_First
}
};
@@ -82,6 +78,40 @@
return cases[first][second];
}
+
+enum MergeResolution {
+ MCR_First,
+ MCR_Second,
+ MCR_Largest,
+ MCR_Error
+};
+
+static MergeResolution mergeCases[4][4] = {
+ // no tentative weak weakAddressUsed
+ {
+ // first is no
+ MCR_Error, MCR_First, MCR_First, MCR_First
+ },
+ {
+ // first is tentative
+ MCR_Second, MCR_Largest, MCR_Second, MCR_Second
+ },
+ {
+ // first is weak
+ MCR_Second, MCR_First, MCR_First, MCR_Second
+ },
+ {
+ // first is weakAddressUsed
+ MCR_Second, MCR_First, MCR_First, MCR_First
+ }
+};
+
+static MergeResolution mergeSelect(DefinedAtom::Merge first,
+ DefinedAtom::Merge second) {
+ return mergeCases[first][second];
+}
+
+
void SymbolTable::addByName(const Atom & newAtom) {
llvm::StringRef name = newAtom.name();
const Atom *existing = this->findByName(name);
@@ -93,31 +123,33 @@
// Name is already in symbol table and associated with another atom.
bool useNew = true;
switch (collide(existing->definition(), newAtom.definition())) {
- case NCR_First:
- useNew = false;
- break;
- case NCR_Second:
- useNew = true;
- break;
- case NCR_Dup:
- if ( existing->mergeDuplicates() && newAtom.mergeDuplicates() ) {
- // Both mergeable. Use auto-hide bit as tie breaker
- if ( existing->autoHide() != newAtom.autoHide() ) {
- // They have different autoHide values, keep non-autohide one
- useNew = existing->autoHide();
- }
- else {
- // They have same autoHide, so just keep using existing
- useNew = false;
+ case NCR_First:
+ useNew = false;
+ break;
+ case NCR_Second:
+ useNew = true;
+ break;
+ case NCR_Dup:
+ assert(existing->definition() == Atom::definitionRegular);
+ assert(newAtom.definition() == Atom::definitionRegular);
+ switch ( mergeSelect(((DefinedAtom*)existing)->merge(),
+ ((DefinedAtom*)(&newAtom))->merge()) ) {
+ case MCR_First:
+ useNew = false;
+ break;
+ case MCR_Second:
+ useNew = true;
+ break;
+ case MCR_Largest:
+ useNew = true;
+ break;
+ case MCR_Error:
+ llvm::report_fatal_error("duplicate symbol error");
+ break;
}
- }
- else {
- const Atom& use = _platform.handleMultipleDefinitions(*existing, newAtom);
- useNew = ( &use != existing );
- }
- break;
- default:
- llvm::report_fatal_error("SymbolTable::addByName(): unhandled switch clause");
+ break;
+ default:
+ llvm::report_fatal_error("SymbolTable::addByName(): unhandled switch clause");
}
if ( useNew ) {
// Update name table to use new atom.
@@ -133,9 +165,9 @@
}
-unsigned SymbolTable::MyMappingInfo::getHashValue(const Atom * const atom) {
+unsigned SymbolTable::MyMappingInfo::getHashValue(const DefinedAtom * const atom) {
unsigned hash = atom->size();
- if ( atom->contentType() != Atom::typeZeroFill ) {
+ if ( atom->contentType() != DefinedAtom::typeZeroFill ) {
llvm::ArrayRef<uint8_t> content = atom->rawContent();
for (unsigned int i=0; i < content.size(); ++i) {
hash = hash * 33 + content[i];
@@ -148,8 +180,8 @@
}
-bool SymbolTable::MyMappingInfo::isEqual(const Atom * const l,
- const Atom * const r) {
+bool SymbolTable::MyMappingInfo::isEqual(const DefinedAtom * const l,
+ const DefinedAtom * const r) {
if ( l == r )
return true;
if ( l == getEmptyKey() )
@@ -171,7 +203,7 @@
}
-void SymbolTable::addByContent(const Atom & newAtom) {
+void SymbolTable::addByContent(const DefinedAtom & newAtom) {
AtomContentSet::iterator pos = _contentTable.find(&newAtom);
if ( pos == _contentTable.end() ) {
_contentTable.insert(&newAtom);
Modified: lld/trunk/lib/Core/YamlKeyValues.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.cpp?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlKeyValues.cpp (original)
+++ lld/trunk/lib/Core/YamlKeyValues.cpp Tue Jan 10 19:06:19 2012
@@ -18,61 +18,33 @@
const char* const KeyValues::nameKeyword = "name";
-const char* const KeyValues::scopeKeyword = "scope";
const char* const KeyValues::definitionKeyword = "definition";
+const char* const KeyValues::scopeKeyword = "scope";
const char* const KeyValues::contentTypeKeyword = "type";
const char* const KeyValues::deadStripKindKeyword = "dead-strip";
const char* const KeyValues::sectionChoiceKeyword = "section-choice";
const char* const KeyValues::internalNameKeyword = "internal-name";
-const char* const KeyValues::mergeDuplicatesKeyword = "merge-duplicates";
-const char* const KeyValues::autoHideKeyword = "auto-hide";
+const char* const KeyValues::interposableKeyword = "interposable";
+const char* const KeyValues::mergeKeyword = "merge";
const char* const KeyValues::isThumbKeyword = "is-thumb";
const char* const KeyValues::isAliasKeyword = "is-alias";
const char* const KeyValues::sectionNameKeyword = "section-name";
const char* const KeyValues::contentKeyword = "content";
const char* const KeyValues::sizeKeyword = "size";
+const char* const KeyValues::permissionsKeyword = "permissions";
-const Atom::Scope KeyValues::scopeDefault = Atom::scopeTranslationUnit;
-const Atom::Definition KeyValues::definitionDefault = Atom::definitionRegular;
-const Atom::ContentType KeyValues::contentTypeDefault = Atom::typeData;
-const Atom::DeadStripKind KeyValues::deadStripKindDefault = Atom::deadStripNormal;
-const Atom::SectionChoice KeyValues::sectionChoiceDefault = Atom::sectionBasedOnContent;
-const bool KeyValues::internalNameDefault = false;
-const bool KeyValues::mergeDuplicatesDefault = false;
-const bool KeyValues::autoHideDefault = false;
-const bool KeyValues::isThumbDefault = false;
-const bool KeyValues::isAliasDefault = false;
-
-
-struct ScopeMapping {
- const char* string;
- Atom::Scope value;
-};
-
-static const ScopeMapping scopeMappings[] = {
- { "global", Atom::scopeGlobal },
- { "hidden", Atom::scopeLinkageUnit },
- { "static", Atom::scopeTranslationUnit },
- { NULL, Atom::scopeGlobal }
-};
-
-Atom::Scope KeyValues::scope(const char* s)
-{
- for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
- if ( strcmp(p->string, s) == 0 )
- return p->value;
- }
- llvm::report_fatal_error("bad scope value");
-}
-
-const char* KeyValues::scope(Atom::Scope s) {
- for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
- if ( p->value == s )
- return p->string;
- }
- llvm::report_fatal_error("bad scope value");
-}
+const DefinedAtom::Definition KeyValues::definitionDefault = Atom::definitionRegular;
+const DefinedAtom::Scope KeyValues::scopeDefault = DefinedAtom::scopeTranslationUnit;
+const DefinedAtom::ContentType KeyValues::contentTypeDefault = DefinedAtom::typeData;
+const DefinedAtom::DeadStripKind KeyValues::deadStripKindDefault = DefinedAtom::deadStripNormal;
+const DefinedAtom::SectionChoice KeyValues::sectionChoiceDefault = DefinedAtom::sectionBasedOnContent;
+const DefinedAtom::Interposable KeyValues::interposableDefault = DefinedAtom::interposeNo;
+const DefinedAtom::Merge KeyValues::mergeDefault = DefinedAtom::mergeNo;
+const DefinedAtom::ContentPermissions KeyValues::permissionsDefault = DefinedAtom::permR__;
+const bool KeyValues::internalNameDefault = false;
+const bool KeyValues::isThumbDefault = false;
+const bool KeyValues::isAliasDefault = false;
@@ -85,8 +57,6 @@
static const DefinitionMapping defMappings[] = {
{ "regular", Atom::definitionRegular },
- { "weak", Atom::definitionWeak },
- { "tentative", Atom::definitionTentative },
{ "absolute", Atom::definitionAbsolute },
{ "undefined", Atom::definitionUndefined },
{ "shared-library", Atom::definitionSharedLibrary },
@@ -114,40 +84,76 @@
+struct ScopeMapping {
+ const char* string;
+ DefinedAtom::Scope value;
+};
+
+static const ScopeMapping scopeMappings[] = {
+ { "global", DefinedAtom::scopeGlobal },
+ { "hidden", DefinedAtom::scopeLinkageUnit },
+ { "static", DefinedAtom::scopeTranslationUnit },
+ { NULL, DefinedAtom::scopeGlobal }
+};
+
+DefinedAtom::Scope KeyValues::scope(const char* s)
+{
+ for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
+ if ( strcmp(p->string, s) == 0 )
+ return p->value;
+ }
+ llvm::report_fatal_error("bad scope value");
+}
+
+const char* KeyValues::scope(DefinedAtom::Scope s) {
+ for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
+ if ( p->value == s )
+ return p->string;
+ }
+ llvm::report_fatal_error("bad scope value");
+}
+
+
+
+
+
+
+
+
struct ContentTypeMapping {
const char* string;
- Atom::ContentType value;
+ DefinedAtom::ContentType value;
};
static const ContentTypeMapping typeMappings[] = {
- { "unknown", Atom::typeUnknown },
- { "code", Atom::typeCode },
- { "resolver", Atom::typeResolver },
- { "constant", Atom::typeConstant },
- { "c-string", Atom::typeCString },
- { "utf16-string", Atom::typeUTF16String },
- { "CFI", Atom::typeCFI },
- { "LSDA", Atom::typeLSDA },
- { "literal-4", Atom::typeLiteral4 },
- { "literal-8", Atom::typeLiteral8 },
- { "literal-16", Atom::typeLiteral16 },
- { "data", Atom::typeData },
- { "zero-fill", Atom::typeZeroFill },
- { "cf-string", Atom::typeCFString },
- { "initializer-ptr",Atom::typeInitializerPtr },
- { "terminator-ptr", Atom::typeTerminatorPtr },
- { "c-string-ptr", Atom::typeCStringPtr },
- { "objc1-class", Atom::typeObjC1Class },
- { "objc1-class-ptr",Atom::typeObjCClassPtr },
- { "objc2-cat-ptr", Atom::typeObjC2CategoryList },
- { "tlv-thunk", Atom::typeThunkTLV },
- { "tlv-data", Atom::typeTLVInitialData },
- { "tlv-zero-fill", Atom::typeTLVInitialZeroFill },
- { "tlv-init-ptr", Atom::typeTLVInitializerPtr },
- { NULL, Atom::typeUnknown }
+ { "unknown", DefinedAtom::typeUnknown },
+ { "code", DefinedAtom::typeCode },
+ { "resolver", DefinedAtom::typeResolver },
+ { "constant", DefinedAtom::typeConstant },
+ { "c-string", DefinedAtom::typeCString },
+ { "utf16-string", DefinedAtom::typeUTF16String },
+ { "CFI", DefinedAtom::typeCFI },
+ { "LSDA", DefinedAtom::typeLSDA },
+ { "literal-4", DefinedAtom::typeLiteral4 },
+ { "literal-8", DefinedAtom::typeLiteral8 },
+ { "literal-16", DefinedAtom::typeLiteral16 },
+ { "data", DefinedAtom::typeData },
+ { "zero-fill", DefinedAtom::typeZeroFill },
+ { "cf-string", DefinedAtom::typeCFString },
+ { "initializer-ptr",DefinedAtom::typeInitializerPtr },
+ { "terminator-ptr", DefinedAtom::typeTerminatorPtr },
+ { "c-string-ptr", DefinedAtom::typeCStringPtr },
+ { "objc1-class", DefinedAtom::typeObjC1Class },
+ { "objc1-class-ptr",DefinedAtom::typeObjCClassPtr },
+ { "objc2-cat-ptr", DefinedAtom::typeObjC2CategoryList },
+ { "tlv-thunk", DefinedAtom::typeThunkTLV },
+ { "tlv-data", DefinedAtom::typeTLVInitialData },
+ { "tlv-zero-fill", DefinedAtom::typeTLVInitialZeroFill },
+ { "tlv-init-ptr", DefinedAtom::typeTLVInitializerPtr },
+ { NULL, DefinedAtom::typeUnknown }
};
-Atom::ContentType KeyValues::contentType(const char* s)
+DefinedAtom::ContentType KeyValues::contentType(const char* s)
{
for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) {
if ( strcmp(p->string, s) == 0 )
@@ -156,7 +162,7 @@
llvm::report_fatal_error("bad content type value");
}
-const char* KeyValues::contentType(Atom::ContentType s) {
+const char* KeyValues::contentType(DefinedAtom::ContentType s) {
for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) {
if ( p->value == s )
return p->string;
@@ -172,17 +178,17 @@
struct DeadStripMapping {
const char* string;
- Atom::DeadStripKind value;
+ DefinedAtom::DeadStripKind value;
};
static const DeadStripMapping deadStripMappings[] = {
- { "normal", Atom::deadStripNormal },
- { "never", Atom::deadStripNever },
- { "always", Atom::deadStripAlways },
- { NULL, Atom::deadStripNormal }
+ { "normal", DefinedAtom::deadStripNormal },
+ { "never", DefinedAtom::deadStripNever },
+ { "always", DefinedAtom::deadStripAlways },
+ { NULL, DefinedAtom::deadStripNormal }
};
-Atom::DeadStripKind KeyValues::deadStripKind(const char* s)
+DefinedAtom::DeadStripKind KeyValues::deadStripKind(const char* s)
{
for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) {
if ( strcmp(p->string, s) == 0 )
@@ -191,7 +197,7 @@
llvm::report_fatal_error("bad dead strip value");
}
-const char* KeyValues::deadStripKind(Atom::DeadStripKind dsk) {
+const char* KeyValues::deadStripKind(DefinedAtom::DeadStripKind dsk) {
for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) {
if ( p->value == dsk )
return p->string;
@@ -203,34 +209,33 @@
-
-struct SectionChoiceMapping {
+struct InterposableMapping {
const char* string;
- Atom::SectionChoice value;
+ DefinedAtom::Interposable value;
};
-static const SectionChoiceMapping sectMappings[] = {
- { "content", Atom::sectionBasedOnContent },
- { "custom", Atom::sectionCustomPreferred },
- { "custom-required", Atom::sectionCustomRequired },
- { NULL, Atom::sectionBasedOnContent }
+static const InterposableMapping interMappings[] = {
+ { "no", DefinedAtom::interposeNo },
+ { "yes", DefinedAtom::interposeYes },
+ { "yesAndWeak", DefinedAtom::interposeYesAndRuntimeWeak },
+ { NULL, DefinedAtom::interposeNo }
};
-Atom::SectionChoice KeyValues::sectionChoice(const char* s)
+DefinedAtom::Interposable KeyValues::interposable(const char* s)
{
- for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
+ for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) {
if ( strcmp(p->string, s) == 0 )
return p->value;
}
- llvm::report_fatal_error("bad dead strip value");
+ llvm::report_fatal_error("bad interposable value");
}
-const char* KeyValues::sectionChoice(Atom::SectionChoice s) {
- for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
- if ( p->value == s )
+const char* KeyValues::interposable(DefinedAtom::Interposable in) {
+ for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) {
+ if ( p->value == in )
return p->string;
}
- llvm::report_fatal_error("bad dead strip value");
+ llvm::report_fatal_error("bad interposable value");
}
@@ -238,18 +243,34 @@
+struct MergeMapping {
+ const char* string;
+ DefinedAtom::Merge value;
+};
-bool KeyValues::internalName(const char* s)
+static const MergeMapping mergeMappings[] = {
+ { "no", DefinedAtom::mergeNo },
+ { "asTentative", DefinedAtom::mergeAsTentative },
+ { "asWeak", DefinedAtom::mergeAsWeak },
+ { "asAddressedWeak",DefinedAtom::mergeAsWeakAndAddressUsed },
+ { NULL, DefinedAtom::mergeNo }
+};
+
+DefinedAtom::Merge KeyValues::merge(const char* s)
{
- if ( strcmp(s, "true") == 0 )
- return true;
- else if ( strcmp(s, "false") == 0 )
- return false;
- llvm::report_fatal_error("bad internal-name value");
+ for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) {
+ if ( strcmp(p->string, s) == 0 )
+ return p->value;
+ }
+ llvm::report_fatal_error("bad merge value");
}
-const char* KeyValues::internalName(bool b) {
- return b ? "true" : "false";
+const char* KeyValues::merge(DefinedAtom::Merge in) {
+ for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) {
+ if ( p->value == in )
+ return p->string;
+ }
+ llvm::report_fatal_error("bad merge value");
}
@@ -257,17 +278,33 @@
-bool KeyValues::mergeDuplicates(const char* s)
+struct SectionChoiceMapping {
+ const char* string;
+ DefinedAtom::SectionChoice value;
+};
+
+static const SectionChoiceMapping sectMappings[] = {
+ { "content", DefinedAtom::sectionBasedOnContent },
+ { "custom", DefinedAtom::sectionCustomPreferred },
+ { "custom-required", DefinedAtom::sectionCustomRequired },
+ { NULL, DefinedAtom::sectionBasedOnContent }
+};
+
+DefinedAtom::SectionChoice KeyValues::sectionChoice(const char* s)
{
- if ( strcmp(s, "true") == 0 )
- return true;
- else if ( strcmp(s, "false") == 0 )
- return false;
- llvm::report_fatal_error("bad merge-duplicates value");
+ for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
+ if ( strcmp(p->string, s) == 0 )
+ return p->value;
+ }
+ llvm::report_fatal_error("bad dead strip value");
}
-const char* KeyValues::mergeDuplicates(bool b) {
- return b ? "true" : "false";
+const char* KeyValues::sectionChoice(DefinedAtom::SectionChoice s) {
+ for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
+ if ( p->value == s )
+ return p->string;
+ }
+ llvm::report_fatal_error("bad dead strip value");
}
@@ -275,23 +312,60 @@
-bool KeyValues::autoHide(const char* s)
+
+struct PermissionsMapping {
+ const char* string;
+ DefinedAtom::ContentPermissions value;
+};
+
+static const PermissionsMapping permMappings[] = {
+ { "content", DefinedAtom::perm___ },
+ { "custom", DefinedAtom::permR__ },
+ { "custom-required", DefinedAtom::permR_X },
+ { "custom-required", DefinedAtom::permRW_ },
+ { "custom-required", DefinedAtom::permRW_L },
+ { NULL, DefinedAtom::perm___ }
+};
+
+DefinedAtom::ContentPermissions KeyValues::permissions(const char* s)
+{
+ for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) {
+ if ( strcmp(p->string, s) == 0 )
+ return p->value;
+ }
+ llvm::report_fatal_error("bad permissions value");
+}
+
+const char* KeyValues::permissions(DefinedAtom::ContentPermissions s) {
+ for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) {
+ if ( p->value == s )
+ return p->string;
+ }
+ llvm::report_fatal_error("bad permissions value");
+}
+
+
+
+
+
+
+
+bool KeyValues::internalName(const char* s)
{
if ( strcmp(s, "true") == 0 )
return true;
else if ( strcmp(s, "false") == 0 )
return false;
- llvm::report_fatal_error("bad auto-hide value");
+ llvm::report_fatal_error("bad internal-name value");
}
-const char* KeyValues::autoHide(bool b) {
+const char* KeyValues::internalName(bool b) {
return b ? "true" : "false";
}
-
bool KeyValues::isThumb(const char* s)
{
if ( strcmp(s, "true") == 0 )
Modified: lld/trunk/lib/Core/YamlKeyValues.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.h?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlKeyValues.h (original)
+++ lld/trunk/lib/Core/YamlKeyValues.h Tue Jan 10 19:06:19 2012
@@ -11,6 +11,7 @@
#define LLD_CORE_YAML_KEY_VALUES_H_
#include "lld/Core/Atom.h"
+#include "lld/Core/DefinedAtom.h"
namespace lld {
@@ -18,61 +19,65 @@
class KeyValues {
public:
- static const char* const nameKeyword;
- static const char* const sectionNameKeyword;
- static const char* const contentKeyword;
- static const char* const sizeKeyword;
+ static const char* const nameKeyword;
+ static const char* const sectionNameKeyword;
+ static const char* const contentKeyword;
+ static const char* const sizeKeyword;
-
- static const char* const scopeKeyword;
- static const Atom::Scope scopeDefault;
- static Atom::Scope scope(const char*);
- static const char* scope(Atom::Scope);
+ static const char* const definitionKeyword;
+ static const Atom::Definition definitionDefault;
+ static Atom::Definition definition(const char*);
+ static const char* definition(Atom::Definition);
+
+ static const char* const scopeKeyword;
+ static const DefinedAtom::Scope scopeDefault;
+ static DefinedAtom::Scope scope(const char*);
+ static const char* scope(DefinedAtom::Scope);
- static const char* const definitionKeyword;
- static const Atom::Definition definitionDefault;
- static Atom::Definition definition(const char*);
- static const char* definition(Atom::Definition);
-
- static const char* const contentTypeKeyword;
- static const Atom::ContentType contentTypeDefault;
- static Atom::ContentType contentType(const char*);
- static const char* contentType(Atom::ContentType);
-
- static const char* const deadStripKindKeyword;
- static const Atom::DeadStripKind deadStripKindDefault;
- static Atom::DeadStripKind deadStripKind(const char*);
- static const char* deadStripKind(Atom::DeadStripKind);
-
- static const char* const sectionChoiceKeyword;
- static const Atom::SectionChoice sectionChoiceDefault;
- static Atom::SectionChoice sectionChoice(const char*);
- static const char* sectionChoice(Atom::SectionChoice);
-
- static const char* const internalNameKeyword;
- static const bool internalNameDefault;
- static bool internalName(const char*);
- static const char* internalName(bool);
-
- static const char* const mergeDuplicatesKeyword;
- static const bool mergeDuplicatesDefault;
- static bool mergeDuplicates(const char*);
- static const char* mergeDuplicates(bool);
-
- static const char* const autoHideKeyword;
- static const bool autoHideDefault;
- static bool autoHide(const char*);
- static const char* autoHide(bool);
-
- static const char* const isThumbKeyword;
- static const bool isThumbDefault;
- static bool isThumb(const char*);
- static const char* isThumb(bool);
-
- static const char* const isAliasKeyword;
- static const bool isAliasDefault;
- static bool isAlias(const char*);
- static const char* isAlias(bool);
+ static const char* const contentTypeKeyword;
+ static const DefinedAtom::ContentType contentTypeDefault;
+ static DefinedAtom::ContentType contentType(const char*);
+ static const char* contentType(DefinedAtom::ContentType);
+
+ static const char* const deadStripKindKeyword;
+ static const DefinedAtom::DeadStripKind deadStripKindDefault;
+ static DefinedAtom::DeadStripKind deadStripKind(const char*);
+ static const char* deadStripKind(DefinedAtom::DeadStripKind);
+
+ static const char* const sectionChoiceKeyword;
+ static const DefinedAtom::SectionChoice sectionChoiceDefault;
+ static DefinedAtom::SectionChoice sectionChoice(const char*);
+ static const char* sectionChoice(DefinedAtom::SectionChoice);
+
+ static const char* const interposableKeyword;
+ static const DefinedAtom::Interposable interposableDefault;
+ static DefinedAtom::Interposable interposable(const char*);
+ static const char* interposable(DefinedAtom::Interposable);
+
+ static const char* const mergeKeyword;
+ static const DefinedAtom::Merge mergeDefault;
+ static DefinedAtom::Merge merge(const char*);
+ static const char* merge(DefinedAtom::Merge);
+
+ static const char* const permissionsKeyword;
+ static const DefinedAtom::ContentPermissions permissionsDefault;
+ static DefinedAtom::ContentPermissions permissions(const char*);
+ static const char* permissions(DefinedAtom::ContentPermissions);
+
+ static const char* const internalNameKeyword;
+ static const bool internalNameDefault;
+ static bool internalName(const char*);
+ static const char* internalName(bool);
+
+ static const char* const isThumbKeyword;
+ static const bool isThumbDefault;
+ static bool isThumb(const char*);
+ static const char* isThumb(bool);
+
+ static const char* const isAliasKeyword;
+ static const bool isAliasDefault;
+ static bool isAlias(const char*);
+ static const char* isAlias(bool);
};
Modified: lld/trunk/lib/Core/YamlReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlReader.cpp?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlReader.cpp (original)
+++ lld/trunk/lib/Core/YamlReader.cpp Tue Jan 10 19:06:19 2012
@@ -289,16 +289,17 @@
virtual bool justInTimeforEachAtom(llvm::StringRef name,
File::AtomHandler &) const;
- std::vector<Atom *> _atoms;
+ std::vector<DefinedAtom*> _definedAtoms;
+ std::vector<UndefinedAtom*> _undefinedAtoms;
std::vector<Reference> _references;
unsigned int _lastRefIndex;
};
bool YAMLFile::forEachAtom(File::AtomHandler &handler) const {
handler.doFile(*this);
- for (std::vector<Atom *>::const_iterator it = _atoms.begin();
- it != _atoms.end(); ++it) {
- handler.doAtom(**it);
+ for (std::vector<DefinedAtom *>::const_iterator it = _definedAtoms.begin();
+ it != _definedAtoms.end(); ++it) {
+ handler.doDefinedAtom(**it);
}
return true;
}
@@ -309,90 +310,153 @@
}
-class YAMLAtom : public Atom {
+class YAMLDefinedAtom : public DefinedAtom {
public:
- YAMLAtom( uint64_t ord
- , Definition d
- , Scope s
- , ContentType ct
- , SectionChoice sc
- , bool intn
- , bool md
- , bool ah
- , DeadStripKind dsk
- , bool tb
- , bool al
- , Alignment a
- , YAMLFile& f
- , const char *n
- , const char* sn
- , uint64_t sz
- , std::vector<uint8_t>* c)
- : Atom(ord, d, s, ct, sc, intn, md, ah, dsk, tb, al, a)
- , _file(f)
- , _name(n)
- , _sectionName(sn)
- , _content(c)
- , _size(sz)
- , _refStartIndex(f._lastRefIndex)
- , _refEndIndex(f._references.size()) {
- f._lastRefIndex = _refEndIndex;
+ YAMLDefinedAtom( uint32_t ord
+ , YAMLFile& file
+ , DefinedAtom::Scope scope
+ , DefinedAtom::ContentType type
+ , DefinedAtom::SectionChoice sectionChoice
+ , DefinedAtom::Interposable interpose
+ , DefinedAtom::Merge merge
+ , DefinedAtom::DeadStripKind deadStrip
+ , DefinedAtom::ContentPermissions perms
+ , bool internalName
+ , bool isThumb
+ , bool isAlias
+ , DefinedAtom::Alignment alignment
+ , const char* name
+ , const char* sectionName
+ , uint64_t size
+ , std::vector<uint8_t>* content)
+ : _file(file)
+ , _name(name)
+ , _sectionName(sectionName)
+ , _size(size)
+ , _ord(ord)
+ , _content(content)
+ , _alignment(alignment)
+ , _scope(scope)
+ , _type(type)
+ , _sectionChoice(sectionChoice)
+ , _interpose(interpose)
+ , _merge(merge)
+ , _deadStrip(deadStrip)
+ , _permissions(perms)
+ , _internalName(internalName)
+ , _isThumb(isThumb)
+ , _isAlias(isAlias)
+ , _refStartIndex(file._lastRefIndex)
+ , _refEndIndex(file._references.size()) {
+ file._lastRefIndex = _refEndIndex;
}
virtual const class File& file() const {
return _file;
}
- virtual bool translationUnitSource(const char* *dir, const char* *name) const{
- return false;
- }
-
virtual llvm::StringRef name() const {
return _name;
}
+
+ virtual bool internalName() const {
+ return _internalName;
+ }
- virtual llvm::StringRef customSectionName() const {
- return (_sectionName ? _sectionName : llvm::StringRef());
+ virtual uint64_t size() const {
+ return (_content ? _content->size() : _size);
}
- virtual uint64_t objectAddress() const {
- return 0;
+ virtual DefinedAtom::Scope scope() const {
+ return _scope;
+ }
+
+ virtual DefinedAtom::Interposable interposable() const {
+ return _interpose;
+ }
+
+ virtual DefinedAtom::Merge merge() const {
+ return _merge;
}
- virtual uint64_t size() const {
- return (_content ? _content->size() : _size);
+ virtual DefinedAtom::ContentType contentType() const {
+ return _type;
+ }
+
+ virtual DefinedAtom::Alignment alignment() const {
+ return _alignment;
+ }
+
+ virtual DefinedAtom::SectionChoice sectionChoice() const {
+ return _sectionChoice;
}
- llvm::ArrayRef<uint8_t> rawContent() const {
+ virtual llvm::StringRef customSectionName() const {
+ return _sectionName;
+ }
+
+ virtual DefinedAtom::DeadStripKind deadStrip() const {
+ return _deadStrip;
+ }
+
+ virtual DefinedAtom::ContentPermissions permissions() const {
+ return _permissions;
+ }
+
+ virtual bool isThumb() const {
+ return _isThumb;
+ }
+
+ virtual bool isAlias() const {
+ return _isAlias;
+ }
+
+ llvm::ArrayRef<uint8_t> rawContent() const {
if ( _content != NULL )
return llvm::ArrayRef<uint8_t>(*_content);
else
return llvm::ArrayRef<uint8_t>();
}
+
+ virtual uint64_t ordinal() const {
+ return _ord;
+ }
+
+
+ virtual Reference::iterator referencesBegin() const {
+ if (_file._references.size() < _refStartIndex)
+ return (Reference::iterator)&_file._references[_refStartIndex];
+ return 0;
+ }
+
+ virtual Reference::iterator referencesEnd() const {
+ if (_file._references.size() < _refEndIndex)
+ return (Reference::iterator)&_file._references[_refEndIndex];
+ return 0;
+ }
- virtual Reference::iterator referencesBegin() const;
- virtual Reference::iterator referencesEnd() const;
private:
- YAMLFile& _file;
- const char * _name;
- const char * _sectionName;
- std::vector<uint8_t>* _content;
- unsigned long _size;
- unsigned int _refStartIndex;
- unsigned int _refEndIndex;
+ YAMLFile& _file;
+ const char * _name;
+ const char * _sectionName;
+ unsigned long _size;
+ uint32_t _ord;
+ std::vector<uint8_t>* _content;
+ DefinedAtom::Alignment _alignment;
+ DefinedAtom::Scope _scope;
+ DefinedAtom::ContentType _type;
+ DefinedAtom::SectionChoice _sectionChoice;
+ DefinedAtom::Interposable _interpose;
+ DefinedAtom::Merge _merge;
+ DefinedAtom::DeadStripKind _deadStrip;
+ DefinedAtom::ContentPermissions _permissions;
+ bool _internalName;
+ bool _isThumb;
+ bool _isAlias;
+ unsigned int _refStartIndex;
+ unsigned int _refEndIndex;
};
-Reference::iterator YAMLAtom::referencesBegin() const {
- if (_file._references.size() < _refStartIndex)
- return (Reference::iterator)&_file._references[_refStartIndex];
- return 0;
-}
-
-Reference::iterator YAMLAtom::referencesEnd() const {
- if (_file._references.size() < _refEndIndex)
- return (Reference::iterator)&_file._references[_refEndIndex];
- return 0;
-}
class YAMLAtomState {
public:
@@ -408,42 +472,46 @@
void makeAtom(YAMLFile&);
- uint64_t _ordinal;
- long long _size;
- const char *_name;
- Atom::Alignment _align;
- Atom::ContentType _type;
- Atom::Scope _scope;
- Atom::Definition _def;
- Atom::SectionChoice _sectionChoice;
- bool _internalName;
- bool _mergeDuplicates;
- Atom::DeadStripKind _deadStrip;
- bool _thumb;
- bool _alias;
- bool _autoHide;
- const char *_sectionName;
- std::vector<uint8_t>* _content;
- Reference _ref;
+ const char * _name;
+ const char * _sectionName;
+ unsigned long long _size;
+ uint32_t _ordinal;
+ std::vector<uint8_t>* _content;
+ DefinedAtom::Alignment _alignment;
+ Atom::Definition _definition;
+ DefinedAtom::Scope _scope;
+ DefinedAtom::ContentType _type;
+ DefinedAtom::SectionChoice _sectionChoice;
+ DefinedAtom::Interposable _interpose;
+ DefinedAtom::Merge _merge;
+ DefinedAtom::DeadStripKind _deadStrip;
+ DefinedAtom::ContentPermissions _permissions;
+ bool _internalName;
+ bool _isThumb;
+ bool _isAlias;
+ Reference _ref;
};
+
YAMLAtomState::YAMLAtomState()
- : _ordinal(0)
+ : _name(NULL)
+ , _sectionName(NULL)
, _size(0)
- , _name(NULL)
- , _align(0, 0)
- , _type(KeyValues::contentTypeDefault)
+ , _ordinal(0)
+ , _content(NULL)
+ , _alignment(0, 0)
+ , _definition(KeyValues::definitionDefault)
, _scope(KeyValues::scopeDefault)
- , _def(KeyValues::definitionDefault)
+ , _type(KeyValues::contentTypeDefault)
, _sectionChoice(KeyValues::sectionChoiceDefault)
- , _internalName(KeyValues::internalNameDefault)
- , _mergeDuplicates(KeyValues::mergeDuplicatesDefault)
+ , _interpose(KeyValues::interposableDefault)
+ , _merge(KeyValues::mergeDefault)
, _deadStrip(KeyValues::deadStripKindDefault)
- , _thumb(KeyValues::isThumbDefault)
- , _alias(KeyValues::isAliasDefault)
- , _autoHide(KeyValues::autoHideDefault)
- , _sectionName(NULL)
- , _content(NULL) {
+ , _permissions(KeyValues::permissionsDefault)
+ , _internalName(KeyValues::internalNameDefault)
+ , _isThumb(KeyValues::isThumbDefault)
+ , _isAlias(KeyValues::isAliasDefault)
+ {
_ref.target = NULL;
_ref.addend = 0;
_ref.offsetInAtom = 0;
@@ -451,31 +519,36 @@
_ref.flags = 0;
}
+
void YAMLAtomState::makeAtom(YAMLFile& f) {
- Atom *a = new YAMLAtom(_ordinal, _def, _scope, _type, _sectionChoice,
- _internalName, _mergeDuplicates, _autoHide,
- _deadStrip, _thumb, _alias, _align, f,
- _name, _sectionName, _size, _content);
+ if ( _definition == Atom::definitionRegular ) {
+ DefinedAtom *a = new YAMLDefinedAtom(_ordinal, f, _scope, _type,
+ _sectionChoice, _interpose, _merge, _deadStrip,
+ _permissions, _internalName, _isThumb, _isAlias,
+ _alignment, _name, _sectionName, _size, _content);
- f._atoms.push_back(a);
- ++_ordinal;
+ f._definedAtoms.push_back(a);
+ ++_ordinal;
+ }
// reset state for next atom
_name = NULL;
- _align.powerOf2 = 0;
- _align.modulus = 0;
- _type = KeyValues::contentTypeDefault;
+ _sectionName = NULL;
+ _size = 0;
+ _ordinal = 0;
+ _content = NULL;
+ _alignment.powerOf2= 0;
+ _alignment.modulus = 0;
+ _definition = KeyValues::definitionDefault;
_scope = KeyValues::scopeDefault;
- _def = KeyValues::definitionDefault;
+ _type = KeyValues::contentTypeDefault;
_sectionChoice = KeyValues::sectionChoiceDefault;
- _internalName = KeyValues::internalNameDefault;
- _mergeDuplicates = KeyValues::mergeDuplicatesDefault;
+ _interpose = KeyValues::interposableDefault;
+ _merge = KeyValues::mergeDefault;
_deadStrip = KeyValues::deadStripKindDefault;
- _thumb = KeyValues::isThumbDefault;
- _alias = KeyValues::isAliasDefault;
- _autoHide = KeyValues::autoHideDefault;
- _sectionName = NULL;
- _content = NULL;
+ _permissions = KeyValues::permissionsDefault;
+ _isThumb = KeyValues::isThumbDefault;
+ _isAlias = KeyValues::isAliasDefault;
_ref.target = NULL;
_ref.addend = 0;
_ref.offsetInAtom = 0;
@@ -492,7 +565,7 @@
llvm::StringRef str(s);
uint32_t res;
str.getAsInteger(10, res);
- _align.powerOf2 = static_cast<uint16_t>(res);
+ _alignment.powerOf2 = static_cast<uint16_t>(res);
}
@@ -590,7 +663,7 @@
haveAtom = true;
}
else if (strcmp(entry->key, KeyValues::definitionKeyword) == 0) {
- atomState._def = KeyValues::definition(entry->value);
+ atomState._definition = KeyValues::definition(entry->value);
haveAtom = true;
}
else if (strcmp(entry->key, KeyValues::scopeKeyword) == 0) {
@@ -609,20 +682,20 @@
atomState._sectionChoice = KeyValues::sectionChoice(entry->value);
haveAtom = true;
}
- else if (strcmp(entry->key, KeyValues::mergeDuplicatesKeyword) == 0) {
- atomState._mergeDuplicates = KeyValues::mergeDuplicates(entry->value);
+ else if (strcmp(entry->key, KeyValues::mergeKeyword) == 0) {
+ atomState._merge = KeyValues::merge(entry->value);
haveAtom = true;
}
- else if (strcmp(entry->key, KeyValues::autoHideKeyword) == 0) {
- atomState._autoHide = KeyValues::autoHide(entry->value);
+ else if (strcmp(entry->key, KeyValues::interposableKeyword) == 0) {
+ atomState._interpose = KeyValues::interposable(entry->value);
haveAtom = true;
}
else if (strcmp(entry->key, KeyValues::isThumbKeyword) == 0) {
- atomState._thumb = KeyValues::isThumb(entry->value);
+ atomState._isThumb = KeyValues::isThumb(entry->value);
haveAtom = true;
}
else if (strcmp(entry->key, KeyValues::isAliasKeyword) == 0) {
- atomState._alias = KeyValues::isAlias(entry->value);
+ atomState._isAlias = KeyValues::isAlias(entry->value);
haveAtom = true;
}
else if (strcmp(entry->key, KeyValues::sectionNameKeyword) == 0) {
Modified: lld/trunk/lib/Core/YamlWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlWriter.cpp?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlWriter.cpp (original)
+++ lld/trunk/lib/Core/YamlWriter.cpp Tue Jan 10 19:06:19 2012
@@ -32,7 +32,7 @@
virtual void doFile(const class File &) { _firstAtom = true; }
- virtual void doAtom(const class Atom &atom) {
+ virtual void doDefinedAtom(const class DefinedAtom &atom) {
// add blank line between atoms for readability
if ( !_firstAtom )
_out << "\n";
@@ -72,6 +72,24 @@
<< "\n";
}
+ if ( atom.interposable() != KeyValues::interposableDefault ) {
+ _out << " "
+ << KeyValues::interposableKeyword
+ << ":"
+ << spacePadding(KeyValues::interposableKeyword)
+ << KeyValues::interposable(atom.interposable())
+ << "\n";
+ }
+
+ if ( atom.merge() != KeyValues::mergeDefault ) {
+ _out << " "
+ << KeyValues::mergeKeyword
+ << ":"
+ << spacePadding(KeyValues::mergeKeyword)
+ << KeyValues::merge(atom.merge())
+ << "\n";
+ }
+
if ( atom.contentType() != KeyValues::contentTypeDefault ) {
_out << " "
<< KeyValues::contentTypeKeyword
@@ -106,25 +124,7 @@
<< "\n";
}
- if ( atom.mergeDuplicates() != KeyValues::mergeDuplicatesDefault ) {
- _out << " "
- << KeyValues::mergeDuplicatesKeyword
- << ":"
- << spacePadding(KeyValues::mergeDuplicatesKeyword)
- << KeyValues::mergeDuplicates(atom.mergeDuplicates())
- << "\n";
- }
-
- if ( atom.autoHide() != KeyValues::autoHideDefault ) {
- _out << " "
- << KeyValues::autoHideKeyword
- << ":"
- << spacePadding(KeyValues::autoHideKeyword)
- << KeyValues::autoHide(atom.autoHide())
- << "\n";
- }
-
- if ( atom.isThumb() != KeyValues::isThumbDefault ) {
+ if ( atom.isThumb() != KeyValues::isThumbDefault ) {
_out << " "
<< KeyValues::isThumbKeyword
<< ":"
@@ -142,8 +142,7 @@
<< "\n";
}
-
- if ( atom.contentType() != Atom::typeZeroFill ) {
+ if ( atom.contentType() != DefinedAtom::typeZeroFill ) {
_out << " "
<< KeyValues::contentKeyword
<< ":"
@@ -172,6 +171,11 @@
}
+ virtual void doUndefinedAtom(const class UndefinedAtom &atom) {
+
+ }
+
+
private:
// return a string of the correct number of spaces to align value
const char* spacePadding(const char* key) {
Modified: lld/trunk/test/auto-hide-coalesce.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/auto-hide-coalesce.objtxt?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/test/auto-hide-coalesce.objtxt (original)
+++ lld/trunk/test/auto-hide-coalesce.objtxt Tue Jan 10 19:06:19 2012
@@ -10,67 +10,59 @@
scope: global
definition: regular
type: code
- merge-duplicates: true
- auto-hide: true
+ merge: asWeak
- name: _inlineFunc2
scope: global
definition: regular
type: code
- merge-duplicates: true
- auto-hide: true
+ merge: asWeak
- name: _inlineFunc3
scope: global
definition: regular
type: code
- merge-duplicates: true
- auto-hide: false
+ merge: asAddressedWeak
- name: _inlineFunc4
scope: global
definition: regular
type: code
- merge-duplicates: true
- auto-hide: false
+ merge: asAddressedWeak
---
atoms:
- name: _inlineFunc1
scope: global
definition: regular
type: code
- merge-duplicates: true
- auto-hide: true
+ merge: asWeak
- name: _inlineFunc2
scope: global
definition: regular
type: code
- merge-duplicates: true
- auto-hide: false
+ merge: asAddressedWeak
- name: _inlineFunc3
scope: global
definition: regular
type: code
- merge-duplicates: true
- auto-hide: true
+ merge: asWeak
- name: _inlineFunc4
scope: global
definition: regular
type: code
- merge-duplicates: true
- auto-hide: false
+ merge: asAddressedWeak
...
# CHECK: name: _inlineFunc1
-# CHECK: auto-hide: true
+# CHECK: merge: asWeak
# CHECK: name: _inlineFunc3
-# CHECK-NOT: auto-hide: true
+# CHECK: merge: asAddressedWeak
# CHECK: name: _inlineFunc4
-# CHECK-NOT: auto-hide: true
+# CHECK: merge: asAddressedWeak
# CHECK: name: _inlineFunc2
-# CHECK-NOT: auto-hide: true
+# CHECK: merge: asAddressedWeak
# CHECK: ...
Modified: lld/trunk/test/cstring-coalesce.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/cstring-coalesce.objtxt?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/test/cstring-coalesce.objtxt (original)
+++ lld/trunk/test/cstring-coalesce.objtxt Tue Jan 10 19:06:19 2012
@@ -10,14 +10,12 @@
internal-name: true
scope: hidden
type: c-string
- merge-duplicates: true
content: [ 68, 65, 6c, 6c, 6f, 00 ]
- name: L1
internal-name: true
scope: hidden
type: c-string
- merge-duplicates: true
content: [ 74, 68, 65, 72, 65, 00 ]
---
atoms:
@@ -25,7 +23,6 @@
internal-name: true
scope: hidden
type: c-string
- merge-duplicates: true
content: [ 68, 65, 6c, 6c, 6f, 00 ]
---
atoms:
@@ -33,7 +30,6 @@
internal-name: true
scope: hidden
type: c-string
- merge-duplicates: true
content: [ 74, 68, 65, 72, 65, 00 ]
...
Modified: lld/trunk/test/inline-coalesce.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/inline-coalesce.objtxt?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/test/inline-coalesce.objtxt (original)
+++ lld/trunk/test/inline-coalesce.objtxt Tue Jan 10 19:06:19 2012
@@ -10,25 +10,25 @@
scope: global
definition: regular
type: code
- merge-duplicates: true
+ merge: asWeak
---
atoms:
- name: _inlineFunc
scope: global
definition: regular
type: code
- merge-duplicates: true
+ merge: asWeak
---
atoms:
- name: _inlineFunc
scope: global
definition: regular
type: code
- merge-duplicates: true
+ merge: asWeak
...
# CHECK: name: _inlineFunc
-# CHECK: merge-duplicates: true
+# CHECK: merge: asWeak
# CHECK-NOT: name: _inlineFunc
# CHECK: ...
Modified: lld/trunk/test/multiple-def-error.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/multiple-def-error.objtxt?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/test/multiple-def-error.objtxt (original)
+++ lld/trunk/test/multiple-def-error.objtxt Tue Jan 10 19:06:19 2012
@@ -1,4 +1,4 @@
-# RUN: lld-core %s 2>&1 | grep "multiply defined"
+# RUN: lld-core %s 2>&1 | grep "duplicate symbol"
#
# Test that multiple definitions cause an error
Modified: lld/trunk/test/tent-merge.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/tent-merge.objtxt?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/test/tent-merge.objtxt (original)
+++ lld/trunk/test/tent-merge.objtxt Tue Jan 10 19:06:19 2012
@@ -8,7 +8,8 @@
---
atoms:
- name: _foo
- definition: tentative
+ definition: regular
+ merge: asTentative
scope: global
type: zero-fill
size: 4
@@ -23,4 +24,4 @@
# CHECK: name: _foo
-# CHECK-NOT: definition: tentative
+# CHECK-NOT: merge: asTentative
Modified: lld/trunk/test/weak-coalesce.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/weak-coalesce.objtxt?rev=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/test/weak-coalesce.objtxt (original)
+++ lld/trunk/test/weak-coalesce.objtxt Tue Jan 10 19:06:19 2012
@@ -7,7 +7,8 @@
---
atoms:
- name: _foo
- definition: weak
+ definition: regular
+ merge: asWeak
scope: global
type: data
---
@@ -19,13 +20,14 @@
---
atoms:
- name: _foo
- definition: weak
+ definition: regular
+ merge: asWeak
scope: global
type: data
...
# CHECK: name: _foo
-# CHECK-NOT: definition: weak
+# CHECK-NOT: merge: asWeak
# CHECK-NOT: name: _foo
# 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=147903&r1=147902&r2=147903&view=diff
==============================================================================
--- lld/trunk/tools/lld-core/lld-core.cpp (original)
+++ lld/trunk/tools/lld-core/lld-core.cpp Tue Jan 10 19:06:19 2012
@@ -9,6 +9,8 @@
#include "lld/Core/InputFiles.h"
#include "lld/Core/Atom.h"
+#include "lld/Core/DefinedAtom.h"
+#include "lld/Core/UndefinedAtom.h"
#include "lld/Core/Resolver.h"
#include "lld/Core/YamlReader.h"
#include "lld/Core/YamlWriter.h"
@@ -58,17 +60,17 @@
virtual void atomAdded(const Atom &file) { }
// give platform a chance to change each atom's scope
- virtual void adjustScope(const Atom &atom) { }
+ virtual void adjustScope(const DefinedAtom &atom) { }
// if specified atom needs alternate names, return AliasAtom(s)
virtual bool getAliasAtoms(const Atom &atom,
- std::vector<const Atom *>&) {
+ std::vector<const DefinedAtom *>&) {
return false;
}
// give platform a chance to resolve platform-specific undefs
virtual bool getPlatformAtoms(llvm::StringRef undefined,
- std::vector<const Atom *>&) {
+ std::vector<const DefinedAtom *>&) {
return false;
}
@@ -83,7 +85,7 @@
}
// if target must have some atoms, denote here
- virtual bool getImplicitDeadStripRoots(std::vector<const Atom *>&) {
+ virtual bool getImplicitDeadStripRoots(std::vector<const DefinedAtom *>&) {
return false;
}
@@ -164,7 +166,18 @@
handler.doFile(*this);
for (std::vector<const Atom *>::iterator it = _atoms.begin();
it != _atoms.end(); ++it) {
- handler.doAtom(**it);
+ const Atom* atom = *it;
+ switch ( atom->definition() ) {
+ case Atom::definitionRegular:
+ handler.doDefinedAtom(*(DefinedAtom*)atom);
+ break;
+ case Atom::definitionUndefined:
+ handler.doUndefinedAtom(*(UndefinedAtom*)atom);
+ break;
+ default:
+ // TO DO
+ break;
+ }
}
return true;
}
More information about the llvm-commits
mailing list