>From b87de21b0809b273217f816858a465ffe931d43b Mon Sep 17 00:00:00 2001 From: Greg Fitzgerald Date: Wed, 17 Oct 2012 17:16:47 -0700 Subject: [PATCH] Added Mapping Symbols for ARM ELF Before this patch, when you objdump an LLVM-compiled file, objdump tried to decode data-in-code sections as if they were code. This patch adds the missing Mapping Symbols, as defined by "ELF for the ARM Architecture" (ARM IHI 0044D). --- include/llvm/MC/MCELF.h | 35 +++++ include/llvm/MC/MCELFStreamer.h | 117 +++++++++++++++++ lib/MC/ELFObjectWriter.cpp | 2 +- lib/MC/MCELF.cpp | 2 +- lib/MC/MCELF.h | 35 ----- lib/MC/MCELFStreamer.cpp | 153 +++++++++-------------- lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp | 148 ++++++++++++++++++++++ lib/Target/ARM/MCTargetDesc/ARMELFStreamer.h | 27 ++++ lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp | 9 ++- lib/Target/ARM/MCTargetDesc/CMakeLists.txt | 1 + test/CodeGen/ARM/2010-11-30-reloc-movt.ll | 4 +- test/MC/ARM/elf-reloc-01.ll | 4 +- test/MC/ARM/elf-reloc-02.ll | 4 +- test/MC/ARM/elf-reloc-03.ll | 4 +- test/MC/ARM/elf-reloc-condcall.s | 12 +- test/MC/ARM/elf-thumbfunc-reloc.ll | 4 +- test/MC/ARM/elf-thumbfunc.s | 4 +- 17 files changed, 414 insertions(+), 151 deletions(-) create mode 100644 include/llvm/MC/MCELF.h create mode 100644 include/llvm/MC/MCELFStreamer.h delete mode 100644 lib/MC/MCELF.h create mode 100644 lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp create mode 100644 lib/Target/ARM/MCTargetDesc/ARMELFStreamer.h diff --git a/include/llvm/MC/MCELF.h b/include/llvm/MC/MCELF.h new file mode 100644 index 0000000..e08f1e6 --- /dev/null +++ b/include/llvm/MC/MCELF.h @@ -0,0 +1,35 @@ +//===- lib/MC/MCELF.h - ELF MC --------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains some support functions used by the ELF Streamer and +// ObjectWriter. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCELF_H +#define LLVM_MC_MCELF_H + +#include "llvm/MC/MCExpr.h" + +namespace llvm { +class MCSymbolData; + +class MCELF { + public: + static void SetBinding(MCSymbolData &SD, unsigned Binding); + static unsigned GetBinding(const MCSymbolData &SD); + static void SetType(MCSymbolData &SD, unsigned Type); + static unsigned GetType(const MCSymbolData &SD); + static void SetVisibility(MCSymbolData &SD, unsigned Visibility); + static unsigned GetVisibility(MCSymbolData &SD); +}; + +} + +#endif diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h new file mode 100644 index 0000000..7b1e73e --- /dev/null +++ b/include/llvm/MC/MCELFStreamer.h @@ -0,0 +1,117 @@ +//===- lib/MC/MCELFStreamer.h - ELF Object Output ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file assembles .s files and emits ELF .o object files. +// +//===----------------------------------------------------------------------===// + +#ifndef MC_ELF_STREAMER_H +#define MC_ELF_STREAMER_H + +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Twine.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCELFSymbolFlags.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCObjectStreamer.h" +#include "llvm/MC/MCELFStreamer.h" +#include "llvm/MC/MCSection.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCValue.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ELF.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { +class MCELFStreamer : public MCObjectStreamer { +public: + MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter); + + MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + MCAssembler *Assembler); + + + virtual ~MCELFStreamer(); + + /// @name MCStreamer Interface + /// @{ + + virtual void InitSections(); + virtual void ChangeSection(const MCSection *Section); + virtual void EmitLabel(MCSymbol *Symbol); + virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); + virtual void EmitThumbFunc(MCSymbol *Func); + virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); + virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); + virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); + virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); + virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment); + virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol); + virtual void EmitCOFFSymbolStorageClass(int StorageClass); + virtual void EmitCOFFSymbolType(int Type); + virtual void EndCOFFSymbolDef(); + + virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value); + + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment); + + virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, + uint64_t Size = 0, unsigned ByteAlignment = 0); + + virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, + uint64_t Size, unsigned ByteAlignment = 0); + + virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, + unsigned AddrSpace); + + virtual void EmitFileDirective(StringRef Filename); + + virtual void FinishImpl(); + +protected: + virtual void EmitInstToFragment(const MCInst &Inst); + virtual void EmitInstToData(const MCInst &Inst); + virtual void SetSectionData(); + virtual void SetSectionText(); + virtual void SetSectionBss(); + virtual void SetSection(StringRef, unsigned int, unsigned int, SectionKind); + +private: + void fixSymbolsInTLSFixups(const MCExpr *expr); + + struct LocalCommon { + MCSymbolData *SD; + uint64_t Size; + unsigned ByteAlignment; + }; + std::vector LocalCommons; + + SmallPtrSet BindingExplicitlySet; + + // FIXME: This information is in ARMAsmBackend, but we currently + // have no way to reach it. + bool IsThumb; + int64_t MappingSymbolCounter; + /// @} +}; +} + +#endif // MC_ELF_STREAMER_H diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 6e37b5c..ab20391 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -11,7 +11,6 @@ // //===----------------------------------------------------------------------===// -#include "MCELF.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" @@ -21,6 +20,7 @@ #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCELF.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCELFSymbolFlags.h" #include "llvm/MC/MCExpr.h" diff --git a/lib/MC/MCELF.cpp b/lib/MC/MCELF.cpp index f9f98e0..e21064a 100644 --- a/lib/MC/MCELF.cpp +++ b/lib/MC/MCELF.cpp @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#include "MCELF.h" #include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCELF.h" #include "llvm/MC/MCELFSymbolFlags.h" #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/Support/ELF.h" diff --git a/lib/MC/MCELF.h b/lib/MC/MCELF.h deleted file mode 100644 index e08f1e6..0000000 --- a/lib/MC/MCELF.h +++ /dev/null @@ -1,35 +0,0 @@ -//===- lib/MC/MCELF.h - ELF MC --------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains some support functions used by the ELF Streamer and -// ObjectWriter. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MCELF_H -#define LLVM_MC_MCELF_H - -#include "llvm/MC/MCExpr.h" - -namespace llvm { -class MCSymbolData; - -class MCELF { - public: - static void SetBinding(MCSymbolData &SD, unsigned Binding); - static unsigned GetBinding(const MCSymbolData &SD); - static void SetType(MCSymbolData &SD, unsigned Type); - static unsigned GetType(const MCSymbolData &SD); - static void SetVisibility(MCSymbolData &SD, unsigned Visibility); - static unsigned GetVisibility(MCSymbolData &SD); -}; - -} - -#endif diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 8107005..ec4cd99 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -11,7 +11,6 @@ // //===----------------------------------------------------------------------===// -#include "MCELF.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" @@ -20,6 +19,8 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCELF.h" +#include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCELFSymbolFlags.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" @@ -35,115 +36,77 @@ using namespace llvm; -namespace { -class MCELFStreamer : public MCObjectStreamer { -public: - MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, +MCELFStreamer::MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter) - : MCObjectStreamer(Context, TAB, OS, Emitter) {} + : MCObjectStreamer(Context, TAB, OS, Emitter) { +} - MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, +MCELFStreamer::MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, MCAssembler *Assembler) - : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler) {} - - - ~MCELFStreamer() {} - - /// @name MCStreamer Interface - /// @{ - - virtual void InitSections(); - virtual void ChangeSection(const MCSection *Section); - virtual void EmitLabel(MCSymbol *Symbol); - virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); - virtual void EmitThumbFunc(MCSymbol *Func); - virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); - virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); - virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); - virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { - llvm_unreachable("ELF doesn't support this directive"); - } - virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment); - virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) { - llvm_unreachable("ELF doesn't support this directive"); - } - - virtual void EmitCOFFSymbolStorageClass(int StorageClass) { - llvm_unreachable("ELF doesn't support this directive"); - } - - virtual void EmitCOFFSymbolType(int Type) { - llvm_unreachable("ELF doesn't support this directive"); - } + : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler) { +} - virtual void EndCOFFSymbolDef() { - llvm_unreachable("ELF doesn't support this directive"); - } - virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { - MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); - SD.setSize(Value); - } +MCELFStreamer::~MCELFStreamer() { +} - virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment); +void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { + llvm_unreachable("ELF doesn't support this directive"); +} +void MCELFStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) { + llvm_unreachable("ELF doesn't support this directive"); +} - virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, - uint64_t Size = 0, unsigned ByteAlignment = 0) { - llvm_unreachable("ELF doesn't support this directive"); - } - virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, - uint64_t Size, unsigned ByteAlignment = 0) { - llvm_unreachable("ELF doesn't support this directive"); - } - virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, - unsigned AddrSpace); +void MCELFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) { + llvm_unreachable("ELF doesn't support this directive"); +} - virtual void EmitFileDirective(StringRef Filename); +void MCELFStreamer::EmitCOFFSymbolType(int Type) { + llvm_unreachable("ELF doesn't support this directive"); +} - virtual void FinishImpl(); +void MCELFStreamer::EndCOFFSymbolDef() { + llvm_unreachable("ELF doesn't support this directive"); +} -private: - virtual void EmitInstToFragment(const MCInst &Inst); - virtual void EmitInstToData(const MCInst &Inst); +void MCELFStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { + MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); + SD.setSize(Value); +} - void fixSymbolsInTLSFixups(const MCExpr *expr); +void MCELFStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, + uint64_t Size, unsigned ByteAlignment) { + llvm_unreachable("ELF doesn't support this directive"); +} - struct LocalCommon { - MCSymbolData *SD; - uint64_t Size; - unsigned ByteAlignment; - }; - std::vector LocalCommons; +void MCELFStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, + uint64_t Size, unsigned ByteAlignment) { + llvm_unreachable("ELF doesn't support this directive"); +} - SmallPtrSet BindingExplicitlySet; - /// @} - void SetSection(StringRef Section, unsigned Type, unsigned Flags, - SectionKind Kind) { - SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind)); - } +void MCELFStreamer::SetSection(StringRef Section, unsigned Type, unsigned Flags, + SectionKind Kind) { + SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind)); +} - void SetSectionData() { - SetSection(".data", ELF::SHT_PROGBITS, - ELF::SHF_WRITE |ELF::SHF_ALLOC, - SectionKind::getDataRel()); - EmitCodeAlignment(4, 0); - } - void SetSectionText() { - SetSection(".text", ELF::SHT_PROGBITS, - ELF::SHF_EXECINSTR | - ELF::SHF_ALLOC, SectionKind::getText()); - EmitCodeAlignment(4, 0); - } - void SetSectionBss() { - SetSection(".bss", ELF::SHT_NOBITS, - ELF::SHF_WRITE | - ELF::SHF_ALLOC, SectionKind::getBSS()); - EmitCodeAlignment(4, 0); - } -}; +void MCELFStreamer::SetSectionData() { + SetSection(".data", ELF::SHT_PROGBITS, + ELF::SHF_WRITE |ELF::SHF_ALLOC, + SectionKind::getDataRel()); + EmitCodeAlignment(4, 0); +} +void MCELFStreamer::SetSectionText() { + SetSection(".text", ELF::SHT_PROGBITS, + ELF::SHF_EXECINSTR | + ELF::SHF_ALLOC, SectionKind::getText()); + EmitCodeAlignment(4, 0); +} +void MCELFStreamer::SetSectionBss() { + SetSection(".bss", ELF::SHT_NOBITS, + ELF::SHF_WRITE | + ELF::SHF_ALLOC, SectionKind::getBSS()); + EmitCodeAlignment(4, 0); } void MCELFStreamer::InitSections() { diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp new file mode 100644 index 0000000..ca53396 --- /dev/null +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -0,0 +1,148 @@ +//===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file assembles .s files and emits ELF .o object files. +// +//===----------------------------------------------------------------------===// + +#include "ARMELFStreamer.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Twine.h" +#include "llvm/MC/MCELFStreamer.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCELF.h" +#include "llvm/MC/MCELFSymbolFlags.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCObjectStreamer.h" +#include "llvm/MC/MCSection.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCValue.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ELF.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +namespace { + +class ARMELFStreamer : public MCELFStreamer { +public: + ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter, bool IsThumb) + : MCELFStreamer(Context, TAB, OS, Emitter), + IsThumb(IsThumb), + AlreadySetData(false), + AlreadySetText(false), + AlreadySetBss(false), + MappingSymbolCounter(0) { + } + + ~ARMELFStreamer() {} + + /// @name ARMELFStreamer Interface + /// @{ + virtual void EmitDataRegion(MCDataRegionType Kind); +private: + virtual void EmitDataMappingSymbol(); + virtual void EmitCodeMappingSymbol(); + virtual void EmitMappingSymbol(StringRef Name); + + bool IsThumb; + bool AlreadySetData; + bool AlreadySetText; + bool AlreadySetBss; + int64_t MappingSymbolCounter; + /// @} + + virtual void SetSectionData() { + MCELFStreamer::SetSectionData(); + if (!AlreadySetData) { + AlreadySetData = true; + EmitDataMappingSymbol(); + } + } + virtual void SetSectionText() { + MCELFStreamer::SetSectionText(); + if (!AlreadySetText) { + AlreadySetText = true; + EmitCodeMappingSymbol(); + } + } + virtual void SetSectionBss() { + MCELFStreamer::SetSectionBss(); + if (!AlreadySetBss) { + AlreadySetBss = true; + EmitDataMappingSymbol(); + } + } +}; + +void ARMELFStreamer::EmitDataMappingSymbol() { + EmitMappingSymbol("$d"); +} + +void ARMELFStreamer::EmitCodeMappingSymbol() { + EmitMappingSymbol(IsThumb ? "$t" : "$a"); +} + +void ARMELFStreamer::EmitMappingSymbol(StringRef Name) { + // 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 + + // Create a temporary label to mark the start of the data region. + MCSymbol *Start = getContext().CreateTempSymbol(); + EmitLabel(Start); + + 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 ARMELFStreamer::EmitDataRegion(MCDataRegionType Kind) { + switch (Kind) { + case MCDR_DataRegion: + case MCDR_DataRegionJT8: + case MCDR_DataRegionJT16: + case MCDR_DataRegionJT32: + EmitDataMappingSymbol(); + break; + case MCDR_DataRegionEnd: + EmitCodeMappingSymbol(); + break; + } +} + +} + +namespace llvm { + MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter, bool IsThumb) { + return new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb); + } +} + + diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.h b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.h new file mode 100644 index 0000000..e7e1f9c --- /dev/null +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.h @@ -0,0 +1,27 @@ +//===-- ARMELFStreamer.h - ELF Streamer for ARM ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements ELF streamer information for the ARM backend. +// +//===----------------------------------------------------------------------===// + +#ifndef ARM_ELF_STREAMER_H +#define ARM_ELF_STREAMER_H + +#include "llvm/MC/MCELFStreamer.h" + +namespace llvm { + + MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + bool IsThumb); +} + +#endif // ARM_ELF_WRITER_INFO_H + diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index bdab255..fc95376 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -14,6 +14,7 @@ #include "ARMMCTargetDesc.h" #include "ARMMCAsmInfo.h" #include "ARMBaseInfo.h" +#include "ARMELFStreamer.h" #include "InstPrinter/ARMInstPrinter.h" #include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCInstrAnalysis.h" @@ -179,6 +180,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT, bool RelaxAll, bool NoExecStack) { Triple TheTriple(TT); + bool IsThumb = TT.substr(0, 5) == "thumb"; if (TheTriple.isOSDarwin()) return createMachOStreamer(Ctx, MAB, OS, Emitter, false); @@ -187,7 +189,12 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT, llvm_unreachable("ARM does not support Windows COFF format"); } - return createELFStreamer(Ctx, MAB, OS, Emitter, false, NoExecStack); + MCELFStreamer *S = createARMELFStreamer(Ctx, MAB, OS, Emitter, IsThumb); + if (RelaxAll) + S->getAssembler().setRelaxAll(true); + if (NoExecStack) + S->getAssembler().setNoExecStack(true); + return S; } static MCInstPrinter *createARMMCInstPrinter(const Target &T, diff --git a/lib/Target/ARM/MCTargetDesc/CMakeLists.txt b/lib/Target/ARM/MCTargetDesc/CMakeLists.txt index 2565994..860ff4a 100644 --- a/lib/Target/ARM/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/ARM/MCTargetDesc/CMakeLists.txt @@ -1,5 +1,6 @@ add_llvm_library(LLVMARMDesc ARMAsmBackend.cpp + ARMELFStreamer.cpp ARMELFObjectWriter.cpp ARMMCAsmInfo.cpp ARMMCCodeEmitter.cpp diff --git a/test/CodeGen/ARM/2010-11-30-reloc-movt.ll b/test/CodeGen/ARM/2010-11-30-reloc-movt.ll index 8b164c5..410acc9 100644 --- a/test/CodeGen/ARM/2010-11-30-reloc-movt.ll +++ b/test/CodeGen/ARM/2010-11-30-reloc-movt.ll @@ -23,7 +23,7 @@ entry: ; OBJ: Relocation 0 ; OBJ-NEXT: 'r_offset', 0x00000004 -; OBJ-NEXT: 'r_sym', 0x000007 +; OBJ-NEXT: 'r_sym', 0x00000a ; OBJ-NEXT: 'r_type', 0x2b ; OBJ: Relocation 1 @@ -33,7 +33,7 @@ entry: ; OBJ: # Relocation 2 ; OBJ-NEXT: 'r_offset', 0x0000000c -; OBJ-NEXT: 'r_sym', 0x000008 +; OBJ-NEXT: 'r_sym', 0x00000b ; OBJ-NEXT: 'r_type', 0x1c } diff --git a/test/MC/ARM/elf-reloc-01.ll b/test/MC/ARM/elf-reloc-01.ll index c98026b..3ebd7c6 100644 --- a/test/MC/ARM/elf-reloc-01.ll +++ b/test/MC/ARM/elf-reloc-01.ll @@ -62,9 +62,9 @@ declare void @exit(i32) noreturn nounwind ;; OBJ: Relocation 1 ;; OBJ-NEXT: 'r_offset', -;; OBJ-NEXT: 'r_sym', 0x000002 +;; OBJ-NEXT: 'r_sym', 0x000007 ;; OBJ-NEXT: 'r_type', 0x2b -;; OBJ: Symbol 2 +;; OBJ: Symbol 7 ;; OBJ-NEXT: '_MergedGlobals' ;; OBJ-NEXT: 'st_value', 0x00000010 diff --git a/test/MC/ARM/elf-reloc-02.ll b/test/MC/ARM/elf-reloc-02.ll index e51bac3..ffabb85 100644 --- a/test/MC/ARM/elf-reloc-02.ll +++ b/test/MC/ARM/elf-reloc-02.ll @@ -43,8 +43,8 @@ declare void @exit(i32) noreturn nounwind ;; OBJ: Relocation 0 ;; OBJ-NEXT: 'r_offset', -;; OBJ-NEXT: 'r_sym', 0x000002 +;; OBJ-NEXT: 'r_sym', 0x000005 ;; OBJ-NEXT: 'r_type', 0x2b -;; OBJ: Symbol 2 +;; OBJ: Symbol 5 ;; OBJ-NEXT: '.L.str' diff --git a/test/MC/ARM/elf-reloc-03.ll b/test/MC/ARM/elf-reloc-03.ll index 922242f..c0dbfa1 100644 --- a/test/MC/ARM/elf-reloc-03.ll +++ b/test/MC/ARM/elf-reloc-03.ll @@ -90,8 +90,8 @@ declare void @exit(i32) noreturn nounwind ;; OBJ: Relocation 1 ;; OBJ-NEXT: 'r_offset', -;; OBJ-NEXT: 'r_sym', 0x00000c +;; OBJ-NEXT: 'r_sym', 0x00000f ;; OBJ-NEXT: 'r_type', 0x2b -;; OBJ: Symbol 12 +;; OBJ: Symbol 15 ;; OBJ-NEXT: 'vtable' diff --git a/test/MC/ARM/elf-reloc-condcall.s b/test/MC/ARM/elf-reloc-condcall.s index 08b4ecc..219707e 100644 --- a/test/MC/ARM/elf-reloc-condcall.s +++ b/test/MC/ARM/elf-reloc-condcall.s @@ -9,25 +9,25 @@ // OBJ: .rel.text // OBJ: 'r_offset', 0x00000000 -// OBJ-NEXT: 'r_sym', 0x000004 +// OBJ-NEXT: 'r_sym', 0x000007 // OBJ-NEXT: 'r_type', 0x1d // OBJ: 'r_offset', 0x00000004 -// OBJ-NEXT: 'r_sym', 0x000004 +// OBJ-NEXT: 'r_sym', 0x000007 // OBJ-NEXT: 'r_type', 0x1c // OBJ: 'r_offset', 0x00000008 -// OBJ-NEXT: 'r_sym', 0x000004 +// OBJ-NEXT: 'r_sym', 0x000007 // OBJ-NEXT: 'r_type', 0x1c // OBJ: 'r_offset', 0x0000000c -// OBJ-NEXT: 'r_sym', 0x000004 +// OBJ-NEXT: 'r_sym', 0x000007 // OBJ-NEXT: 'r_type', 0x1d // OBJ: 'r_offset', 0x00000010 -// OBJ-NEXT: 'r_sym', 0x000004 +// OBJ-NEXT: 'r_sym', 0x000007 // OBJ-NEXT: 'r_type', 0x1d // OBJ: .symtab -// OBJ: Symbol 4 +// OBJ: Symbol 7 // OBJ-NEXT: some_label diff --git a/test/MC/ARM/elf-thumbfunc-reloc.ll b/test/MC/ARM/elf-thumbfunc-reloc.ll index ecac11d..c547727 100644 --- a/test/MC/ARM/elf-thumbfunc-reloc.ll +++ b/test/MC/ARM/elf-thumbfunc-reloc.ll @@ -28,10 +28,10 @@ entry: ; 00000008 0000070a R_ARM_THM_CALL 00000001 foo ; CHECK: Relocation 0 ; CHECK-NEXT: 'r_offset', 0x00000008 -; CHECK-NEXT: 'r_sym', 0x000007 +; CHECK-NEXT: 'r_sym', 0x00000a ; CHECK-NEXT: 'r_type', 0x0a ; make sure foo is thumb function: bit 0 = 1 -; CHECK: Symbol 7 +; CHECK: Symbol 10 ; CHECK-NEXT: 'foo' ; CHECK-NEXT: 'st_value', 0x00000001 diff --git a/test/MC/ARM/elf-thumbfunc.s b/test/MC/ARM/elf-thumbfunc.s index 0aa7f41..bb97b5d 100644 --- a/test/MC/ARM/elf-thumbfunc.s +++ b/test/MC/ARM/elf-thumbfunc.s @@ -12,8 +12,8 @@ foo: bx lr @@ make sure foo is thumb function: bit 0 = 1 (st_value) -@CHECK: Symbol 4 -@CHECK-NEXT: 'st_name', 0x00000001 +@CHECK: Symbol 7 +@CHECK-NEXT: 'st_name', 0x00000010 @CHECK-NEXT: 'st_value', 0x00000001 @CHECK-NEXT: 'st_size', 0x00000000 @CHECK-NEXT: 'st_bind', 0x1 -- 1.7.8.3