<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Sorry.  Pilot error.  The commit message was supposed to be:</div><div><br></div><div>Implement References. lld::Reference is an abstract base class (like lld::Atom)<br>with virtual methods for all methods.  To iterate over an Atom's References use<br>the Atom's forEachReference() method.  Add a bunch of test cases.  Remove<br>Atom::internalName() method.  Atoms without a user supplied name will have<br>the Atom::name() method return an empty string. <br></div><div><br></div><div>-Nick</div><br><div><div>On Feb 14, 2012, at 4:51 PM, Chandler Carruth wrote:</div><blockquote type="cite"><p>I know this is early stage stuff, but others are interested, so commit log messages would be good. ;)</p>
<div class="gmail_quote">On Feb 14, 2012 2:45 PM, "Nick Kledzik" <<a href="mailto:kledzik@apple.com">kledzik@apple.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: kledzik<br>
Date: Tue Feb 14 18:38:09 2012<br>
New Revision: 150539<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=150539&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=150539&view=rev</a><br>
Log:<br>
<br>
<br>
Added:<br>
    lld/trunk/test/fixups-addend.objtxt<br>
    lld/trunk/test/fixups-dup-named.objtxt<br>
    lld/trunk/test/fixups-named.objtxt<br>
    lld/trunk/test/fixups-unnamed.objtxt<br>
Removed:<br>
    lld/trunk/test/internal-name-attributes.objtxt<br>
Modified:<br>
    lld/trunk/include/lld/Core/DefinedAtom.h<br>
    lld/trunk/include/lld/Core/Reference.h<br>
    lld/trunk/include/lld/Core/Resolver.h<br>
    lld/trunk/lib/Core/NativeFileFormat.h<br>
    lld/trunk/lib/Core/NativeReader.cpp<br>
    lld/trunk/lib/Core/NativeWriter.cpp<br>
    lld/trunk/lib/Core/Resolver.cpp<br>
    lld/trunk/lib/Core/SymbolTable.cpp<br>
    lld/trunk/lib/Core/YamlKeyValues.cpp<br>
    lld/trunk/lib/Core/YamlKeyValues.h<br>
    lld/trunk/lib/Core/YamlReader.cpp<br>
    lld/trunk/lib/Core/YamlWriter.cpp<br>
    lld/trunk/test/cstring-coalesce.objtxt<br>
    lld/trunk/tools/lld-core/lld-core.cpp<br>
<br>
Modified: lld/trunk/include/lld/Core/DefinedAtom.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/DefinedAtom.h?rev=150539&r1=150538&r2=150539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/DefinedAtom.h?rev=150539&r1=150538&r2=150539&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/include/lld/Core/DefinedAtom.h (original)<br>
+++ lld/trunk/include/lld/Core/DefinedAtom.h Tue Feb 14 18:38:09 2012<br>
@@ -34,7 +34,7 @@<br>
 /// Here are some example attribute sets for common atoms. If a particular<br>
 /// attribute is not listed, the default values are:  definition=regular,<br>
 /// sectionChoice=basedOnContent, scope=translationUnit, merge=no,<br>
-/// internalName=false, deadStrip=normal, interposable=no<br>
+/// deadStrip=normal, interposable=no<br>
 ///<br>
 ///  C function:  void foo() {} <br><br>
 ///    name=foo, type=code, perm=r_x, scope=global<br>
@@ -71,16 +71,16 @@<br>
 ///    mergeDupes=asAddressedWeak<br>
 ///<br>
 ///  literal c-string:  "hello" <br><br>
-///    name=L0, internalName=true, type=cstring, perm=r__, scope=linkageUnit<br>
+///    name="" type=cstring, perm=r__, scope=linkageUnit<br>
 ///<br>
 ///  literal double:  1.234 <br><br>
-///    name=L0, internalName=true, type=literal8, perm=r__, scope=linkageUnit<br>
+///    name="" type=literal8, perm=r__, scope=linkageUnit<br>
 ///<br>
 ///  constant:  { 1,2,3 } <br><br>
-///    name=L0, internalName=true, type=constant, perm=r__, scope=linkageUnit<br>
+///    name="" type=constant, perm=r__, scope=linkageUnit<br>
 ///<br>
 ///  Pointer to initializer function:  <br><br>
-///    name=_init, internalName=true, type=initializer, perm=rw_l,<br>
+///    name="" type=initializer, perm=rw_l,<br>
 ///    sectionChoice=customRequired<br>
 ///<br>
 ///  C function place in custom section:  __attribute__((section("__foo")))<br>
@@ -195,15 +195,18 @@<br>
     uint16_t modulus;<br>
   };<br>
<br>
+  /// for use iterating over this Atom's References<br>
+  class ReferenceHandler {<br>
+  public:<br>
+    virtual ~ReferenceHandler() {}<br>
+    virtual void doReference(const Reference &) = 0;<br>
+  };<br>
+<br>
   /// ordinal - returns a value for the order of this Atom within its file.<br>
   /// This is used by the linker to order the layout of Atoms so that<br>
   /// the resulting image is stable and reproducible.<br>
   virtual uint64_t ordinal() const = 0;<br>
-<br>
-  /// internalName - If the name is just a temporary label that should<br>
-  /// not show up in the final linked image.<br>
-  virtual bool internalName() const = 0;<br>
-<br>
+<br>
   /// size - the number of bytes of space this atom's content will occupy<br>
   /// in the final linked image.  For a function atom, it is the number<br>
   /// of bytes of code in the function.<br>
@@ -264,12 +267,9 @@<br>
   /// this Atom's content.<br>
   virtual llvm::ArrayRef<uint8_t> rawContent() const = 0;<br>
<br>
-  /// referencesBegin - used to start iterating this Atom's References<br>
-  virtual Reference::iterator referencesBegin() const = 0;<br>
-<br>
-  /// referencesEnd - used to end iterating this Atom's References<br>
-  virtual Reference::iterator referencesEnd() const = 0;<br>
-<br>
+  /// iterator over this Atom's References<br>
+  virtual void forEachReference(ReferenceHandler&) const = 0;<br>
+<br>
 protected:<br>
   /// DefinedAtom is an abstract base class.<br>
   /// Only subclasses can access constructor.<br>
<br>
Modified: lld/trunk/include/lld/Core/Reference.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Reference.h?rev=150539&r1=150538&r2=150539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Reference.h?rev=150539&r1=150538&r2=150539&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/include/lld/Core/Reference.h (original)<br>
+++ lld/trunk/include/lld/Core/Reference.h Tue Feb 14 18:38:09 2012<br>
@@ -12,22 +12,60 @@<br>
<br>
 #include <stdint.h><br>
<br>
-<br>
 namespace lld {<br>
<br>
-class Atom;<br>
-<br>
+///<br>
+/// The linker has a Graph Theory model of linking. An object file is seen<br>
+/// as a set of Atoms with References to other Atoms.  Each Atom is a node<br>
+/// and each Reference is an edge.<br>
+///<br>
+/// For example if a function contains a call site to "malloc" 40 bytes into<br>
+/// the Atom, then the function Atom will have a Reference of: offsetInAtom=40,<br>
+/// kind=callsite, target=malloc, addend=0.<br>
+///<br>
+/// Besides supporting traditional "relocations", References are also used<br>
+/// grouping atoms (group comdat), forcing layout (one atom must follow<br>
+/// another), marking data-in-code (jump tables or ARM constants), etc.<br>
+///<br>
 class Reference {<br>
 public:<br>
-  typedef Reference *iterator;<br>
-<br>
-  const Atom *target;<br>
-  uint64_t    addend;<br>
-  uint32_t    offsetInAtom;<br>
-  uint16_t    kind;<br>
-  uint16_t    flags;<br>
+  /// The meaning of positive kind values is architecture specific.<br>
+  /// Negative kind values are architecture independent.<br>
+  typedef int32_t Kind;<br>
+<br>
+  // A value to be added to the value of a target<br>
+  typedef int64_t Addend;<br>
+<br>
+  /// What sort of reference this is.<br>
+  virtual Kind kind() const = 0;<br>
+<br>
+  /// If the reference is a fixup in the Atom, then this returns the<br>
+  /// byte offset into the Atom's content to do the fix up.<br>
+  virtual uint64_t offsetInAtom() const = 0;<br>
+<br>
+  /// If the reference is an edge to another Atom, then this returns the<br>
+  /// other Atom.  Otherwise, it returns NULL.<br>
+  virtual const class Atom * target() const = 0;<br>
+<br>
+  /// During linking, the linker may merge graphs which coalesces some nodes<br>
+  /// (i.e. Atoms).  To switch the target of a reference, this method is called.<br>
+  virtual void setTarget(const class Atom *) = 0;<br>
+<br>
+  /// Some relocations require a symbol and a value (e.g. foo + 4).<br>
+  virtual Addend addend() const = 0;<br>
+<br>
+protected:<br>
+  /// Atom is an abstract base class.  Only subclasses can access constructor.<br>
+  Reference() {}<br>
+<br>
+  /// The memory for Reference objects is always managed by the owning File<br>
+  /// object.  Therefore, no one but the owning File object should call<br>
+  /// delete on an Reference.  In fact, some File objects may bulk allocate<br>
+  /// an array of References, so they cannot be individually deleted by anyone.<br>
+  virtual ~Reference() {}<br>
 };<br>
<br>
+<br>
 } // namespace lld<br>
<br>
 #endif // LLD_CORE_REFERENCES_H_<br>
<br>
Modified: lld/trunk/include/lld/Core/Resolver.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Resolver.h?rev=150539&r1=150538&r2=150539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Resolver.h?rev=150539&r1=150538&r2=150539&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/include/lld/Core/Resolver.h (original)<br>
+++ lld/trunk/include/lld/Core/Resolver.h Tue Feb 14 18:38:09 2012<br>
@@ -70,6 +70,22 @@<br>
   void markLive(const Atom &atom, WhyLiveBackChain *previous);<br>
   void addAtoms(const std::vector<const DefinedAtom *>&);<br>
<br>
+<br>
+  // helper to update targets for use with forEachReference()<br>
+  class MarkLiveReferences : public DefinedAtom::ReferenceHandler {<br>
+  public:<br>
+             MarkLiveReferences(Resolver& resolver, WhyLiveBackChain* chain)<br>
+                  : _resolver(resolver), _chain(chain) { }<br>
+<br>
+    virtual void doReference(const Reference& ref) {<br>
+    _resolver.markLive(*ref.target(), _chain);<br>
+    }<br>
+<br>
+  private:<br>
+    Resolver&          _resolver;<br>
+    WhyLiveBackChain*  _chain;<br>
+  };<br>
+<br>
   Platform &_platform;<br>
   const InputFiles &_inputFiles;<br>
   SymbolTable _symbolTable;<br>
<br>
Modified: lld/trunk/lib/Core/NativeFileFormat.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeFileFormat.h?rev=150539&r1=150538&r2=150539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeFileFormat.h?rev=150539&r1=150538&r2=150539&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/Core/NativeFileFormat.h (original)<br>
+++ lld/trunk/lib/Core/NativeFileFormat.h Tue Feb 14 18:38:09 2012<br>
@@ -80,6 +80,7 @@<br>
   uint32_t    architecture;<br>
   uint32_t    fileSize;<br>
   uint32_t    chunkCount;<br>
+  // NativeChunk chunks[]<br>
 };<br>
<br>
 //<br>
@@ -90,8 +91,11 @@<br>
   NCS_AttributesArrayV1 = 2,<br>
   NCS_UndefinedAtomsV1 = 3,<br>
   NCS_Strings = 4,<br>
-  NCS_Content = 5,<br>
-  NCS_ReferencesArray = 6,<br>
+  NCS_ReferencesArrayV1 = 5,<br>
+  NCS_ReferencesArrayV2 = 6,<br>
+  NCS_TargetsTable = 7,<br>
+  NCS_AddendsTable = 8,<br>
+  NCS_Content = 9,<br>
 };<br>
<br>
 //<br>
@@ -125,6 +129,8 @@<br>
 struct NativeDefinedAtomIvarsV1 {<br>
   uint32_t  nameOffset;<br>
   uint32_t  attributesOffset;<br>
+  uint32_t  referencesStartIndex;<br>
+  uint32_t  referencesCount;<br>
   uint32_t  contentOffset;<br>
   uint32_t  contentSize;<br>
 };<br>
@@ -137,7 +143,6 @@<br>
   uint32_t  sectionNameOffset;<br>
   uint16_t  align2;<br>
   uint16_t  alignModulus;<br>
-  uint8_t   internalName;<br>
   uint8_t   scope;<br>
   uint8_t   interposable;<br>
   uint8_t   merge;<br>
@@ -145,10 +150,7 @@<br>
   uint8_t   sectionChoice;<br>
   uint8_t   deadStrip;<br>
   uint8_t   permissions;<br>
-  uint8_t   thumb;<br>
   uint8_t   alias;<br>
-  uint8_t   pad1;<br>
-  uint8_t   pad2;<br>
 };<br>
<br>
<br>
@@ -164,6 +166,51 @@<br>
<br>
<br>
<br>
+//<br>
+// The NCS_ReferencesArrayV1 chunk contains an array of these structs<br>
+//<br>
+struct NativeReferenceIvarsV1 {<br>
+  uint16_t  offsetInAtom;<br>
+   int16_t  kind;<br>
+  uint16_t  targetIndex;<br>
+  uint16_t  addendIndex;<br>
+};<br>
+<br>
+<br>
+<br>
+//<br>
+// The NCS_ReferencesArrayV2 chunk contains an array of these structs<br>
+//<br>
+struct NativeReferenceIvarsV2 {<br>
+  uint64_t  offsetInAtom;<br>
+  int64_t   addend;<br>
+  int32_t   kind;<br>
+  uint32_t  targetIndex;<br>
+};<br>
+<br>
+<br>
+//<br>
+// The NCS_TargetsTable chunk contains an array of uint32_t entries.<br>
+// The C++ class Reference has a target() method that returns a<br>
+// pointer to another Atom.  We can't have pointers in object files,<br>
+// so instead  NativeReferenceIvarsV1 contains an index to the target.<br>
+// The index is into this NCS_TargetsTable of uint32_t entries.<br>
+// The values in this table are the index of the (target) atom in this file.<br>
+// For DefinedAtoms the value is from 0 to NCS_DefinedAtomsV1.elementCount.<br>
+// For UndefinedAtoms the value is from NCS_DefinedAtomsV1.elementCount to<br>
+// NCS_DefinedAtomsV1.elementCount+NCS_UndefinedAtomsV1.elementCount.<br>
+//<br>
+<br>
+<br>
+//<br>
+// The NCS_AddendsTable chunk contains an array of int64_t entries.<br>
+// If we allocated space for addends directly in NativeReferenceIvarsV1<br>
+// it would double the size of that struct.  But since addends are rare,<br>
+// we instead just keep a pool of addends and have NativeReferenceIvarsV1<br>
+// (if it needs an addend) just store the index (into the pool) of the<br>
+// addend it needs.<br>
+//<br>
+<br>
<br>
<br>
 } // namespace lld<br>
<br>
Modified: lld/trunk/lib/Core/NativeReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeReader.cpp?rev=150539&r1=150538&r2=150539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeReader.cpp?rev=150539&r1=150538&r2=150539&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/Core/NativeReader.cpp (original)<br>
+++ lld/trunk/lib/Core/NativeReader.cpp Tue Feb 14 18:38:09 2012<br>
@@ -44,10 +44,6 @@<br>
<br>
   virtual llvm::StringRef name() const;<br>
<br>
-  virtual bool internalName() const {<br>
-    return attributes().internalName;<br>
-  }<br>
-<br>
   virtual uint64_t size() const {<br>
     return _ivarData->contentSize;<br>
   }<br>
@@ -88,23 +84,17 @@<br>
   }<br>
<br>
   virtual bool isThumb() const {<br>
-     return (attributes().thumb != 0);<br>
+     return false; //(attributes().thumb != 0);<br>
   }<br>
<br>
   virtual bool isAlias() const {<br>
      return (attributes().alias != 0);<br>
   }<br>
<br>
-  llvm::ArrayRef<uint8_t> rawContent() const;<br>
+  virtual llvm::ArrayRef<uint8_t> rawContent() const;<br>
<br>
-  virtual Reference::iterator referencesBegin() const {<br>
-     return 0;<br>
-  }<br>
-<br>
-  virtual Reference::iterator referencesEnd() const {<br>
-    return 0;<br>
-  }<br>
-<br>
+  virtual void forEachReference(ReferenceHandler&) const;<br>
+<br>
 private:<br>
   const NativeAtomAttributesV1& attributes() const;<br>
<br>
@@ -139,6 +129,35 @@<br>
<br>
<br>
 //<br>
+// An object of this class is instantied for each NativeReferenceIvarsV1<br>
+// struct in the NCS_ReferencesArrayV1 chunk.<br>
+//<br>
+class NativeReferenceV1 : public Reference {<br>
+public:<br>
+       NativeReferenceV1(const NativeFile& f,<br>
+                             const NativeReferenceIvarsV1* ivarData)<br>
+        : _file(&f), _ivarData(ivarData) { }<br>
+<br>
+  virtual uint64_t offsetInAtom() const {<br>
+    return _ivarData->offsetInAtom;<br>
+  }<br>
+<br>
+  virtual Kind kind() const {<br>
+    return _ivarData->kind;<br>
+  }<br>
+<br>
+  virtual const Atom* target() const;<br>
+  virtual Addend addend() const;<br>
+  virtual void setTarget(const Atom* newAtom);<br>
+<br>
+private:<br>
+  const NativeFile*                 _file;<br>
+  const NativeReferenceIvarsV1*     _ivarData;<br>
+};<br>
+<br>
+<br>
+<br>
+//<br>
 // lld::File object for native llvm object file<br>
 //<br>
 class NativeFile : public File {<br>
@@ -187,6 +206,15 @@<br>
         case NCS_UndefinedAtomsV1:<br>
           ec = file->processUndefinedAtomsV1(base, chunk);<br>
           break;<br>
+        case NCS_ReferencesArrayV1:<br>
+          ec = file->processReferencesV1(base, chunk);<br>
+          break;<br>
+        case NCS_TargetsTable:<br>
+          ec = file->processTargetsTable(base, chunk);<br>
+          break;<br>
+        case NCS_AddendsTable:<br>
+          ec = file->processAddendsTable(base, chunk);<br>
+          break;<br>
         case NCS_Content:<br>
           ec = file->processContent(base, chunk);<br>
           break;<br>
@@ -219,6 +247,8 @@<br>
     // to just delete the memory.<br>
     delete _definedAtoms.arrayStart;<br>
     delete _undefinedAtoms.arrayStart;<br>
+    delete _references.arrayStart;<br>
+    delete _targetsTable;<br>
   }<br>
<br>
   // visits each atom in the file<br>
@@ -245,6 +275,7 @@<br>
 private:<br>
   friend class NativeDefinedAtomV1;<br>
   friend class NativeUndefinedAtomV1;<br>
+  friend class NativeReferenceV1;<br>
<br>
   // instantiate array of DefinedAtoms from v1 ivar data in file<br>
   llvm::error_code processDefinedAtomsV1(const uint8_t* base,<br>
@@ -272,6 +303,7 @@<br>
     this->_definedAtoms.arrayStart = atomsStart;<br>
     this->_definedAtoms.arrayEnd = atomsEnd;<br>
     this->_definedAtoms.elementSize = atomSize;<br>
+    this->_definedAtoms.elementCount = chunk->elementCount;<br>
     return make_error_code(native_reader_error::success);<br>
   }<br>
<br>
@@ -307,6 +339,77 @@<br>
     this->_undefinedAtoms.arrayStart = atomsStart;<br>
     this->_undefinedAtoms.arrayEnd = atomsEnd;<br>
     this->_undefinedAtoms.elementSize = atomSize;<br>
+    this->_undefinedAtoms.elementCount = chunk->elementCount;<br>
+    return make_error_code(native_reader_error::success);<br>
+  }<br>
+<br>
+<br>
+  // instantiate array of Referemces from v1 ivar data in file<br>
+  llvm::error_code processReferencesV1(const uint8_t* base,<br>
+                                                const NativeChunk* chunk) {<br>
+    if ( chunk->elementCount == 0 )<br>
+      return make_error_code(native_reader_error::success);<br>
+    const size_t refSize = sizeof(NativeReferenceV1);<br>
+    size_t refsArraySize = chunk->elementCount * refSize;<br>
+    uint8_t* refsStart = reinterpret_cast<uint8_t*><br>
+                                (operator new(refsArraySize, std::nothrow));<br>
+    if (refsStart == NULL )<br>
+      return make_error_code(native_reader_error::memory_error);<br>
+    const size_t ivarElementSize = chunk->fileSize<br>
+                                          / chunk->elementCount;<br>
+    if ( ivarElementSize != sizeof(NativeReferenceIvarsV1) )<br>
+      return make_error_code(native_reader_error::file_malformed);<br>
+    uint8_t* refsEnd = refsStart + refsArraySize;<br>
+    const NativeReferenceIvarsV1* ivarData =<br>
+                             reinterpret_cast<const NativeReferenceIvarsV1*><br>
+                                                  (base + chunk->fileOffset);<br>
+    for(uint8_t* s = refsStart; s != refsEnd; s += refSize) {<br>
+      NativeReferenceV1* atomAllocSpace =<br>
+                  reinterpret_cast<NativeReferenceV1*>(s);<br>
+      new (atomAllocSpace) NativeReferenceV1(*this, ivarData);<br>
+      ++ivarData;<br>
+    }<br>
+    this->_references.arrayStart = refsStart;<br>
+    this->_references.arrayEnd = refsEnd;<br>
+    this->_references.elementSize = refSize;<br>
+    this->_references.elementCount = chunk->elementCount;<br>
+    return make_error_code(native_reader_error::success);<br>
+  }<br>
+<br>
+  // set up pointers to target table<br>
+  llvm::error_code processTargetsTable(const uint8_t* base,<br>
+                                                const NativeChunk* chunk) {<br>
+    const uint32_t* targetIndexes = reinterpret_cast<const uint32_t*><br>
+                                                  (base + chunk->fileOffset);<br>
+    this->_targetsTableCount = chunk->elementCount;<br>
+    this->_targetsTable = new const Atom*[chunk->elementCount];<br>
+    for (uint32_t i=0; i < chunk->elementCount; ++i) {<br>
+      const uint32_t index = targetIndexes[i];<br>
+      if ( index < _definedAtoms.elementCount ) {<br>
+        const uint8_t* p = _definedAtoms.arrayStart<br>
+                                    + index * _definedAtoms.elementSize;<br>
+        this->_targetsTable[i] = reinterpret_cast<const DefinedAtom*>(p);<br>
+        continue;<br>
+      }<br>
+      const uint32_t undefIndex = index - _definedAtoms.elementCount;<br>
+      if ( undefIndex < _undefinedAtoms.elementCount ) {<br>
+        const uint8_t* p = _undefinedAtoms.arrayStart<br>
+                                    + undefIndex * _undefinedAtoms.elementSize;<br>
+        this->_targetsTable[i] = reinterpret_cast<const UndefinedAtom*>(p);<br>
+        continue;<br>
+      }<br>
+      return make_error_code(native_reader_error::file_malformed);<br>
+    }<br>
+    return make_error_code(native_reader_error::success);<br>
+  }<br>
+<br>
+<br>
+  // set up pointers to addend pool in file<br>
+  llvm::error_code processAddendsTable(const uint8_t* base,<br>
+                                                const NativeChunk* chunk) {<br>
+    this->_addends = reinterpret_cast<const Reference::Addend*><br>
+                                                  (base + chunk->fileOffset);<br>
+    this->_addendsMaxIndex = chunk->elementCount;<br>
     return make_error_code(native_reader_error::success);<br>
   }<br>
<br>
@@ -331,9 +434,16 @@<br>
     return llvm::StringRef(&_strings[offset]);<br>
   }<br>
<br>
-  const NativeAtomAttributesV1& attribute(uint32_t offset) const {<br>
-    assert(offset < _attributesMaxOffset);<br>
-    return *reinterpret_cast<const NativeAtomAttributesV1*>(_attributes + offset);<br>
+  Reference::Addend addend(uint32_t index) const {<br>
+    if ( index == 0 )<br>
+      return 0; // addend index zero is used to mean "no addend"<br>
+    assert(index <= _addendsMaxIndex);<br>
+    return _addends[index-1]; // one-based indexing<br>
+  }<br>
+<br>
+  const NativeAtomAttributesV1& attribute(uint32_t off) const {<br>
+    assert(off < _attributesMaxOffset);<br>
+    return *reinterpret_cast<const NativeAtomAttributesV1*>(_attributes + off);<br>
   }<br>
<br>
   const uint8_t* content(uint32_t offset, uint32_t size) const {<br>
@@ -342,44 +452,75 @@<br>
     return result;<br>
   }<br>
<br>
-<br>
+  void forEachReference(DefinedAtom::ReferenceHandler& handler,<br>
+                                        uint32_t start, uint32_t count) const {<br>
+    assert(start < _references.elementCount);<br>
+    assert(start+count <= _references.elementCount);<br>
+    const uint8_t* arrStart = _references.arrayStart<br>
+                                   + start * _references.elementSize;<br>
+    const uint8_t* arrEnd = arrStart + count * _references.elementSize;<br>
+    for(const uint8_t* p=arrStart; p != arrEnd; p += _references.elementSize) {<br>
+      const NativeReferenceV1* ref<br>
+                              = reinterpret_cast<const NativeReferenceV1*>(p);<br>
+      handler.doReference(*ref);<br>
+    }<br>
+  }<br>
+<br>
+  const Atom* target(uint32_t index) const {<br>
+    assert(index < _targetsTableCount);<br>
+    return _targetsTable[index];<br>
+  }<br>
+<br>
+  void setTarget(uint32_t index, const Atom* newAtom) const {<br>
+    assert(index > _targetsTableCount);<br>
+    _targetsTable[index] = newAtom;<br>
+  }<br>
+<br>
+<br>
   // private constructor, only called by make()<br>
   NativeFile(llvm::OwningPtr<llvm::MemoryBuffer>& mb, llvm::StringRef path) :<br>
     lld::File(path),<br>
     _buffer(mb.take()),  // NativeFile now takes ownership of buffer<br>
     _header(NULL),<br>
+    _targetsTable(NULL),<br>
+    _targetsTableCount(0),<br>
     _strings(NULL),<br>
     _stringsMaxOffset(0),<br>
+    _addends(NULL),<br>
+    _addendsMaxIndex(0),<br>
     _contentStart(NULL),<br>
     _contentEnd(NULL)<br>
   {<br>
     _header = reinterpret_cast<const NativeFileHeader*>(_buffer->getBufferStart());<br>
-    _definedAtoms.arrayStart = NULL;<br>
-    _undefinedAtoms.arrayStart = NULL;<br>
   }<br>
<br>
-  struct AtomArray {<br>
-                      AtomArray() : arrayStart(NULL), arrayEnd(NULL),<br>
-                                    elementSize(0) { }<br>
+  struct IvarArray {<br>
+                      IvarArray() : arrayStart(NULL), arrayEnd(NULL),<br>
+                                    elementSize(0), elementCount(0) { }<br>
     const uint8_t*     arrayStart;<br>
     const uint8_t*     arrayEnd;<br>
     uint32_t           elementSize;<br>
-  };<br>
+    uint32_t           elementCount;<br>
+ };<br>
<br>
   llvm::OwningPtr<llvm::MemoryBuffer>  _buffer;<br>
   const NativeFileHeader*         _header;<br>
-  AtomArray                       _definedAtoms;<br>
-  AtomArray                       _undefinedAtoms;<br>
+  IvarArray                       _definedAtoms;<br>
+  IvarArray                       _undefinedAtoms;<br>
   const uint8_t*                  _attributes;<br>
   uint32_t                        _attributesMaxOffset;<br>
+  IvarArray                       _references;<br>
+  const Atom**                    _targetsTable;<br>
+  uint32_t                        _targetsTableCount;<br>
   const char*                     _strings;<br>
   uint32_t                        _stringsMaxOffset;<br>
+  const Reference::Addend*        _addends;<br>
+  uint32_t                        _addendsMaxIndex;<br>
   const uint8_t*                  _contentStart;<br>
   const uint8_t*                  _contentEnd;<br>
 };<br>
<br>
-<br>
-<br>
+<br>
 inline const class File& NativeDefinedAtomV1::file() const {<br>
   return *_file;<br>
 }<br>
@@ -410,8 +551,12 @@<br>
   return _file->string(offset);<br>
 }<br>
<br>
-<br>
-<br>
+inline void NativeDefinedAtomV1::forEachReference(ReferenceHandler& hnd) const {<br>
+  if ( _ivarData->referencesCount == 0 )<br>
+    return;<br>
+  _file->forEachReference(hnd, _ivarData->referencesStartIndex,<br>
+                               _ivarData->referencesCount);<br>
+}<br>
<br>
 inline const class File& NativeUndefinedAtomV1::file() const {<br>
   return *_file;<br>
@@ -422,6 +567,17 @@<br>
 }<br>
<br>
<br>
+inline const Atom* NativeReferenceV1::target() const {<br>
+  return _file->target(_ivarData->targetIndex);<br>
+}<br>
+<br>
+inline Reference::Addend NativeReferenceV1::addend() const {<br>
+  return _file->addend(_ivarData->addendIndex);<br>
+}<br>
+<br>
+inline void NativeReferenceV1::setTarget(const Atom* newAtom) {<br>
+  return _file->setTarget(_ivarData->targetIndex, newAtom);<br>
+}<br>
<br>
<br>
 //<br>
<br>
Modified: lld/trunk/lib/Core/NativeWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeWriter.cpp?rev=150539&r1=150538&r2=150539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeWriter.cpp?rev=150539&r1=150538&r2=150539&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/Core/NativeWriter.cpp (original)<br>
+++ lld/trunk/lib/Core/NativeWriter.cpp Tue Feb 14 18:38:09 2012<br>
@@ -12,6 +12,7 @@<br>
<br>
 #include "llvm/ADT/StringRef.h"<br>
 #include "llvm/ADT/ArrayRef.h"<br>
+#include "llvm/ADT/DenseMap.h"<br>
<br>
 #include "lld/Core/File.h"<br>
 #include "lld/Core/NativeWriter.h"<br>
@@ -25,10 +26,13 @@<br>
 ///<br>
 /// Class for writing native object files.<br>
 ///<br>
-class NativeWriter : public File::AtomHandler {<br>
+class NativeWriter : public File::AtomHandler,<br>
+                     public DefinedAtom::ReferenceHandler {<br>
 public:<br>
   /// construct writer for an lld::File object<br>
   NativeWriter(const lld::File& file) : _file(file) {<br>
+    // reserve first byte for unnamed atoms<br>
+    _stringPool.push_back('\0');<br>
     // visit all atoms<br>
     _file.forEachAtom(*this);<br>
     // construct file header based on atom information accumulated<br>
@@ -37,36 +41,73 @@<br>
<br>
   // write the lld::File in native format to the specified stream<br>
   void write(llvm::raw_ostream& out) {<br>
+    assert( out.tell() == 0 );<br>
     out.write((char*)_headerBuffer, _headerBufferSize);<br>
-    if (!_definedAtomIvars.empty())<br>
+<br>
+    if (!_definedAtomIvars.empty()) {<br>
+      assert( out.tell() == findChunk(NCS_DefinedAtomsV1).fileOffset );<br>
       out.write((char*)&_definedAtomIvars[0],<br>
                 _definedAtomIvars.size()*sizeof(NativeDefinedAtomIvarsV1));<br>
-    if (!_attributes.empty())<br>
+    }<br>
+<br>
+    if (!_attributes.empty()) {<br>
+      assert( out.tell() == findChunk(NCS_AttributesArrayV1).fileOffset );<br>
       out.write((char*)&_attributes[0],<br>
                 _attributes.size()*sizeof(NativeAtomAttributesV1));<br>
-    if ( !_undefinedAtomIvars.empty() )<br>
+    }<br>
+<br>
+    if ( !_undefinedAtomIvars.empty() ) {<br>
+      assert( out.tell() == findChunk(NCS_UndefinedAtomsV1).fileOffset );<br>
       out.write((char*)&_undefinedAtomIvars[0],<br>
               _undefinedAtomIvars.size()*sizeof(NativeUndefinedAtomIvarsV1));<br>
-    if (!_stringPool.empty())<br>
+    }<br>
+<br>
+    if (!_stringPool.empty()) {<br>
+      assert( out.tell() == findChunk(NCS_Strings).fileOffset );<br>
       out.write(&_stringPool[0], _stringPool.size());<br>
-    if (!_contentPool.empty())<br>
+    }<br>
+<br>
+    if ( !_references.empty() ) {<br>
+      assert( out.tell() == findChunk(NCS_ReferencesArrayV1).fileOffset );<br>
+      out.write((char*)&_references[0],<br>
+              _references.size()*sizeof(NativeReferenceIvarsV1));<br>
+    }<br>
+<br>
+    if ( !_targetsTableIndex.empty() ) {<br>
+      assert( out.tell() == findChunk(NCS_TargetsTable).fileOffset );<br>
+      writeTargetTable(out);<br>
+    }<br>
+<br>
+    if ( !_addendsTableIndex.empty() ) {<br>
+      assert( out.tell() == findChunk(NCS_AddendsTable).fileOffset );<br>
+      writeAddendTable(out);<br>
+    }<br>
+<br>
+    if (!_contentPool.empty()) {<br>
+      assert( out.tell() == findChunk(NCS_Content).fileOffset );<br>
       out.write((char*)&_contentPool[0], _contentPool.size());<br>
+    }<br>
   }<br>
<br>
 private:<br>
<br>
   // visitor routine called by forEachAtom()<br>
-  virtual void doDefinedAtom(const class DefinedAtom& atom) {<br>
+  virtual void doDefinedAtom(const DefinedAtom& atom) {<br>
+    _definedAtomIndex[&atom] = _definedAtomIvars.size();<br>
     NativeDefinedAtomIvarsV1 ivar;<br>
+    unsigned refsCount;<br>
     ivar.nameOffset = getNameOffset(atom);<br>
     ivar.attributesOffset = getAttributeOffset(atom);<br>
+    ivar.referencesStartIndex = getReferencesIndex(atom, refsCount);<br>
+    ivar.referencesCount = refsCount;<br>
     ivar.contentOffset = getContentOffset(atom);<br>
     ivar.contentSize = atom.size();<br>
     _definedAtomIvars.push_back(ivar);<br>
   }<br>
<br>
   // visitor routine called by forEachAtom()<br>
-  virtual void doUndefinedAtom(const class UndefinedAtom& atom) {<br>
+  virtual void doUndefinedAtom(const UndefinedAtom& atom) {<br>
+    _undefinedAtomIndex[&atom] = _undefinedAtomIvars.size();<br>
     NativeUndefinedAtomIvarsV1 ivar;<br>
     ivar.nameOffset = getNameOffset(atom);<br>
     ivar.flags = (atom.weakImport() ? 1 : 0);<br>
@@ -74,13 +115,18 @@<br>
   }<br>
<br>
   // visitor routine called by forEachAtom()<br>
-  virtual void doFile(const class File &) {<br>
+  virtual void doFile(const File &) {<br>
   }<br>
<br>
   // fill out native file header and chunk directory<br>
   void makeHeader() {<br>
     const bool hasUndefines = !_undefinedAtomIvars.empty();<br>
-    const int chunkCount = hasUndefines ? 5 : 4;<br>
+    const bool hasTargetsTable = !_targetsTableIndex.empty();<br>
+    const bool hasAddendTable = !_addendsTableIndex.empty();<br>
+    int chunkCount = 5;<br>
+    if ( hasUndefines ) ++chunkCount;<br>
+    if ( hasTargetsTable ) ++chunkCount;<br>
+    if ( hasAddendTable ) ++chunkCount;<br>
     _headerBufferSize = sizeof(NativeFileHeader)<br>
                          + chunkCount*sizeof(NativeChunk);<br>
     _headerBuffer = reinterpret_cast<NativeFileHeader*><br>
@@ -124,6 +170,9 @@<br>
     }<br>
<br>
     // create chunk for symbol strings<br>
+    // pad end of string pool to 4-bytes<br>
+    while ( (_stringPool.size() % 4) != 0 )<br>
+      _stringPool.push_back('\0');<br>
     NativeChunk& chs = chunks[nextIndex++];<br>
     chs.signature = NCS_Strings;<br>
     chs.fileOffset = nextFileOffset;<br>
@@ -131,6 +180,34 @@<br>
     chs.elementCount = _stringPool.size();<br>
     nextFileOffset = chs.fileOffset + chs.fileSize;<br>
<br>
+    // create chunk for references<br>
+    NativeChunk& chr = chunks[nextIndex++];<br>
+    chr.signature = NCS_ReferencesArrayV1;<br>
+    chr.fileOffset = nextFileOffset;<br>
+    chr.fileSize = _references.size() * sizeof(NativeReferenceIvarsV1);<br>
+    chr.elementCount = _references.size();<br>
+    nextFileOffset = chr.fileOffset + chr.fileSize;<br>
+<br>
+    // create chunk for target table<br>
+    if ( hasTargetsTable ) {<br>
+      NativeChunk& cht = chunks[nextIndex++];<br>
+      cht.signature = NCS_TargetsTable;<br>
+      cht.fileOffset = nextFileOffset;<br>
+      cht.fileSize = _targetsTableIndex.size() * sizeof(uint32_t);<br>
+      cht.elementCount = _targetsTableIndex.size();<br>
+      nextFileOffset = cht.fileOffset + cht.fileSize;<br>
+    }<br>
+<br>
+    // create chunk for addend table<br>
+    if ( hasAddendTable ) {<br>
+      NativeChunk& chad = chunks[nextIndex++];<br>
+      chad.signature = NCS_AddendsTable;<br>
+      chad.fileOffset = nextFileOffset;<br>
+      chad.fileSize = _addendsTableIndex.size() * sizeof(Reference::Addend);<br>
+      chad.elementCount = _addendsTableIndex.size();<br>
+      nextFileOffset = chad.fileOffset + chad.fileSize;<br>
+    }<br>
+<br>
     // create chunk for content<br>
     NativeChunk& chc = chunks[nextIndex++];<br>
     chc.signature = NCS_Content;<br>
@@ -142,6 +219,18 @@<br>
     _headerBuffer->fileSize = nextFileOffset;<br>
   }<br>
<br>
+  // scan header to find particular chunk<br>
+  NativeChunk& findChunk(uint32_t signature) {<br>
+    const uint32_t chunkCount = _headerBuffer->chunkCount;<br>
+    NativeChunk* chunks =<br>
+      reinterpret_cast<NativeChunk*>(reinterpret_cast<char*>(_headerBuffer)<br>
+                                     + sizeof(NativeFileHeader));<br>
+    for (uint32_t i=0; i < chunkCount; ++i) {<br>
+      if ( chunks[i].signature == signature )<br>
+        return chunks[i];<br>
+    }<br>
+    assert(0 && "findChunk() signature not found");<br>
+  }<br>
<br>
   // append atom name to string pool and return offset<br>
   uint32_t getNameOffset(const Atom& atom) {<br>
@@ -150,6 +239,8 @@<br>
<br>
  // append atom name to string pool and return offset<br>
   uint32_t getNameOffset(llvm::StringRef name) {<br>
+    if ( name.empty() )<br>
+      return 0;<br>
     uint32_t result = _stringPool.size();<br>
     _stringPool.insert(_stringPool.end(), name.size()+1, 0);<br>
     strcpy(&_stringPool[result], name.data());<br>
@@ -206,7 +297,6 @@<br>
     attrs.sectionNameOffset = sectionNameOffset(atom);<br>
     attrs.align2            = atom.alignment().powerOf2;<br>
     attrs.alignModulus      = atom.alignment().modulus;<br>
-    attrs.internalName      = atom.internalName();<br>
     attrs.scope             = atom.scope();<br>
     attrs.interposable      = atom.interposable();<br>
     attrs.merge             = atom.merge();<br>
@@ -214,12 +304,99 @@<br>
     attrs.sectionChoice     = atom.sectionChoice();<br>
     attrs.deadStrip         = atom.deadStrip();<br>
     attrs.permissions       = atom.permissions();<br>
-    attrs.thumb             = atom.isThumb();<br>
+    //attrs.thumb             = atom.isThumb();<br>
     attrs.alias             = atom.isAlias();<br>
   }<br>
<br>
+  // add references for this atom in a contiguous block in NCS_ReferencesArrayV1<br>
+  uint32_t getReferencesIndex(const DefinedAtom& atom, unsigned& count) {<br>
+    count = 0;<br>
+    size_t startRefSize = _references.size();<br>
+    uint32_t result = startRefSize;<br>
+    atom.forEachReference(*this);<br>
+    count = _references.size() - startRefSize;<br>
+    if ( count == 0 )<br>
+      return 0;<br>
+    else<br>
+      return result;<br>
+  }<br>
+<br>
+  void doReference(const Reference& ref) {<br>
+    NativeReferenceIvarsV1 nref;<br>
+    nref.offsetInAtom = ref.offsetInAtom();<br>
+    nref.kind = ref.kind();<br>
+    nref.targetIndex = this->getTargetIndex(ref.target());<br>
+    nref.addendIndex = this->getAddendIndex(ref.addend());<br>
+    _references.push_back(nref);<br>
+  }<br>
+<br>
+  uint32_t getTargetIndex(const Atom* target) {<br>
+    TargetToIndex::const_iterator pos = _targetsTableIndex.find(target);<br>
+    if ( pos != _targetsTableIndex.end() ) {<br>
+      return pos->second;<br>
+    }<br>
+    uint32_t result = _targetsTableIndex.size();<br>
+    _targetsTableIndex[target] = result;<br>
+    return result;<br>
+  }<br>
+<br>
+  void writeTargetTable(llvm::raw_ostream& out) {<br>
+    // Build table of target indexes<br>
+    uint32_t maxTargetIndex = _targetsTableIndex.size();<br>
+    uint32_t targetIndexes[maxTargetIndex];<br>
+    for (TargetToIndex::iterator it = _targetsTableIndex.begin();<br>
+                                 it != _targetsTableIndex.end(); ++it) {<br>
+      const Atom* atom = it->first;<br>
+      uint32_t targetIndex = it->second;<br>
+      assert(targetIndex < maxTargetIndex);<br>
+      uint32_t atomIndex = 0;<br>
+      TargetToIndex::iterator pos = _definedAtomIndex.find(atom);<br>
+      if ( pos != _definedAtomIndex.end() ) {<br>
+        atomIndex = pos->second;<br>
+      }<br>
+      else {<br>
+        pos = _undefinedAtomIndex.find(atom);<br>
+        assert(pos != _undefinedAtomIndex.end());<br>
+        atomIndex = pos->second + _definedAtomIvars.size();<br>
+      }<br>
+      targetIndexes[targetIndex] = atomIndex;<br>
+    }<br>
+    // write table<br>
+    out.write((char*)&targetIndexes[0], maxTargetIndex*sizeof(uint32_t));<br>
+  }<br>
+<br>
+  uint32_t getAddendIndex(Reference::Addend addend) {<br>
+    if ( addend == 0 )<br>
+      return 0; // addend index zero is used to mean "no addend"<br>
+    AddendToIndex::const_iterator pos = _addendsTableIndex.find(addend);<br>
+    if ( pos != _addendsTableIndex.end() ) {<br>
+      return pos->second;<br>
+    }<br>
+    uint32_t result = _addendsTableIndex.size() + 1; // one-based index<br>
+    _addendsTableIndex[addend] = result;<br>
+    return result;<br>
+  }<br>
+<br>
+  void writeAddendTable(llvm::raw_ostream& out) {<br>
+    // Build table of addends<br>
+    uint32_t maxAddendIndex = _addendsTableIndex.size();<br>
+    Reference::Addend addends[maxAddendIndex];<br>
+    for (AddendToIndex::iterator it = _addendsTableIndex.begin();<br>
+                                 it != _addendsTableIndex.end(); ++it) {<br>
+      Reference::Addend addend = it->first;<br>
+      uint32_t index = it->second;<br>
+      assert(index <= maxAddendIndex);<br>
+      addends[index-1] = addend;<br>
+    }<br>
+    // write table<br>
+    out.write((char*)&addends[0], maxAddendIndex*sizeof(Reference::Addend));<br>
+  }<br>
+<br>
   typedef std::vector<std::pair<llvm::StringRef, uint32_t> > NameToOffsetVector;<br>
<br>
+  typedef llvm::DenseMap<const Atom*, uint32_t> TargetToIndex;<br>
+  typedef llvm::DenseMap<Reference::Addend, uint32_t> AddendToIndex;<br>
+<br>
   const lld::File&                        _file;<br>
   NativeFileHeader*                       _headerBuffer;<br>
   size_t                                  _headerBufferSize;<br>
@@ -228,6 +405,11 @@<br>
   std::vector<NativeDefinedAtomIvarsV1>   _definedAtomIvars;<br>
   std::vector<NativeAtomAttributesV1>     _attributes;<br>
   std::vector<NativeUndefinedAtomIvarsV1> _undefinedAtomIvars;<br>
+  std::vector<NativeReferenceIvarsV1>     _references;<br>
+  TargetToIndex                           _targetsTableIndex;<br>
+  TargetToIndex                           _definedAtomIndex;<br>
+  TargetToIndex                           _undefinedAtomIndex;<br>
+  AddendToIndex                           _addendsTableIndex;<br>
   NameToOffsetVector                      _sectionNames;<br>
 };<br>
<br>
<br>
Modified: lld/trunk/lib/Core/Resolver.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=150539&r1=150538&r2=150539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=150539&r1=150538&r2=150539&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/Core/Resolver.cpp (original)<br>
+++ lld/trunk/lib/Core/Resolver.cpp Tue Feb 14 18:38:09 2012<br>
@@ -199,20 +199,34 @@<br>
   }<br>
 }<br>
<br>
+// helper to update targets for use with forEachReference()<br>
+class ReferenceUpdater : public DefinedAtom::ReferenceHandler {<br>
+public:<br>
+                          ReferenceUpdater(SymbolTable& sym) : _symbolTable(sym) { }<br>
+<br>
+       virtual void doReference(const Reference& ref) {<br>
+    const Atom* newTarget = _symbolTable.replacement(ref.target());<br>
+    (const_cast<Reference*>(&ref))->setTarget(newTarget);<br>
+  }<br>
+<br>
+private:<br>
+       SymbolTable&  _symbolTable;<br>
+};<br>
+<br>
+<br>
 // switch all references to undefined or coalesced away atoms<br>
 // to the new defined atom<br>
 void Resolver::updateReferences() {<br>
+  ReferenceUpdater updater(_symbolTable);<br>
   for (std::vector<const Atom *>::iterator it = _atoms.begin();<br>
        it != _atoms.end(); ++it) {<br>
     if ( const DefinedAtom* defAtom = (*it)->definedAtom() ) {<br>
-      for (Reference::iterator rit = defAtom->referencesBegin(),<br>
-         end = defAtom->referencesEnd(); rit != end; ++rit) {<br>
-        rit->target = _symbolTable.replacement(rit->target);<br>
-      }<br>
+      defAtom->forEachReference(updater);<br>
     }<br>
   }<br>
 }<br>
<br>
+<br>
 // for dead code stripping, recursively mark atom "live"<br>
 void Resolver::markLive(const Atom &atom, WhyLiveBackChain *previous) {<br>
   // if -why_live cares about this symbol, then dump chain<br>
@@ -240,10 +254,8 @@<br>
   thisChain.previous = previous;<br>
   thisChain.referer = &atom;<br>
   if ( const DefinedAtom* defAtom = atom.definedAtom() ) {<br>
-    for (Reference::iterator rit = defAtom->referencesBegin(),<br>
-        end = defAtom->referencesEnd(); rit != end; ++rit) {<br>
-      this->markLive(*(rit->target), &thisChain);<br>
-    }<br>
+    MarkLiveReferences markRefs(*this, &thisChain);<br>
+    defAtom->forEachReference(markRefs);<br>
   }<br>
 }<br>
<br>
<br>
Modified: lld/trunk/lib/Core/SymbolTable.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/SymbolTable.cpp?rev=150539&r1=150538&r2=150539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/SymbolTable.cpp?rev=150539&r1=150538&r2=150539&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/Core/SymbolTable.cpp (original)<br>
+++ lld/trunk/lib/Core/SymbolTable.cpp Tue Feb 14 18:38:09 2012<br>
@@ -38,7 +38,7 @@<br>
<br>
 void SymbolTable::add(const DefinedAtom &atom) {<br>
   assert(atom.scope() != DefinedAtom::scopeTranslationUnit);<br>
-  if ( !atom.internalName() ) {<br>
+  if ( !<a href="http://atom.name/" target="_blank">atom.name</a>().empty() ) {<br>
     this->addByName(atom);<br>
   }<br>
   else {<br>
<br>
Modified: lld/trunk/lib/Core/YamlKeyValues.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.cpp?rev=150539&r1=150538&r2=150539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.cpp?rev=150539&r1=150538&r2=150539&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/Core/YamlKeyValues.cpp (original)<br>
+++ lld/trunk/lib/Core/YamlKeyValues.cpp Tue Feb 14 18:38:09 2012<br>
@@ -18,12 +18,12 @@<br>
<br>
<br>
 const char* const KeyValues::nameKeyword            = "name";<br>
+const char* const KeyValues::refNameKeyword         = "ref-name";<br>
 const char* const KeyValues::definitionKeyword      = "definition";<br>
 const char* const KeyValues::scopeKeyword           = "scope";<br>
 const char* const KeyValues::contentTypeKeyword     = "type";<br>
 const char* const KeyValues::deadStripKindKeyword   = "dead-strip";<br>
 const char* const KeyValues::sectionChoiceKeyword   = "section-choice";<br>
-const char* const KeyValues::internalNameKeyword    = "internal-name";<br>
 const char* const KeyValues::interposableKeyword    = "interposable";<br>
 const char* const KeyValues::mergeKeyword           = "merge";<br>
 const char* const KeyValues::isThumbKeyword         = "is-thumb";<br>
@@ -31,8 +31,14 @@<br>
 const char* const KeyValues::sectionNameKeyword     = "section-name";<br>
 const char* const KeyValues::contentKeyword         = "content";<br>
 const char* const KeyValues::sizeKeyword            = "size";<br>
+const char* const KeyValues::fixupsKeyword          = "fixups";<br>
 const char* const KeyValues::permissionsKeyword     = "permissions";<br>
 const char* const KeyValues::weakImportKeyword      = "weak-import";<br>
+const char* const KeyValues::fixupsKindKeyword      = "kind";<br>
+const char* const KeyValues::fixupsOffsetKeyword    = "offset";<br>
+const char* const KeyValues::fixupsTargetKeyword    = "target";<br>
+const char* const KeyValues::fixupsAddendKeyword    = "addend";<br>
+<br>
<br>
<br>
 const DefinedAtom::Definition         KeyValues::definitionDefault = Atom::definitionRegular;<br>
@@ -43,7 +49,6 @@<br>
 const DefinedAtom::Interposable       KeyValues::interposableDefault = DefinedAtom::interposeNo;<br>
 const DefinedAtom::Merge              KeyValues::mergeDefault = DefinedAtom::mergeNo;<br>
 const DefinedAtom::ContentPermissions KeyValues::permissionsDefault = DefinedAtom::permR__;<br>
-const bool                            KeyValues::internalNameDefault = false;<br>
 const bool                            KeyValues::isThumbDefault = false;<br>
 const bool                            KeyValues::isAliasDefault = false;<br>
 const bool                            KeyValues::weakImportDefault = false;<br>
@@ -352,22 +357,6 @@<br>
<br>
<br>
<br>
-bool KeyValues::internalName(const char* s)<br>
-{<br>
-  if ( strcmp(s, "true") == 0 )<br>
-    return true;<br>
-  else if ( strcmp(s, "false") == 0 )<br>
-    return false;<br>
-  llvm::report_fatal_error("bad internal-name value");<br>
-}<br>
-<br>
-const char* KeyValues::internalName(bool b) {<br>
-  return b ? "true" : "false";<br>
-}<br>
-<br>
-<br>
-<br>
-<br>
 bool KeyValues::isThumb(const char* s)<br>
 {<br>
   if ( strcmp(s, "true") == 0 )<br>
<br>
Modified: lld/trunk/lib/Core/YamlKeyValues.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.h?rev=150539&r1=150538&r2=150539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.h?rev=150539&r1=150538&r2=150539&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/Core/YamlKeyValues.h (original)<br>
+++ lld/trunk/lib/Core/YamlKeyValues.h Tue Feb 14 18:38:09 2012<br>
@@ -20,10 +20,12 @@<br>
 class KeyValues {<br>
 public:<br>
   static const char* const                nameKeyword;<br>
+  static const char* const                refNameKeyword;<br>
   static const char* const                sectionNameKeyword;<br>
   static const char* const                contentKeyword;<br>
   static const char* const                sizeKeyword;<br>
-<br>
+  static const char* const                fixupsKeyword;<br>
+<br>
   static const char* const                definitionKeyword;<br>
   static const Atom::Definition           definitionDefault;<br>
   static Atom::Definition                 definition(const char*);<br>
@@ -64,11 +66,6 @@<br>
   static DefinedAtom::ContentPermissions        permissions(const char*);<br>
   static const char*                            permissions(DefinedAtom::ContentPermissions);<br>
<br>
-  static const char* const                internalNameKeyword;<br>
-  static const bool                       internalNameDefault;<br>
-  static bool                             internalName(const char*);<br>
-  static const char*                      internalName(bool);<br>
-<br>
   static const char* const                isThumbKeyword;<br>
   static const bool                       isThumbDefault;<br>
   static bool                             isThumb(const char*);<br>
@@ -84,6 +81,12 @@<br>
   static bool                             weakImport(const char*);<br>
   static const char*                      weakImport(bool);<br>
<br>
+<br>
+  static const char* const                fixupsKindKeyword;<br>
+  static const char* const                fixupsOffsetKeyword;<br>
+  static const char* const                fixupsTargetKeyword;<br>
+  static const char* const                fixupsAddendKeyword;<br>
+<br>
 };<br>
<br>
 } // namespace yaml<br>
<br>
Modified: lld/trunk/lib/Core/YamlReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlReader.cpp?rev=150539&r1=150538&r2=150539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlReader.cpp?rev=150539&r1=150538&r2=150539&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/Core/YamlReader.cpp (original)<br>
+++ lld/trunk/lib/Core/YamlReader.cpp Tue Feb 14 18:38:09 2012<br>
@@ -7,6 +7,8 @@<br>
 //<br>
 //===----------------------------------------------------------------------===//<br>
<br>
+#include <string.h><br>
+<br>
 #include "YamlKeyValues.h"<br>
<br>
 #include "lld/Core/YamlReader.h"<br>
@@ -30,6 +32,8 @@<br>
 namespace lld {<br>
 namespace yaml {<br>
<br>
+namespace {<br>
+<br>
 class YAML {<br>
 public:<br>
   struct Entry {<br>
@@ -214,7 +218,7 @@<br>
         sequenceBytes->push_back(contentByte);<br>
         state = inValueSequenceEnd;<br>
       }<br>
-      else if (c == ' ') {<br>
+      else if ( (c == ' ') || (c == '\n') ) {<br>
         // eat white space<br>
       }<br>
       else if (c == ',') {<br>
@@ -245,6 +249,44 @@<br>
   }<br>
 }<br>
<br>
+<br>
+<br>
+class YAMLReference : public Reference {<br>
+public:<br>
+                YAMLReference() : _target(NULL), _targetName(NULL),<br>
+                                   _offsetInAtom(0), _addend(0), _kind(0) { }<br>
+<br>
+  virtual uint64_t offsetInAtom() const {<br>
+    return _offsetInAtom;<br>
+  }<br>
+<br>
+  virtual Kind kind() const {<br>
+    return _kind;<br>
+  }<br>
+<br>
+  virtual const Atom* target() const {<br>
+    return _target;<br>
+  }<br>
+<br>
+  virtual Addend addend() const {<br>
+    return _addend;<br>
+  }<br>
+<br>
+  virtual void setTarget(const Atom* newAtom) {<br>
+    _target = newAtom;<br>
+  }<br>
+<br>
+  const Atom*  _target;<br>
+  const char*  _targetName;<br>
+  uint64_t     _offsetInAtom;<br>
+  Addend       _addend;<br>
+  Kind         _kind;<br>
+};<br>
+<br>
+<br>
+<br>
+class YAMLDefinedAtom;<br>
+<br>
 class YAMLFile : public File {<br>
 public:<br>
   YAMLFile()<br>
@@ -255,29 +297,24 @@<br>
   virtual bool justInTimeforEachAtom(llvm::StringRef name,<br>
                                      File::AtomHandler &) const;<br>
<br>
-  std::vector<DefinedAtom*> _definedAtoms;<br>
-  std::vector<UndefinedAtom*> _undefinedAtoms;<br>
-  std::vector<Reference> _references;<br>
-  unsigned int _lastRefIndex;<br>
-};<br>
+  void bindTargetReferences();<br>
+  void addDefinedAtom(YAMLDefinedAtom* atom, const char* refName);<br>
+  void addUndefinedAtom(UndefinedAtom* atom);<br>
+  Atom* findAtom(const char* name);<br>
+<br>
+  struct NameAtomPair {<br>
+                 NameAtomPair(const char* n, Atom* a) : name(n), atom(a) {}<br>
+    const char*  name;<br>
+    Atom*        atom;<br>
+  };<br>
<br>
-bool YAMLFile::forEachAtom(File::AtomHandler &handler) const {<br>
-  handler.doFile(*this);<br>
-  for (std::vector<DefinedAtom *>::const_iterator it = _definedAtoms.begin();<br>
-       it != _definedAtoms.end(); ++it) {<br>
-    handler.doDefinedAtom(**it);<br>
-  }<br>
-  for (std::vector<UndefinedAtom *>::const_iterator it = _undefinedAtoms.begin();<br>
-       it != _undefinedAtoms.end(); ++it) {<br>
-    handler.doUndefinedAtom(**it);<br>
-  }<br>
-  return true;<br>
-}<br>
+  std::vector<YAMLDefinedAtom*>   _definedAtoms;<br>
+  std::vector<UndefinedAtom*>     _undefinedAtoms;<br>
+  std::vector<YAMLReference>      _references;<br>
+  std::vector<NameAtomPair>       _nameToAtomMapping;<br>
+  unsigned int                    _lastRefIndex;<br>
+};<br>
<br>
-bool YAMLFile::justInTimeforEachAtom(llvm::StringRef name,<br>
-                                     File::AtomHandler &handler) const {<br>
-  return false;<br>
-}<br>
<br>
<br>
 class YAMLDefinedAtom : public DefinedAtom {<br>
@@ -291,7 +328,6 @@<br>
           , DefinedAtom::Merge merge<br>
           , DefinedAtom::DeadStripKind deadStrip<br>
           , DefinedAtom::ContentPermissions perms<br>
-          , bool internalName<br>
           , bool isThumb<br>
           , bool isAlias<br>
           , DefinedAtom::Alignment alignment<br>
@@ -313,7 +349,6 @@<br>
     , _merge(merge)<br>
     , _deadStrip(deadStrip)<br>
     , _permissions(perms)<br>
-    , _internalName(internalName)<br>
     , _isThumb(isThumb)<br>
     , _isAlias(isAlias)<br>
     , _refStartIndex(file._lastRefIndex)<br>
@@ -326,13 +361,12 @@<br>
   }<br>
<br>
   virtual llvm::StringRef name() const {<br>
-    return _name;<br>
+    if ( _name == NULL )<br>
+      return llvm::StringRef();<br>
+    else<br>
+      return _name;<br>
   }<br>
<br>
-  virtual bool internalName() const {<br>
-    return _internalName;<br>
-  }<br>
-<br>
  virtual uint64_t size() const {<br>
     return (_content ? _content->size() : _size);<br>
   }<br>
@@ -393,16 +427,18 @@<br>
   }<br>
<br>
<br>
-  virtual Reference::iterator referencesBegin() const {<br>
-    if (_file._references.size() < _refStartIndex)<br>
-      return (Reference::iterator)&_file._references[_refStartIndex];<br>
-    return 0;<br>
+  virtual void forEachReference(ReferenceHandler& handler) const {<br>
+    for (uint32_t i=_refStartIndex; i < _refEndIndex; ++i) {<br>
+      handler.doReference(_file._references[i]);<br>
+    }<br>
   }<br>
-<br>
-  virtual Reference::iterator referencesEnd() const {<br>
-    if (_file._references.size() < _refEndIndex)<br>
-      return (Reference::iterator)&_file._references[_refEndIndex];<br>
-    return 0;<br>
+<br>
+  void bindTargetReferences() {<br>
+    for (unsigned int i=_refStartIndex; i < _refEndIndex; ++i) {<br>
+      const char* targetName = _file._references[i]._targetName;<br>
+      Atom* targetAtom = _file.findAtom(targetName);<br>
+      _file._references[i]._target = targetAtom;<br>
+    }<br>
   }<br>
<br>
 private:<br>
@@ -420,7 +456,6 @@<br>
   DefinedAtom::Merge          _merge;<br>
   DefinedAtom::DeadStripKind  _deadStrip;<br>
   DefinedAtom::ContentPermissions _permissions;<br>
-  bool                        _internalName;<br>
   bool                        _isThumb;<br>
   bool                        _isAlias;<br>
   unsigned int                _refStartIndex;<br>
@@ -453,22 +488,71 @@<br>
 };<br>
<br>
<br>
+bool YAMLFile::forEachAtom(File::AtomHandler &handler) const {<br>
+  handler.doFile(*this);<br>
+  for (std::vector<YAMLDefinedAtom *>::const_iterator it = _definedAtoms.begin();<br>
+       it != _definedAtoms.end(); ++it) {<br>
+    handler.doDefinedAtom(**it);<br>
+  }<br>
+  for (std::vector<UndefinedAtom *>::const_iterator it = _undefinedAtoms.begin();<br>
+       it != _undefinedAtoms.end(); ++it) {<br>
+    handler.doUndefinedAtom(**it);<br>
+  }<br>
+  return true;<br>
+}<br>
+<br>
+bool YAMLFile::justInTimeforEachAtom(llvm::StringRef name,<br>
+                                     File::AtomHandler &handler) const {<br>
+  return false;<br>
+}<br>
+<br>
+void YAMLFile::bindTargetReferences() {<br>
+    for (std::vector<YAMLDefinedAtom *>::const_iterator<br>
+         it = _definedAtoms.begin(); it != _definedAtoms.end(); ++it) {<br>
+      YAMLDefinedAtom* atom = *it;<br>
+      atom->bindTargetReferences();<br>
+    }<br>
+}<br>
+<br>
+Atom* YAMLFile::findAtom(const char* name) {<br>
+  for (std::vector<NameAtomPair>::const_iterator it = _nameToAtomMapping.begin();<br>
+                                    it != _nameToAtomMapping.end(); ++it) {<br>
+    if ( strcmp(name, it->name) == 0 )<br>
+      return it->atom;<br>
+  }<br>
+  llvm::report_fatal_error("reference to atom that does not exist");<br>
+}<br>
+<br>
+void YAMLFile::addDefinedAtom(YAMLDefinedAtom* atom, const char* refName) {<br>
+  _definedAtoms.push_back(atom);<br>
+  assert(refName != NULL);<br>
+  _nameToAtomMapping.push_back(NameAtomPair(refName, atom));<br>
+}<br>
+<br>
+void YAMLFile::addUndefinedAtom(UndefinedAtom* atom) {<br>
+  _undefinedAtoms.push_back(atom);<br>
+  _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));<br>
+}<br>
+<br>
<br>
 class YAMLAtomState {<br>
 public:<br>
   YAMLAtomState();<br>
<br>
   void setName(const char *n);<br>
+  void setRefName(const char *n);<br>
   void setAlign2(const char *n);<br>
<br>
   void setFixupKind(const char *n);<br>
   void setFixupOffset(const char *n);<br>
   void setFixupTarget(const char *n);<br>
+  void setFixupAddend(const char *n);<br>
   void addFixup(YAMLFile *f);<br>
<br>
   void makeAtom(YAMLFile&);<br>
<br>
   const char *                _name;<br>
+  const char *                _refName;<br>
   const char *                _sectionName;<br>
   unsigned long long          _size;<br>
   uint32_t                    _ordinal;<br>
@@ -482,16 +566,16 @@<br>
   DefinedAtom::Merge          _merge;<br>
   DefinedAtom::DeadStripKind  _deadStrip;<br>
   DefinedAtom::ContentPermissions _permissions;<br>
-  bool                        _internalName;<br>
   bool                        _isThumb;<br>
   bool                        _isAlias;<br>
   bool                        _weakImport;<br>
-  Reference                   _ref;<br>
+  YAMLReference               _ref;<br>
 };<br>
<br>
<br>
 YAMLAtomState::YAMLAtomState()<br>
   : _name(NULL)<br>
+  , _refName(NULL)<br>
   , _sectionName(NULL)<br>
   , _size(0)<br>
   , _ordinal(0)<br>
@@ -505,38 +589,31 @@<br>
   , _merge(KeyValues::mergeDefault)<br>
   , _deadStrip(KeyValues::deadStripKindDefault)<br>
   , _permissions(KeyValues::permissionsDefault)<br>
-  , _internalName(KeyValues::internalNameDefault)<br>
   , _isThumb(KeyValues::isThumbDefault)<br>
   , _isAlias(KeyValues::isAliasDefault)<br>
   , _weakImport(false)<br>
   {<br>
-  _ref.target       = NULL;<br>
-  _ref.addend       = 0;<br>
-  _ref.offsetInAtom = 0;<br>
-  _ref.kind         = 0;<br>
-  _ref.flags        = 0;<br>
-}<br>
+  }<br>
<br>
<br>
 void YAMLAtomState::makeAtom(YAMLFile& f) {<br>
   if ( _definition == Atom::definitionRegular ) {<br>
-    DefinedAtom *a = new YAMLDefinedAtom(_ordinal, f, _scope, _type,<br>
+    YAMLDefinedAtom *a = new YAMLDefinedAtom(_ordinal, f, _scope, _type,<br>
                           _sectionChoice, _interpose, _merge, _deadStrip,<br>
-                          _permissions,  _internalName, _isThumb, _isAlias,<br>
+                          _permissions, _isThumb, _isAlias,<br>
                           _alignment, _name, _sectionName, _size, _content);<br>
-<br>
-    f._definedAtoms.push_back(a);<br>
+    f.addDefinedAtom(a, _refName ? _refName : _name);<br>
     ++_ordinal;<br>
   }<br>
   else if ( _definition == Atom::definitionUndefined ) {<br>
     UndefinedAtom *a = new YAMLUndefinedAtom(f, _ordinal, _name, _weakImport);<br>
-<br>
-    f._undefinedAtoms.push_back(a);<br>
+    f.addUndefinedAtom(a);<br>
     ++_ordinal;<br>
   }<br>
<br>
   // reset state for next atom<br>
   _name             = NULL;<br>
+  _refName          = NULL;<br>
   _sectionName      = NULL;<br>
   _size             = 0;<br>
   _ordinal          = 0;<br>
@@ -554,17 +631,20 @@<br>
   _isThumb          = KeyValues::isThumbDefault;<br>
   _isAlias          = KeyValues::isAliasDefault;<br>
   _weakImport       = KeyValues::weakImportDefault;<br>
-  _ref.target       = NULL;<br>
-  _ref.addend       = 0;<br>
-  _ref.offsetInAtom = 0;<br>
-  _ref.kind         = 0;<br>
-  _ref.flags        = 0;<br>
+  _ref._target       = NULL;<br>
+  _ref._targetName   = NULL;<br>
+  _ref._addend       = 0;<br>
+  _ref._offsetInAtom = 0;<br>
+  _ref._kind         = 0;<br>
 }<br>
<br>
 void YAMLAtomState::setName(const char *n) {<br>
   _name = n;<br>
 }<br>
<br>
+void YAMLAtomState::setRefName(const char *n) {<br>
+  _refName = n;<br>
+}<br>
<br>
 void YAMLAtomState::setAlign2(const char *s) {<br>
   llvm::StringRef str(s);<br>
@@ -576,33 +656,54 @@<br>
<br>
 void YAMLAtomState::setFixupKind(const char *s) {<br>
   if (strcmp(s, "pcrel32") == 0)<br>
-    _ref.kind = 1;<br>
+    _ref._kind = 1;<br>
   else if (strcmp(s, "call32") == 0)<br>
-    _ref.kind = 2;<br>
-  else<br>
-    llvm::report_fatal_error("bad fixup kind value");<br>
+    _ref._kind = 2;<br>
+  else {<br>
+    int k;<br>
+    llvm::StringRef(s).getAsInteger(10, k);<br>
+    _ref._kind = k;<br>
+  }<br>
 }<br>
<br>
 void YAMLAtomState::setFixupOffset(const char *s) {<br>
   if ((s[0] == '0') && (s[1] == 'x'))<br>
-    llvm::StringRef(s).getAsInteger(16, _ref.offsetInAtom);<br>
+    llvm::StringRef(s).getAsInteger(16, _ref._offsetInAtom);<br>
   else<br>
-    llvm::StringRef(s).getAsInteger(10, _ref.offsetInAtom);<br>
+    llvm::StringRef(s).getAsInteger(10, _ref._offsetInAtom);<br>
 }<br>
<br>
 void YAMLAtomState::setFixupTarget(const char *s) {<br>
+  _ref._targetName = s;<br>
 }<br>
<br>
+void YAMLAtomState::setFixupAddend(const char *s) {<br>
+  if ((s[0] == '0') && (s[1] == 'x'))<br>
+    llvm::StringRef(s).getAsInteger(16, _ref._addend);<br>
+  else<br>
+    llvm::StringRef(s).getAsInteger(10, _ref._addend);<br>
+}<br>
+<br>
+<br>
 void YAMLAtomState::addFixup(YAMLFile *f) {<br>
   f->_references.push_back(_ref);<br>
   // clear for next ref<br>
-  _ref.target       = NULL;<br>
-  _ref.addend       = 0;<br>
-  _ref.offsetInAtom = 0;<br>
-  _ref.kind         = 0;<br>
-  _ref.flags        = 0;<br>
+  _ref._target       = NULL;<br>
+  _ref._targetName   = NULL;<br>
+  _ref._addend       = 0;<br>
+  _ref._offsetInAtom = 0;<br>
+  _ref._kind         = 0;<br>
 }<br>
<br>
+<br>
+} // anonymous namespace<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+/// parseObjectText - Parse the specified YAML formatted MemoryBuffer<br>
+/// into lld::File object(s) and append each to the specified vector<File*>.<br>
 llvm::error_code parseObjectText( llvm::MemoryBuffer *mb<br>
                                 , std::vector<File *> &result) {<br>
   std::vector<const YAML::Entry *> entries;<br>
@@ -628,6 +729,7 @@<br>
           atomState.makeAtom(*file);<br>
           haveAtom = false;<br>
         }<br>
+        file->bindTargetReferences();<br>
         result.push_back(file);<br>
       }<br>
       file = new YAMLFile();<br>
@@ -663,10 +765,10 @@<br>
           atomState.setName(entry->value);<br>
           haveAtom = true;<br>
         }<br>
-        else if (strcmp(entry->key, KeyValues::internalNameKeyword) == 0) {<br>
-          atomState._internalName = KeyValues::internalName(entry->value);<br>
+        else if (strcmp(entry->key, KeyValues::refNameKeyword) == 0) {<br>
+          atomState.setRefName(entry->value);<br>
           haveAtom = true;<br>
-        }<br>
+        }<br>
         else if (strcmp(entry->key, KeyValues::definitionKeyword) == 0) {<br>
           atomState._definition = KeyValues::definition(entry->value);<br>
           haveAtom = true;<br>
@@ -725,8 +827,9 @@<br>
           atomState.setAlign2(entry->value);<br>
           haveAtom = true;<br>
         }<br>
-        else if (strcmp(entry->key, "fixups") == 0) {<br>
+        else if (strcmp(entry->key, KeyValues::fixupsKeyword) == 0) {<br>
           inFixups = true;<br>
+<br>
         }<br>
         else {<br>
           return make_error_code(yaml_reader_error::unknown_keyword);<br>
@@ -739,16 +842,22 @@<br>
             haveFixup = false;<br>
           }<br>
         }<br>
-        if (strcmp(entry->key, "kind") == 0) {<br>
+        if (strcmp(entry->key, KeyValues::fixupsKindKeyword) == 0) {<br>
           atomState.setFixupKind(entry->value);<br>
           haveFixup = true;<br>
-        } else if (strcmp(entry->key, "offset") == 0) {<br>
+        }<br>
+        else if (strcmp(entry->key, KeyValues::fixupsOffsetKeyword) == 0) {<br>
           atomState.setFixupOffset(entry->value);<br>
           haveFixup = true;<br>
-        } else if (strcmp(entry->key, "target") == 0) {<br>
+        }<br>
+        else if (strcmp(entry->key, KeyValues::fixupsTargetKeyword) == 0) {<br>
           atomState.setFixupTarget(entry->value);<br>
           haveFixup = true;<br>
         }<br>
+        else if (strcmp(entry->key, KeyValues::fixupsAddendKeyword) == 0) {<br>
+          atomState.setFixupAddend(entry->value);<br>
+          haveFixup = true;<br>
+        }<br>
       }<br>
     }<br>
     lastDepth = entry->depth;<br>
@@ -757,10 +866,12 @@<br>
     atomState.makeAtom(*file);<br>
   }<br>
<br>
+  file->bindTargetReferences();<br>
   result.push_back(file);<br>
   return make_error_code(yaml_reader_error::success);<br>
 }<br>
<br>
+<br>
 //<br>
 // Fill in vector<File*> from path to input text file.<br>
 //<br>
<br>
Modified: lld/trunk/lib/Core/YamlWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlWriter.cpp?rev=150539&r1=150538&r2=150539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlWriter.cpp?rev=150539&r1=150538&r2=150539&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/Core/YamlWriter.cpp (original)<br>
+++ lld/trunk/lib/Core/YamlWriter.cpp Tue Feb 14 18:38:09 2012<br>
@@ -15,6 +15,8 @@<br>
 #include "lld/Core/Reference.h"<br>
<br>
 #include "llvm/ADT/OwningPtr.h"<br>
+#include "llvm/ADT/DenseMap.h"<br>
+#include "llvm/ADT/StringExtras.h"<br>
 #include "llvm/ADT/ArrayRef.h"<br>
 #include "llvm/ADT/StringExtras.h"<br>
 #include "llvm/Support/DataTypes.h"<br>
@@ -26,50 +28,154 @@<br>
 namespace lld {<br>
 namespace yaml {<br>
<br>
-class Handler : public File::AtomHandler {<br>
+namespace {<br>
+///<br>
+/// In most cases, atoms names are unambiguous, so references can just<br>
+/// use the atom name as the target (e.g. target: foo).  But in a few<br>
+/// cases that does not work, so ref-names are added.  These are labels<br>
+/// used only in yaml.  The labels do not exist in the Atom model.<br>
+///<br>
+/// One need for ref-names are when atoms have no user supplied name<br>
+/// (e.g. c-string literal).  Another case is when two object files with<br>
+/// identically named static functions are merged (ld -r) into one object file.<br>
+/// In that case referencing the function by name is ambiguous, so a unique<br>
+/// ref-name is added.<br>
+///<br>
+class RefNameBuilder : public File::AtomHandler,<br>
+                       public DefinedAtom::ReferenceHandler {<br>
 public:<br>
-  Handler(llvm::raw_ostream &out) : _out(out), _firstAtom(true) { }<br>
+  RefNameBuilder() { }<br>
+<br>
+  virtual void doReference(const Reference& ref) {<br>
+    // create refname for any unnamed reference target<br>
+    if ( ref.target()->name().empty() ) {<br>
+      char* buffer;<br>
+      asprintf(&buffer, "L%03d", _unnamedCounter++);<br>
+      _refNames[ref.target()] = buffer;<br>
+    }<br>
+  }<br>
+<br>
+  virtual void doFile(const File &) { }<br>
+<br>
+  virtual void doDefinedAtom(const DefinedAtom& atom) {<br>
+    // Build map of atoms names to detect duplicates<br>
+    if ( ! <a href="http://atom.name/" target="_blank">atom.name</a>().empty() )<br>
+      buildDuplicateNameMap(atom);<br>
+<br>
+    // Find references to unnamed atoms and create ref-names for them.<br>
+    _unnamedCounter = 0;<br>
+    atom.forEachReference(*this);<br>
+  }<br>
+<br>
+  virtual void doUndefinedAtom(const UndefinedAtom& atom) {<br>
+    buildDuplicateNameMap(atom);<br>
+  }<br>
+<br>
+  void buildDuplicateNameMap(const Atom& atom) {<br>
+    assert(!<a href="http://atom.name/" target="_blank">atom.name</a>().empty());<br>
+    NameToAtom::iterator pos = _nameMap.find(<a href="http://atom.name/" target="_blank">atom.name</a>());<br>
+    if ( pos != _nameMap.end() ) {<br>
+      // Found name collision, give each a unique ref-name.<br>
+      char* buffer;<br>
+      asprintf(&buffer, "%s.%03d", <a href="http://atom.name/" target="_blank">atom.name</a>().data(), ++_collisionCount);<br>
+      _refNames[&atom] = buffer;<br>
+      const Atom* prevAtom = pos->second;<br>
+      AtomToRefName::iterator pos2 = _refNames.find(prevAtom);<br>
+      if ( pos2 == _refNames.end() ) {<br>
+        // only create ref-name for previous if none already created<br>
+        asprintf(&buffer, "%s.%03d", prevAtom->name().data(), ++_collisionCount);<br>
+        _refNames[prevAtom] = buffer;<br>
+      }<br>
+    }<br>
+    else {<br>
+      // First time we've seen this name, just add it to map.<br>
+      _nameMap[<a href="http://atom.name/" target="_blank">atom.name</a>()] = &atom;<br>
+    }<br>
+  }<br>
+<br>
+  bool hasRefName(const Atom* atom) {<br>
+     return _refNames.count(atom);<br>
+  }<br>
+<br>
+  const char* refName(const Atom* atom) {<br>
+     return _refNames.find(atom)->second;<br>
+  }<br>
+<br>
+private:<br>
+  struct MyMappingInfo {<br>
+    static llvm::StringRef getEmptyKey() { return llvm::StringRef(); }<br>
+    static llvm::StringRef getTombstoneKey() { return llvm::StringRef(" ", 0); }<br>
+    static unsigned getHashValue(llvm::StringRef const val) {<br>
+                                               return llvm::HashString(val); }<br>
+    static bool isEqual(llvm::StringRef const lhs,<br>
+                        llvm::StringRef const rhs) { return lhs.equals(rhs); }<br>
+  };<br>
+  typedef llvm::DenseMap<llvm::StringRef, const Atom*, MyMappingInfo> NameToAtom;<br>
+  typedef llvm::DenseMap<const Atom*, const char*> AtomToRefName;<br>
+<br>
+  unsigned int      _collisionCount;<br>
+  unsigned int      _unnamedCounter;<br>
+  NameToAtom        _nameMap;<br>
+  AtomToRefName     _refNames;<br>
+};<br>
+<br>
+<br>
+///<br>
+/// Helper class for writeObjectText() to write out atoms in yaml format.<br>
+///<br>
+class AtomWriter : public File::AtomHandler,<br>
+                   public DefinedAtom::ReferenceHandler {<br>
+public:<br>
+  AtomWriter(RefNameBuilder& rnb, llvm::raw_ostream &out)<br>
+    : _out(out), _rnb(rnb), _firstAtom(true) { }<br>
<br>
   virtual void doFile(const class File &) { _firstAtom = true; }<br>
<br>
   virtual void doDefinedAtom(const class DefinedAtom &atom) {<br>
-      // add blank line between atoms for readability<br>
-      if ( !_firstAtom )<br>
-        _out << "\n";<br>
-      _firstAtom = false;<br>
-<br>
+    // add blank line between atoms for readability<br>
+    if ( !_firstAtom )<br>
+      _out << "\n";<br>
+    _firstAtom = false;<br>
+<br>
+    bool hasDash = false;<br>
+    if ( !<a href="http://atom.name/" target="_blank">atom.name</a>().empty() ) {<br>
       _out  << "    - "<br>
             << KeyValues::nameKeyword<br>
             << ":"<br>
             << spacePadding(KeyValues::nameKeyword)<br>
             << <a href="http://atom.name/" target="_blank">atom.name</a>()<br>
             << "\n";<br>
-<br>
-    if ( atom.internalName() != KeyValues::internalNameDefault ) {<br>
-      _out  << "      "<br>
-            << KeyValues::internalNameKeyword<br>
+      hasDash = true;<br>
+    }<br>
+<br>
+    if ( _rnb.hasRefName(&atom) ) {<br>
+      _out  << (hasDash ? "      " : "    - ")<br>
+            << KeyValues::refNameKeyword<br>
             << ":"<br>
-            << spacePadding(KeyValues::internalNameKeyword)<br>
-            << KeyValues::internalName(atom.internalName())<br>
+            << spacePadding(KeyValues::refNameKeyword)<br>
+            << _rnb.refName(&atom)<br>
             << "\n";<br>
+      hasDash = true;<br>
     }<br>
<br>
     if ( atom.definition() != KeyValues::definitionDefault ) {<br>
-      _out  << "      "<br>
+      _out  << (hasDash ? "      " : "    - ")<br>
             << KeyValues::definitionKeyword<br>
             << ":"<br>
             << spacePadding(KeyValues::definitionKeyword)<br>
             << KeyValues::definition(atom.definition())<br>
             << "\n";<br>
+      hasDash = true;<br>
     }<br>
<br>
     if ( atom.scope() != KeyValues::scopeDefault ) {<br>
-      _out  << "      "<br>
+      _out  << (hasDash ? "      " : "    - ")<br>
             << KeyValues::scopeKeyword<br>
             << ":"<br>
             << spacePadding(KeyValues::scopeKeyword)<br>
             << KeyValues::scope(atom.scope())<br>
             << "\n";<br>
+      hasDash = true;<br>
     }<br>
<br>
      if ( atom.interposable() != KeyValues::interposableDefault ) {<br>
@@ -161,17 +267,51 @@<br>
       _out << " ]\n";<br>
     }<br>
<br>
-    if (atom.referencesBegin() != atom.referencesEnd()) {<br>
+    _wroteFirstFixup = false;<br>
+    atom.forEachReference(*this);<br>
+  }<br>
+<br>
+  virtual void doReference(const Reference& ref) {<br>
+    if ( !_wroteFirstFixup ) {<br>
       _out << "      fixups:\n";<br>
-      for (Reference::iterator it = atom.referencesBegin(),<br>
-           end = atom.referencesEnd(); it != end; ++it) {<br>
-        _out << "      - kind:      " << it->kind << "\n";<br>
-        _out << "        offset:    " << it->offsetInAtom << "\n";<br>
-      }<br>
+      _wroteFirstFixup = true;<br>
+    }<br>
+    _out  << "      - "<br>
+          << KeyValues::fixupsOffsetKeyword<br>
+          << ":"<br>
+          << spacePadding(KeyValues::fixupsOffsetKeyword)<br>
+          << ref.offsetInAtom()<br>
+          << "\n";<br>
+    _out  << "        "<br>
+          << KeyValues::fixupsKindKeyword<br>
+          << ":"<br>
+          << spacePadding(KeyValues::fixupsKindKeyword)<br>
+          << ref.kind()<br>
+          << "\n";<br>
+    const Atom* target = ref.target();<br>
+    if ( target != NULL ) {<br>
+      llvm::StringRef refName = target->name();<br>
+      if ( _rnb.hasRefName(target) )<br>
+        refName = _rnb.refName(target);<br>
+      assert(!refName.empty());<br>
+      _out  << "        "<br>
+            << KeyValues::fixupsTargetKeyword<br>
+            << ":"<br>
+            << spacePadding(KeyValues::fixupsTargetKeyword)<br>
+            << refName<br>
+            << "\n";<br>
+    }<br>
+    if ( ref.addend() != 0 ) {<br>
+      _out  << "        "<br>
+            << KeyValues::fixupsAddendKeyword<br>
+            << ":"<br>
+            << spacePadding(KeyValues::fixupsAddendKeyword)<br>
+            << ref.addend()<br>
+            << "\n";<br>
     }<br>
-<br>
   }<br>
<br>
+<br>
   virtual void doUndefinedAtom(const class UndefinedAtom &atom) {<br>
       // add blank line between atoms for readability<br>
       if ( !_firstAtom )<br>
@@ -219,11 +359,26 @@<br>
   }<br>
<br>
   llvm::raw_ostream&  _out;<br>
+  RefNameBuilder      _rnb;<br>
   bool                _firstAtom;<br>
+  bool                _wroteFirstFixup;<br>
 };<br>
<br>
+} // anonymous namespace<br>
+<br>
+<br>
+<br>
+///<br>
+/// writeObjectText - writes the lld::File object as in YAML<br>
+/// format to the specified stream.<br>
+///<br>
 void writeObjectText(const File &file, llvm::raw_ostream &out) {<br>
-  Handler h(out);<br>
+  // Figure what ref-name labels are needed<br>
+  RefNameBuilder rnb;<br>
+  file.forEachAtom(rnb);<br>
+<br>
+  // Write out all atoms<br>
+  AtomWriter h(rnb, out);<br>
   out << "---\n";<br>
   out << "atoms:\n";<br>
   file.forEachAtom(h);<br>
<br>
Modified: lld/trunk/test/cstring-coalesce.objtxt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/cstring-coalesce.objtxt?rev=150539&r1=150538&r2=150539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/cstring-coalesce.objtxt?rev=150539&r1=150538&r2=150539&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/test/cstring-coalesce.objtxt (original)<br>
+++ lld/trunk/test/cstring-coalesce.objtxt Tue Feb 14 18:38:09 2012<br>
@@ -6,28 +6,24 @@<br>
<br>
 ---<br>
 atoms:<br>
-    - name:              L0<br>
-      internal-name:     true<br>
+    - ref-name:          L0<br>
       scope:             hidden<br>
       type:              c-string<br>
       content:           [ 68, 65, 6c, 6c, 6f, 00 ]<br>
<br>
-    - name:              L1<br>
-      internal-name:     true<br>
+    - ref-name:          L1<br>
       scope:             hidden<br>
       type:              c-string<br>
       content:           [ 74, 68, 65, 72, 65, 00 ]<br>
 ---<br>
 atoms:<br>
-    - name:              L2<br>
-      internal-name:     true<br>
+    - ref-name:          L2<br>
       scope:             hidden<br>
       type:              c-string<br>
       content:           [ 68, 65, 6c, 6c, 6f, 00 ]<br>
 ---<br>
 atoms:<br>
-    - name:              L2<br>
-      internal-name:     true<br>
+    - ref-name:          L2<br>
       scope:             hidden<br>
       type:              c-string<br>
       content:           [ 74, 68, 65, 72, 65, 00 ]<br>
<br>
Added: lld/trunk/test/fixups-addend.objtxt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/fixups-addend.objtxt?rev=150539&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/fixups-addend.objtxt?rev=150539&view=auto</a><br>

==============================================================================<br>
--- lld/trunk/test/fixups-addend.objtxt (added)<br>
+++ lld/trunk/test/fixups-addend.objtxt Tue Feb 14 18:38:09 2012<br>
@@ -0,0 +1,50 @@<br>
+# RUN: lld-core %s | FileCheck %s<br>
+<br>
+#<br>
+# Test addends in fixups<br>
+#<br>
+<br>
+---<br>
+atoms:<br>
+    - name:              foo<br>
+      type:              code<br>
+      content:           [ 48, 8D, 3D, 00, 00, 00, 00,<br>
+                           48, 8D, 3D, 00, 00, 00, 00 ]<br>
+      fixups:<br>
+      - offset:          3<br>
+        kind:            3<br>
+        target:          bar<br>
+        addend:          100<br>
+      - offset:          10<br>
+        kind:            3<br>
+        target:          bar<br>
+        addend:          -50<br>
+<br>
+    - name:              func<br>
+      type:              code<br>
+      content:           [ 48, 8D, 3D, 00, 00, 00, 00,<br>
+                           48, 8D, 3D, 00, 00, 00, 00 ]<br>
+      fixups:<br>
+      - offset:          3<br>
+        kind:            3<br>
+        target:          bar<br>
+        addend:          8000000000<br>
+      - offset:          10<br>
+        kind:            3<br>
+        target:          bar<br>
+        addend:          -50<br>
+<br>
+    - name:              bar<br>
+      definition:        undefined<br>
+<br>
+<br>
+...<br>
+<br>
+# CHECK:      name: foo<br>
+# CHECK:      fixups:<br>
+# CHECK:      addend: 100<br>
+# CHECK:      addend: -50<br>
+# CHECK:      name: func<br>
+# CHECK:      fixups:<br>
+# CHECK:      addend: 8000000000<br>
+# CHECK:      addend: -50<br>
<br>
Added: lld/trunk/test/fixups-dup-named.objtxt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/fixups-dup-named.objtxt?rev=150539&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/fixups-dup-named.objtxt?rev=150539&view=auto</a><br>

==============================================================================<br>
--- lld/trunk/test/fixups-dup-named.objtxt (added)<br>
+++ lld/trunk/test/fixups-dup-named.objtxt Tue Feb 14 18:38:09 2012<br>
@@ -0,0 +1,31 @@<br>
+# RUN: lld-core %s | FileCheck %s<br>
+<br>
+#<br>
+# Test fixups referencing multiple atoms that have the same name<br>
+#<br>
+<br>
+---<br>
+atoms:<br>
+    - name:              foo<br>
+      type:              code<br>
+      content:           [ E8, 00, 00, 00, 00, E8, 00, 00, 00, 00 ]<br>
+      fixups:<br>
+      - offset:          1<br>
+        kind:            3<br>
+        target:          bar_1<br>
+      - offset:          6<br>
+        kind:            3<br>
+        target:          bar_2<br>
+<br>
+    - name:              bar<br>
+      ref-name:          bar_1<br>
+      scope:             static<br>
+<br>
+    - name:              bar<br>
+      ref-name:          bar_2<br>
+      scope:             static<br>
+<br>
+<br>
+...<br>
+<br>
+# CHECK:       ...<br>
<br>
Added: lld/trunk/test/fixups-named.objtxt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/fixups-named.objtxt?rev=150539&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/fixups-named.objtxt?rev=150539&view=auto</a><br>

==============================================================================<br>
--- lld/trunk/test/fixups-named.objtxt (added)<br>
+++ lld/trunk/test/fixups-named.objtxt Tue Feb 14 18:38:09 2012<br>
@@ -0,0 +1,35 @@<br>
+# RUN: lld-core %s | FileCheck %s<br>
+<br>
+#<br>
+# Test fixups to simple named atoms<br>
+#<br>
+<br>
+---<br>
+atoms:<br>
+    - name:              foo<br>
+      type:              code<br>
+      content:           [ E8, 00, 00, 00, 00, E8, 00, 00, 00, 00 ]<br>
+      fixups:<br>
+      - offset:          1<br>
+        kind:            3<br>
+        target:          bar<br>
+      - offset:          6<br>
+        kind:            3<br>
+        target:          baz<br>
+<br>
+    - name:              baz<br>
+      scope:             static<br>
+      type:              code<br>
+<br>
+    - name:              bar<br>
+      definition:        undefined<br>
+<br>
+<br>
+...<br>
+<br>
+# CHECK:      name: foo<br>
+# CHECK:      fixups:<br>
+# CHECK:      target: bar<br>
+# CHECK:      target: baz<br>
+# CHECK:      ...<br>
+<br>
<br>
Added: lld/trunk/test/fixups-unnamed.objtxt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/fixups-unnamed.objtxt?rev=150539&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/fixups-unnamed.objtxt?rev=150539&view=auto</a><br>

==============================================================================<br>
--- lld/trunk/test/fixups-unnamed.objtxt (added)<br>
+++ lld/trunk/test/fixups-unnamed.objtxt Tue Feb 14 18:38:09 2012<br>
@@ -0,0 +1,40 @@<br>
+# RUN: lld-core %s | FileCheck %s<br>
+<br>
+#<br>
+# Test fixups to unnamed atoms<br>
+#<br>
+<br>
+---<br>
+atoms:<br>
+    - name:              foo<br>
+      type:              code<br>
+      content:           [ 48, 8D, 3D, 00, 00, 00, 00,<br>
+                           48, 8D, 3D, 00, 00, 00, 00 ]<br>
+      fixups:<br>
+      - offset:          3<br>
+        kind:            3<br>
+        target:          LC1<br>
+      - offset:          10<br>
+        kind:            3<br>
+        target:          LC2<br>
+<br>
+<br>
+    - ref-name:          LC1<br>
+      scope:             hidden<br>
+      type:              c-string<br>
+      content:           [ 68, 65, 6c, 6c, 6f, 00 ]<br>
+<br>
+    - ref-name:          LC2<br>
+      scope:             hidden<br>
+      type:              c-string<br>
+      content:           [ 74, 68, 65, 72, 65, 00 ]<br>
+<br>
+<br>
+...<br>
+<br>
+# CHECK:      name: foo<br>
+# CHECK:      fixups:<br>
+# CHECK:      offset: 3<br>
+# CHECK:      offset: 10<br>
+# CHECK:      ref-name:<br>
+# CHECK:      ref-name:<br>
<br>
Removed: lld/trunk/test/internal-name-attributes.objtxt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/internal-name-attributes.objtxt?rev=150538&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/internal-name-attributes.objtxt?rev=150538&view=auto</a><br>

==============================================================================<br>
--- lld/trunk/test/internal-name-attributes.objtxt (original)<br>
+++ lld/trunk/test/internal-name-attributes.objtxt (removed)<br>
@@ -1,27 +0,0 @@<br>
-# RUN: lld-core %s | FileCheck %s<br>
-<br>
-#<br>
-# Test that internal-name attributes are preserved<br>
-#<br>
-<br>
----<br>
-atoms:<br>
-    - name:          foo<br>
-      internal-name: false<br>
-    - name:          L0<br>
-      internal-name: true<br>
-    - name:          L1<br>
-      internal-name: true<br>
-    - name:          bar<br>
-...<br>
-<br>
-<br>
-# CHECK:       name: foo<br>
-# CHECK-NOT:   internal-name: false<br>
-# CHECK:       name: L0<br>
-# CHECK:       internal-name: true<br>
-# CHECK:       name: L1<br>
-# CHECK:       internal-name: true<br>
-# CHECK:       name: bar<br>
-# CHECK-NOT:   internal-name: false<br>
-# CHECK:       ...<br>
<br>
Modified: lld/trunk/tools/lld-core/lld-core.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/tools/lld-core/lld-core.cpp?rev=150539&r1=150538&r2=150539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/tools/lld-core/lld-core.cpp?rev=150539&r1=150538&r2=150539&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/tools/lld-core/lld-core.cpp (original)<br>
+++ lld/trunk/tools/lld-core/lld-core.cpp Tue Feb 14 18:38:09 2012<br>
@@ -234,8 +234,9 @@<br>
<br>
   // read native file<br>
   llvm::OwningPtr<lld::File> natFile;<br>
-  parseNativeObjectFileOrSTDIN(tempPath, natFile);<br>
-<br>
+  if ( error(parseNativeObjectFileOrSTDIN(tempPath, natFile)) )<br>
+       return 1;<br>
+<br>
   // write new atom graph out as YAML doc<br>
   yaml::writeObjectText(*natFile, out);<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>
</blockquote></div><br></body></html>