[LLVMdev] R_ARM_ABS32 disassembly with integrated-as

Greg Fitzgerald garious at gmail.com
Wed Oct 17 07:05:24 PDT 2012


Hi Jim,

The diff below is not intended to be a patch, but a starting point.
It is the shortest path (I hope) to getting LLVM to emit ARM mapping
symbols to the ELF without changing any shared interfaces.  Could you
have a look at the FIXME comments and offer some pointers on how to
get this code out of MCELFStreamer?

Thanks,
Greg

diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index 8107005..153ca78 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -40,12 +40,14 @@ class MCELFStreamer : public MCObjectStreamer {
 public:
   MCELFStreamer(MCContext &Context, MCAsmBackend &TAB,
                   raw_ostream &OS, MCCodeEmitter *Emitter)
-    : MCObjectStreamer(Context, TAB, OS, Emitter) {}
+    : MCObjectStreamer(Context, TAB, OS, Emitter),
+      IsThumb(false), MappingSymbolCounter(0) {}

   MCELFStreamer(MCContext &Context, MCAsmBackend &TAB,
                 raw_ostream &OS, MCCodeEmitter *Emitter,
                 MCAssembler *Assembler)
-    : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler) {}
+    : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler),
+      IsThumb(false), MappingSymbolCounter(0) {}


   ~MCELFStreamer() {}
@@ -58,6 +60,7 @@ public:
   virtual void EmitLabel(MCSymbol *Symbol);
   virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
   virtual void EmitThumbFunc(MCSymbol *Func);
+  virtual void EmitDataRegion(MCDataRegionType Kind);
   virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
   virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
   virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
@@ -108,6 +111,7 @@ public:
 private:
   virtual void EmitInstToFragment(const MCInst &Inst);
   virtual void EmitInstToData(const MCInst &Inst);
+  virtual void EmitMappingSymbol(bool IsData);

   void fixSymbolsInTLSFixups(const MCExpr *expr);

@@ -119,6 +123,11 @@ private:
   std::vector<LocalCommon> LocalCommons;

   SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
+
+  // FIXME: This information is in ARMAsmBackend, but we currently
+  //        have no way to reach it.
+  bool IsThumb;
+  int64_t MappingSymbolCounter;
   /// @}
   void SetSection(StringRef Section, unsigned Type, unsigned Flags,
                   SectionKind Kind) {
@@ -130,18 +139,21 @@ private:
                ELF::SHF_WRITE |ELF::SHF_ALLOC,
                SectionKind::getDataRel());
     EmitCodeAlignment(4, 0);
+    EmitMappingSymbol(/*IsData*/true);
   }
   void SetSectionText() {
     SetSection(".text", ELF::SHT_PROGBITS,
                ELF::SHF_EXECINSTR |
                ELF::SHF_ALLOC, SectionKind::getText());
     EmitCodeAlignment(4, 0);
+    EmitMappingSymbol(/*IsData*/false);
   }
   void SetSectionBss() {
     SetSection(".bss", ELF::SHT_NOBITS,
                ELF::SHF_WRITE |
                ELF::SHF_ALLOC, SectionKind::getBSS());
     EmitCodeAlignment(4, 0);
+    EmitMappingSymbol(/*IsData*/true);
   }
 };
 }
@@ -188,6 +200,55 @@ void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {

   MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func);
   SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc);
+
+  // Use this flag to output Thumb symbols after data sections.
+  IsThumb = true;
+
+  // FIXME: Instead, emit the correct mapping symbol at .text
+  EmitMappingSymbol(/*IsData*/false);
+}
+
+void MCELFStreamer::EmitMappingSymbol(bool IsData) {
+  // FIXME: The following is specific to the ARM.  This should be moved
+  //        to ARMAsmBackend.
+
+  if (!getAssembler().getBackend().hasDataInCodeSupport())
+    return;
+
+  // Create a temporary label to mark the start of the data region.
+  MCSymbol *Start = getContext().CreateTempSymbol();
+  EmitLabel(Start);
+
+  // FIXME: We want to generate symbols with the same name, but
+  //        CreateSymbol() is not a public function.  So instead
+  //        we generate a unique name as we go.  Luckily, the ARM
+  //        ELF spec says that everything after the '.' is ignored.
+  StringRef Name = IsData ? "$d" : IsThumb ? "$t" : "$a";
+  StringRef UniqueName = Name.str() + "." + itostr(MappingSymbolCounter++);
+  MCSymbol *Symbol = getContext().GetOrCreateSymbol(UniqueName);
+
+  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+  MCELF::SetType(SD, ELF::STT_NOTYPE);
+  MCELF::SetBinding(SD, ELF::STB_LOCAL);
+  SD.setExternal(false);
+  Symbol->setSection(*getCurrentSection());
+
+  const MCExpr *Value = MCSymbolRefExpr::Create(Start, getContext());
+  Symbol->setVariableValue(Value);
+}
+
+void MCELFStreamer::EmitDataRegion(MCDataRegionType Kind) {
+    switch (Kind) {
+        case MCDR_DataRegion:
+        case MCDR_DataRegionJT8:
+        case MCDR_DataRegionJT16:
+        case MCDR_DataRegionJT32:
+            EmitMappingSymbol(/*IsData*/true);
+            break;
+        case MCDR_DataRegionEnd:
+            EmitMappingSymbol(/*IsData*/false);
+            break;
+    }
 }

 void MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 1ba6ab0..a2c6f7d 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -561,7 +561,10 @@ public:
   uint8_t OSABI;
   ELFARMAsmBackend(const Target &T, const StringRef TT,
                    uint8_t _OSABI)
-    : ARMAsmBackend(T, TT), OSABI(_OSABI) { }
+    : ARMAsmBackend(T, TT), OSABI(_OSABI) {
+        // FIXME: Are there versions of ELF-ARM that do not support
data-in-code?
+        HasDataInCodeSupport = true;
+    }

   void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
                   uint64_t Value) const;



More information about the llvm-dev mailing list