[llvm-commits] [llvm] r79684 - in /llvm/trunk: include/llvm/MC/MCAssembler.h lib/MC/MCAssembler.cpp lib/MC/MCMachOStreamer.cpp test/MC/MachO/data.s

Daniel Dunbar daniel at zuster.org
Fri Aug 21 16:07:39 PDT 2009


Author: ddunbar
Date: Fri Aug 21 18:07:38 2009
New Revision: 79684

URL: http://llvm.org/viewvc/llvm-project?rev=79684&view=rev
Log:
llvm-mc/Mach-O: Support .o emission for .org and .align.

Modified:
    llvm/trunk/include/llvm/MC/MCAssembler.h
    llvm/trunk/lib/MC/MCAssembler.cpp
    llvm/trunk/lib/MC/MCMachOStreamer.cpp
    llvm/trunk/test/MC/MachO/data.s

Modified: llvm/trunk/include/llvm/MC/MCAssembler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=79684&r1=79683&r2=79684&view=diff

==============================================================================
--- llvm/trunk/include/llvm/MC/MCAssembler.h (original)
+++ llvm/trunk/include/llvm/MC/MCAssembler.h Fri Aug 21 18:07:38 2009
@@ -64,7 +64,7 @@
   FragmentType getKind() const { return Kind; }
 
   // FIXME: This should be abstract, fix sentinel.
-  virtual unsigned getMaxFileSize() const {
+  virtual uint64_t getMaxFileSize() const {
     assert(0 && "Invalid getMaxFileSize call !");
   };
 
@@ -102,7 +102,7 @@
   /// @name Accessors
   /// @{
 
-  unsigned getMaxFileSize() const {
+  uint64_t getMaxFileSize() const {
     return Contents.size();
   }
 
@@ -141,7 +141,7 @@
   /// @name Accessors
   /// @{
 
-  unsigned getMaxFileSize() const {
+  uint64_t getMaxFileSize() const {
     return std::max(Alignment - 1, MaxBytesToEmit);
   }
 
@@ -180,7 +180,7 @@
   /// @name Accessors
   /// @{
 
-  unsigned getMaxFileSize() const {
+  uint64_t getMaxFileSize() const {
     return ValueSize * Count;
   }
 
@@ -203,29 +203,23 @@
   MCValue Offset;
 
   /// Value - Value to use for filling bytes.  
-  int64_t Value;
-
-  /// ValueSize - The size (in bytes) of \arg Value to use when filling.
-  unsigned ValueSize;
+  int8_t Value;
 
 public:
-  MCOrgFragment(MCValue _Offset, int64_t _Value, unsigned _ValueSize,
-                MCSectionData *SD = 0)
+  MCOrgFragment(MCValue _Offset, int8_t _Value, MCSectionData *SD = 0)
     : MCFragment(FT_Org, SD),
-      Offset(_Offset), Value(_Value), ValueSize(_ValueSize) {}
+      Offset(_Offset), Value(_Value) {}
   /// @name Accessors
   /// @{
 
-  unsigned getMaxFileSize() const {
-    // FIXME
-    return 0;
+  uint64_t getMaxFileSize() const {
+    // FIXME: This doesn't make much sense.
+    return ~UINT64_C(0);
   }
 
   MCValue getOffset() const { return Offset; }
   
-  int64_t getValue() const { return Value; }
-  
-  unsigned getValueSize() const { return ValueSize; }
+  uint8_t getValue() const { return Value; }
 
   /// @}
 

Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=79684&r1=79683&r2=79684&view=diff

==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Fri Aug 21 18:07:38 2009
@@ -8,6 +8,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/MC/MCAssembler.h"
+
+#include "llvm/ADT/Twine.h"
 #include "llvm/MC/MCSectionMachO.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -232,17 +234,58 @@
 }
 
 void MCAssembler::LayoutSection(MCSectionData &SD) {
-  uint64_t Offset = SD.getFileOffset();
+  uint64_t FileOffset = SD.getFileOffset();
+  uint64_t SectionOffset = 0;
 
   for (MCSectionData::iterator it = SD.begin(), ie = SD.end(); it != ie; ++it) {
     MCFragment &F = *it;
-    F.setFileOffset(Offset);
-    F.setFileSize(F.getMaxFileSize());
-    Offset += F.getFileSize();
+
+    F.setFileOffset(FileOffset);
+
+    // Evaluate fragment size.
+    switch (F.getKind()) {
+    case MCFragment::FT_Align: {
+      MCAlignFragment &AF = cast<MCAlignFragment>(F);
+      
+      uint64_t AlignedOffset =
+        RoundUpToAlignment(SectionOffset, AF.getAlignment());
+      uint64_t PaddingBytes = AlignedOffset - SectionOffset;
+
+      if (PaddingBytes > AF.getMaxBytesToEmit())
+        AF.setFileSize(0);
+      else
+        AF.setFileSize(PaddingBytes);
+      break;
+    }
+
+    case MCFragment::FT_Data:
+    case MCFragment::FT_Fill:
+      F.setFileSize(F.getMaxFileSize());
+      break;
+
+    case MCFragment::FT_Org: {
+      MCOrgFragment &OF = cast<MCOrgFragment>(F);
+
+      if (!OF.getOffset().isAbsolute())
+        llvm_unreachable("FIXME: Not yet implemented!");
+      uint64_t OrgOffset = OF.getOffset().getConstant();
+
+      // FIXME: We need a way to communicate this error.
+      if (OrgOffset < SectionOffset)
+        llvm_report_error("invalid .org offset '" + Twine(OrgOffset) + 
+                          "' (section offset '" + Twine(SectionOffset) + "'");
+        
+      F.setFileSize(OrgOffset - SectionOffset);
+      break;
+    }      
+    }
+
+    FileOffset += F.getFileSize();
+    SectionOffset += F.getFileSize();
   }
 
   // FIXME: Pad section?
-  SD.setFileSize(Offset - SD.getFileOffset());
+  SD.setFileSize(FileOffset - SD.getFileOffset());
 }
 
 /// WriteFileData - Write the \arg F data to the output file.
@@ -251,39 +294,68 @@
   uint64_t Start = OS.tell();
   (void) Start;
     
+  assert(F.getFileOffset() == Start && "Invalid file offset!");
+
   // FIXME: Embed in fragments instead?
   switch (F.getKind()) {
-  default:
-    assert(0 && "Invalid section kind!");
+  case MCFragment::FT_Align: {
+    MCAlignFragment &AF = cast<MCAlignFragment>(F);
+    uint64_t Count = AF.getFileSize() / AF.getValueSize();
+
+    // FIXME: This error shouldn't actually occur (the front end should emit
+    // multiple .align directives to enforce the semantics it wants), but is
+    // severe enough that we want to report it. How to handle this?
+    if (Count * AF.getValueSize() != AF.getFileSize())
+      llvm_report_error("undefined .align directive, value size '" + 
+                        Twine(AF.getValueSize()) + 
+                        "' is not a divisor of padding size '" +
+                        Twine(AF.getFileSize()) + "'");
+
+    for (uint64_t i = 0; i != Count; ++i) {
+      switch (AF.getValueSize()) {
+      default:
+        assert(0 && "Invalid size!");
+      case 1: MOW.Write8 (uint8_t (AF.getValue())); break;
+      case 2: MOW.Write16(uint16_t(AF.getValue())); break;
+      case 4: MOW.Write32(uint32_t(AF.getValue())); break;
+      case 8: MOW.Write64(uint64_t(AF.getValue())); break;
+      }
+    }
+    break;
+  }
 
   case MCFragment::FT_Data:
     OS << cast<MCDataFragment>(F).getContents().str();
     break;
 
-  case MCFragment::FT_Align:
-    llvm_unreachable("FIXME: Not yet implemented!");
-
   case MCFragment::FT_Fill: {
     MCFillFragment &FF = cast<MCFillFragment>(F);
 
     if (!FF.getValue().isAbsolute())
       llvm_unreachable("FIXME: Not yet implemented!");
+    int64_t Value = FF.getValue().getConstant();
 
     for (uint64_t i = 0, e = FF.getCount(); i != e; ++i) {
       switch (FF.getValueSize()) {
       default:
         assert(0 && "Invalid size!");
-      case 1: MOW.Write8 (uint8_t (FF.getValue().getConstant())); break;
-      case 2: MOW.Write16(uint16_t(FF.getValue().getConstant())); break;
-      case 4: MOW.Write32(uint32_t(FF.getValue().getConstant())); break;
-      case 8: MOW.Write64(uint64_t(FF.getValue().getConstant())); break;
+      case 1: MOW.Write8 (uint8_t (Value)); break;
+      case 2: MOW.Write16(uint16_t(Value)); break;
+      case 4: MOW.Write32(uint32_t(Value)); break;
+      case 8: MOW.Write64(uint64_t(Value)); break;
       }
     }
     break;
   }
     
-  case MCFragment::FT_Org:
-    llvm_unreachable("FIXME: Not yet implemented!");
+  case MCFragment::FT_Org: {
+    MCOrgFragment &OF = cast<MCOrgFragment>(F);
+
+    for (uint64_t i = 0, e = OF.getFileSize(); i != e; ++i)
+      MOW.Write8(uint8_t(OF.getValue()));
+
+    break;
+  }
   }
 
   assert(OS.tell() - Start == F.getFileSize());

Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=79684&r1=79683&r2=79684&view=diff

==============================================================================
--- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Fri Aug 21 18:07:38 2009
@@ -150,6 +150,8 @@
 void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment,
                                            int64_t Value, unsigned ValueSize,
                                            unsigned MaxBytesToEmit) {
+  if (MaxBytesToEmit == 0)
+    MaxBytesToEmit = ByteAlignment;
   new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
                       CurSectionData);
 
@@ -160,7 +162,7 @@
 
 void MCMachOStreamer::EmitValueToOffset(const MCValue &Offset,
                                         unsigned char Value) {
-  new MCOrgFragment(Offset, Value, 1, CurSectionData);
+  new MCOrgFragment(Offset, Value, CurSectionData);
 }
 
 void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {

Modified: llvm/trunk/test/MC/MachO/data.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/data.s?rev=79684&r1=79683&r2=79684&view=diff

==============================================================================
--- llvm/trunk/test/MC/MachO/data.s (original)
+++ llvm/trunk/test/MC/MachO/data.s Fri Aug 21 18:07:38 2009
@@ -6,6 +6,13 @@
         .short 0xABCD
         .long 0xABCDABCD
         .quad 0xABCDABCDABCDABCD
+.org 30
+        .long 0xF000            // 34
+        .p2align  3, 0xAB       // 40 (0xAB * 6)
+        .short 0                // 42
+        .p2alignw 3, 0xABCD     // 48 (0xABCD * 2)
+        .short 0                // 50
+        .p2alignw 3, 0xABCD, 5  // 50
 
 // CHECK: ('cputype', 7)
 // CHECK: ('cpusubtype', 3)
@@ -19,9 +26,9 @@
 // CHECK:   ('size', 192)
 // CHECK:   ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
 // CHECK:   ('vm_addr', 0)
-// CHECK:   ('vm_size', 20)
+// CHECK:   ('vm_size', 50)
 // CHECK:   ('file_offset', 220)
-// CHECK:   ('file_size', 20)
+// CHECK:   ('file_size', 50)
 // CHECK:   ('maxprot', 7)
 // CHECK:   ('initprot', 7)
 // CHECK:   ('num_sections', 2)
@@ -44,9 +51,9 @@
 // CHECK:    (('section_name', '__data\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
 // CHECK:     ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
 // CHECK:     ('address', 0)
-// CHECK:     ('size', 20)
+// CHECK:     ('size', 50)
 // CHECK:     ('offset', 220)
-// CHECK:     ('alignment', 0)
+// CHECK:     ('alignment', 3)
 // CHECK:     ('reloc_offset', 0)
 // CHECK:     ('num_reloc', 0)
 // CHECK:     ('flags', 0x0)





More information about the llvm-commits mailing list