Add an assert.
[oota-llvm.git] / lib / MC / MCAssembler.cpp
index f0e1d7fbc21c5ebc0a2a455c7a31d5dc1edb758f..9ca8928bcecf7c80e051659ca77bf658e536f78b 100644 (file)
 #include "llvm/MC/MCCodeEmitter.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSection.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/MCValue.h"
+#include "llvm/MC/MCDwarf.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringExtras.h"
@@ -52,10 +54,10 @@ MCAsmLayout::MCAsmLayout(MCAssembler &Asm)
  {
   // Compute the section layout order. Virtual sections must go last.
   for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
-    if (!Asm.getBackend().isVirtualSection(it->getSection()))
+    if (!it->getSection().isVirtualSection())
       SectionOrder.push_back(&*it);
   for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
-    if (Asm.getBackend().isVirtualSection(it->getSection()))
+    if (it->getSection().isVirtualSection())
       SectionOrder.push_back(&*it);
 }
 
@@ -155,7 +157,7 @@ uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const {
 
 uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const {
   // Virtual sections have no file size.
-  if (getAssembler().getBackend().isVirtualSection(SD->getSection()))
+  if (SD->getSection().isVirtualSection())
     return 0;
 
   // Otherwise, the file size is the same as the address space size.
@@ -221,98 +223,17 @@ MCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment,
 /* *** */
 
 MCAssembler::MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend,
-                         MCCodeEmitter &_Emitter, raw_ostream &_OS)
+                         MCCodeEmitter &_Emitter, bool _PadSectionToAlignment,
+                         raw_ostream &_OS)
   : Context(_Context), Backend(_Backend), Emitter(_Emitter),
-    OS(_OS), RelaxAll(false), SubsectionsViaSymbols(false)
+    OS(_OS), RelaxAll(false), SubsectionsViaSymbols(false),
+    PadSectionToAlignment(_PadSectionToAlignment)
 {
 }
 
 MCAssembler::~MCAssembler() {
 }
 
-static bool isScatteredFixupFullyResolvedSimple(const MCAssembler &Asm,
-                                                const MCFixup &Fixup,
-                                                const MCValue Target,
-                                                const MCSection *BaseSection) {
-  // The effective fixup address is
-  //     addr(atom(A)) + offset(A)
-  //   - addr(atom(B)) - offset(B)
-  //   - addr(<base symbol>) + <fixup offset from base symbol>
-  // and the offsets are not relocatable, so the fixup is fully resolved when
-  //  addr(atom(A)) - addr(atom(B)) - addr(<base symbol>)) == 0.
-  //
-  // The simple (Darwin, except on x86_64) way of dealing with this was to
-  // assume that any reference to a temporary symbol *must* be a temporary
-  // symbol in the same atom, unless the sections differ. Therefore, any PCrel
-  // relocation to a temporary symbol (in the same section) is fully
-  // resolved. This also works in conjunction with absolutized .set, which
-  // requires the compiler to use .set to absolutize the differences between
-  // symbols which the compiler knows to be assembly time constants, so we don't
-  // need to worry about considering symbol differences fully resolved.
-
-  // Non-relative fixups are only resolved if constant.
-  if (!BaseSection)
-    return Target.isAbsolute();
-
-  // Otherwise, relative fixups are only resolved if not a difference and the
-  // target is a temporary in the same section.
-  if (Target.isAbsolute() || Target.getSymB())
-    return false;
-
-  const MCSymbol *A = &Target.getSymA()->getSymbol();
-  if (!A->isTemporary() || !A->isInSection() ||
-      &A->getSection() != BaseSection)
-    return false;
-
-  return true;
-}
-
-static bool isScatteredFixupFullyResolved(const MCAssembler &Asm,
-                                          const MCAsmLayout &Layout,
-                                          const MCFixup &Fixup,
-                                          const MCValue Target,
-                                          const MCSymbolData *BaseSymbol) {
-  // The effective fixup address is
-  //     addr(atom(A)) + offset(A)
-  //   - addr(atom(B)) - offset(B)
-  //   - addr(BaseSymbol) + <fixup offset from base symbol>
-  // and the offsets are not relocatable, so the fixup is fully resolved when
-  //  addr(atom(A)) - addr(atom(B)) - addr(BaseSymbol) == 0.
-  //
-  // Note that "false" is almost always conservatively correct (it means we emit
-  // a relocation which is unnecessary), except when it would force us to emit a
-  // relocation which the target cannot encode.
-
-  const MCSymbolData *A_Base = 0, *B_Base = 0;
-  if (const MCSymbolRefExpr *A = Target.getSymA()) {
-    // Modified symbol references cannot be resolved.
-    if (A->getKind() != MCSymbolRefExpr::VK_None)
-      return false;
-
-    A_Base = Asm.getAtom(Layout, &Asm.getSymbolData(A->getSymbol()));
-    if (!A_Base)
-      return false;
-  }
-
-  if (const MCSymbolRefExpr *B = Target.getSymB()) {
-    // Modified symbol references cannot be resolved.
-    if (B->getKind() != MCSymbolRefExpr::VK_None)
-      return false;
-
-    B_Base = Asm.getAtom(Layout, &Asm.getSymbolData(B->getSymbol()));
-    if (!B_Base)
-      return false;
-  }
-
-  // If there is no base, A and B have to be the same atom for this fixup to be
-  // fully resolved.
-  if (!BaseSymbol)
-    return A_Base == B_Base;
-
-  // Otherwise, B must be missing and A must be the base.
-  return !B_Base && BaseSymbol == A_Base;
-}
-
 bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const {
   // Non-temporary labels should always be visible to the linker.
   if (!Symbol.isTemporary())
@@ -326,8 +247,7 @@ bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const {
   return getBackend().doesSectionRequireSymbols(Symbol.getSection());
 }
 
-const MCSymbolData *MCAssembler::getAtom(const MCAsmLayout &Layout,
-                                         const MCSymbolData *SD) const {
+const MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const {
   // Linker visible symbols define atoms.
   if (isSymbolLinkerVisible(SD->getSymbol()))
     return SD;
@@ -346,7 +266,8 @@ const MCSymbolData *MCAssembler::getAtom(const MCAsmLayout &Layout,
   return SD->getFragment()->getAtom();
 }
 
-bool MCAssembler::EvaluateFixup(const MCAsmLayout &Layout,
+bool MCAssembler::EvaluateFixup(const MCObjectWriter &Writer,
+                                const MCAsmLayout &Layout,
                                 const MCFixup &Fixup, const MCFragment *DF,
                                 MCValue &Target, uint64_t &Value) const {
   ++stats::EvaluateFixup;
@@ -364,43 +285,22 @@ bool MCAssembler::EvaluateFixup(const MCAsmLayout &Layout,
     Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel;
   bool IsResolved = true;
   if (const MCSymbolRefExpr *A = Target.getSymA()) {
-    if (A->getSymbol().isDefined())
-      Value += Layout.getSymbolAddress(&getSymbolData(A->getSymbol()));
+    const MCSymbol &Sym = A->getSymbol().AliasedSymbol();
+    if (Sym.isDefined())
+      Value += Layout.getSymbolAddress(&getSymbolData(Sym));
     else
       IsResolved = false;
   }
   if (const MCSymbolRefExpr *B = Target.getSymB()) {
-    if (B->getSymbol().isDefined())
-      Value -= Layout.getSymbolAddress(&getSymbolData(B->getSymbol()));
+    const MCSymbol &Sym = B->getSymbol().AliasedSymbol();
+    if (Sym.isDefined())
+      Value -= Layout.getSymbolAddress(&getSymbolData(Sym));
     else
       IsResolved = false;
   }
 
-  // If we are using scattered symbols, determine whether this value is actually
-  // resolved; scattering may cause atoms to move.
-  if (IsResolved && getBackend().hasScatteredSymbols()) {
-    if (getBackend().hasReliableSymbolDifference()) {
-      // If this is a PCrel relocation, find the base atom (identified by its
-      // symbol) that the fixup value is relative to.
-      const MCSymbolData *BaseSymbol = 0;
-      if (IsPCRel) {
-        BaseSymbol = DF->getAtom();
-        if (!BaseSymbol)
-          IsResolved = false;
-      }
-
-      if (IsResolved)
-        IsResolved = isScatteredFixupFullyResolved(*this, Layout, Fixup, Target,
-                                                   BaseSymbol);
-    } else {
-      const MCSection *BaseSection = 0;
-      if (IsPCRel)
-        BaseSection = &DF->getParent()->getSection();
-
-      IsResolved = isScatteredFixupFullyResolvedSimple(*this, Fixup, Target,
-                                                       BaseSection);
-    }
-  }
+  if (IsResolved)
+    IsResolved = Writer.IsFixupFullyResolved(*this, Target, IsPCRel, DF);
 
   if (IsPCRel)
     Value -= Layout.getFragmentAddress(DF) + Fixup.getOffset();
@@ -420,6 +320,9 @@ uint64_t MCAssembler::ComputeFragmentSize(MCAsmLayout &Layout,
   case MCFragment::FT_Inst:
     return cast<MCInstFragment>(F).getInstSize();
 
+  case MCFragment::FT_LEB:
+    return cast<MCLEBFragment>(F).getSize();
+
   case MCFragment::FT_Align: {
     const MCAlignFragment &AF = cast<MCAlignFragment>(F);
 
@@ -436,23 +339,11 @@ uint64_t MCAssembler::ComputeFragmentSize(MCAsmLayout &Layout,
     return Size;
   }
 
-  case MCFragment::FT_Org: {
-    const MCOrgFragment &OF = cast<MCOrgFragment>(F);
-
-    // FIXME: We should compute this sooner, we don't want to recurse here, and
-    // we would like to be more functional.
-    int64_t TargetLocation;
-    if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, &Layout))
-      report_fatal_error("expected assembly-time absolute expression");
-
-    // FIXME: We need a way to communicate this error.
-    int64_t Offset = TargetLocation - FragmentOffset;
-    if (Offset < 0)
-      report_fatal_error("invalid .org offset '" + Twine(TargetLocation) +
-                         "' (at offset '" + Twine(FragmentOffset) + "'");
+  case MCFragment::FT_Org:
+    return cast<MCOrgFragment>(F).getSize();
 
-    return Offset;
-  }
+  case MCFragment::FT_Dwarf:
+    return cast<MCDwarfLineAddrFragment>(F).getSize();
   }
 
   assert(0 && "invalid fragment kind");
@@ -602,6 +493,25 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
     llvm_unreachable("unexpected inst fragment after lowering");
     break;
 
+  case MCFragment::FT_LEB: {
+    MCLEBFragment &LF = cast<MCLEBFragment>(F);
+
+    // FIXME: It is probably better if we don't call EvaluateAsAbsolute in
+    // here.
+    int64_t Value;
+    bool IsAbs = LF.getValue().EvaluateAsAbsolute(Value, &Layout);
+    assert(IsAbs);
+    (void) IsAbs;
+    SmallString<32> Tmp;
+    raw_svector_ostream OSE(Tmp);
+    if (LF.isSigned())
+      MCObjectWriter::EncodeSLEB128(Value, OSE);
+    else
+      MCObjectWriter::EncodeULEB128(Value, OSE);
+    OW->WriteBytes(OSE.str());
+    break;
+  }
+
   case MCFragment::FT_Org: {
     MCOrgFragment &OF = cast<MCOrgFragment>(F);
 
@@ -610,6 +520,20 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
 
     break;
   }
+
+  case MCFragment::FT_Dwarf: {
+    const MCDwarfLineAddrFragment &OF = cast<MCDwarfLineAddrFragment>(F);
+
+    // The AddrDelta is really unsigned and it can only increase.
+    int64_t AddrDelta;
+    OF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, &Layout);
+
+    int64_t LineDelta;
+    LineDelta = OF.getLineDelta();
+
+    MCDwarfLineAddr::Write(OW, LineDelta, (uint64_t)AddrDelta);
+    break;
+  }
   }
 
   assert(OW->getStream().tell() - Start == FragmentSize);
@@ -619,7 +543,7 @@ void MCAssembler::WriteSectionData(const MCSectionData *SD,
                                    const MCAsmLayout &Layout,
                                    MCObjectWriter *OW) const {
   // Ignore virtual sections.
-  if (getBackend().isVirtualSection(SD->getSection())) {
+  if (SD->getSection().isVirtualSection()) {
     assert(Layout.getSectionFileSize(SD) == 0 && "Invalid size for section!");
 
     // Check that contents are only things legal inside a virtual section.
@@ -667,26 +591,17 @@ void MCAssembler::WriteSectionData(const MCSectionData *SD,
   assert(OW->getStream().tell() - Start == Layout.getSectionFileSize(SD));
 }
 
-void MCAssembler::AddSectionToTheEnd(MCSectionData &SD, MCAsmLayout &Layout) {
+void MCAssembler::AddSectionToTheEnd(const MCObjectWriter &Writer,
+                                     MCSectionData &SD, MCAsmLayout &Layout) {
   // Create dummy fragments and assign section ordinals.
-  unsigned SectionIndex = 0;
-  for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it)
-    SectionIndex++;
-
+  unsigned SectionIndex = size();
   SD.setOrdinal(SectionIndex);
 
   // Assign layout order indices to sections and fragments.
-  unsigned FragmentIndex = 0;
-  unsigned i = 0;
-  for (unsigned e = Layout.getSectionOrder().size(); i != e; ++i) {
-    MCSectionData *SD = Layout.getSectionOrder()[i];
-
-    for (MCSectionData::iterator it2 = SD->begin(),
-           ie2 = SD->end(); it2 != ie2; ++it2)
-      FragmentIndex++;
-  }
+  const MCFragment &Last = *Layout.getSectionOrder().back()->rbegin();
+  unsigned FragmentIndex = Last.getLayoutOrder() + 1;
 
-  SD.setLayoutOrder(i);
+  SD.setLayoutOrder(Layout.getSectionOrder().size());
   for (MCSectionData::iterator it2 = SD.begin(),
          ie2 = SD.end(); it2 != ie2; ++it2) {
     it2->setLayoutOrder(FragmentIndex++);
@@ -694,11 +609,6 @@ void MCAssembler::AddSectionToTheEnd(MCSectionData &SD, MCAsmLayout &Layout) {
   Layout.getSectionOrder().push_back(&SD);
 
   Layout.LayoutSection(&SD);
-
-  // Layout until everything fits.
-  while (LayoutOnce(Layout))
-    continue;
-
 }
 
 void MCAssembler::Finish(MCObjectWriter *Writer) {
@@ -712,25 +622,25 @@ void MCAssembler::Finish(MCObjectWriter *Writer) {
   // Insert additional align fragments for concrete sections to explicitly pad
   // the previous section to match their alignment requirements. This is for
   // 'gas' compatibility, it shouldn't strictly be necessary.
-  //
-  // FIXME: This may be Mach-O specific.
-  for (unsigned i = 1, e = Layout.getSectionOrder().size(); i < e; ++i) {
-    MCSectionData *SD = Layout.getSectionOrder()[i];
+  if (PadSectionToAlignment) {
+    for (unsigned i = 1, e = Layout.getSectionOrder().size(); i < e; ++i) {
+      MCSectionData *SD = Layout.getSectionOrder()[i];
 
-    // Ignore sections without alignment requirements.
-    unsigned Align = SD->getAlignment();
-    if (Align <= 1)
-      continue;
+      // Ignore sections without alignment requirements.
+      unsigned Align = SD->getAlignment();
+      if (Align <= 1)
+        continue;
 
-    // Ignore virtual sections, they don't cause file size modifications.
-    if (getBackend().isVirtualSection(SD->getSection()))
-      continue;
+      // Ignore virtual sections, they don't cause file size modifications.
+      if (SD->getSection().isVirtualSection())
+        continue;
 
-    // Otherwise, create a new align fragment at the end of the previous
-    // section.
-    MCAlignFragment *AF = new MCAlignFragment(Align, 0, 1, Align,
-                                              Layout.getSectionOrder()[i - 1]);
-    AF->setOnlyAlignAddress(true);
+      // Otherwise, create a new align fragment at the end of the previous
+      // section.
+      MCAlignFragment *AF = new MCAlignFragment(Align, 0, 1, Align,
+                                                Layout.getSectionOrder()[i - 1]);
+      AF->setOnlyAlignAddress(true);
+    }
   }
 
   // Create dummy fragments and assign section ordinals.
@@ -739,7 +649,7 @@ void MCAssembler::Finish(MCObjectWriter *Writer) {
     // Create dummy fragments to eliminate any empty sections, this simplifies
     // layout.
     if (it->getFragmentList().empty())
-      new MCFillFragment(0, 1, 0, it);
+      new MCDataFragment(it);
 
     it->setOrdinal(SectionIndex++);
   }
@@ -755,8 +665,17 @@ void MCAssembler::Finish(MCObjectWriter *Writer) {
       it2->setLayoutOrder(FragmentIndex++);
   }
 
+  llvm::OwningPtr<MCObjectWriter> OwnWriter(0);
+  if (Writer == 0) {
+    //no custom Writer_ : create the default one life-managed by OwningPtr
+    OwnWriter.reset(getBackend().createObjectWriter(OS));
+    Writer = OwnWriter.get();
+    if (!Writer)
+      report_fatal_error("unable to create object writer!");
+  }
+
   // Layout until everything fits.
-  while (LayoutOnce(Layout))
+  while (LayoutOnce(*Writer, Layout))
     continue;
 
   DEBUG_WITH_TYPE("mc-dump", {
@@ -772,15 +691,6 @@ void MCAssembler::Finish(MCObjectWriter *Writer) {
 
   uint64_t StartOffset = OS.tell();
 
-  llvm::OwningPtr<MCObjectWriter> OwnWriter(0);
-  if (Writer == 0) {
-    //no custom Writer_ : create the default one life-managed by OwningPtr
-    OwnWriter.reset(getBackend().createObjectWriter(OS));
-    Writer = OwnWriter.get();
-    if (!Writer)
-      report_fatal_error("unable to create object writer!");
-  }
-
   // Allow the object writer a chance to perform post-layout binding (for
   // example, to set the index fields in the symbol data).
   Writer->ExecutePostLayoutBinding(*this);
@@ -800,7 +710,7 @@ void MCAssembler::Finish(MCObjectWriter *Writer) {
         // Evaluate the fixup.
         MCValue Target;
         uint64_t FixedValue;
-        if (!EvaluateFixup(Layout, Fixup, DF, Target, FixedValue)) {
+        if (!EvaluateFixup(*Writer, Layout, Fixup, DF, Target, FixedValue)) {
           // The fixup was unresolved, we need a relocation. Inform the object
           // writer of the relocation, and give it an opportunity to adjust the
           // fixup value if need be.
@@ -818,7 +728,8 @@ void MCAssembler::Finish(MCObjectWriter *Writer) {
   stats::ObjectBytes += OS.tell() - StartOffset;
 }
 
-bool MCAssembler::FixupNeedsRelaxation(const MCFixup &Fixup,
+bool MCAssembler::FixupNeedsRelaxation(const MCObjectWriter &Writer,
+                                       const MCFixup &Fixup,
                                        const MCFragment *DF,
                                        const MCAsmLayout &Layout) const {
   if (getRelaxAll())
@@ -827,7 +738,7 @@ bool MCAssembler::FixupNeedsRelaxation(const MCFixup &Fixup,
   // If we cannot resolve the fixup value, it requires relaxation.
   MCValue Target;
   uint64_t Value;
-  if (!EvaluateFixup(Layout, Fixup, DF, Target, Value))
+  if (!EvaluateFixup(Writer, Layout, Fixup, DF, Target, Value))
     return true;
 
   // Otherwise, relax if the value is too big for a (signed) i8.
@@ -836,7 +747,8 @@ bool MCAssembler::FixupNeedsRelaxation(const MCFixup &Fixup,
   return int64_t(Value) != int64_t(int8_t(Value));
 }
 
-bool MCAssembler::FragmentNeedsRelaxation(const MCInstFragment *IF,
+bool MCAssembler::FragmentNeedsRelaxation(const MCObjectWriter &Writer,
+                                          const MCInstFragment *IF,
                                           const MCAsmLayout &Layout) const {
   // If this inst doesn't ever need relaxation, ignore it. This occurs when we
   // are intentionally pushing out inst fragments, or because we relaxed a
@@ -846,13 +758,101 @@ bool MCAssembler::FragmentNeedsRelaxation(const MCInstFragment *IF,
 
   for (MCInstFragment::const_fixup_iterator it = IF->fixup_begin(),
          ie = IF->fixup_end(); it != ie; ++it)
-    if (FixupNeedsRelaxation(*it, IF, Layout))
+    if (FixupNeedsRelaxation(Writer, *it, IF, Layout))
       return true;
 
   return false;
 }
 
-bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) {
+bool MCAssembler::RelaxInstruction(const MCObjectWriter &Writer,
+                                   MCAsmLayout &Layout,
+                                   MCInstFragment &IF) {
+  if (!FragmentNeedsRelaxation(Writer, &IF, Layout))
+    return false;
+
+  ++stats::RelaxedInstructions;
+
+  // FIXME-PERF: We could immediately lower out instructions if we can tell
+  // they are fully resolved, to avoid retesting on later passes.
+
+  // Relax the fragment.
+
+  MCInst Relaxed;
+  getBackend().RelaxInstruction(IF.getInst(), Relaxed);
+
+  // Encode the new instruction.
+  //
+  // FIXME-PERF: If it matters, we could let the target do this. It can
+  // probably do so more efficiently in many cases.
+  SmallVector<MCFixup, 4> Fixups;
+  SmallString<256> Code;
+  raw_svector_ostream VecOS(Code);
+  getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups);
+  VecOS.flush();
+
+  // Update the instruction fragment.
+  int SlideAmount = Code.size() - IF.getInstSize();
+  IF.setInst(Relaxed);
+  IF.getCode() = Code;
+  IF.getFixups().clear();
+  // FIXME: Eliminate copy.
+  for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
+    IF.getFixups().push_back(Fixups[i]);
+
+  // Update the layout, and remember that we relaxed.
+  Layout.UpdateForSlide(&IF, SlideAmount);
+  return true;
+}
+
+bool MCAssembler::RelaxOrg(const MCObjectWriter &Writer,
+                           MCAsmLayout &Layout,
+                           MCOrgFragment &OF) {
+  int64_t TargetLocation;
+  if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, &Layout))
+    report_fatal_error("expected assembly-time absolute expression");
+
+  // FIXME: We need a way to communicate this error.
+  uint64_t FragmentOffset = Layout.getFragmentOffset(&OF);
+  int64_t Offset = TargetLocation - FragmentOffset;
+  if (Offset < 0 || Offset >= 0x40000000)
+    report_fatal_error("invalid .org offset '" + Twine(TargetLocation) +
+                       "' (at offset '" + Twine(FragmentOffset) + "')");
+
+  unsigned OldSize = OF.getSize();
+  OF.setSize(Offset);
+  return OldSize != OF.getSize();
+}
+
+bool MCAssembler::RelaxLEB(const MCObjectWriter &Writer,
+                           MCAsmLayout &Layout,
+                           MCLEBFragment &LF) {
+  int64_t Value;
+  LF.getValue().EvaluateAsAbsolute(Value, &Layout);
+  SmallString<32> Tmp;
+  raw_svector_ostream OSE(Tmp);
+  if (LF.isSigned())
+    MCObjectWriter::EncodeSLEB128(Value, OSE);
+  else
+    MCObjectWriter::EncodeULEB128(Value, OSE);
+  uint64_t OldSize = LF.getSize();
+  LF.setSize(OSE.GetNumBytesInBuffer());
+  return OldSize != LF.getSize();
+}
+
+bool MCAssembler::RelaxDwarfLineAddr(const MCObjectWriter &Writer,
+                                    MCAsmLayout &Layout,
+                                    MCDwarfLineAddrFragment &DF) {
+  int64_t AddrDelta;
+  DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, &Layout);
+  int64_t LineDelta;
+  LineDelta = DF.getLineDelta();
+  uint64_t OldSize = DF.getSize();
+  DF.setSize(MCDwarfLineAddr::ComputeSize(LineDelta, AddrDelta));
+  return OldSize != DF.getSize();  
+}
+
+bool MCAssembler::LayoutOnce(const MCObjectWriter &Writer,
+                             MCAsmLayout &Layout) {
   ++stats::RelaxationSteps;
 
   // Layout the sections in order.
@@ -865,43 +865,25 @@ bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) {
 
     for (MCSectionData::iterator it2 = SD.begin(),
            ie2 = SD.end(); it2 != ie2; ++it2) {
-      // Check if this is an instruction fragment that needs relaxation.
-      MCInstFragment *IF = dyn_cast<MCInstFragment>(it2);
-      if (!IF || !FragmentNeedsRelaxation(IF, Layout))
-        continue;
-
-      ++stats::RelaxedInstructions;
-
-      // FIXME-PERF: We could immediately lower out instructions if we can tell
-      // they are fully resolved, to avoid retesting on later passes.
-
-      // Relax the fragment.
-
-      MCInst Relaxed;
-      getBackend().RelaxInstruction(IF->getInst(), Relaxed);
-
-      // Encode the new instruction.
-      //
-      // FIXME-PERF: If it matters, we could let the target do this. It can
-      // probably do so more efficiently in many cases.
-      SmallVector<MCFixup, 4> Fixups;
-      SmallString<256> Code;
-      raw_svector_ostream VecOS(Code);
-      getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups);
-      VecOS.flush();
-
-      // Update the instruction fragment.
-      int SlideAmount = Code.size() - IF->getInstSize();
-      IF->setInst(Relaxed);
-      IF->getCode() = Code;
-      IF->getFixups().clear();
-      // FIXME: Eliminate copy.
-      for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
-        IF->getFixups().push_back(Fixups[i]);
-
-      // Update the layout, and remember that we relaxed.
-      Layout.UpdateForSlide(IF, SlideAmount);
-      WasRelaxed = true;
+      // Check if this is an fragment that needs relaxation.
+      switch(it2->getKind()) {
+      default:
+        break;
+      case MCFragment::FT_Inst:
+        WasRelaxed |= RelaxInstruction(Writer, Layout,
+                                       *cast<MCInstFragment>(it2));
+        break;
+      case MCFragment::FT_Org:
+        WasRelaxed |= RelaxOrg(Writer, Layout, *cast<MCOrgFragment>(it2));
+        break;
+      case MCFragment::FT_Dwarf:
+        WasRelaxed |= RelaxDwarfLineAddr(Writer, Layout,
+                                        *cast<MCDwarfLineAddrFragment>(it2));
+       break;
+      case MCFragment::FT_LEB:
+        WasRelaxed |= RelaxLEB(Writer, Layout, *cast<MCLEBFragment>(it2));
+        break;
+      }
     }
   }
 
@@ -972,6 +954,8 @@ void MCFragment::dump() {
   case MCFragment::FT_Fill:  OS << "MCFillFragment"; break;
   case MCFragment::FT_Inst:  OS << "MCInstFragment"; break;
   case MCFragment::FT_Org:   OS << "MCOrgFragment"; break;
+  case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break;
+  case MCFragment::FT_LEB:   OS << "MCLEBFragment"; break;
   }
 
   OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder
@@ -1032,6 +1016,19 @@ void MCFragment::dump() {
     OS << " Offset:" << OF->getOffset() << " Value:" << OF->getValue();
     break;
   }
+  case MCFragment::FT_Dwarf:  {
+    const MCDwarfLineAddrFragment *OF = cast<MCDwarfLineAddrFragment>(this);
+    OS << "\n       ";
+    OS << " AddrDelta:" << OF->getAddrDelta()
+       << " LineDelta:" << OF->getLineDelta();
+    break;
+  }
+  case MCFragment::FT_LEB: {
+    const MCLEBFragment *LF = cast<MCLEBFragment>(this);
+    OS << "\n       ";
+    OS << " Value:" << LF->getValue() << " Signed:" << LF->isSigned();
+    break;
+  }
   }
   OS << ">";
 }