Add a InitSections method to the streamer interface.
authorRafael Espindola <rafael.espindola@gmail.com>
Wed, 15 Sep 2010 21:48:40 +0000 (21:48 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Wed, 15 Sep 2010 21:48:40 +0000 (21:48 +0000)
The ELF implementation now creates text, data and bss to match the gnu as
behavior.

The text streamer still has the old MachO specific behavior since
the testsuite checks that it will error when a directive is given
before a setting the current section for example.

A nice benefit is that -n is not required anymore when producing
ELF files.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114027 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
include/llvm/MC/MCStreamer.h
lib/MC/MCAsmStreamer.cpp
lib/MC/MCAssembler.cpp
lib/MC/MCELFStreamer.cpp
lib/MC/MCLoggingStreamer.cpp
lib/MC/MCMachOStreamer.cpp
lib/MC/MCNullStreamer.cpp
lib/MC/MCParser/AsmParser.cpp
lib/MC/MCParser/ELFAsmParser.cpp
lib/MC/WinCOFFStreamer.cpp
test/MC/ELF/empty.s [new file with mode: 0644]
test/MC/ELF/sleb.s
test/MC/ELF/uleb.s

index f983617a3c43d930857ae8c8d63943cddc04b5f7..0e43ce611d6a0837eb94ba05da8eb666491f5d9d 100644 (file)
@@ -110,6 +110,9 @@ namespace llvm {
     /// This corresponds to assembler directives like .section, .text, etc.
     virtual void SwitchSection(const MCSection *Section) = 0;
 
+    /// InitSections - Create the default sections and set the initial one.
+    virtual void InitSections() = 0;
+
     /// EmitLabel - Emit a label for @p Symbol into the current section.
     ///
     /// This corresponds to an assembler statement such as:
index 1cc8fb0b548672a6636b407d39121baeb2c43a80..efde8aa35004d139afcbcc4a2f5d995241a11f21 100644 (file)
@@ -100,6 +100,14 @@ public:
 
   virtual void SwitchSection(const MCSection *Section);
 
+  virtual void InitSections() {
+    // FIXME, this is MachO specific, but the testsuite
+    // expects this.
+    SwitchSection(getContext().getMachOSection("__TEXT", "__text",
+                         MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+                         0, SectionKind::getText()));
+  }
+
   virtual void EmitLabel(MCSymbol *Symbol);
 
   virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
index 8db1536d2d505f0b8d48a9c9b5ca36e53ac6f382..bb1249950cba9486f5b49aa866b164fbbbac1131 100644 (file)
@@ -739,7 +739,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++);
   }
index 6490cc7a82ef80960fc02329690dffbb193f1392..deb1a0de2086be983e702ae47c758e8bb6b21350 100644 (file)
@@ -46,6 +46,7 @@ public:
   /// @name MCStreamer Interface
   /// @{
 
+  virtual void InitSections();
   virtual void EmitLabel(MCSymbol *Symbol);
   virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
   virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
@@ -109,10 +110,42 @@ public:
   virtual void Finish();
 
   /// @}
+  void SetSection(StringRef Section, unsigned Type, unsigned Flags,
+                  SectionKind Kind) {
+    SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind));
+  }
+
+  void SetSectionData() {
+    SetSection(".data", MCSectionELF::SHT_PROGBITS,
+               MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC,
+               SectionKind::getDataRel());
+    EmitCodeAlignment(4, 0);
+  }
+  void SetSectionText() {
+    SetSection(".text", MCSectionELF::SHT_PROGBITS,
+               MCSectionELF::SHF_EXECINSTR |
+               MCSectionELF::SHF_ALLOC, SectionKind::getText());
+    EmitCodeAlignment(4, 0);
+  }
+  void SetSectionBss() {
+    SetSection(".bss", MCSectionELF::SHT_NOBITS,
+               MCSectionELF::SHF_WRITE |
+               MCSectionELF::SHF_ALLOC, SectionKind::getBSS());
+    EmitCodeAlignment(4, 0);
+  }
 };
 
 } // end anonymous namespace.
 
+void MCELFStreamer::InitSections() {
+  // This emulates the same behavior of GNU as. This makes it easier
+  // to compare the output as the major sections are in the same order.
+  SetSectionText();
+  SetSectionData();
+  SetSectionBss();
+  SetSectionText();
+}
+
 void MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
 
index b96040abd0c102f4eb070b88440177c79050f729..879afa44c5b090ca1f6a76d9ba0c77e61762b0f8 100644 (file)
@@ -54,6 +54,10 @@ public:
     return Child->SwitchSection(Section);
   }
 
+  virtual void InitSections() {
+    LogCall("InitSections");
+  }
+
   virtual void EmitLabel(MCSymbol *Symbol) {
     LogCall("EmitLabel");
     return Child->EmitLabel(Symbol);
index 671874df2c69e054ae203a7f248e4b1de2f79d38..cd6fd50933f0a09b10474d10f1e6fc74233e299c 100644 (file)
@@ -46,6 +46,7 @@ public:
   /// @name MCStreamer Interface
   /// @{
 
+  virtual void InitSections();
   virtual void EmitLabel(MCSymbol *Symbol);
   virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
   virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
@@ -110,6 +111,13 @@ public:
 
 } // end anonymous namespace.
 
+void MCMachOStreamer::InitSections() {
+  SwitchSection(getContext().getMachOSection("__TEXT", "__text",
+                                    MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+                                    0, SectionKind::getText()));
+
+}
+
 void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
   // TODO: This is almost exactly the same as WinCOFFStreamer. Consider merging
   // into MCObjectStreamer.
index f7a2f20ca4bc3dcf8291cbb9174becaa5fce1b93..b2db410c1119adee6a9ee61eff65dd7f84e29ae6 100644 (file)
@@ -25,6 +25,9 @@ namespace {
     /// @name MCStreamer Interface
     /// @{
 
+    virtual void InitSections() {
+    }
+
     virtual void SwitchSection(const MCSection *Section) {
       PrevSection = CurSection;
       CurSection = Section;
index 5ef6f682bfa8a2586d2fb0450f154a9c300ac9b5..b3ffed846d5d0a4270993ed1ceb1f9833fa47ca1 100644 (file)
@@ -365,12 +365,8 @@ const AsmToken &AsmParser::Lex() {
 
 bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
   // Create the initial section, if requested.
-  //
-  // FIXME: Target hook & command line option for initial section.
   if (!NoInitialTextSection)
-    Out.SwitchSection(Ctx.getMachOSection("__TEXT", "__text",
-                                      MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
-                                      0, SectionKind::getText()));
+    Out.InitSections();
 
   // Prime the lexer.
   Lex();
index 38288d78b015d61e11473aaa65d42a786c2f58c2..ddf988faa64291774436574841f050fc2c272b75 100644 (file)
@@ -51,20 +51,28 @@ public:
     AddDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous");
   }
 
+  // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is
+  // the best way for us to get access to it?
   bool ParseSectionDirectiveData(StringRef, SMLoc) {
-    return ParseSectionSwitch(".data", MCSectionELF::SHT_PROGBITS,
+    bool ret =  ParseSectionSwitch(".data", MCSectionELF::SHT_PROGBITS,
                               MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC,
                               SectionKind::getDataRel());
+    getStreamer().EmitCodeAlignment(4, 0);
+    return ret;
   }
   bool ParseSectionDirectiveText(StringRef, SMLoc) {
-    return ParseSectionSwitch(".text", MCSectionELF::SHT_PROGBITS,
+    bool ret = ParseSectionSwitch(".text", MCSectionELF::SHT_PROGBITS,
                               MCSectionELF::SHF_EXECINSTR |
                               MCSectionELF::SHF_ALLOC, SectionKind::getText());
+    getStreamer().EmitCodeAlignment(4, 0);
+    return ret;
   }
   bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
-    return ParseSectionSwitch(".bss", MCSectionELF::SHT_NOBITS,
+    bool ret = ParseSectionSwitch(".bss", MCSectionELF::SHT_NOBITS,
                               MCSectionELF::SHF_WRITE |
                               MCSectionELF::SHF_ALLOC, SectionKind::getBSS());
+    getStreamer().EmitCodeAlignment(4, 0);
+    return ret;
   }
   bool ParseSectionDirectiveRoData(StringRef, SMLoc) {
     return ParseSectionSwitch(".rodata", MCSectionELF::SHT_PROGBITS,
index 8a194bff215137b695b1136153b00fb7eff38071..faecfcbe333b42affd18b3e32dde75db3a486aae 100644 (file)
@@ -48,6 +48,7 @@ public:
 
   // MCStreamer interface
 
+  virtual void InitSections();
   virtual void EmitLabel(MCSymbol *Symbol);
   virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
   virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
@@ -126,6 +127,9 @@ void WinCOFFStreamer::AddCommonSymbol(MCSymbol *Symbol, uint64_t Size,
 
 // MCStreamer interface
 
+void WinCOFFStreamer::InitSections() {
+}
+
 void WinCOFFStreamer::EmitLabel(MCSymbol *Symbol) {
   // TODO: This is copied almost exactly from the MachOStreamer. Consider
   // merging into MCObjectStreamer?
diff --git a/test/MC/ELF/empty.s b/test/MC/ELF/empty.s
new file mode 100644 (file)
index 0000000..ba98a8c
--- /dev/null
@@ -0,0 +1,36 @@
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump   | FileCheck %s
+
+// Test that like gnu as we create text, data and bss by default.
+
+// CHECK:      ('sh_name', 1) # '.text'
+// CHECK-NEXT: ('sh_type', 1)
+// CHECK-NEXT: ('sh_flags', 6)
+// CHECK-NEXT: ('sh_addr', 0)
+// CHECK-NEXT: ('sh_offset', 64)
+// CHECK-NEXT: ('sh_size', 0)
+// CHECK-NEXT: ('sh_link', 0)
+// CHECK-NEXT: ('sh_info', 0)
+// CHECK-NEXT: ('sh_addralign', 4)
+// CHECK-NEXT: ('sh_entsize', 0)
+
+// CHECK:      ('sh_name', 7) # '.data'
+// CHECK-NEXT: ('sh_type', 1)
+// CHECK-NEXT: ('sh_flags', 3)
+// CHECK-NEXT: ('sh_addr', 0)
+// CHECK-NEXT: ('sh_offset', 64)
+// CHECK-NEXT: ('sh_size', 0)
+// CHECK-NEXT: ('sh_link', 0)
+// CHECK-NEXT: ('sh_info', 0)
+// CHECK-NEXT: ('sh_addralign', 4)
+// CHECK-NEXT: ('sh_entsize', 0)
+
+// CHECK:      ('sh_name', 13) # '.bss'
+// CHECK-NEXT: ('sh_type', 8)
+// CHECK-NEXT: ('sh_flags', 3)
+// CHECK-NEXT: ('sh_addr', 0)
+// CHECK-NEXT: ('sh_offset', 64)
+// CHECK-NEXT: ('sh_size', 0)
+// CHECK-NEXT: ('sh_link', 0)
+// CHECK-NEXT: ('sh_info', 0)
+// CHECK-NEXT: ('sh_addralign', 4)
+// CHECK-NEXT: ('sh_entsize', 0)
index ed656b67550b4da73b5cedaa3e5c237ca2bb162d..c3e471f6250873c71584cd5030cb80ab30c7abb8 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu -n %s -o - | elf-dump  --dump-section-data | FileCheck -check-prefix=ELF_32 %s
-// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -n %s -o - | elf-dump  --dump-section-data | FileCheck -check-prefix=ELF_64 %s
+// RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu %s -o - | elf-dump  --dump-section-data | FileCheck -check-prefix=ELF_32 %s
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump  --dump-section-data | FileCheck -check-prefix=ELF_64 %s
 // RUN: llvm-mc -filetype=obj -triple i386-apple-darwin9 %s -o - | macho-dump  --dump-section-data | FileCheck -check-prefix=MACHO_32 %s
 // RUN: llvm-mc -filetype=obj -triple x86_64-apple-darwin9 %s -o - | macho-dump  --dump-section-data | FileCheck -check-prefix=MACHO_64 %s
 
index 1fb2a2347a5985eaa121ff795612dfadbe9768f3..d8d1727af7cd8f314730b2a6cd19405a0f7998f1 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu -n %s -o - | elf-dump  --dump-section-data | FileCheck -check-prefix=ELF_32 %s
-// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -n %s -o - | elf-dump  --dump-section-data | FileCheck -check-prefix=ELF_64 %s
+// RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu %s -o - | elf-dump  --dump-section-data | FileCheck -check-prefix=ELF_32 %s
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump  --dump-section-data | FileCheck -check-prefix=ELF_64 %s
 // RUN: llvm-mc -filetype=obj -triple i386-apple-darwin9 %s -o - | macho-dump  --dump-section-data | FileCheck -check-prefix=MACHO_32 %s
 // RUN: llvm-mc -filetype=obj -triple x86_64-apple-darwin9 %s -o - | macho-dump  --dump-section-data | FileCheck -check-prefix=MACHO_64 %s