[llvm] r341593 - The initial .text section generated in object files was missing the

Eric Christopher via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 6 15:09:31 PDT 2018


Author: echristo
Date: Thu Sep  6 15:09:31 2018
New Revision: 341593

URL: http://llvm.org/viewvc/llvm-project?rev=341593&view=rev
Log:
The initial .text section generated in object files was missing the
SHF_ARM_PURECODE flag when being built with the -mexecute-only flag.
All code sections of an ELF must have the flag set for the final .text
section to be execute-only, otherwise the flag gets removed.

A HasData flag is added to MCSection to aid in the determination that
the section is empty. A virtual setTargetSectionFlags is added to
MCELFObjectTargetWriter to allow subclasses to set target specific
section flags to be added to sections which we then use in the ARM
backend to set SHF_ARM_PURECODE.

Patch by Ivan Lozano!

Reviewed By: echristo

Differential Revision: https://reviews.llvm.org/D48792

Added:
    llvm/trunk/test/MC/ARM/elf-execute-only-section.ll
    llvm/trunk/test/MC/ELF/ARM/execute-only-populated-text-section.s
      - copied, changed from r341587, llvm/trunk/test/MC/ELF/ARM/execute-only-section.s
    llvm/trunk/test/MC/ELF/ARM/execute-only-text-section-data.s
      - copied, changed from r341587, llvm/trunk/test/MC/ELF/ARM/execute-only-section.s
Modified:
    llvm/trunk/include/llvm/MC/MCELFObjectWriter.h
    llvm/trunk/include/llvm/MC/MCSection.h
    llvm/trunk/lib/MC/ELFObjectWriter.cpp
    llvm/trunk/lib/MC/MCELFObjectTargetWriter.cpp
    llvm/trunk/lib/MC/MCObjectStreamer.cpp
    llvm/trunk/lib/MC/MCSection.cpp
    llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp
    llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
    llvm/trunk/test/CodeGen/ARM/execute-only.ll
    llvm/trunk/test/MC/ELF/ARM/execute-only-section.s

Modified: llvm/trunk/include/llvm/MC/MCELFObjectWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCELFObjectWriter.h?rev=341593&r1=341592&r2=341593&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCELFObjectWriter.h (original)
+++ llvm/trunk/include/llvm/MC/MCELFObjectWriter.h Thu Sep  6 15:09:31 2018
@@ -13,6 +13,7 @@
 #include "llvm/ADT/Triple.h"
 #include "llvm/BinaryFormat/ELF.h"
 #include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSectionELF.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdint>
@@ -92,6 +93,8 @@ public:
   virtual void sortRelocs(const MCAssembler &Asm,
                           std::vector<ELFRelocationEntry> &Relocs);
 
+  virtual void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec);
+
   /// \name Accessors
   /// @{
   uint8_t getOSABI() const { return OSABI; }

Modified: llvm/trunk/include/llvm/MC/MCSection.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSection.h?rev=341593&r1=341592&r2=341593&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCSection.h (original)
+++ llvm/trunk/include/llvm/MC/MCSection.h Thu Sep  6 15:09:31 2018
@@ -78,6 +78,10 @@ private:
   /// Whether this section has had instructions emitted into it.
   bool HasInstructions : 1;
 
+  /// Whether this section has had data emitted into it.
+  /// Right now this is only used by the ARM backend.
+  bool HasData : 1;
+
   bool IsRegistered : 1;
 
   MCDummyFragment DummyFragment;
@@ -137,6 +141,9 @@ public:
   bool hasInstructions() const { return HasInstructions; }
   void setHasInstructions(bool Value) { HasInstructions = Value; }
 
+  bool hasData() const { return HasData; }
+  void setHasData(bool Value) { HasData = Value; }
+
   bool isRegistered() const { return IsRegistered; }
   void setIsRegistered(bool Value) { IsRegistered = Value; }
 

Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=341593&r1=341592&r2=341593&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Thu Sep  6 15:09:31 2018
@@ -29,6 +29,7 @@
 #include "llvm/MC/MCFixup.h"
 #include "llvm/MC/MCFixupKindInfo.h"
 #include "llvm/MC/MCFragment.h"
+#include "llvm/MC/MCObjectFileInfo.h"
 #include "llvm/MC/MCObjectWriter.h"
 #include "llvm/MC/MCSection.h"
 #include "llvm/MC/MCSectionELF.h"
@@ -1107,6 +1108,8 @@ uint64_t ELFWriter::writeObject(MCAssemb
       SectionIndexMap[RelSection] = addToSectionTable(RelSection);
       Relocations.push_back(RelSection);
     }
+
+    OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Section);
   }
 
   MCSectionELF *CGProfileSection = nullptr;

Modified: llvm/trunk/lib/MC/MCELFObjectTargetWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFObjectTargetWriter.cpp?rev=341593&r1=341592&r2=341593&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCELFObjectTargetWriter.cpp (original)
+++ llvm/trunk/lib/MC/MCELFObjectTargetWriter.cpp Thu Sep  6 15:09:31 2018
@@ -26,3 +26,6 @@ void
 MCELFObjectTargetWriter::sortRelocs(const MCAssembler &Asm,
                                     std::vector<ELFRelocationEntry> &Relocs) {
 }
+
+void MCELFObjectTargetWriter::addTargetSectionFlags(MCContext &Ctx,
+                                                    MCSectionELF &Sec) {}

Modified: llvm/trunk/lib/MC/MCObjectStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectStreamer.cpp?rev=341593&r1=341592&r2=341593&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCObjectStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCObjectStreamer.cpp Thu Sep  6 15:09:31 2018
@@ -496,6 +496,12 @@ void MCObjectStreamer::EmitBytes(StringR
   MCDataFragment *DF = getOrCreateDataFragment();
   flushPendingLabels(DF, DF->getContents().size());
   DF->getContents().append(Data.begin(), Data.end());
+
+  // EmitBytes might not cover all possible ways we emit data (or could be used
+  // to emit executable code in some cases), but is the best method we have
+  // right now for checking this.
+  MCSection *Sec = getCurrentSectionOnly();
+  Sec->setHasData(true);
 }
 
 void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,

Modified: llvm/trunk/lib/MC/MCSection.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSection.cpp?rev=341593&r1=341592&r2=341593&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCSection.cpp (original)
+++ llvm/trunk/lib/MC/MCSection.cpp Thu Sep  6 15:09:31 2018
@@ -23,7 +23,8 @@ using namespace llvm;
 
 MCSection::MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin)
     : Begin(Begin), BundleGroupBeforeFirstInst(false), HasInstructions(false),
-      IsRegistered(false), DummyFragment(this), Variant(V), Kind(K) {}
+      HasData(false), IsRegistered(false), DummyFragment(this), Variant(V),
+      Kind(K) {}
 
 MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) {
   if (!End)

Modified: llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp?rev=341593&r1=341592&r2=341593&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp Thu Sep  6 15:09:31 2018
@@ -32,7 +32,8 @@ void ARMElfTargetObjectFile::Initialize(
                                         const TargetMachine &TM) {
   const ARMBaseTargetMachine &ARM_TM = static_cast<const ARMBaseTargetMachine &>(TM);
   bool isAAPCS_ABI = ARM_TM.TargetABI == ARMBaseTargetMachine::ARMABI::ARM_ABI_AAPCS;
-  //  genExecuteOnly = ARM_TM.getSubtargetImpl()->genExecuteOnly();
+  bool genExecuteOnly =
+      ARM_TM.getMCSubtargetInfo()->hasFeature(ARM::FeatureExecuteOnly);
 
   TargetLoweringObjectFileELF::Initialize(Ctx, TM);
   InitializeELF(isAAPCS_ABI);
@@ -40,6 +41,17 @@ void ARMElfTargetObjectFile::Initialize(
   if (isAAPCS_ABI) {
     LSDASection = nullptr;
   }
+
+  // Make code section unreadable when in execute-only mode
+  if (genExecuteOnly) {
+    unsigned Type = ELF::SHT_PROGBITS;
+    unsigned Flags =
+        ELF::SHF_EXECINSTR | ELF::SHF_ALLOC | ELF::SHF_ARM_PURECODE;
+    // Since we cannot modify flags for an existing section, we create a new
+    // section with the right flags, and use 0 as the unique ID for
+    // execute-only text
+    TextSection = Ctx.getELFSection(".text", Type, Flags, 0, "", 0U);
+  }
 }
 
 const MCExpr *ARMElfTargetObjectFile::getTTypeGlobalReference(

Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp?rev=341593&r1=341592&r2=341593&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp Thu Sep  6 15:09:31 2018
@@ -14,6 +14,7 @@
 #include "llvm/MC/MCELFObjectWriter.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCObjectFileInfo.h"
 #include "llvm/MC/MCObjectWriter.h"
 #include "llvm/MC/MCValue.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -40,6 +41,8 @@ namespace {
 
     bool needsRelocateWithSymbol(const MCSymbol &Sym,
                                  unsigned Type) const override;
+
+    void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec) override;
   };
 
 } // end anonymous namespace
@@ -236,6 +239,21 @@ unsigned ARMELFObjectWriter::GetRelocTyp
   }
 }
 
+void ARMELFObjectWriter::addTargetSectionFlags(MCContext &Ctx,
+                                               MCSectionELF &Sec) {
+  // The mix of execute-only and non-execute-only at link time is
+  // non-execute-only. To avoid the empty implicitly created .text
+  // section from making the whole .text section non-execute-only, we
+  // mark it execute-only if it is empty and there is at least one
+  // execute-only section in the object.
+  MCSectionELF *TextSection =
+      static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
+  if (Sec.getKind().isExecuteOnly() && !TextSection->hasInstructions() &&
+      !TextSection->hasData()) {
+    TextSection->setFlags(TextSection->getFlags() | ELF::SHF_ARM_PURECODE);
+  }
+}
+
 std::unique_ptr<MCObjectTargetWriter>
 llvm::createARMELFObjectWriter(uint8_t OSABI) {
   return llvm::make_unique<ARMELFObjectWriter>(OSABI);

Modified: llvm/trunk/test/CodeGen/ARM/execute-only.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/execute-only.ll?rev=341593&r1=341592&r2=341593&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/execute-only.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/execute-only.ll Thu Sep  6 15:09:31 2018
@@ -2,6 +2,9 @@
 ; RUN: llc -mtriple=thumbv7m-eabi      -mattr=+execute-only %s -o - | FileCheck --check-prefix=CHECK --check-prefix=CHECK-T2 %s
 ; RUN: llc -mtriple=thumbv8m.main-eabi -mattr=+execute-only %s -o - | FileCheck --check-prefix=CHECK --check-prefix=CHECK-T2 %s
 
+; CHECK-NOT: {{^ *}}.text{{$}}
+; CHECK: .section .text,"axy",%progbits,unique,0
+
 @var = global i32 0
 
 define i32 @global() minsize {

Added: llvm/trunk/test/MC/ARM/elf-execute-only-section.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/elf-execute-only-section.ll?rev=341593&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/elf-execute-only-section.ll (added)
+++ llvm/trunk/test/MC/ARM/elf-execute-only-section.ll Thu Sep  6 15:09:31 2018
@@ -0,0 +1,13 @@
+; RUN: llc < %s -mtriple=thumbv8m.base-eabi -mattr=+execute-only -filetype=obj %s -o - | \
+; RUN: llvm-readelf -s | FileCheck %s
+; RUN: llc < %s -mtriple=thumbv8m.main-eabi -mattr=+execute-only -filetype=obj %s -o - | \
+; RUN: llvm-readelf -s | FileCheck %s
+; RUN: llc < %s -mtriple=thumbv7m-eabi -mattr=+execute-only -filetype=obj %s -o - | \
+; RUN: llvm-readelf -s | FileCheck %s
+
+; CHECK-NOT: {{.text[ ]+PROGBITS[ ]+[0-9]+ [0-9]+ [0-9]+ [0-9]+ AX[^p]}}
+; CHECK: {{.text[ ]+PROGBITS[ ]+[0-9]+ [0-9]+ [0-9]+ [0-9]+ AXp}}
+define void @test_func() {
+entry:
+  ret void
+}

Copied: llvm/trunk/test/MC/ELF/ARM/execute-only-populated-text-section.s (from r341587, llvm/trunk/test/MC/ELF/ARM/execute-only-section.s)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/ARM/execute-only-populated-text-section.s?p2=llvm/trunk/test/MC/ELF/ARM/execute-only-populated-text-section.s&p1=llvm/trunk/test/MC/ELF/ARM/execute-only-section.s&r1=341587&r2=341593&rev=341593&view=diff
==============================================================================
--- llvm/trunk/test/MC/ELF/ARM/execute-only-section.s (original)
+++ llvm/trunk/test/MC/ELF/ARM/execute-only-populated-text-section.s Thu Sep  6 15:09:31 2018
@@ -1,44 +1,27 @@
 // RUN: llvm-mc -filetype=obj -triple thumbv7m-arm-linux-gnu %s -o - \
 // RUN: | llvm-readobj -s -t | FileCheck %s
 
-        .section        .text,"axy",%progbits,unique,0
-        .globl  foo
-        .align  2
-        .type   foo,%function
-        .code   16
-        .thumb_func
-foo:
-        .fnstart
+        .text
         bx      lr
-.Lfunc_end0:
-        .size   foo, .Lfunc_end0-foo
-        .fnend
-
-        .section        ".note.GNU-stack","",%progbits
 
+        .section        .text.foo,"axy"
+        bx      lr
 
 // CHECK:      Section {
-// CHECK:        Name: .text (16)
+// CHECK:        Name: .text
 // CHECK-NEXT:   Type: SHT_PROGBITS (0x1)
 // CHECK-NEXT:   Flags [ (0x6)
 // CHECK-NEXT:     SHF_ALLOC (0x2)
 // CHECK-NEXT:     SHF_EXECINSTR (0x4)
 // CHECK-NEXT:   ]
-// CHECK:        Size: 0
 // CHECK:      }
 
 // CHECK:      Section {
-// CHECK:        Name: .text (16)
+// CHECK:        Name: .text.foo
 // CHECK-NEXT:   Type: SHT_PROGBITS (0x1)
 // CHECK-NEXT:   Flags [ (0x20000006)
 // CHECK-NEXT:     SHF_ALLOC (0x2)
 // CHECK-NEXT:     SHF_ARM_PURECODE (0x20000000)
 // CHECK-NEXT:     SHF_EXECINSTR (0x4)
 // CHECK-NEXT:   ]
-// CHECK:        Size: 2
 // CHECK:      }
-
-// CHECK: Symbol {
-// CHECK:   Name: foo (22)
-// CHECK:   Section: .text (0x3)
-// CHECK: }

Modified: llvm/trunk/test/MC/ELF/ARM/execute-only-section.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/ARM/execute-only-section.s?rev=341593&r1=341592&r2=341593&view=diff
==============================================================================
--- llvm/trunk/test/MC/ELF/ARM/execute-only-section.s (original)
+++ llvm/trunk/test/MC/ELF/ARM/execute-only-section.s Thu Sep  6 15:09:31 2018
@@ -20,8 +20,9 @@ foo:
 // CHECK:      Section {
 // CHECK:        Name: .text (16)
 // CHECK-NEXT:   Type: SHT_PROGBITS (0x1)
-// CHECK-NEXT:   Flags [ (0x6)
+// CHECK-NEXT:   Flags [ (0x20000006)
 // CHECK-NEXT:     SHF_ALLOC (0x2)
+// CHECK-NEXT:     SHF_ARM_PURECODE (0x20000000)
 // CHECK-NEXT:     SHF_EXECINSTR (0x4)
 // CHECK-NEXT:   ]
 // CHECK:        Size: 0

Copied: llvm/trunk/test/MC/ELF/ARM/execute-only-text-section-data.s (from r341587, llvm/trunk/test/MC/ELF/ARM/execute-only-section.s)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/ARM/execute-only-text-section-data.s?p2=llvm/trunk/test/MC/ELF/ARM/execute-only-text-section-data.s&p1=llvm/trunk/test/MC/ELF/ARM/execute-only-section.s&r1=341587&r2=341593&rev=341593&view=diff
==============================================================================
--- llvm/trunk/test/MC/ELF/ARM/execute-only-section.s (original)
+++ llvm/trunk/test/MC/ELF/ARM/execute-only-text-section-data.s Thu Sep  6 15:09:31 2018
@@ -1,44 +1,27 @@
 // RUN: llvm-mc -filetype=obj -triple thumbv7m-arm-linux-gnu %s -o - \
 // RUN: | llvm-readobj -s -t | FileCheck %s
 
-        .section        .text,"axy",%progbits,unique,0
-        .globl  foo
-        .align  2
-        .type   foo,%function
-        .code   16
-        .thumb_func
-foo:
-        .fnstart
-        bx      lr
-.Lfunc_end0:
-        .size   foo, .Lfunc_end0-foo
-        .fnend
-
-        .section        ".note.GNU-stack","",%progbits
+        .text
+        .ascii "test"
 
+        .section        .text.foo,"axy"
+        bx      lr
 
 // CHECK:      Section {
-// CHECK:        Name: .text (16)
+// CHECK:        Name: .text
 // CHECK-NEXT:   Type: SHT_PROGBITS (0x1)
 // CHECK-NEXT:   Flags [ (0x6)
 // CHECK-NEXT:     SHF_ALLOC (0x2)
 // CHECK-NEXT:     SHF_EXECINSTR (0x4)
 // CHECK-NEXT:   ]
-// CHECK:        Size: 0
 // CHECK:      }
 
 // CHECK:      Section {
-// CHECK:        Name: .text (16)
+// CHECK:        Name: .text.foo
 // CHECK-NEXT:   Type: SHT_PROGBITS (0x1)
 // CHECK-NEXT:   Flags [ (0x20000006)
 // CHECK-NEXT:     SHF_ALLOC (0x2)
 // CHECK-NEXT:     SHF_ARM_PURECODE (0x20000000)
 // CHECK-NEXT:     SHF_EXECINSTR (0x4)
 // CHECK-NEXT:   ]
-// CHECK:        Size: 2
 // CHECK:      }
-
-// CHECK: Symbol {
-// CHECK:   Name: foo (22)
-// CHECK:   Section: .text (0x3)
-// CHECK: }




More information about the llvm-commits mailing list