aboutsummaryrefslogtreecommitdiffstats
path: root/lib/MC
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2012-03-05 14:40:54 -0800
committerStephen Hines <srhines@google.com>2012-03-05 14:40:54 -0800
commitc02a5c5e8d9c1fd2a20ad4aed40f328564e95b40 (patch)
tree9a892d465bc8a229322b6c296c346250a95ecd6c /lib/MC
parent2987cbcdaef9e14f635b6f9ac32c58ff26a2fc0f (diff)
parentc3384c93c0e4c50da4ad093f08997507f9281c75 (diff)
downloadexternal_llvm-c02a5c5e8d9c1fd2a20ad4aed40f328564e95b40.zip
external_llvm-c02a5c5e8d9c1fd2a20ad4aed40f328564e95b40.tar.gz
external_llvm-c02a5c5e8d9c1fd2a20ad4aed40f328564e95b40.tar.bz2
Merge branch 'upstream' into merge-20120305
Conflicts: lib/Support/Atomic.cpp Change-Id: I563b3bc2a82942ccbae5bed42e53b9149a8bf3a0
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/CMakeLists.txt1
-rw-r--r--lib/MC/ELFObjectWriter.cpp1021
-rw-r--r--lib/MC/ELFObjectWriter.h460
-rw-r--r--lib/MC/MCAsmBackend.cpp6
-rw-r--r--lib/MC/MCAsmInfo.cpp1
-rw-r--r--lib/MC/MCAsmInfoCOFF.cpp6
-rw-r--r--lib/MC/MCAsmInfoDarwin.cpp2
-rw-r--r--lib/MC/MCAsmStreamer.cpp69
-rw-r--r--lib/MC/MCAssembler.cpp47
-rw-r--r--lib/MC/MCContext.cpp23
-rw-r--r--lib/MC/MCDisassembler/Disassembler.cpp18
-rw-r--r--lib/MC/MCDisassembler/EDDisassembler.cpp78
-rw-r--r--lib/MC/MCDisassembler/EDDisassembler.h13
-rw-r--r--lib/MC/MCDisassembler/EDMain.cpp2
-rw-r--r--lib/MC/MCDisassembler/EDOperand.cpp20
-rw-r--r--lib/MC/MCDwarf.cpp171
-rw-r--r--lib/MC/MCELFObjectTargetWriter.cpp21
-rw-r--r--lib/MC/MCELFStreamer.cpp141
-rw-r--r--lib/MC/MCELFStreamer.h141
-rw-r--r--lib/MC/MCExpr.cpp41
-rw-r--r--lib/MC/MCInst.cpp2
-rw-r--r--lib/MC/MCInstPrinter.cpp3
-rw-r--r--lib/MC/MCLoggingStreamer.cpp252
-rw-r--r--lib/MC/MCMachOStreamer.cpp25
-rw-r--r--lib/MC/MCNullStreamer.cpp11
-rw-r--r--lib/MC/MCObjectFileInfo.cpp43
-rw-r--r--lib/MC/MCObjectStreamer.cpp32
-rw-r--r--lib/MC/MCObjectWriter.cpp2
-rw-r--r--lib/MC/MCParser/AsmParser.cpp132
-rw-r--r--lib/MC/MCParser/COFFAsmParser.cpp17
-rw-r--r--lib/MC/MCPureStreamer.cpp12
-rw-r--r--lib/MC/MCStreamer.cpp72
-rw-r--r--lib/MC/MachObjectWriter.cpp6
-rw-r--r--lib/MC/WinCOFFObjectWriter.cpp55
-rw-r--r--lib/MC/WinCOFFStreamer.cpp19
35 files changed, 1120 insertions, 1845 deletions
diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt
index b2e62a5..f11e686 100644
--- a/lib/MC/CMakeLists.txt
+++ b/lib/MC/CMakeLists.txt
@@ -20,7 +20,6 @@ add_llvm_library(LLVMMC
MCInstPrinter.cpp
MCInstrAnalysis.cpp
MCLabel.cpp
- MCLoggingStreamer.cpp
MCMachOStreamer.cpp
MCMachObjectTargetWriter.cpp
MCModule.cpp
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 92aad94..36f94b4 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -11,13 +11,19 @@
//
//===----------------------------------------------------------------------===//
-#include "ELFObjectWriter.h"
+#include "MCELF.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmLayout.h"
+#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCELFObjectWriter.h"
+#include "llvm/MC/MCELFSymbolFlags.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCValue.h"
@@ -25,20 +31,338 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringSwitch.h"
-#include "../Target/Mips/MCTargetDesc/MipsFixupKinds.h"
-#include "../Target/X86/MCTargetDesc/X86FixupKinds.h"
-#include "../Target/ARM/MCTargetDesc/ARMFixupKinds.h"
-#include "../Target/PowerPC/MCTargetDesc/PPCFixupKinds.h"
-
#include <vector>
using namespace llvm;
#undef DEBUG_TYPE
#define DEBUG_TYPE "reloc-info"
+namespace {
+class ELFObjectWriter : public MCObjectWriter {
+ protected:
+
+ static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
+ static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant);
+ static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout);
+ static bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data,
+ bool Used, bool Renamed);
+ static bool isLocal(const MCSymbolData &Data, bool isSignature,
+ bool isUsedInReloc);
+ static bool IsELFMetaDataSection(const MCSectionData &SD);
+ static uint64_t DataSectionSize(const MCSectionData &SD);
+ static uint64_t GetSectionFileSize(const MCAsmLayout &Layout,
+ const MCSectionData &SD);
+ static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout,
+ const MCSectionData &SD);
+
+ void WriteDataSectionData(MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCSectionELF &Section);
+
+ /*static bool isFixupKindX86RIPRel(unsigned Kind) {
+ return Kind == X86::reloc_riprel_4byte ||
+ Kind == X86::reloc_riprel_4byte_movq_load;
+ }*/
+
+ /// ELFSymbolData - Helper struct for containing some precomputed
+ /// information on symbols.
+ struct ELFSymbolData {
+ MCSymbolData *SymbolData;
+ uint64_t StringIndex;
+ uint32_t SectionIndex;
+
+ // Support lexicographic sorting.
+ bool operator<(const ELFSymbolData &RHS) const {
+ if (MCELF::GetType(*SymbolData) == ELF::STT_FILE)
+ return true;
+ if (MCELF::GetType(*RHS.SymbolData) == ELF::STT_FILE)
+ return false;
+ return SymbolData->getSymbol().getName() <
+ RHS.SymbolData->getSymbol().getName();
+ }
+ };
+
+ /// @name Relocation Data
+ /// @{
+
+ struct ELFRelocationEntry {
+ // Make these big enough for both 32-bit and 64-bit
+ uint64_t r_offset;
+ int Index;
+ unsigned Type;
+ const MCSymbol *Symbol;
+ uint64_t r_addend;
+
+ ELFRelocationEntry()
+ : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0) {}
+
+ ELFRelocationEntry(uint64_t RelocOffset, int Idx,
+ unsigned RelType, const MCSymbol *Sym,
+ uint64_t Addend)
+ : r_offset(RelocOffset), Index(Idx), Type(RelType),
+ Symbol(Sym), r_addend(Addend) {}
+
+ // Support lexicographic sorting.
+ bool operator<(const ELFRelocationEntry &RE) const {
+ return RE.r_offset < r_offset;
+ }
+ };
+
+ /// The target specific ELF writer instance.
+ llvm::OwningPtr<MCELFObjectTargetWriter> TargetObjectWriter;
+
+ SmallPtrSet<const MCSymbol *, 16> UsedInReloc;
+ SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc;
+ DenseMap<const MCSymbol *, const MCSymbol *> Renames;
+
+ llvm::DenseMap<const MCSectionData*,
+ std::vector<ELFRelocationEntry> > Relocations;
+ DenseMap<const MCSection*, uint64_t> SectionStringTableIndex;
+
+ /// @}
+ /// @name Symbol Table Data
+ /// @{
+
+ SmallString<256> StringTable;
+ std::vector<ELFSymbolData> LocalSymbolData;
+ std::vector<ELFSymbolData> ExternalSymbolData;
+ std::vector<ELFSymbolData> UndefinedSymbolData;
+
+ /// @}
+
+ bool NeedsGOT;
+
+ bool NeedsSymtabShndx;
+
+ // This holds the symbol table index of the last local symbol.
+ unsigned LastLocalSymbolIndex;
+ // This holds the .strtab section index.
+ unsigned StringTableIndex;
+ // This holds the .symtab section index.
+ unsigned SymbolTableIndex;
+
+ unsigned ShstrtabIndex;
+
+
+ const MCSymbol *SymbolToReloc(const MCAssembler &Asm,
+ const MCValue &Target,
+ const MCFragment &F,
+ const MCFixup &Fixup,
+ bool IsPCRel) const;
+
+ // TargetObjectWriter wrappers.
+ const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
+ const MCValue &Target,
+ const MCFragment &F,
+ const MCFixup &Fixup,
+ bool IsPCRel) const {
+ return TargetObjectWriter->ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
+ }
+
+ bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
+ bool hasRelocationAddend() const {
+ return TargetObjectWriter->hasRelocationAddend();
+ }
+ unsigned getEFlags() const {
+ return TargetObjectWriter->getEFlags();
+ }
+ unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
+ bool IsPCRel, bool IsRelocWithSymbol,
+ int64_t Addend) const {
+ return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel,
+ IsRelocWithSymbol, Addend);
+ }
+
+
+ public:
+ ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
+ raw_ostream &_OS, bool IsLittleEndian)
+ : MCObjectWriter(_OS, IsLittleEndian),
+ TargetObjectWriter(MOTW),
+ NeedsGOT(false), NeedsSymtabShndx(false){
+ }
+
+ virtual ~ELFObjectWriter();
+
+ void WriteWord(uint64_t W) {
+ if (is64Bit())
+ Write64(W);
+ else
+ Write32(W);
+ }
+
+ void StringLE16(char *buf, uint16_t Value) {
+ buf[0] = char(Value >> 0);
+ buf[1] = char(Value >> 8);
+ }
+
+ void StringLE32(char *buf, uint32_t Value) {
+ StringLE16(buf, uint16_t(Value >> 0));
+ StringLE16(buf + 2, uint16_t(Value >> 16));
+ }
+
+ void StringLE64(char *buf, uint64_t Value) {
+ StringLE32(buf, uint32_t(Value >> 0));
+ StringLE32(buf + 4, uint32_t(Value >> 32));
+ }
+
+ void StringBE16(char *buf ,uint16_t Value) {
+ buf[0] = char(Value >> 8);
+ buf[1] = char(Value >> 0);
+ }
+
+ void StringBE32(char *buf, uint32_t Value) {
+ StringBE16(buf, uint16_t(Value >> 16));
+ StringBE16(buf + 2, uint16_t(Value >> 0));
+ }
+
+ void StringBE64(char *buf, uint64_t Value) {
+ StringBE32(buf, uint32_t(Value >> 32));
+ StringBE32(buf + 4, uint32_t(Value >> 0));
+ }
+
+ void String8(MCDataFragment &F, uint8_t Value) {
+ char buf[1];
+ buf[0] = Value;
+ F.getContents() += StringRef(buf, 1);
+ }
+
+ void String16(MCDataFragment &F, uint16_t Value) {
+ char buf[2];
+ if (isLittleEndian())
+ StringLE16(buf, Value);
+ else
+ StringBE16(buf, Value);
+ F.getContents() += StringRef(buf, 2);
+ }
+
+ void String32(MCDataFragment &F, uint32_t Value) {
+ char buf[4];
+ if (isLittleEndian())
+ StringLE32(buf, Value);
+ else
+ StringBE32(buf, Value);
+ F.getContents() += StringRef(buf, 4);
+ }
+
+ void String64(MCDataFragment &F, uint64_t Value) {
+ char buf[8];
+ if (isLittleEndian())
+ StringLE64(buf, Value);
+ else
+ StringBE64(buf, Value);
+ F.getContents() += StringRef(buf, 8);
+ }
+
+ void WriteHeader(uint64_t SectionDataSize,
+ unsigned NumberOfSections);
+
+ void WriteSymbolEntry(MCDataFragment *SymtabF,
+ MCDataFragment *ShndxF,
+ uint64_t name, uint8_t info,
+ uint64_t value, uint64_t size,
+ uint8_t other, uint32_t shndx,
+ bool Reserved);
+
+ void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF,
+ ELFSymbolData &MSD,
+ const MCAsmLayout &Layout);
+
+ typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy;
+ void WriteSymbolTable(MCDataFragment *SymtabF,
+ MCDataFragment *ShndxF,
+ const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const SectionIndexMapTy &SectionIndexMap);
+
+ virtual void RecordRelocation(const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup,
+ MCValue Target, uint64_t &FixedValue);
+
+ uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm,
+ const MCSymbol *S);
+
+ // Map from a group section to the signature symbol
+ typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy;
+ // Map from a signature symbol to the group section
+ typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy;
+ // Map from a section to the section with the relocations
+ typedef DenseMap<const MCSectionELF*, const MCSectionELF*> RelMapTy;
+ // Map from a section to its offset
+ typedef DenseMap<const MCSectionELF*, uint64_t> SectionOffsetMapTy;
+
+ /// ComputeSymbolTable - Compute the symbol table data
+ ///
+ /// \param StringTable [out] - The string table data.
+ /// \param StringIndexMap [out] - Map from symbol names to offsets in the
+ /// string table.
+ void ComputeSymbolTable(MCAssembler &Asm,
+ const SectionIndexMapTy &SectionIndexMap,
+ RevGroupMapTy RevGroupMap,
+ unsigned NumRegularSections);
+
+ void ComputeIndexMap(MCAssembler &Asm,
+ SectionIndexMapTy &SectionIndexMap,
+ const RelMapTy &RelMap);
+
+ void CreateRelocationSections(MCAssembler &Asm, MCAsmLayout &Layout,
+ RelMapTy &RelMap);
+
+ void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
+ const RelMapTy &RelMap);
+
+ void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout,
+ SectionIndexMapTy &SectionIndexMap,
+ const RelMapTy &RelMap);
+
+ // Create the sections that show up in the symbol table. Currently
+ // those are the .note.GNU-stack section and the group sections.
+ void CreateIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout,
+ GroupMapTy &GroupMap,
+ RevGroupMapTy &RevGroupMap,
+ SectionIndexMapTy &SectionIndexMap,
+ const RelMapTy &RelMap);
+
+ virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout);
+
+ void WriteSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap,
+ const MCAsmLayout &Layout,
+ const SectionIndexMapTy &SectionIndexMap,
+ const SectionOffsetMapTy &SectionOffsetMap);
+
+ void ComputeSectionOrder(MCAssembler &Asm,
+ std::vector<const MCSectionELF*> &Sections);
+
+ void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
+ uint64_t Address, uint64_t Offset,
+ uint64_t Size, uint32_t Link, uint32_t Info,
+ uint64_t Alignment, uint64_t EntrySize);
+
+ void WriteRelocationsFragment(const MCAssembler &Asm,
+ MCDataFragment *F,
+ const MCSectionData *SD);
+
+ virtual bool
+ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const;
+
+ virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
+ void WriteSection(MCAssembler &Asm,
+ const SectionIndexMapTy &SectionIndexMap,
+ uint32_t GroupSymbolIndex,
+ uint64_t Offset, uint64_t Size, uint64_t Alignment,
+ const MCSectionELF &Section);
+ };
+}
+
bool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
const MCFixupKindInfo &FKI =
Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);
@@ -93,11 +417,7 @@ void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION]
// e_ident[EI_OSABI]
- switch (TargetObjectWriter->getOSType()) {
- case Triple::FreeBSD: Write8(ELF::ELFOSABI_FREEBSD); break;
- case Triple::Linux: Write8(ELF::ELFOSABI_LINUX); break;
- default: Write8(ELF::ELFOSABI_NONE); break;
- }
+ Write8(TargetObjectWriter->getOSABI());
Write8(0); // e_ident[EI_ABIVERSION]
WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD);
@@ -113,7 +433,7 @@ void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
sizeof(ELF::Elf32_Ehdr))); // e_shoff = sec hdr table off in bytes
// e_flags = whatever the target wants
- WriteEFlags();
+ Write32(getEFlags());
// e_ehsize = ELF header size
Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
@@ -447,11 +767,16 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
FixedValue = Value;
unsigned Type = GetRelocType(Target, Fixup, IsPCRel,
(RelocSymbol != 0), Addend);
+ MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
+ MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
+ if (RelocNeedsGOT(Modifier))
+ NeedsGOT = true;
uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
Fixup.getOffset();
- adjustFixupOffset(Fixup, RelocOffset);
+ // FIXME: no tests cover this. Is adjustFixupOffset dead code?
+ TargetObjectWriter->adjustFixupOffset(Fixup, RelocOffset);
if (!hasRelocationAddend())
Addend = 0;
@@ -1055,14 +1380,10 @@ uint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout,
void ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCSectionELF &Section) {
- uint64_t FileOff = OS.tell();
const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
- uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment());
+ uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment());
WriteZeros(Padding);
- FileOff += Padding;
-
- FileOff += GetSectionFileSize(Layout, SD);
if (IsELFMetaDataSection(SD)) {
for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
@@ -1228,16 +1549,13 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
for (unsigned i = 0; i < NumRegularSections + 1; ++i)
WriteDataSectionData(Asm, Layout, *Sections[i]);
- FileOff = OS.tell();
- uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment);
+ uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment);
WriteZeros(Padding);
// ... then the section header table ...
WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap,
SectionOffsetMap);
- FileOff = OS.tell();
-
// ... and then the remaining sections ...
for (unsigned i = NumRegularSections + 1; i < NumSections; ++i)
WriteDataSectionData(Asm, Layout, *Sections[i]);
@@ -1258,660 +1576,5 @@ ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
raw_ostream &OS,
bool IsLittleEndian) {
- switch (MOTW->getEMachine()) {
- case ELF::EM_386:
- case ELF::EM_X86_64:
- return new X86ELFObjectWriter(MOTW, OS, IsLittleEndian); break;
- case ELF::EM_ARM:
- return new ARMELFObjectWriter(MOTW, OS, IsLittleEndian); break;
- case ELF::EM_MBLAZE:
- return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break;
- case ELF::EM_PPC:
- case ELF::EM_PPC64:
- return new PPCELFObjectWriter(MOTW, OS, IsLittleEndian); break;
- case ELF::EM_MIPS:
- return new MipsELFObjectWriter(MOTW, OS, IsLittleEndian); break;
- default: llvm_unreachable("Unsupported architecture"); break;
- }
-}
-
-/// START OF SUBCLASSES for ELFObjectWriter
-//===- ARMELFObjectWriter -------------------------------------------===//
-
-ARMELFObjectWriter::ARMELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &_OS,
- bool IsLittleEndian)
- : ELFObjectWriter(MOTW, _OS, IsLittleEndian)
-{}
-
-ARMELFObjectWriter::~ARMELFObjectWriter()
-{}
-
-// FIXME: get the real EABI Version from the Triple.
-void ARMELFObjectWriter::WriteEFlags() {
- Write32(ELF::EF_ARM_EABIMASK & DefaultEABIVersion);
-}
-
-// In ARM, _MergedGlobals and other most symbols get emitted directly.
-// I.e. not as an offset to a section symbol.
-// This code is an approximation of what ARM/gcc does.
-
-STATISTIC(PCRelCount, "Total number of PIC Relocations");
-STATISTIC(NonPCRelCount, "Total number of non-PIC relocations");
-
-const MCSymbol *ARMELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
- const MCValue &Target,
- const MCFragment &F,
- const MCFixup &Fixup,
- bool IsPCRel) const {
- const MCSymbol &Symbol = Target.getSymA()->getSymbol();
- bool EmitThisSym = false;
-
- const MCSectionELF &Section =
- static_cast<const MCSectionELF&>(Symbol.getSection());
- bool InNormalSection = true;
- unsigned RelocType = 0;
- RelocType = GetRelocTypeInner(Target, Fixup, IsPCRel);
-
- DEBUG(
- const MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();
- MCSymbolRefExpr::VariantKind Kind2;
- Kind2 = Target.getSymB() ? Target.getSymB()->getKind() :
- MCSymbolRefExpr::VK_None;
- dbgs() << "considering symbol "
- << Section.getSectionName() << "/"
- << Symbol.getName() << "/"
- << " Rel:" << (unsigned)RelocType
- << " Kind: " << (int)Kind << "/" << (int)Kind2
- << " Tmp:"
- << Symbol.isAbsolute() << "/" << Symbol.isDefined() << "/"
- << Symbol.isVariable() << "/" << Symbol.isTemporary()
- << " Counts:" << PCRelCount << "/" << NonPCRelCount << "\n");
-
- if (IsPCRel) { ++PCRelCount;
- switch (RelocType) {
- default:
- // Most relocation types are emitted as explicit symbols
- InNormalSection =
- StringSwitch<bool>(Section.getSectionName())
- .Case(".data.rel.ro.local", false)
- .Case(".data.rel", false)
- .Case(".bss", false)
- .Default(true);
- EmitThisSym = true;
- break;
- case ELF::R_ARM_ABS32:
- // But things get strange with R_ARM_ABS32
- // In this case, most things that go in .rodata show up
- // as section relative relocations
- InNormalSection =
- StringSwitch<bool>(Section.getSectionName())
- .Case(".data.rel.ro.local", false)
- .Case(".data.rel", false)
- .Case(".rodata", false)
- .Case(".bss", false)
- .Default(true);
- EmitThisSym = false;
- break;
- }
- } else {
- NonPCRelCount++;
- InNormalSection =
- StringSwitch<bool>(Section.getSectionName())
- .Case(".data.rel.ro.local", false)
- .Case(".rodata", false)
- .Case(".data.rel", false)
- .Case(".bss", false)
- .Default(true);
-
- switch (RelocType) {
- default: EmitThisSym = true; break;
- case ELF::R_ARM_ABS32: EmitThisSym = false; break;
- }
- }
-
- if (EmitThisSym)
- return &Symbol;
- if (! Symbol.isTemporary() && InNormalSection) {
- return &Symbol;
- }
- return NULL;
-}
-
-// Need to examine the Fixup when determining whether to
-// emit the relocation as an explicit symbol or as a section relative
-// offset
-unsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,
- const MCFixup &Fixup,
- bool IsPCRel,
- bool IsRelocWithSymbol,
- int64_t Addend) {
- MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
- MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
-
- unsigned Type = GetRelocTypeInner(Target, Fixup, IsPCRel);
-
- if (RelocNeedsGOT(Modifier))
- NeedsGOT = true;
-
- return Type;
-}
-
-unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
- const MCFixup &Fixup,
- bool IsPCRel) const {
- MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
- MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
-
- unsigned Type = 0;
- if (IsPCRel) {
- switch ((unsigned)Fixup.getKind()) {
- default: assert(0 && "Unimplemented");
- case FK_Data_4:
- switch (Modifier) {
- default: llvm_unreachable("Unsupported Modifier");
- case MCSymbolRefExpr::VK_None:
- Type = ELF::R_ARM_REL32;
- break;
- case MCSymbolRefExpr::VK_ARM_TLSGD:
- assert(0 && "unimplemented");
- break;
- case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
- Type = ELF::R_ARM_TLS_IE32;
- break;
- }
- break;
- case ARM::fixup_arm_uncondbranch:
- switch (Modifier) {
- case MCSymbolRefExpr::VK_ARM_PLT:
- Type = ELF::R_ARM_PLT32;
- break;
- default:
- Type = ELF::R_ARM_CALL;
- break;
- }
- break;
- case ARM::fixup_arm_condbranch:
- Type = ELF::R_ARM_JUMP24;
- break;
- case ARM::fixup_arm_movt_hi16:
- case ARM::fixup_arm_movt_hi16_pcrel:
- Type = ELF::R_ARM_MOVT_PREL;
- break;
- case ARM::fixup_arm_movw_lo16:
- case ARM::fixup_arm_movw_lo16_pcrel:
- Type = ELF::R_ARM_MOVW_PREL_NC;
- break;
- case ARM::fixup_t2_movt_hi16:
- case ARM::fixup_t2_movt_hi16_pcrel:
- Type = ELF::R_ARM_THM_MOVT_PREL;
- break;
- case ARM::fixup_t2_movw_lo16:
- case ARM::fixup_t2_movw_lo16_pcrel:
- Type = ELF::R_ARM_THM_MOVW_PREL_NC;
- break;
- case ARM::fixup_arm_thumb_bl:
- case ARM::fixup_arm_thumb_blx:
- switch (Modifier) {
- case MCSymbolRefExpr::VK_ARM_PLT:
- Type = ELF::R_ARM_THM_CALL;
- break;
- default:
- Type = ELF::R_ARM_NONE;
- break;
- }
- break;
- }
- } else {
- switch ((unsigned)Fixup.getKind()) {
- default: llvm_unreachable("invalid fixup kind!");
- case FK_Data_4:
- switch (Modifier) {
- default: llvm_unreachable("Unsupported Modifier"); break;
- case MCSymbolRefExpr::VK_ARM_GOT:
- Type = ELF::R_ARM_GOT_BREL;
- break;
- case MCSymbolRefExpr::VK_ARM_TLSGD:
- Type = ELF::R_ARM_TLS_GD32;
- break;
- case MCSymbolRefExpr::VK_ARM_TPOFF:
- Type = ELF::R_ARM_TLS_LE32;
- break;
- case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
- Type = ELF::R_ARM_TLS_IE32;
- break;
- case MCSymbolRefExpr::VK_None:
- Type = ELF::R_ARM_ABS32;
- break;
- case MCSymbolRefExpr::VK_ARM_GOTOFF:
- Type = ELF::R_ARM_GOTOFF32;
- break;
- }
- break;
- case ARM::fixup_arm_ldst_pcrel_12:
- case ARM::fixup_arm_pcrel_10:
- case ARM::fixup_arm_adr_pcrel_12:
- case ARM::fixup_arm_thumb_bl:
- case ARM::fixup_arm_thumb_cb:
- case ARM::fixup_arm_thumb_cp:
- case ARM::fixup_arm_thumb_br:
- assert(0 && "Unimplemented");
- break;
- case ARM::fixup_arm_uncondbranch:
- Type = ELF::R_ARM_CALL;
- break;
- case ARM::fixup_arm_condbranch:
- Type = ELF::R_ARM_JUMP24;
- break;
- case ARM::fixup_arm_movt_hi16:
- Type = ELF::R_ARM_MOVT_ABS;
- break;
- case ARM::fixup_arm_movw_lo16:
- Type = ELF::R_ARM_MOVW_ABS_NC;
- break;
- case ARM::fixup_t2_movt_hi16:
- Type = ELF::R_ARM_THM_MOVT_ABS;
- break;
- case ARM::fixup_t2_movw_lo16:
- Type = ELF::R_ARM_THM_MOVW_ABS_NC;
- break;
- }
- }
-
- return Type;
-}
-
-//===- PPCELFObjectWriter -------------------------------------------===//
-
-PPCELFObjectWriter::PPCELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &_OS,
- bool IsLittleEndian)
- : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {
-}
-
-PPCELFObjectWriter::~PPCELFObjectWriter() {
-}
-
-unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target,
- const MCFixup &Fixup,
- bool IsPCRel,
- bool IsRelocWithSymbol,
- int64_t Addend) {
- // determine the type of the relocation
- unsigned Type;
- if (IsPCRel) {
- switch ((unsigned)Fixup.getKind()) {
- default:
- llvm_unreachable("Unimplemented");
- case PPC::fixup_ppc_br24:
- Type = ELF::R_PPC_REL24;
- break;
- case FK_PCRel_4:
- Type = ELF::R_PPC_REL32;
- break;
- }
- } else {
- switch ((unsigned)Fixup.getKind()) {
- default: llvm_unreachable("invalid fixup kind!");
- case PPC::fixup_ppc_br24:
- Type = ELF::R_PPC_ADDR24;
- break;
- case PPC::fixup_ppc_brcond14:
- Type = ELF::R_PPC_ADDR14_BRTAKEN; // XXX: or BRNTAKEN?_
- break;
- case PPC::fixup_ppc_ha16:
- Type = ELF::R_PPC_ADDR16_HA;
- break;
- case PPC::fixup_ppc_lo16:
- Type = ELF::R_PPC_ADDR16_LO;
- break;
- case PPC::fixup_ppc_lo14:
- Type = ELF::R_PPC_ADDR14;
- break;
- case FK_Data_4:
- Type = ELF::R_PPC_ADDR32;
- break;
- case FK_Data_2:
- Type = ELF::R_PPC_ADDR16;
- break;
- }
- }
- return Type;
-}
-
-void PPCELFObjectWriter::
-adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset) {
- switch ((unsigned)Fixup.getKind()) {
- case PPC::fixup_ppc_ha16:
- case PPC::fixup_ppc_lo16:
- RelocOffset += 2;
- break;
- default:
- break;
- }
-}
-
-//===- MBlazeELFObjectWriter -------------------------------------------===//
-
-MBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &_OS,
- bool IsLittleEndian)
- : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {
-}
-
-MBlazeELFObjectWriter::~MBlazeELFObjectWriter() {
-}
-
-unsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target,
- const MCFixup &Fixup,
- bool IsPCRel,
- bool IsRelocWithSymbol,
- int64_t Addend) {
- // determine the type of the relocation
- unsigned Type;
- if (IsPCRel) {
- switch ((unsigned)Fixup.getKind()) {
- default:
- llvm_unreachable("Unimplemented");
- case FK_PCRel_4:
- Type = ELF::R_MICROBLAZE_64_PCREL;
- break;
- case FK_PCRel_2:
- Type = ELF::R_MICROBLAZE_32_PCREL;
- break;
- }
- } else {
- switch ((unsigned)Fixup.getKind()) {
- default: llvm_unreachable("invalid fixup kind!");
- case FK_Data_4:
- Type = ((IsRelocWithSymbol || Addend !=0)
- ? ELF::R_MICROBLAZE_32
- : ELF::R_MICROBLAZE_64);
- break;
- case FK_Data_2:
- Type = ELF::R_MICROBLAZE_32;
- break;
- }
- }
- return Type;
-}
-
-//===- X86ELFObjectWriter -------------------------------------------===//
-
-
-X86ELFObjectWriter::X86ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &_OS,
- bool IsLittleEndian)
- : ELFObjectWriter(MOTW, _OS, IsLittleEndian)
-{}
-
-X86ELFObjectWriter::~X86ELFObjectWriter()
-{}
-
-unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
- const MCFixup &Fixup,
- bool IsPCRel,
- bool IsRelocWithSymbol,
- int64_t Addend) {
- // determine the type of the relocation
-
- MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
- MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
- unsigned Type;
- if (is64Bit()) {
- if (IsPCRel) {
- switch ((unsigned)Fixup.getKind()) {
- default: llvm_unreachable("invalid fixup kind!");
-
- case FK_Data_8: Type = ELF::R_X86_64_PC64; break;
- case FK_Data_4: Type = ELF::R_X86_64_PC32; break;
- case FK_Data_2: Type = ELF::R_X86_64_PC16; break;
-
- case FK_PCRel_8:
- assert(Modifier == MCSymbolRefExpr::VK_None);
- Type = ELF::R_X86_64_PC64;
- break;
- case X86::reloc_signed_4byte:
- case X86::reloc_riprel_4byte_movq_load:
- case X86::reloc_riprel_4byte:
- case FK_PCRel_4:
- switch (Modifier) {
- default:
- llvm_unreachable("Unimplemented");
- case MCSymbolRefExpr::VK_None:
- Type = ELF::R_X86_64_PC32;
- break;
- case MCSymbolRefExpr::VK_PLT:
- Type = ELF::R_X86_64_PLT32;
- break;
- case MCSymbolRefExpr::VK_GOTPCREL:
- Type = ELF::R_X86_64_GOTPCREL;
- break;
- case MCSymbolRefExpr::VK_GOTTPOFF:
- Type = ELF::R_X86_64_GOTTPOFF;
- break;
- case MCSymbolRefExpr::VK_TLSGD:
- Type = ELF::R_X86_64_TLSGD;
- break;
- case MCSymbolRefExpr::VK_TLSLD:
- Type = ELF::R_X86_64_TLSLD;
- break;
- }
- break;
- case FK_PCRel_2:
- assert(Modifier == MCSymbolRefExpr::VK_None);
- Type = ELF::R_X86_64_PC16;
- break;
- case FK_PCRel_1:
- assert(Modifier == MCSymbolRefExpr::VK_None);
- Type = ELF::R_X86_64_PC8;
- break;
- }
- } else {
- switch ((unsigned)Fixup.getKind()) {
- default: llvm_unreachable("invalid fixup kind!");
- case FK_Data_8: Type = ELF::R_X86_64_64; break;
- case X86::reloc_signed_4byte:
- switch (Modifier) {
- default:
- llvm_unreachable("Unimplemented");
- case MCSymbolRefExpr::VK_None:
- Type = ELF::R_X86_64_32S;
- break;
- case MCSymbolRefExpr::VK_GOT:
- Type = ELF::R_X86_64_GOT32;
- break;
- case MCSymbolRefExpr::VK_GOTPCREL:
- Type = ELF::R_X86_64_GOTPCREL;
- break;
- case MCSymbolRefExpr::VK_TPOFF:
- Type = ELF::R_X86_64_TPOFF32;
- break;
- case MCSymbolRefExpr::VK_DTPOFF:
- Type = ELF::R_X86_64_DTPOFF32;
- break;
- }
- break;
- case FK_Data_4:
- Type = ELF::R_X86_64_32;
- break;
- case FK_Data_2: Type = ELF::R_X86_64_16; break;
- case FK_PCRel_1:
- case FK_Data_1: Type = ELF::R_X86_64_8; break;
- }
- }
- } else {
- if (IsPCRel) {
- switch ((unsigned)Fixup.getKind()) {
- default: llvm_unreachable("invalid fixup kind!");
-
- case X86::reloc_global_offset_table:
- Type = ELF::R_386_GOTPC;
- break;
-
- case X86::reloc_signed_4byte:
- case FK_PCRel_4:
- case FK_Data_4:
- switch (Modifier) {
- default:
- llvm_unreachable("Unimplemented");
- case MCSymbolRefExpr::VK_None:
- Type = ELF::R_386_PC32;
- break;
- case MCSymbolRefExpr::VK_PLT:
- Type = ELF::R_386_PLT32;
- break;
- }
- break;
- }
- } else {
- switch ((unsigned)Fixup.getKind()) {
- default: llvm_unreachable("invalid fixup kind!");
-
- case X86::reloc_global_offset_table:
- Type = ELF::R_386_GOTPC;
- break;
-
- // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
- // instead?
- case X86::reloc_signed_4byte:
- case FK_PCRel_4:
- case FK_Data_4:
- switch (Modifier) {
- default:
- llvm_unreachable("Unimplemented");
- case MCSymbolRefExpr::VK_None:
- Type = ELF::R_386_32;
- break;
- case MCSymbolRefExpr::VK_GOT:
- Type = ELF::R_386_GOT32;
- break;
- case MCSymbolRefExpr::VK_GOTOFF:
- Type = ELF::R_386_GOTOFF;
- break;
- case MCSymbolRefExpr::VK_TLSGD:
- Type = ELF::R_386_TLS_GD;
- break;
- case MCSymbolRefExpr::VK_TPOFF:
- Type = ELF::R_386_TLS_LE_32;
- break;
- case MCSymbolRefExpr::VK_INDNTPOFF:
- Type = ELF::R_386_TLS_IE;
- break;
- case MCSymbolRefExpr::VK_NTPOFF:
- Type = ELF::R_386_TLS_LE;
- break;
- case MCSymbolRefExpr::VK_GOTNTPOFF:
- Type = ELF::R_386_TLS_GOTIE;
- break;
- case MCSymbolRefExpr::VK_TLSLDM:
- Type = ELF::R_386_TLS_LDM;
- break;
- case MCSymbolRefExpr::VK_DTPOFF:
- Type = ELF::R_386_TLS_LDO_32;
- break;
- case MCSymbolRefExpr::VK_GOTTPOFF:
- Type = ELF::R_386_TLS_IE_32;
- break;
- }
- break;
- case FK_Data_2: Type = ELF::R_386_16; break;
- case FK_PCRel_1:
- case FK_Data_1: Type = ELF::R_386_8; break;
- }
- }
- }
-
- if (RelocNeedsGOT(Modifier))
- NeedsGOT = true;
-
- return Type;
-}
-
-//===- MipsELFObjectWriter -------------------------------------------===//
-
-MipsELFObjectWriter::MipsELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &_OS,
- bool IsLittleEndian)
- : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {}
-
-MipsELFObjectWriter::~MipsELFObjectWriter() {}
-
-// FIXME: get the real EABI Version from the Triple.
-void MipsELFObjectWriter::WriteEFlags() {
- Write32(ELF::EF_MIPS_NOREORDER |
- ELF::EF_MIPS_ARCH_32R2);
-}
-
-const MCSymbol *MipsELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
- const MCValue &Target,
- const MCFragment &F,
- const MCFixup &Fixup,
- bool IsPCRel) const {
- assert(Target.getSymA() && "SymA cannot be 0.");
- const MCSymbol &Sym = Target.getSymA()->getSymbol();
-
- if (Sym.getSection().getKind().isMergeableCString() ||
- Sym.getSection().getKind().isMergeableConst())
- return &Sym;
-
- return NULL;
-}
-
-unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
- const MCFixup &Fixup,
- bool IsPCRel,
- bool IsRelocWithSymbol,
- int64_t Addend) {
- // determine the type of the relocation
- unsigned Type = (unsigned)ELF::R_MIPS_NONE;
- unsigned Kind = (unsigned)Fixup.getKind();
-
- switch (Kind) {
- default:
- llvm_unreachable("invalid fixup kind!");
- case FK_Data_4:
- Type = ELF::R_MIPS_32;
- break;
- case FK_GPRel_4:
- Type = ELF::R_MIPS_GPREL32;
- break;
- case Mips::fixup_Mips_GPREL16:
- Type = ELF::R_MIPS_GPREL16;
- break;
- case Mips::fixup_Mips_26:
- Type = ELF::R_MIPS_26;
- break;
- case Mips::fixup_Mips_CALL16:
- Type = ELF::R_MIPS_CALL16;
- break;
- case Mips::fixup_Mips_GOT_Global:
- case Mips::fixup_Mips_GOT_Local:
- Type = ELF::R_MIPS_GOT16;
- break;
- case Mips::fixup_Mips_HI16:
- Type = ELF::R_MIPS_HI16;
- break;
- case Mips::fixup_Mips_LO16:
- Type = ELF::R_MIPS_LO16;
- break;
- case Mips::fixup_Mips_TLSGD:
- Type = ELF::R_MIPS_TLS_GD;
- break;
- case Mips::fixup_Mips_GOTTPREL:
- Type = ELF::R_MIPS_TLS_GOTTPREL;
- break;
- case Mips::fixup_Mips_TPREL_HI:
- Type = ELF::R_MIPS_TLS_TPREL_HI16;
- break;
- case Mips::fixup_Mips_TPREL_LO:
- Type = ELF::R_MIPS_TLS_TPREL_LO16;
- break;
- case Mips::fixup_Mips_Branch_PCRel:
- case Mips::fixup_Mips_PC16:
- Type = ELF::R_MIPS_PC16;
- break;
- }
-
- return Type;
+ return new ELFObjectWriter(MOTW, OS, IsLittleEndian);
}
diff --git a/lib/MC/ELFObjectWriter.h b/lib/MC/ELFObjectWriter.h
deleted file mode 100644
index 9adf0b1..0000000
--- a/lib/MC/ELFObjectWriter.h
+++ /dev/null
@@ -1,460 +0,0 @@
-//===- lib/MC/ELFObjectWriter.h - ELF File Writer -------------------------===//
-//
-// 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 object file writer information.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_MC_ELFOBJECTWRITER_H
-#define LLVM_MC_ELFOBJECTWRITER_H
-
-#include "MCELF.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/MC/MCAssembler.h"
-#include "llvm/MC/MCELFObjectWriter.h"
-#include "llvm/MC/MCELFSymbolFlags.h"
-#include "llvm/MC/MCObjectWriter.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCSymbol.h"
-
-#include <vector>
-
-namespace llvm {
-
-class MCSection;
-class MCDataFragment;
-class MCSectionELF;
-
-class ELFObjectWriter : public MCObjectWriter {
- protected:
-
- static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
- static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant);
- static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout);
- static bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data,
- bool Used, bool Renamed);
- static bool isLocal(const MCSymbolData &Data, bool isSignature,
- bool isUsedInReloc);
- static bool IsELFMetaDataSection(const MCSectionData &SD);
- static uint64_t DataSectionSize(const MCSectionData &SD);
- static uint64_t GetSectionFileSize(const MCAsmLayout &Layout,
- const MCSectionData &SD);
- static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout,
- const MCSectionData &SD);
-
- void WriteDataSectionData(MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCSectionELF &Section);
-
- /*static bool isFixupKindX86RIPRel(unsigned Kind) {
- return Kind == X86::reloc_riprel_4byte ||
- Kind == X86::reloc_riprel_4byte_movq_load;
- }*/
-
- /// ELFSymbolData - Helper struct for containing some precomputed
- /// information on symbols.
- struct ELFSymbolData {
- MCSymbolData *SymbolData;
- uint64_t StringIndex;
- uint32_t SectionIndex;
-
- // Support lexicographic sorting.
- bool operator<(const ELFSymbolData &RHS) const {
- if (MCELF::GetType(*SymbolData) == ELF::STT_FILE)
- return true;
- if (MCELF::GetType(*RHS.SymbolData) == ELF::STT_FILE)
- return false;
- return SymbolData->getSymbol().getName() <
- RHS.SymbolData->getSymbol().getName();
- }
- };
-
- /// @name Relocation Data
- /// @{
-
- struct ELFRelocationEntry {
- // Make these big enough for both 32-bit and 64-bit
- uint64_t r_offset;
- int Index;
- unsigned Type;
- const MCSymbol *Symbol;
- uint64_t r_addend;
-
- ELFRelocationEntry()
- : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0) {}
-
- ELFRelocationEntry(uint64_t RelocOffset, int Idx,
- unsigned RelType, const MCSymbol *Sym,
- uint64_t Addend)
- : r_offset(RelocOffset), Index(Idx), Type(RelType),
- Symbol(Sym), r_addend(Addend) {}
-
- // Support lexicographic sorting.
- bool operator<(const ELFRelocationEntry &RE) const {
- return RE.r_offset < r_offset;
- }
- };
-
- /// The target specific ELF writer instance.
- llvm::OwningPtr<MCELFObjectTargetWriter> TargetObjectWriter;
-
- SmallPtrSet<const MCSymbol *, 16> UsedInReloc;
- SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc;
- DenseMap<const MCSymbol *, const MCSymbol *> Renames;
-
- llvm::DenseMap<const MCSectionData*,
- std::vector<ELFRelocationEntry> > Relocations;
- DenseMap<const MCSection*, uint64_t> SectionStringTableIndex;
-
- /// @}
- /// @name Symbol Table Data
- /// @{
-
- SmallString<256> StringTable;
- std::vector<ELFSymbolData> LocalSymbolData;
- std::vector<ELFSymbolData> ExternalSymbolData;
- std::vector<ELFSymbolData> UndefinedSymbolData;
-
- /// @}
-
- bool NeedsGOT;
-
- bool NeedsSymtabShndx;
-
- // This holds the symbol table index of the last local symbol.
- unsigned LastLocalSymbolIndex;
- // This holds the .strtab section index.
- unsigned StringTableIndex;
- // This holds the .symtab section index.
- unsigned SymbolTableIndex;
-
- unsigned ShstrtabIndex;
-
-
- virtual const MCSymbol *SymbolToReloc(const MCAssembler &Asm,
- const MCValue &Target,
- const MCFragment &F,
- const MCFixup &Fixup,
- bool IsPCRel) const;
-
- // For arch-specific emission of explicit reloc symbol
- virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
- const MCValue &Target,
- const MCFragment &F,
- const MCFixup &Fixup,
- bool IsPCRel) const {
- return NULL;
- }
-
- bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
- bool hasRelocationAddend() const {
- return TargetObjectWriter->hasRelocationAddend();
- }
-
- public:
- ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &_OS, bool IsLittleEndian)
- : MCObjectWriter(_OS, IsLittleEndian),
- TargetObjectWriter(MOTW),
- NeedsGOT(false), NeedsSymtabShndx(false){
- }
-
- virtual ~ELFObjectWriter();
-
- void WriteWord(uint64_t W) {
- if (is64Bit())
- Write64(W);
- else
- Write32(W);
- }
-
- void StringLE16(char *buf, uint16_t Value) {
- buf[0] = char(Value >> 0);
- buf[1] = char(Value >> 8);
- }
-
- void StringLE32(char *buf, uint32_t Value) {
- StringLE16(buf, uint16_t(Value >> 0));
- StringLE16(buf + 2, uint16_t(Value >> 16));
- }
-
- void StringLE64(char *buf, uint64_t Value) {
- StringLE32(buf, uint32_t(Value >> 0));
- StringLE32(buf + 4, uint32_t(Value >> 32));
- }
-
- void StringBE16(char *buf ,uint16_t Value) {
- buf[0] = char(Value >> 8);
- buf[1] = char(Value >> 0);
- }
-
- void StringBE32(char *buf, uint32_t Value) {
- StringBE16(buf, uint16_t(Value >> 16));
- StringBE16(buf + 2, uint16_t(Value >> 0));
- }
-
- void StringBE64(char *buf, uint64_t Value) {
- StringBE32(buf, uint32_t(Value >> 32));
- StringBE32(buf + 4, uint32_t(Value >> 0));
- }
-
- void String8(MCDataFragment &F, uint8_t Value) {
- char buf[1];
- buf[0] = Value;
- F.getContents() += StringRef(buf, 1);
- }
-
- void String16(MCDataFragment &F, uint16_t Value) {
- char buf[2];
- if (isLittleEndian())
- StringLE16(buf, Value);
- else
- StringBE16(buf, Value);
- F.getContents() += StringRef(buf, 2);
- }
-
- void String32(MCDataFragment &F, uint32_t Value) {
- char buf[4];
- if (isLittleEndian())
- StringLE32(buf, Value);
- else
- StringBE32(buf, Value);
- F.getContents() += StringRef(buf, 4);
- }
-
- void String64(MCDataFragment &F, uint64_t Value) {
- char buf[8];
- if (isLittleEndian())
- StringLE64(buf, Value);
- else
- StringBE64(buf, Value);
- F.getContents() += StringRef(buf, 8);
- }
-
- virtual void WriteHeader(uint64_t SectionDataSize,
- unsigned NumberOfSections);
-
- /// Default e_flags = 0
- virtual void WriteEFlags() { Write32(0); }
-
- virtual void WriteSymbolEntry(MCDataFragment *SymtabF,
- MCDataFragment *ShndxF,
- uint64_t name, uint8_t info,
- uint64_t value, uint64_t size,
- uint8_t other, uint32_t shndx,
- bool Reserved);
-
- virtual void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF,
- ELFSymbolData &MSD,
- const MCAsmLayout &Layout);
-
- typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy;
- virtual void WriteSymbolTable(MCDataFragment *SymtabF,
- MCDataFragment *ShndxF,
- const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const SectionIndexMapTy &SectionIndexMap);
-
- virtual void RecordRelocation(const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCFragment *Fragment,
- const MCFixup &Fixup,
- MCValue Target, uint64_t &FixedValue);
-
- virtual uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm,
- const MCSymbol *S);
-
- // Map from a group section to the signature symbol
- typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy;
- // Map from a signature symbol to the group section
- typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy;
- // Map from a section to the section with the relocations
- typedef DenseMap<const MCSectionELF*, const MCSectionELF*> RelMapTy;
- // Map from a section to its offset
- typedef DenseMap<const MCSectionELF*, uint64_t> SectionOffsetMapTy;
-
- /// ComputeSymbolTable - Compute the symbol table data
- ///
- /// \param StringTable [out] - The string table data.
- /// \param StringIndexMap [out] - Map from symbol names to offsets in the
- /// string table.
- virtual void ComputeSymbolTable(MCAssembler &Asm,
- const SectionIndexMapTy &SectionIndexMap,
- RevGroupMapTy RevGroupMap,
- unsigned NumRegularSections);
-
- virtual void ComputeIndexMap(MCAssembler &Asm,
- SectionIndexMapTy &SectionIndexMap,
- const RelMapTy &RelMap);
-
- void CreateRelocationSections(MCAssembler &Asm, MCAsmLayout &Layout,
- RelMapTy &RelMap);
-
- void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
- const RelMapTy &RelMap);
-
- virtual void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout,
- SectionIndexMapTy &SectionIndexMap,
- const RelMapTy &RelMap);
-
- // Create the sections that show up in the symbol table. Currently
- // those are the .note.GNU-stack section and the group sections.
- virtual void CreateIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout,
- GroupMapTy &GroupMap,
- RevGroupMapTy &RevGroupMap,
- SectionIndexMapTy &SectionIndexMap,
- const RelMapTy &RelMap);
-
- virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
- const MCAsmLayout &Layout);
-
- void WriteSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap,
- const MCAsmLayout &Layout,
- const SectionIndexMapTy &SectionIndexMap,
- const SectionOffsetMapTy &SectionOffsetMap);
-
- void ComputeSectionOrder(MCAssembler &Asm,
- std::vector<const MCSectionELF*> &Sections);
-
- virtual void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
- uint64_t Address, uint64_t Offset,
- uint64_t Size, uint32_t Link, uint32_t Info,
- uint64_t Alignment, uint64_t EntrySize);
-
- virtual void WriteRelocationsFragment(const MCAssembler &Asm,
- MCDataFragment *F,
- const MCSectionData *SD);
-
- virtual bool
- IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
- const MCSymbolData &DataA,
- const MCFragment &FB,
- bool InSet,
- bool IsPCRel) const;
-
- virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
- virtual void WriteSection(MCAssembler &Asm,
- const SectionIndexMapTy &SectionIndexMap,
- uint32_t GroupSymbolIndex,
- uint64_t Offset, uint64_t Size, uint64_t Alignment,
- const MCSectionELF &Section);
-
- protected:
- virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsPCRel, bool IsRelocWithSymbol,
- int64_t Addend) = 0;
- virtual void adjustFixupOffset(const MCFixup &Fixup,
- uint64_t &RelocOffset) {}
- };
-
- //===- X86ELFObjectWriter -------------------------------------------===//
-
- class X86ELFObjectWriter : public ELFObjectWriter {
- public:
- X86ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &_OS,
- bool IsLittleEndian);
-
- virtual ~X86ELFObjectWriter();
- protected:
- virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsPCRel, bool IsRelocWithSymbol,
- int64_t Addend);
- };
-
-
- //===- ARMELFObjectWriter -------------------------------------------===//
-
- class ARMELFObjectWriter : public ELFObjectWriter {
- public:
- // FIXME: MCAssembler can't yet return the Subtarget,
- enum { DefaultEABIVersion = 0x05000000U };
-
- ARMELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &_OS,
- bool IsLittleEndian);
-
- virtual ~ARMELFObjectWriter();
-
- virtual void WriteEFlags();
- protected:
- virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
- const MCValue &Target,
- const MCFragment &F,
- const MCFixup &Fixup,
- bool IsPCRel) const;
-
- virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsPCRel, bool IsRelocWithSymbol,
- int64_t Addend);
- private:
- unsigned GetRelocTypeInner(const MCValue &Target,
- const MCFixup &Fixup, bool IsPCRel) const;
-
- };
-
- //===- PPCELFObjectWriter -------------------------------------------===//
-
- class PPCELFObjectWriter : public ELFObjectWriter {
- public:
- PPCELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &_OS,
- bool IsLittleEndian);
-
- virtual ~PPCELFObjectWriter();
- protected:
- virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsPCRel, bool IsRelocWithSymbol,
- int64_t Addend);
- virtual void adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset);
- };
-
- //===- MBlazeELFObjectWriter -------------------------------------------===//
-
- class MBlazeELFObjectWriter : public ELFObjectWriter {
- public:
- MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &_OS,
- bool IsLittleEndian);
-
- virtual ~MBlazeELFObjectWriter();
- protected:
- virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsPCRel, bool IsRelocWithSymbol,
- int64_t Addend);
- };
-
- //===- MipsELFObjectWriter -------------------------------------------===//
-
- class MipsELFObjectWriter : public ELFObjectWriter {
- public:
- MipsELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &_OS,
- bool IsLittleEndian);
-
- virtual ~MipsELFObjectWriter();
- virtual void WriteEFlags();
-
- protected:
- virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
- const MCValue &Target,
- const MCFragment &F,
- const MCFixup &Fixup,
- bool IsPCRel) const;
-
- virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsPCRel, bool IsRelocWithSymbol,
- int64_t Addend);
- };
-}
-
-#endif
diff --git a/lib/MC/MCAsmBackend.cpp b/lib/MC/MCAsmBackend.cpp
index 936ed55..51c3977 100644
--- a/lib/MC/MCAsmBackend.cpp
+++ b/lib/MC/MCAsmBackend.cpp
@@ -32,7 +32,11 @@ MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{ "FK_GPRel_1", 0, 8, 0 },
{ "FK_GPRel_2", 0, 16, 0 },
{ "FK_GPRel_4", 0, 32, 0 },
- { "FK_GPRel_8", 0, 64, 0 }
+ { "FK_GPRel_8", 0, 64, 0 },
+ { "FK_SecRel_1", 0, 8, 0 },
+ { "FK_SecRel_2", 0, 16, 0 },
+ { "FK_SecRel_4", 0, 32, 0 },
+ { "FK_SecRel_8", 0, 64, 0 }
};
assert((size_t)Kind <= sizeof(Builtins) / sizeof(Builtins[0]) &&
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp
index b1e1bdf..582d21f 100644
--- a/lib/MC/MCAsmInfo.cpp
+++ b/lib/MC/MCAsmInfo.cpp
@@ -67,6 +67,7 @@ MCAsmInfo::MCAsmInfo() {
AlignDirective = "\t.align\t";
AlignmentIsInBytes = true;
TextAlignFillValue = 0;
+ GPRel64Directive = 0;
GPRel32Directive = 0;
GlobalDirective = "\t.globl\t";
HasSetDirective = true;
diff --git a/lib/MC/MCAsmInfoCOFF.cpp b/lib/MC/MCAsmInfoCOFF.cpp
index 6d34801..767ac29 100644
--- a/lib/MC/MCAsmInfoCOFF.cpp
+++ b/lib/MC/MCAsmInfoCOFF.cpp
@@ -16,6 +16,8 @@
#include "llvm/ADT/SmallVector.h"
using namespace llvm;
+void MCAsmInfoCOFF::anchor() { }
+
MCAsmInfoCOFF::MCAsmInfoCOFF() {
GlobalPrefix = "_";
COMMDirectiveAlignmentIsInBytes = false;
@@ -39,10 +41,14 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() {
SupportsDataRegions = false;
}
+void MCAsmInfoMicrosoft::anchor() { }
+
MCAsmInfoMicrosoft::MCAsmInfoMicrosoft() {
AllowQuotesInName = true;
}
+void MCAsmInfoGNUCOFF::anchor() { }
+
MCAsmInfoGNUCOFF::MCAsmInfoGNUCOFF() {
}
diff --git a/lib/MC/MCAsmInfoDarwin.cpp b/lib/MC/MCAsmInfoDarwin.cpp
index 24f1243..c1e2635 100644
--- a/lib/MC/MCAsmInfoDarwin.cpp
+++ b/lib/MC/MCAsmInfoDarwin.cpp
@@ -18,6 +18,8 @@
#include "llvm/MC/MCStreamer.h"
using namespace llvm;
+void MCAsmInfoDarwin::anchor() { }
+
MCAsmInfoDarwin::MCAsmInfoDarwin() {
// Common settings for all Darwin targets.
// Syntax:
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index c785c03..11f0f72 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -61,6 +61,8 @@ private:
bool needsSet(const MCExpr *Value);
void EmitRegisterName(int64_t Register);
+ virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
+ virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame);
public:
MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
@@ -154,6 +156,7 @@ public:
virtual void EmitCOFFSymbolStorageClass(int StorageClass);
virtual void EmitCOFFSymbolType(int Type);
virtual void EndCOFFSymbolDef();
+ virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment);
@@ -183,6 +186,8 @@ public:
virtual void EmitSLEB128Value(const MCExpr *Value);
+ virtual void EmitGPRel64Value(const MCExpr *Value);
+
virtual void EmitGPRel32Value(const MCExpr *Value);
@@ -196,7 +201,7 @@ public:
virtual void EmitCodeAlignment(unsigned ByteAlignment,
unsigned MaxBytesToEmit = 0);
- virtual void EmitValueToOffset(const MCExpr *Offset,
+ virtual bool EmitValueToOffset(const MCExpr *Offset,
unsigned char Value = 0);
virtual void EmitFileDirective(StringRef Filename);
@@ -208,8 +213,6 @@ public:
StringRef FileName);
virtual void EmitCFISections(bool EH, bool Debug);
- virtual void EmitCFIStartProc();
- virtual void EmitCFIEndProc();
virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
virtual void EmitCFIDefCfaOffset(int64_t Offset);
virtual void EmitCFIDefCfaRegister(int64_t Register);
@@ -221,6 +224,7 @@ public:
virtual void EmitCFISameValue(int64_t Register);
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
+ virtual void EmitCFISignalFrame();
virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
virtual void EmitWin64EHEndProc();
@@ -254,7 +258,7 @@ public:
/// indicated by the hasRawTextSupport() predicate.
virtual void EmitRawText(StringRef String);
- virtual void Finish();
+ virtual void FinishImpl();
/// @}
};
@@ -339,7 +343,6 @@ void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
switch (Flag) {
- default: assert(0 && "Invalid flag!");
case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
case MCAF_Code16: OS << '\t'<< MAI.getCode16Directive(); break;
@@ -391,7 +394,7 @@ void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
MCSymbolAttr Attribute) {
switch (Attribute) {
- case MCSA_Invalid: assert(0 && "Invalid symbol attribute");
+ case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
@@ -403,7 +406,7 @@ void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
OS << "\t.type\t" << *Symbol << ','
<< ((MAI.getCommentString()[0] != '@') ? '@' : '%');
switch (Attribute) {
- default: assert(0 && "Unknown ELF .type");
+ default: llvm_unreachable("Unknown ELF .type");
case MCSA_ELF_TypeFunction: OS << "function"; break;
case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
case MCSA_ELF_TypeObject: OS << "object"; break;
@@ -470,6 +473,11 @@ void MCAsmStreamer::EndCOFFSymbolDef() {
EmitEOL();
}
+void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
+ OS << "\t.secrel32\t" << *Symbol << '\n';
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
assert(MAI.hasDotTypeDotSizeDirective());
OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
@@ -657,6 +665,12 @@ void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
EmitEOL();
}
+void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
+ assert(MAI.getGPRel64Directive() != 0);
+ OS << MAI.getGPRel64Directive() << *Value;
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
assert(MAI.getGPRel32Directive() != 0);
OS << MAI.getGPRel32Directive() << *Value;
@@ -738,11 +752,12 @@ void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
1, MaxBytesToEmit);
}
-void MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
+bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
unsigned char Value) {
// FIXME: Verify that Offset is associated with the current section.
OS << ".org " << *Offset << ", " << (unsigned) Value;
EmitEOL();
+ return false;
}
@@ -835,21 +850,25 @@ void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
EmitEOL();
}
-void MCAsmStreamer::EmitCFIStartProc() {
- MCStreamer::EmitCFIStartProc();
-
- if (!UseCFI)
+void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
+ if (!UseCFI) {
+ RecordProcStart(Frame);
return;
+ }
OS << "\t.cfi_startproc";
EmitEOL();
}
-void MCAsmStreamer::EmitCFIEndProc() {
- MCStreamer::EmitCFIEndProc();
-
- if (!UseCFI)
+void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
+ if (!UseCFI) {
+ RecordProcEnd(Frame);
return;
+ }
+
+ // Put a dummy non-null value in Frame.End to mark that this frame has been
+ // closed.
+ Frame.End = (MCSymbol *) 1;
OS << "\t.cfi_endproc";
EmitEOL();
@@ -984,6 +1003,16 @@ void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
EmitEOL();
}
+void MCAsmStreamer::EmitCFISignalFrame() {
+ MCStreamer::EmitCFISignalFrame();
+
+ if (!UseCFI)
+ return;
+
+ OS << "\t.cif_signal_frame";
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
MCStreamer::EmitWin64EHStartProc(Symbol);
@@ -1279,14 +1308,16 @@ void MCAsmStreamer::EmitRawText(StringRef String) {
EmitEOL();
}
-void MCAsmStreamer::Finish() {
+void MCAsmStreamer::FinishImpl() {
+ // FIXME: This header is duplicated with MCObjectStreamer
// Dump out the dwarf file & directory tables and line tables.
+ const MCSymbol *LineSectionSymbol = NULL;
if (getContext().hasDwarfFiles() && !UseLoc)
- MCDwarfFileTable::Emit(this);
+ LineSectionSymbol = MCDwarfFileTable::Emit(this);
// If we are generating dwarf for assembly source files dump out the sections.
if (getContext().getGenDwarfForAssembly())
- MCGenDwarfInfo::Emit(this);
+ MCGenDwarfInfo::Emit(this, LineSectionSymbol);
if (!UseCFI)
EmitFrames(false);
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index c5bf6b9..a2aaf4e 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -243,7 +243,7 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
++stats::evaluateFixup;
if (!Fixup.getValue()->EvaluateAsRelocatable(Target, Layout))
- report_fatal_error("expected relocatable expression");
+ getContext().FatalError(Fixup.getLoc(), "expected relocatable expression");
bool IsPCRel = Backend.getFixupKindInfo(
Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel;
@@ -273,13 +273,10 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
Value = Target.getConstant();
- bool IsThumb = false;
if (const MCSymbolRefExpr *A = Target.getSymA()) {
const MCSymbol &Sym = A->getSymbol().AliasedSymbol();
if (Sym.isDefined())
Value += Layout.getSymbolOffset(&getSymbolData(Sym));
- if (isThumbFunc(&Sym))
- IsThumb = true;
}
if (const MCSymbolRefExpr *B = Target.getSymB()) {
const MCSymbol &Sym = B->getSymbol().AliasedSymbol();
@@ -302,12 +299,10 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
Value -= Offset;
}
- // ARM fixups based from a thumb function address need to have the low
- // bit set. The actual value is always at least 16-bit aligned, so the
- // low bit is normally clear and available for use as an ISA flag for
- // interworking.
- if (IsThumb)
- Value |= 1;
+ // Let the backend adjust the fixup value if necessary, including whether
+ // we need a relocation.
+ Backend.processFixupValue(*this, Layout, Fixup, DF, Target, Value,
+ IsResolved);
return IsResolved;
}
@@ -355,8 +350,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
return cast<MCDwarfCallFrameFragment>(F).getContents().size();
}
- assert(0 && "invalid fragment kind");
- return 0;
+ llvm_unreachable("invalid fragment kind");
}
void MCAsmLayout::LayoutFragment(MCFragment *F) {
@@ -412,7 +406,7 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
// bytes left to fill use the the Value and ValueSize to fill the rest.
// If we are aligning with nops, ask that target to emit the right data.
if (AF.hasEmitNops()) {
- if (!Asm.getBackend().WriteNopData(Count, OW))
+ if (!Asm.getBackend().writeNopData(Count, OW))
report_fatal_error("unable to write nop sequence of " +
Twine(Count) + " bytes");
break;
@@ -421,8 +415,7 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
// Otherwise, write out in multiples of the value size.
for (uint64_t i = 0; i != Count; ++i) {
switch (AF.getValueSize()) {
- default:
- assert(0 && "Invalid size!");
+ default: llvm_unreachable("Invalid size!");
case 1: OW->Write8 (uint8_t (AF.getValue())); break;
case 2: OW->Write16(uint16_t(AF.getValue())); break;
case 4: OW->Write32(uint32_t(AF.getValue())); break;
@@ -446,8 +439,7 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
for (uint64_t i = 0, e = FF.getSize() / FF.getValueSize(); i != e; ++i) {
switch (FF.getValueSize()) {
- default:
- assert(0 && "Invalid size!");
+ default: llvm_unreachable("Invalid size!");
case 1: OW->Write8 (uint8_t (FF.getValue())); break;
case 2: OW->Write16(uint16_t(FF.getValue())); break;
case 4: OW->Write32(uint32_t(FF.getValue())); break;
@@ -503,8 +495,7 @@ void MCAssembler::writeSectionData(const MCSectionData *SD,
for (MCSectionData::const_iterator it = SD->begin(),
ie = SD->end(); it != ie; ++it) {
switch (it->getKind()) {
- default:
- assert(0 && "Invalid fragment in virtual section!");
+ default: llvm_unreachable("Invalid fragment in virtual section!");
case MCFragment::FT_Data: {
// Check that we aren't trying to write a non-zero contents (or fixups)
// into a virtual section. This is to support clients which use standard
@@ -622,7 +613,7 @@ void MCAssembler::Finish() {
ie3 = DF->fixup_end(); it3 != ie3; ++it3) {
MCFixup &Fixup = *it3;
uint64_t FixedValue = handleFixup(Layout, *DF, Fixup);
- getBackend().ApplyFixup(Fixup, DF->getContents().data(),
+ getBackend().applyFixup(Fixup, DF->getContents().data(),
DF->getContents().size(), FixedValue);
}
}
@@ -632,7 +623,7 @@ void MCAssembler::Finish() {
ie3 = IF->fixup_end(); it3 != ie3; ++it3) {
MCFixup &Fixup = *it3;
uint64_t FixedValue = handleFixup(Layout, *IF, Fixup);
- getBackend().ApplyFixup(Fixup, IF->getCode().data(),
+ getBackend().applyFixup(Fixup, IF->getCode().data(),
IF->getCode().size(), FixedValue);
}
}
@@ -665,7 +656,7 @@ bool MCAssembler::fragmentNeedsRelaxation(const MCInstFragment *IF,
// If this inst doesn't ever need relaxation, ignore it. This occurs when we
// are intentionally pushing out inst fragments, or because we relaxed a
// previous instruction to one that doesn't need relaxation.
- if (!getBackend().MayNeedRelaxation(IF->getInst()))
+ if (!getBackend().mayNeedRelaxation(IF->getInst()))
return false;
for (MCInstFragment::const_fixup_iterator it = IF->fixup_begin(),
@@ -689,7 +680,7 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout,
// Relax the fragment.
MCInst Relaxed;
- getBackend().RelaxInstruction(IF.getInst(), Relaxed);
+ getBackend().relaxInstruction(IF.getInst(), Relaxed);
// Encode the new instruction.
//
@@ -972,3 +963,13 @@ void MCAssembler::dump() {
}
OS << "]>\n";
}
+
+// anchors for MC*Fragment vtables
+void MCDataFragment::anchor() { }
+void MCInstFragment::anchor() { }
+void MCAlignFragment::anchor() { }
+void MCFillFragment::anchor() { }
+void MCOrgFragment::anchor() { }
+void MCLEBFragment::anchor() { }
+void MCDwarfLineAddrFragment::anchor() { }
+void MCDwarfCallFrameFragment::anchor() { }
diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp
index a1a01e3..d3c4fb1 100644
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -20,6 +20,9 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ELF.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/Signals.h"
using namespace llvm;
typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
@@ -28,8 +31,8 @@ typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
MCContext::MCContext(const MCAsmInfo &mai, const MCRegisterInfo &mri,
- const MCObjectFileInfo *mofi) :
- MAI(mai), MRI(mri), MOFI(mofi),
+ const MCObjectFileInfo *mofi, const SourceMgr *mgr) :
+ SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi),
Allocator(), Symbols(Allocator), UsedNames(Allocator),
NextUniqueID(0),
CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0),
@@ -321,3 +324,19 @@ bool MCContext::isValidDwarfFileNumber(unsigned FileNumber) {
return MCDwarfFiles[FileNumber] != 0;
}
+
+void MCContext::FatalError(SMLoc Loc, const Twine &Msg) {
+ // If we have a source manager and a location, use it. Otherwise just
+ // use the generic report_fatal_error().
+ if (!SrcMgr || Loc == SMLoc())
+ report_fatal_error(Msg);
+
+ // Use the source manager to print the message.
+ SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
+
+ // If we reached here, we are failing ungracefully. Run the interrupt handlers
+ // to make sure any special cleanups get done, in particular that we remove
+ // files registered with RemoveFileOnSignal.
+ sys::RunInterruptHandlers();
+ exit(1);
+}
diff --git a/lib/MC/MCDisassembler/Disassembler.cpp b/lib/MC/MCDisassembler/Disassembler.cpp
index f156760..572a5a5 100644
--- a/lib/MC/MCDisassembler/Disassembler.cpp
+++ b/lib/MC/MCDisassembler/Disassembler.cpp
@@ -18,6 +18,8 @@
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/ErrorHandling.h"
namespace llvm {
class Target;
@@ -34,6 +36,18 @@ using namespace llvm;
LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
int TagType, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp) {
+ // Initialize targets and assembly printers/parsers.
+ // FIXME: Clients are responsible for initializing the targets. And this
+ // would be done by calling routines in "llvm-c/Target.h" which are static
+ // line functions. But the current use of LLVMCreateDisasm() is to dynamically
+ // load libLTO with dlopen() and then lookup the symbols using dlsym().
+ // And since these initialize routines are static that does not work which
+ // is why the call to them in this 'C' library API was added back.
+ llvm::InitializeAllTargetInfos();
+ llvm::InitializeAllTargetMCs();
+ llvm::InitializeAllAsmParsers();
+ llvm::InitializeAllDisassemblers();
+
// Get the target.
std::string Error;
const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
@@ -66,7 +80,7 @@ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
// Set up the instruction printer.
int AsmPrinterVariant = MAI->getAssemblerDialect();
MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant,
- *MAI, *STI);
+ *MAI, *MRI, *STI);
assert(IP && "Unable to create instruction printer!");
LLVMDisasmContext *DC = new LLVMDisasmContext(TripleName, DisInfo, TagType,
@@ -163,5 +177,5 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes,
return Size;
}
}
- return 0;
+ llvm_unreachable("Invalid DecodeStatus!");
}
diff --git a/lib/MC/MCDisassembler/EDDisassembler.cpp b/lib/MC/MCDisassembler/EDDisassembler.cpp
index 3540334..4c2dae8 100644
--- a/lib/MC/MCDisassembler/EDDisassembler.cpp
+++ b/lib/MC/MCDisassembler/EDDisassembler.cpp
@@ -47,8 +47,7 @@ static struct TripleMap triplemap[] = {
{ Triple::x86, "i386-unknown-unknown" },
{ Triple::x86_64, "x86_64-unknown-unknown" },
{ Triple::arm, "arm-unknown-unknown" },
- { Triple::thumb, "thumb-unknown-unknown" },
- { Triple::InvalidArch, NULL, }
+ { Triple::thumb, "thumb-unknown-unknown" }
};
/// infoFromArch - Returns the TripleMap corresponding to a given architecture,
@@ -75,76 +74,69 @@ static const char *tripleFromArch(Triple::ArchType arch) {
static int getLLVMSyntaxVariant(Triple::ArchType arch,
EDDisassembler::AssemblySyntax syntax) {
switch (syntax) {
- default:
- return -1;
// Mappings below from X86AsmPrinter.cpp
case EDDisassembler::kEDAssemblySyntaxX86ATT:
if (arch == Triple::x86 || arch == Triple::x86_64)
return 0;
- else
- return -1;
+ break;
case EDDisassembler::kEDAssemblySyntaxX86Intel:
if (arch == Triple::x86 || arch == Triple::x86_64)
return 1;
- else
- return -1;
+ break;
case EDDisassembler::kEDAssemblySyntaxARMUAL:
if (arch == Triple::arm || arch == Triple::thumb)
return 0;
- else
- return -1;
+ break;
}
+
+ return -1;
}
EDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch,
AssemblySyntax syntax) {
+ const char *triple = tripleFromArch(arch);
+ return getDisassembler(StringRef(triple), syntax);
+}
+
+EDDisassembler *EDDisassembler::getDisassembler(StringRef str,
+ AssemblySyntax syntax) {
CPUKey key;
- key.Arch = arch;
+ key.Triple = str.str();
key.Syntax = syntax;
-
+
EDDisassembler::DisassemblerMap_t::iterator i = sDisassemblers.find(key);
-
+
if (i != sDisassemblers.end()) {
- return i->second;
- } else {
- EDDisassembler* sdd = new EDDisassembler(key);
- if (!sdd->valid()) {
- delete sdd;
- return NULL;
- }
-
- sDisassemblers[key] = sdd;
-
- return sdd;
+ return i->second;
}
-
- return NULL;
-}
-EDDisassembler *EDDisassembler::getDisassembler(StringRef str,
- AssemblySyntax syntax) {
- return getDisassembler(Triple(str).getArch(), syntax);
+ EDDisassembler *sdd = new EDDisassembler(key);
+ if (!sdd->valid()) {
+ delete sdd;
+ return NULL;
+ }
+
+ sDisassemblers[key] = sdd;
+
+ return sdd;
}
EDDisassembler::EDDisassembler(CPUKey &key) :
Valid(false),
HasSemantics(false),
ErrorStream(nulls()),
- Key(key) {
- const char *triple = tripleFromArch(key.Arch);
-
- if (!triple)
- return;
+ Key(key),
+ TgtTriple(key.Triple.c_str()) {
- LLVMSyntaxVariant = getLLVMSyntaxVariant(key.Arch, key.Syntax);
+ LLVMSyntaxVariant = getLLVMSyntaxVariant(TgtTriple.getArch(), key.Syntax);
if (LLVMSyntaxVariant < 0)
return;
- std::string tripleString(triple);
+ std::string tripleString(key.Triple);
std::string errorString;
- Tgt = TargetRegistry::lookupTarget(tripleString,
+ Tgt = TargetRegistry::lookupTarget(key.Triple,
errorString);
if (!Tgt)
@@ -176,7 +168,8 @@ EDDisassembler::EDDisassembler(CPUKey &key) :
InstString.reset(new std::string);
InstStream.reset(new raw_string_ostream(*InstString));
- InstPrinter.reset(Tgt->createMCInstPrinter(LLVMSyntaxVariant, *AsmInfo, *STI));
+ InstPrinter.reset(Tgt->createMCInstPrinter(LLVMSyntaxVariant, *AsmInfo,
+ *MRI, *STI));
if (!InstPrinter)
return;
@@ -263,7 +256,7 @@ void EDDisassembler::initMaps(const MCRegisterInfo &registerInfo) {
RegRMap[registerName] = registerIndex;
}
- switch (Key.Arch) {
+ switch (TgtTriple.getArch()) {
default:
break;
case Triple::x86:
@@ -331,7 +324,7 @@ int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands,
const std::string &str) {
int ret = 0;
- switch (Key.Arch) {
+ switch (TgtTriple.getArch()) {
default:
return -1;
case Triple::x86:
@@ -356,8 +349,7 @@ int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands,
context, *streamer,
*AsmInfo));
- StringRef triple = tripleFromArch(Key.Arch);
- OwningPtr<MCSubtargetInfo> STI(Tgt->createMCSubtargetInfo(triple, "", ""));
+ OwningPtr<MCSubtargetInfo> STI(Tgt->createMCSubtargetInfo(Key.Triple.c_str(), "", ""));
OwningPtr<MCTargetAsmParser>
TargetParser(Tgt->createMCAsmParser(*STI, *genericParser));
diff --git a/lib/MC/MCDisassembler/EDDisassembler.h b/lib/MC/MCDisassembler/EDDisassembler.h
index 97c2d1f..e97f11d 100644
--- a/lib/MC/MCDisassembler/EDDisassembler.h
+++ b/lib/MC/MCDisassembler/EDDisassembler.h
@@ -25,6 +25,7 @@
#include <map>
#include <set>
+#include <string>
#include <vector>
namespace llvm {
@@ -74,21 +75,21 @@ struct EDDisassembler {
/// pair
struct CPUKey {
/// The architecture type
- llvm::Triple::ArchType Arch;
+ std::string Triple;
/// The assembly syntax
AssemblySyntax Syntax;
/// operator== - Equality operator
bool operator==(const CPUKey &key) const {
- return (Arch == key.Arch &&
+ return (Triple == key.Triple &&
Syntax == key.Syntax);
}
/// operator< - Less-than operator
bool operator<(const CPUKey &key) const {
- return ((Arch < key.Arch) ||
- ((Arch == key.Arch) && Syntax < (key.Syntax)));
+ return ((Triple < key.Triple) ||
+ ((Triple == key.Triple) && Syntax < (key.Syntax)));
}
};
@@ -126,8 +127,10 @@ struct EDDisassembler {
/// The stream to write errors to
llvm::raw_ostream &ErrorStream;
- /// The architecture/syntax pair for the current architecture
+ /// The triple/syntax pair for the current architecture
CPUKey Key;
+ /// The Triple fur the current architecture
+ Triple TgtTriple;
/// The LLVM target corresponding to the disassembler
const llvm::Target *Tgt;
/// The assembly information for the target architecture
diff --git a/lib/MC/MCDisassembler/EDMain.cpp b/lib/MC/MCDisassembler/EDMain.cpp
index 3fd355b..c658717 100644
--- a/lib/MC/MCDisassembler/EDMain.cpp
+++ b/lib/MC/MCDisassembler/EDMain.cpp
@@ -23,7 +23,7 @@ int EDGetDisassembler(EDDisassemblerRef *disassembler,
EDAssemblySyntax_t syntax) {
EDDisassembler::AssemblySyntax Syntax;
switch (syntax) {
- default: assert(0 && "Unknown assembly syntax!");
+ default: llvm_unreachable("Unknown assembly syntax!");
case kEDAssemblySyntaxX86Intel:
Syntax = EDDisassembler::kEDAssemblySyntaxX86Intel;
break;
diff --git a/lib/MC/MCDisassembler/EDOperand.cpp b/lib/MC/MCDisassembler/EDOperand.cpp
index 6a4e56f..48b3746 100644
--- a/lib/MC/MCDisassembler/EDOperand.cpp
+++ b/lib/MC/MCDisassembler/EDOperand.cpp
@@ -30,8 +30,10 @@ EDOperand::EDOperand(const EDDisassembler &disassembler,
MCOpIndex(mcOpIndex) {
unsigned int numMCOperands = 0;
- if (Disassembler.Key.Arch == Triple::x86 ||
- Disassembler.Key.Arch == Triple::x86_64) {
+ Triple::ArchType arch = Disassembler.TgtTriple.getArch();
+
+ if (arch == Triple::x86 ||
+ arch == Triple::x86_64) {
uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
switch (operandType) {
@@ -54,8 +56,8 @@ EDOperand::EDOperand(const EDDisassembler &disassembler,
break;
}
}
- else if (Disassembler.Key.Arch == Triple::arm ||
- Disassembler.Key.Arch == Triple::thumb) {
+ else if (arch == Triple::arm ||
+ arch == Triple::thumb) {
uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
switch (operandType) {
@@ -126,7 +128,9 @@ int EDOperand::evaluate(uint64_t &result,
void *arg) {
uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
- switch (Disassembler.Key.Arch) {
+ Triple::ArchType arch = Disassembler.TgtTriple.getArch();
+
+ switch (arch) {
default:
return -1;
case Triple::x86:
@@ -168,7 +172,7 @@ int EDOperand::evaluate(uint64_t &result,
unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
- if (segmentReg != 0 && Disassembler.Key.Arch == Triple::x86_64) {
+ if (segmentReg != 0 && arch == Triple::x86_64) {
unsigned fsID = Disassembler.registerIDWithName("FS");
unsigned gsID = Disassembler.registerIDWithName("GS");
@@ -200,7 +204,6 @@ int EDOperand::evaluate(uint64_t &result,
return 0;
}
} // switch (operandType)
- break;
case Triple::arm:
case Triple::thumb:
switch (operandType) {
@@ -236,10 +239,7 @@ int EDOperand::evaluate(uint64_t &result,
return 0;
}
}
- break;
}
-
- return -1;
}
int EDOperand::isRegister() {
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp
index 46ab65f..e16f7ae 100644
--- a/lib/MC/MCDwarf.cpp
+++ b/lib/MC/MCDwarf.cpp
@@ -209,7 +209,7 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS,
//
// This emits the Dwarf file and the line tables.
//
-void MCDwarfFileTable::Emit(MCStreamer *MCOS) {
+const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
MCContext &context = MCOS->getContext();
// Switch to the section where the table will be emitted into.
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
@@ -322,6 +322,8 @@ void MCDwarfFileTable::Emit(MCStreamer *MCOS) {
// This is the end of the section, so set the value of the symbol at the end
// of this section (that was used in a previous expression).
MCOS->EmitLabel(LineEndSym);
+
+ return LineStartSym;
}
/// Utility function to write the encoding to an object writer.
@@ -454,15 +456,14 @@ static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
EmitAbbrev(MCOS, 0, 0);
- // DW_TAG_subprogram DIE abbrev (2).
+ // DW_TAG_label DIE abbrev (2).
MCOS->EmitULEB128IntValue(2);
- MCOS->EmitULEB128IntValue(dwarf::DW_TAG_subprogram);
+ MCOS->EmitULEB128IntValue(dwarf::DW_TAG_label);
MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1);
EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
- EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
EmitAbbrev(MCOS, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag);
EmitAbbrev(MCOS, 0, 0);
@@ -545,8 +546,10 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS) {
// When generating dwarf for assembly source files this emits the data for
// .debug_info section which contains three parts. The header, the compile_unit
-// DIE and a list of subprogram DIEs.
-static void EmitGenDwarfInfo(MCStreamer *MCOS) {
+// DIE and a list of label DIEs.
+static void EmitGenDwarfInfo(MCStreamer *MCOS,
+ const MCSymbol *AbbrevSectionSymbol,
+ const MCSymbol *LineSectionSymbol) {
MCContext &context = MCOS->getContext();
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
@@ -569,7 +572,11 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS) {
// The 4 byte offset to the debug abbrevs from the start of the .debug_abbrev,
// it is at the start of that section so this is zero.
- MCOS->EmitIntValue(0, 4);
+ if (AbbrevSectionSymbol) {
+ MCOS->EmitSymbolValue(AbbrevSectionSymbol, 4);
+ } else {
+ MCOS->EmitIntValue(0, 4);
+ }
const MCAsmInfo &asmInfo = context.getAsmInfo();
int AddrSize = asmInfo.getPointerSize();
@@ -583,7 +590,11 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS) {
// DW_AT_stmt_list, a 4 byte offset from the start of the .debug_line section,
// which is at the start of that section so this is zero.
- MCOS->EmitIntValue(0, 4);
+ if (LineSectionSymbol) {
+ MCOS->EmitSymbolValue(LineSectionSymbol, 4);
+ } else {
+ MCOS->EmitIntValue(0, 4);
+ }
// AT_low_pc, the first address of the default .text section.
const MCExpr *Start = MCSymbolRefExpr::Create(
@@ -630,17 +641,17 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS) {
// draft has no standard code for assembler.
MCOS->EmitIntValue(dwarf::DW_LANG_Mips_Assembler, 2);
- // Third part: the list of subprogram DIEs.
+ // Third part: the list of label DIEs.
- // Loop on saved info for dwarf subprograms and create the DIEs for them.
- const std::vector<const MCGenDwarfSubprogramEntry *> &Entries =
- MCOS->getContext().getMCGenDwarfSubprogramEntries();
- for (std::vector<const MCGenDwarfSubprogramEntry *>::const_iterator it =
+ // Loop on saved info for dwarf labels and create the DIEs for them.
+ const std::vector<const MCGenDwarfLabelEntry *> &Entries =
+ MCOS->getContext().getMCGenDwarfLabelEntries();
+ for (std::vector<const MCGenDwarfLabelEntry *>::const_iterator it =
Entries.begin(), ie = Entries.end(); it != ie;
++it) {
- const MCGenDwarfSubprogramEntry *Entry = *it;
+ const MCGenDwarfLabelEntry *Entry = *it;
- // The DW_TAG_subprogram DIE abbrev (2).
+ // The DW_TAG_label DIE abbrev (2).
MCOS->EmitULEB128IntValue(2);
// AT_name, of the label without any leading underbar.
@@ -658,17 +669,6 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS) {
MCSymbolRefExpr::VK_None, context);
MCOS->EmitAbsValue(AT_low_pc, AddrSize);
- // AT_high_pc, end address which is the next label or end of the section.
- std::vector<const MCGenDwarfSubprogramEntry *>::const_iterator next = it+1;
- if (next != Entries.end()){
- const MCGenDwarfSubprogramEntry *NextEntry = *next;
- const MCExpr *AT_high_pc = MCSymbolRefExpr::Create(NextEntry->getLabel(),
- MCSymbolRefExpr::VK_None, context);
- MCOS->EmitAbsValue(AT_high_pc, AddrSize);
- } else {
- MCOS->EmitAbsValue(End, AddrSize);
- }
-
// DW_AT_prototyped, a one byte flag value of 0 saying we have no prototype.
MCOS->EmitIntValue(0, 1);
@@ -678,12 +678,12 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS) {
// Add the NULL DIE terminating the DW_TAG_unspecified_parameters DIE's.
MCOS->EmitIntValue(0, 1);
}
- // Deallocate the MCGenDwarfSubprogramEntry classes that saved away the info
- // for the dwarf subprograms.
- for (std::vector<const MCGenDwarfSubprogramEntry *>::const_iterator it =
+ // Deallocate the MCGenDwarfLabelEntry classes that saved away the info
+ // for the dwarf labels.
+ for (std::vector<const MCGenDwarfLabelEntry *>::const_iterator it =
Entries.begin(), ie = Entries.end(); it != ie;
++it) {
- const MCGenDwarfSubprogramEntry *Entry = *it;
+ const MCGenDwarfLabelEntry *Entry = *it;
delete Entry;
}
@@ -698,11 +698,20 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS) {
// When generating dwarf for assembly source files this emits the Dwarf
// sections.
//
-void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
+void MCGenDwarfInfo::Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol) {
// Create the dwarf sections in this order (.debug_line already created).
MCContext &context = MCOS->getContext();
+ const MCAsmInfo &AsmInfo = context.getAsmInfo();
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection());
+ MCSymbol *AbbrevSectionSymbol;
+ if (AsmInfo.doesDwarfRequireRelocationForSectionOffset()) {
+ AbbrevSectionSymbol = context.CreateTempSymbol();
+ MCOS->EmitLabel(AbbrevSectionSymbol);
+ } else {
+ AbbrevSectionSymbol = NULL;
+ LineSectionSymbol = NULL;
+ }
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
// If there are no line table entries then do not emit any section contents.
@@ -716,18 +725,18 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
EmitGenDwarfAbbrev(MCOS);
// Output the data for .debug_info section.
- EmitGenDwarfInfo(MCOS);
+ EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol);
}
//
// When generating dwarf for assembly source files this is called when symbol
// for a label is created. If this symbol is not a temporary and is in the
// section that dwarf is being generated for, save the needed info to create
-// a dwarf subprogram.
+// a dwarf label.
//
-void MCGenDwarfSubprogramEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
+void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
SourceMgr &SrcMgr, SMLoc &Loc) {
- // We won't create dwarf subprogram's for temporary symbols or symbols not in
+ // We won't create dwarf labels for temporary symbols or symbols not in
// the default text.
if (Symbol->isTemporary())
return;
@@ -735,17 +744,17 @@ void MCGenDwarfSubprogramEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
if (context.getGenDwarfSection() != MCOS->getCurrentSection())
return;
- // The dwarf subprogram's name does not have the symbol name's leading
+ // The dwarf label's name does not have the symbol name's leading
// underbar if any.
StringRef Name = Symbol->getName();
if (Name.startswith("_"))
Name = Name.substr(1, Name.size()-1);
- // Get the dwarf file number to be used for the dwarf subprogram.
+ // Get the dwarf file number to be used for the dwarf label.
unsigned FileNumber = context.getGenDwarfFileNumber();
// Finding the line number is the expensive part which is why we just don't
- // pass it in as for some symbols we won't create a dwarf subprogram.
+ // pass it in as for some symbols we won't create a dwarf label.
int CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
unsigned LineNumber = SrcMgr.FindLineNumber(Loc, CurBuffer);
@@ -757,9 +766,9 @@ void MCGenDwarfSubprogramEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
MCOS->EmitLabel(Label);
// Create and entry for the info and add it to the other entries.
- MCGenDwarfSubprogramEntry *Entry =
- new MCGenDwarfSubprogramEntry(Name, FileNumber, LineNumber, Label);
- MCOS->getContext().addMCGenDwarfSubprogramEntry(Entry);
+ MCGenDwarfLabelEntry *Entry =
+ new MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label);
+ MCOS->getContext().addMCGenDwarfLabelEntry(Entry);
}
static int getDataAlignmentFactor(MCStreamer &streamer) {
@@ -777,8 +786,7 @@ static unsigned getSizeForEncoding(MCStreamer &streamer,
MCContext &context = streamer.getContext();
unsigned format = symbolEncoding & 0x0f;
switch (format) {
- default:
- assert(0 && "Unknown Encoding");
+ default: llvm_unreachable("Unknown Encoding");
case dwarf::DW_EH_PE_absptr:
case dwarf::DW_EH_PE_signed:
return context.getAsmInfo().getPointerSize();
@@ -852,6 +860,7 @@ namespace {
const MCSymbol *personality,
unsigned personalityEncoding,
const MCSymbol *lsda,
+ bool IsSignalFrame,
unsigned lsdaEncoding);
MCSymbol *EmitFDE(MCStreamer &streamer,
const MCSymbol &cieStart,
@@ -868,28 +877,40 @@ namespace {
static void EmitEncodingByte(MCStreamer &Streamer, unsigned Encoding,
StringRef Prefix) {
if (Streamer.isVerboseAsm()) {
- const char *EncStr = 0;
+ const char *EncStr;
switch (Encoding) {
- default: EncStr = "<unknown encoding>";
- case dwarf::DW_EH_PE_absptr: EncStr = "absptr";
- case dwarf::DW_EH_PE_omit: EncStr = "omit";
- case dwarf::DW_EH_PE_pcrel: EncStr = "pcrel";
- case dwarf::DW_EH_PE_udata4: EncStr = "udata4";
- case dwarf::DW_EH_PE_udata8: EncStr = "udata8";
- case dwarf::DW_EH_PE_sdata4: EncStr = "sdata4";
- case dwarf::DW_EH_PE_sdata8: EncStr = "sdata8";
- case dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata4: EncStr = "pcrel udata4";
- case dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata4: EncStr = "pcrel sdata4";
- case dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata8: EncStr = "pcrel udata8";
- case dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata8: EncStr = "pcrel sdata8";
+ default: EncStr = "<unknown encoding>"; break;
+ case dwarf::DW_EH_PE_absptr: EncStr = "absptr"; break;
+ case dwarf::DW_EH_PE_omit: EncStr = "omit"; break;
+ case dwarf::DW_EH_PE_pcrel: EncStr = "pcrel"; break;
+ case dwarf::DW_EH_PE_udata4: EncStr = "udata4"; break;
+ case dwarf::DW_EH_PE_udata8: EncStr = "udata8"; break;
+ case dwarf::DW_EH_PE_sdata4: EncStr = "sdata4"; break;
+ case dwarf::DW_EH_PE_sdata8: EncStr = "sdata8"; break;
+ case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
+ EncStr = "pcrel udata4";
+ break;
+ case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
+ EncStr = "pcrel sdata4";
+ break;
+ case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
+ EncStr = "pcrel udata8";
+ break;
+ case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
+ EncStr = "screl sdata8";
+ break;
case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata4:
EncStr = "indirect pcrel udata4";
+ break;
case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata4:
EncStr = "indirect pcrel sdata4";
+ break;
case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata8:
EncStr = "indirect pcrel udata8";
+ break;
case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata8:
EncStr = "indirect pcrel sdata8";
+ break;
}
Streamer.AddComment(Twine(Prefix) + " = " + EncStr);
@@ -971,11 +992,11 @@ void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer,
}
return;
}
- case MCCFIInstruction::Remember:
+ case MCCFIInstruction::RememberState:
if (VerboseAsm) Streamer.AddComment("DW_CFA_remember_state");
Streamer.EmitIntValue(dwarf::DW_CFA_remember_state, 1);
return;
- case MCCFIInstruction::Restore:
+ case MCCFIInstruction::RestoreState:
if (VerboseAsm) Streamer.AddComment("DW_CFA_restore_state");
Streamer.EmitIntValue(dwarf::DW_CFA_restore_state, 1);
return;
@@ -987,6 +1008,19 @@ void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer,
Streamer.EmitULEB128IntValue(Reg);
return;
}
+ case MCCFIInstruction::Restore: {
+ unsigned Reg = Instr.getDestination().getReg();
+ if (VerboseAsm) {
+ Streamer.AddComment("DW_CFA_restore");
+ Streamer.AddComment(Twine("Reg ") + Twine(Reg));
+ }
+ Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
+ return;
+ }
+ case MCCFIInstruction::Escape:
+ if (VerboseAsm) Streamer.AddComment("Escape bytes");
+ Streamer.EmitBytes(Instr.getValues(), 0);
+ return;
}
llvm_unreachable("Unhandled case in switch");
}
@@ -1098,6 +1132,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
const MCSymbol *personality,
unsigned personalityEncoding,
const MCSymbol *lsda,
+ bool IsSignalFrame,
unsigned lsdaEncoding) {
MCContext &context = streamer.getContext();
const MCRegisterInfo &MRI = context.getRegisterInfo();
@@ -1140,6 +1175,8 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
if (lsda)
Augmentation += "L";
Augmentation += "R";
+ if (IsSignalFrame)
+ Augmentation += "S";
streamer.EmitBytes(Augmentation.str(), 0);
}
streamer.EmitIntValue(0, 1);
@@ -1299,17 +1336,18 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
namespace {
struct CIEKey {
- static const CIEKey getEmptyKey() { return CIEKey(0, 0, -1); }
- static const CIEKey getTombstoneKey() { return CIEKey(0, -1, 0); }
+ static const CIEKey getEmptyKey() { return CIEKey(0, 0, -1, false); }
+ static const CIEKey getTombstoneKey() { return CIEKey(0, -1, 0, false); }
CIEKey(const MCSymbol* Personality_, unsigned PersonalityEncoding_,
- unsigned LsdaEncoding_) : Personality(Personality_),
- PersonalityEncoding(PersonalityEncoding_),
- LsdaEncoding(LsdaEncoding_) {
+ unsigned LsdaEncoding_, bool IsSignalFrame_) :
+ Personality(Personality_), PersonalityEncoding(PersonalityEncoding_),
+ LsdaEncoding(LsdaEncoding_), IsSignalFrame(IsSignalFrame_) {
}
const MCSymbol* Personality;
unsigned PersonalityEncoding;
unsigned LsdaEncoding;
+ bool IsSignalFrame;
};
}
@@ -1327,13 +1365,15 @@ namespace llvm {
ID.AddPointer(Key.Personality);
ID.AddInteger(Key.PersonalityEncoding);
ID.AddInteger(Key.LsdaEncoding);
+ ID.AddBoolean(Key.IsSignalFrame);
return ID.ComputeHash();
}
static bool isEqual(const CIEKey &LHS,
const CIEKey &RHS) {
return LHS.Personality == RHS.Personality &&
LHS.PersonalityEncoding == RHS.PersonalityEncoding &&
- LHS.LsdaEncoding == RHS.LsdaEncoding;
+ LHS.LsdaEncoding == RHS.LsdaEncoding &&
+ LHS.IsSignalFrame == RHS.IsSignalFrame;
}
};
}
@@ -1369,11 +1409,12 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer,
for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
const MCDwarfFrameInfo &Frame = FrameArray[i];
CIEKey Key(Frame.Personality, Frame.PersonalityEncoding,
- Frame.LsdaEncoding);
+ Frame.LsdaEncoding, Frame.IsSignalFrame);
const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
if (!CIEStart)
CIEStart = &Emitter.EmitCIE(Streamer, Frame.Personality,
Frame.PersonalityEncoding, Frame.Lsda,
+ Frame.IsSignalFrame,
Frame.LsdaEncoding);
FDEEnd = Emitter.EmitFDE(Streamer, *CIEStart, Frame);
diff --git a/lib/MC/MCELFObjectTargetWriter.cpp b/lib/MC/MCELFObjectTargetWriter.cpp
index 12a02a9..15bf476 100644
--- a/lib/MC/MCELFObjectTargetWriter.cpp
+++ b/lib/MC/MCELFObjectTargetWriter.cpp
@@ -12,12 +12,27 @@
using namespace llvm;
MCELFObjectTargetWriter::MCELFObjectTargetWriter(bool Is64Bit_,
- Triple::OSType OSType_,
+ uint8_t OSABI_,
uint16_t EMachine_,
bool HasRelocationAddend_)
- : OSType(OSType_), EMachine(EMachine_),
+ : OSABI(OSABI_), EMachine(EMachine_),
HasRelocationAddend(HasRelocationAddend_), Is64Bit(Is64Bit_) {
}
-MCELFObjectTargetWriter::~MCELFObjectTargetWriter() {
+/// Default e_flags = 0
+unsigned MCELFObjectTargetWriter::getEFlags() const {
+ return 0;
+}
+
+const MCSymbol *MCELFObjectTargetWriter::ExplicitRelSym(const MCAssembler &Asm,
+ const MCValue &Target,
+ const MCFragment &F,
+ const MCFixup &Fixup,
+ bool IsPCRel) const {
+ return NULL;
+}
+
+
+void MCELFObjectTargetWriter::adjustFixupOffset(const MCFixup &Fixup,
+ uint64_t &RelocOffset) {
}
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index dcc4666..6c4d0e3 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -11,13 +11,17 @@
//
//===----------------------------------------------------------------------===//
-#include "MCELFStreamer.h"
#include "MCELF.h"
-#include "llvm/MC/MCStreamer.h"
+#include "llvm/ADT/SmallPtrSet.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/MCSection.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
@@ -29,6 +33,123 @@
using namespace llvm;
+namespace {
+class MCELFStreamer : public MCObjectStreamer {
+public:
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *Emitter)
+ : MCObjectStreamer(Context, TAB, OS, Emitter) {}
+
+ 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");
+ }
+
+ 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);
+ }
+
+ virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment);
+
+ virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
+ unsigned 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 EmitBytes(StringRef Data, unsigned AddrSpace);
+ virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
+ unsigned ValueSize = 1,
+ unsigned MaxBytesToEmit = 0);
+ virtual void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit = 0);
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace);
+
+ virtual void EmitFileDirective(StringRef Filename);
+
+ virtual void FinishImpl();
+
+private:
+ virtual void EmitInstToFragment(const MCInst &Inst);
+ virtual void EmitInstToData(const MCInst &Inst);
+
+ void fixSymbolsInTLSFixups(const MCExpr *expr);
+
+ struct LocalCommon {
+ MCSymbolData *SD;
+ uint64_t Size;
+ unsigned ByteAlignment;
+ };
+ std::vector<LocalCommon> LocalCommons;
+
+ SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
+ /// @}
+ void 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::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.
@@ -61,7 +182,7 @@ void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
return;
}
- assert(0 && "invalid assembler flag!");
+ llvm_unreachable("invalid assembler flag!");
}
void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {
@@ -131,8 +252,7 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
case MCSA_WeakDefAutoPrivate:
case MCSA_Invalid:
case MCSA_IndirectSymbol:
- assert(0 && "Invalid symbol attribute for ELF!");
- break;
+ llvm_unreachable("Invalid symbol attribute for ELF!");
case MCSA_ELF_TypeGnuUniqueObject:
// Ignore for now.
@@ -269,6 +389,13 @@ void MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment,
getCurrentSectionData()->setAlignment(ByteAlignment);
}
+void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace) {
+ fixSymbolsInTLSFixups(Value);
+ MCObjectStreamer::EmitValueImpl(Value, Size, AddrSpace);
+}
+
+
// Add a symbol for the file name of this module. This is the second
// entry in the module's symbol table (the first being the null symbol).
void MCELFStreamer::EmitFileDirective(StringRef Filename) {
@@ -356,7 +483,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
DF->getContents().append(Code.begin(), Code.end());
}
-void MCELFStreamer::Finish() {
+void MCELFStreamer::FinishImpl() {
EmitFrames(true);
for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(),
@@ -379,7 +506,7 @@ void MCELFStreamer::Finish() {
SectData.setAlignment(ByteAlignment);
}
- this->MCObjectStreamer::Finish();
+ this->MCObjectStreamer::FinishImpl();
}
MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB,
diff --git a/lib/MC/MCELFStreamer.h b/lib/MC/MCELFStreamer.h
deleted file mode 100644
index 10bf775..0000000
--- a/lib/MC/MCELFStreamer.h
+++ /dev/null
@@ -1,141 +0,0 @@
-//===- 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 LLVM_MC_MCELFSTREAMER_H
-#define LLVM_MC_MCELFSTREAMER_H
-
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/MC/MCAssembler.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCObjectStreamer.h"
-#include "llvm/MC/MCSectionELF.h"
-
-namespace llvm {
-
-class MCELFStreamer : public MCObjectStreamer {
-public:
- MCELFStreamer(MCContext &Context, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, TAB, OS, Emitter) {}
-
- 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) {
- assert(0 && "ELF doesn't support this directive");
- }
- virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment);
- virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {
- assert(0 && "ELF doesn't support this directive");
- }
-
- virtual void EmitCOFFSymbolStorageClass(int StorageClass) {
- assert(0 && "ELF doesn't support this directive");
- }
-
- virtual void EmitCOFFSymbolType(int Type) {
- assert(0 && "ELF doesn't support this directive");
- }
-
- virtual void EndCOFFSymbolDef() {
- assert(0 && "ELF doesn't support this directive");
- }
-
- virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
- MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
- SD.setSize(Value);
- }
-
- virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment);
-
- virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
- unsigned Size = 0, unsigned ByteAlignment = 0) {
- assert(0 && "ELF doesn't support this directive");
- }
- virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size, unsigned ByteAlignment = 0) {
- assert(0 && "ELF doesn't support this directive");
- }
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
- virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
- unsigned ValueSize = 1,
- unsigned MaxBytesToEmit = 0);
- virtual void EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit = 0);
-
- virtual void EmitFileDirective(StringRef Filename);
-
- virtual void Finish();
-
-private:
- virtual void EmitInstToFragment(const MCInst &Inst);
- virtual void EmitInstToData(const MCInst &Inst);
-
- void fixSymbolsInTLSFixups(const MCExpr *expr);
-
- struct LocalCommon {
- MCSymbolData *SD;
- uint64_t Size;
- unsigned ByteAlignment;
- };
- std::vector<LocalCommon> LocalCommons;
-
- SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
- /// @}
- void 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);
- }
-};
-
-} // end llvm namespace
-
-#endif
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp
index da297fb..ceaecd0 100644
--- a/lib/MC/MCExpr.cpp
+++ b/lib/MC/MCExpr.cpp
@@ -17,6 +17,7 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -57,7 +58,8 @@ void MCExpr::print(raw_ostream &OS) const {
SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOT ||
SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTOFF ||
SRE.getKind() == MCSymbolRefExpr::VK_ARM_TPOFF ||
- SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTTPOFF)
+ SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTTPOFF ||
+ SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET1)
OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
else if (SRE.getKind() != MCSymbolRefExpr::VK_None &&
SRE.getKind() != MCSymbolRefExpr::VK_PPC_DARWIN_HA16 &&
@@ -70,7 +72,6 @@ void MCExpr::print(raw_ostream &OS) const {
case MCExpr::Unary: {
const MCUnaryExpr &UE = cast<MCUnaryExpr>(*this);
switch (UE.getOpcode()) {
- default: assert(0 && "Invalid opcode!");
case MCUnaryExpr::LNot: OS << '!'; break;
case MCUnaryExpr::Minus: OS << '-'; break;
case MCUnaryExpr::Not: OS << '~'; break;
@@ -91,7 +92,6 @@ void MCExpr::print(raw_ostream &OS) const {
}
switch (BE.getOpcode()) {
- default: assert(0 && "Invalid opcode!");
case MCBinaryExpr::Add:
// Print "X-42" instead of "X+-42".
if (const MCConstantExpr *RHSC = dyn_cast<MCConstantExpr>(BE.getRHS())) {
@@ -132,7 +132,7 @@ void MCExpr::print(raw_ostream &OS) const {
}
}
- assert(0 && "Invalid expression kind!");
+ llvm_unreachable("Invalid expression kind!");
}
void MCExpr::dump() const {
@@ -171,7 +171,6 @@ const MCSymbolRefExpr *MCSymbolRefExpr::Create(StringRef Name, VariantKind Kind,
StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
switch (Kind) {
- default:
case VK_Invalid: return "<<invalid>>";
case VK_None: return "<<none>>";
@@ -189,18 +188,39 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_TPOFF: return "TPOFF";
case VK_DTPOFF: return "DTPOFF";
case VK_TLVP: return "TLVP";
+ case VK_SECREL: return "SECREL";
case VK_ARM_PLT: return "(PLT)";
case VK_ARM_GOT: return "(GOT)";
case VK_ARM_GOTOFF: return "(GOTOFF)";
case VK_ARM_TPOFF: return "(tpoff)";
case VK_ARM_GOTTPOFF: return "(gottpoff)";
case VK_ARM_TLSGD: return "(tlsgd)";
+ case VK_ARM_TARGET1: return "(target1)";
case VK_PPC_TOC: return "toc";
case VK_PPC_DARWIN_HA16: return "ha16";
case VK_PPC_DARWIN_LO16: return "lo16";
case VK_PPC_GAS_HA16: return "ha";
case VK_PPC_GAS_LO16: return "l";
+ case VK_Mips_GPREL: return "GPREL";
+ case VK_Mips_GOT_CALL: return "GOT_CALL";
+ case VK_Mips_GOT16: return "GOT16";
+ case VK_Mips_GOT: return "GOT";
+ case VK_Mips_ABS_HI: return "ABS_HI";
+ case VK_Mips_ABS_LO: return "ABS_LO";
+ case VK_Mips_TLSGD: return "TLSGD";
+ case VK_Mips_TLSLDM: return "TLSLDM";
+ case VK_Mips_DTPREL_HI: return "DTPREL_HI";
+ case VK_Mips_DTPREL_LO: return "DTPREL_LO";
+ case VK_Mips_GOTTPREL: return "GOTTPREL";
+ case VK_Mips_TPREL_HI: return "TPREL_HI";
+ case VK_Mips_TPREL_LO: return "TPREL_LO";
+ case VK_Mips_GPOFF_HI: return "GPOFF_HI";
+ case VK_Mips_GPOFF_LO: return "GPOFF_LO";
+ case VK_Mips_GOT_DISP: return "GOT_DISP";
+ case VK_Mips_GOT_PAGE: return "GOT_PAGE";
+ case VK_Mips_GOT_OFST: return "GOT_OFST";
}
+ llvm_unreachable("Invalid variant kind");
}
MCSymbolRefExpr::VariantKind
@@ -337,6 +357,11 @@ static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,
if (Addrs && (&SecA != &SecB))
Addend += (Addrs->lookup(&SecA) - Addrs->lookup(&SecB));
+ // Pointers to Thumb symbols need to have their low-bit set to allow
+ // for interworking.
+ if (Asm->isThumbFunc(&SA))
+ Addend |= 1;
+
// Clear the symbol expr pointers to indicate we have folded these
// operands.
A = B = 0;
@@ -557,8 +582,7 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
}
}
- assert(0 && "Invalid assembly expression kind!");
- return false;
+ llvm_unreachable("Invalid assembly expression kind!");
}
const MCSection *MCExpr::FindAssociatedSection() const {
@@ -599,6 +623,5 @@ const MCSection *MCExpr::FindAssociatedSection() const {
}
}
- assert(0 && "Invalid assembly expression kind!");
- return 0;
+ llvm_unreachable("Invalid assembly expression kind!");
}
diff --git a/lib/MC/MCInst.cpp b/lib/MC/MCInst.cpp
index 4cb628b..7bbfd2e 100644
--- a/lib/MC/MCInst.cpp
+++ b/lib/MC/MCInst.cpp
@@ -25,6 +25,8 @@ void MCOperand::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
OS << "Imm:" << getImm();
else if (isExpr()) {
OS << "Expr:(" << *getExpr() << ")";
+ } else if (isInst()) {
+ OS << "Inst:(" << *getInst() << ")";
} else
OS << "UNDEFINED";
OS << ">";
diff --git a/lib/MC/MCInstPrinter.cpp b/lib/MC/MCInstPrinter.cpp
index 2317a28..3060ad6 100644
--- a/lib/MC/MCInstPrinter.cpp
+++ b/lib/MC/MCInstPrinter.cpp
@@ -10,6 +10,7 @@
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -23,7 +24,7 @@ StringRef MCInstPrinter::getOpcodeName(unsigned Opcode) const {
}
void MCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
- assert(0 && "Target should implement this");
+ llvm_unreachable("Target should implement this");
}
void MCInstPrinter::printAnnotation(raw_ostream &OS, StringRef Annot) {
diff --git a/lib/MC/MCLoggingStreamer.cpp b/lib/MC/MCLoggingStreamer.cpp
deleted file mode 100644
index a7b7947..0000000
--- a/lib/MC/MCLoggingStreamer.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-//===- lib/MC/MCLoggingStreamer.cpp - API Logging Streamer ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
-
-namespace {
-
-class MCLoggingStreamer : public MCStreamer {
- llvm::OwningPtr<MCStreamer> Child;
-
- raw_ostream &OS;
-
-public:
- MCLoggingStreamer(MCStreamer *_Child, raw_ostream &_OS)
- : MCStreamer(_Child->getContext()), Child(_Child), OS(_OS) {}
-
- void LogCall(const char *Function) {
- OS << Function << "\n";
- }
-
- void LogCall(const char *Function, const Twine &Message) {
- OS << Function << ": " << Message << "\n";
- }
-
- virtual bool isVerboseAsm() const { return Child->isVerboseAsm(); }
-
- virtual bool hasRawTextSupport() const { return Child->hasRawTextSupport(); }
-
- virtual raw_ostream &GetCommentOS() { return Child->GetCommentOS(); }
-
- virtual void AddComment(const Twine &T) {
- LogCall("AddComment", T);
- return Child->AddComment(T);
- }
-
- virtual void AddBlankLine() {
- LogCall("AddBlankLine");
- return Child->AddBlankLine();
- }
-
- virtual void ChangeSection(const MCSection *Section) {
- LogCall("ChangeSection");
- return Child->ChangeSection(Section);
- }
-
- virtual void InitSections() {
- LogCall("InitSections");
- return Child->InitSections();
- }
-
- virtual void EmitLabel(MCSymbol *Symbol) {
- LogCall("EmitLabel");
- return Child->EmitLabel(Symbol);
- }
-
- virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {
- LogCall("EmitAssemblerFlag");
- return Child->EmitAssemblerFlag(Flag);
- }
-
- virtual void EmitThumbFunc(MCSymbol *Func) {
- LogCall("EmitThumbFunc");
- return Child->EmitThumbFunc(Func);
- }
-
- virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
- LogCall("EmitAssignment");
- return Child->EmitAssignment(Symbol, Value);
- }
-
- virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
- LogCall("EmitWeakReference");
- return Child->EmitWeakReference(Alias, Symbol);
- }
-
- virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
- const MCSymbol *LastLabel,
- const MCSymbol *Label,
- unsigned PointerSize) {
- LogCall("EmitDwarfAdvanceLineAddr");
- return Child->EmitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
- PointerSize);
- }
-
- virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) {
- LogCall("EmitSymbolAttribute");
- return Child->EmitSymbolAttribute(Symbol, Attribute);
- }
-
- virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
- LogCall("EmitSymbolDesc");
- return Child->EmitSymbolDesc(Symbol, DescValue);
- }
-
- virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {
- LogCall("BeginCOFFSymbolDef");
- return Child->BeginCOFFSymbolDef(Symbol);
- }
-
- virtual void EmitCOFFSymbolStorageClass(int StorageClass) {
- LogCall("EmitCOFFSymbolStorageClass");
- return Child->EmitCOFFSymbolStorageClass(StorageClass);
- }
-
- virtual void EmitCOFFSymbolType(int Type) {
- LogCall("EmitCOFFSymbolType");
- return Child->EmitCOFFSymbolType(Type);
- }
-
- virtual void EndCOFFSymbolDef() {
- LogCall("EndCOFFSymbolDef");
- return Child->EndCOFFSymbolDef();
- }
-
- virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
- LogCall("EmitELFSize");
- return Child->EmitELFSize(Symbol, Value);
- }
-
- virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment) {
- LogCall("EmitCommonSymbol");
- return Child->EmitCommonSymbol(Symbol, Size, ByteAlignment);
- }
-
- virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment) {
- LogCall("EmitLocalCommonSymbol");
- return Child->EmitLocalCommonSymbol(Symbol, Size, ByteAlignment);
- }
-
- virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
- unsigned Size = 0, unsigned ByteAlignment = 0) {
- LogCall("EmitZerofill");
- return Child->EmitZerofill(Section, Symbol, Size, ByteAlignment);
- }
-
- virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size, unsigned ByteAlignment = 0) {
- LogCall("EmitTBSSSymbol");
- return Child->EmitTBSSSymbol(Section, Symbol, Size, ByteAlignment);
- }
-
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {
- LogCall("EmitBytes");
- return Child->EmitBytes(Data, AddrSpace);
- }
-
- virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace){
- LogCall("EmitValue");
- return Child->EmitValueImpl(Value, Size, AddrSpace);
- }
-
- virtual void EmitULEB128Value(const MCExpr *Value) {
- LogCall("EmitULEB128Value");
- return Child->EmitULEB128Value(Value);
- }
-
- virtual void EmitSLEB128Value(const MCExpr *Value) {
- LogCall("EmitSLEB128Value");
- return Child->EmitSLEB128Value(Value);
- }
-
- virtual void EmitGPRel32Value(const MCExpr *Value) {
- LogCall("EmitGPRel32Value");
- return Child->EmitGPRel32Value(Value);
- }
-
- virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
- unsigned AddrSpace) {
- LogCall("EmitFill");
- return Child->EmitFill(NumBytes, FillValue, AddrSpace);
- }
-
- virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
- unsigned ValueSize = 1,
- unsigned MaxBytesToEmit = 0) {
- LogCall("EmitValueToAlignment");
- return Child->EmitValueToAlignment(ByteAlignment, Value,
- ValueSize, MaxBytesToEmit);
- }
-
- virtual void EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit = 0) {
- LogCall("EmitCodeAlignment");
- return Child->EmitCodeAlignment(ByteAlignment, MaxBytesToEmit);
- }
-
- virtual void EmitValueToOffset(const MCExpr *Offset,
- unsigned char Value = 0) {
- LogCall("EmitValueToOffset");
- return Child->EmitValueToOffset(Offset, Value);
- }
-
- virtual void EmitFileDirective(StringRef Filename) {
- LogCall("EmitFileDirective", "FileName:" + Filename);
- return Child->EmitFileDirective(Filename);
- }
-
- virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
- StringRef Filename) {
- LogCall("EmitDwarfFileDirective",
- "FileNo:" + Twine(FileNo) + " Directory:" + Directory +
- " Filename:" + Filename);
- return Child->EmitDwarfFileDirective(FileNo, Directory, Filename);
- }
-
- virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
- unsigned Column, unsigned Flags,
- unsigned Isa, unsigned Discriminator,
- StringRef FileName) {
- LogCall("EmitDwarfLocDirective",
- "FileNo:" + Twine(FileNo) + " Line:" + Twine(Line) +
- " Column:" + Twine(Column) + " Flags:" + Twine(Flags) +
- " Isa:" + Twine(Isa) + " Discriminator:" + Twine(Discriminator));
- return Child->EmitDwarfLocDirective(FileNo, Line, Column, Flags,
- Isa, Discriminator, FileName);
- }
-
- virtual void EmitInstruction(const MCInst &Inst) {
- LogCall("EmitInstruction");
- return Child->EmitInstruction(Inst);
- }
-
- virtual void EmitRawText(StringRef String) {
- LogCall("EmitRawText", "\"" + String + "\"");
- return Child->EmitRawText(String);
- }
-
- virtual void Finish() {
- LogCall("Finish");
- return Child->Finish();
- }
-
-};
-
-} // end anonymous namespace.
-
-MCStreamer *llvm::createLoggingStreamer(MCStreamer *Child, raw_ostream &OS) {
- return new MCLoggingStreamer(Child, OS);
-}
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index 50ab1f8..bc6cf77 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -53,23 +53,23 @@ public:
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment);
virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {
- assert(0 && "macho doesn't support this directive");
+ llvm_unreachable("macho doesn't support this directive");
}
virtual void EmitCOFFSymbolStorageClass(int StorageClass) {
- assert(0 && "macho doesn't support this directive");
+ llvm_unreachable("macho doesn't support this directive");
}
virtual void EmitCOFFSymbolType(int Type) {
- assert(0 && "macho doesn't support this directive");
+ llvm_unreachable("macho doesn't support this directive");
}
virtual void EndCOFFSymbolDef() {
- assert(0 && "macho doesn't support this directive");
+ llvm_unreachable("macho doesn't support this directive");
}
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
- assert(0 && "macho doesn't support this directive");
+ llvm_unreachable("macho doesn't support this directive");
}
virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {
- assert(0 && "macho doesn't support this directive");
+ llvm_unreachable("macho doesn't support this directive");
}
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
unsigned Size = 0, unsigned ByteAlignment = 0);
@@ -89,7 +89,7 @@ public:
//report_fatal_error("unsupported directive: '.file'");
}
- virtual void Finish();
+ virtual void FinishImpl();
/// @}
};
@@ -140,7 +140,7 @@ void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
// Let the target do whatever target specific stuff it needs to do.
- getAssembler().getBackend().HandleAssemblerFlag(Flag);
+ getAssembler().getBackend().handleAssemblerFlag(Flag);
// Do any generic stuff we need to do.
switch (Flag) {
case MCAF_SyntaxUnified: return; // no-op here.
@@ -150,8 +150,6 @@ void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
case MCAF_SubsectionsViaSymbols:
getAssembler().setSubsectionsViaSymbols(true);
return;
- default:
- llvm_unreachable("invalid assembler flag!");
}
}
@@ -213,8 +211,7 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
case MCSA_Protected:
case MCSA_Weak:
case MCSA_Local:
- assert(0 && "Invalid symbol attribute for Mach-O!");
- break;
+ llvm_unreachable("Invalid symbol attribute for Mach-O!");
case MCSA_Global:
SD.setExternal(true);
@@ -375,7 +372,7 @@ void MCMachOStreamer::EmitInstToData(const MCInst &Inst) {
DF->getContents().append(Code.begin(), Code.end());
}
-void MCMachOStreamer::Finish() {
+void MCMachOStreamer::FinishImpl() {
EmitFrames(true);
// We have to set the fragment atom associations so we can relax properly for
@@ -407,7 +404,7 @@ void MCMachOStreamer::Finish() {
}
}
- this->MCObjectStreamer::Finish();
+ this->MCObjectStreamer::FinishImpl();
}
MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp
index d178b50..7ff2d1b 100644
--- a/lib/MC/MCNullStreamer.cpp
+++ b/lib/MC/MCNullStreamer.cpp
@@ -55,6 +55,7 @@ namespace {
virtual void EmitCOFFSymbolStorageClass(int StorageClass) {}
virtual void EmitCOFFSymbolType(int Type) {}
virtual void EndCOFFSymbolDef() {}
+ virtual void EmitCOFFSecRel32(MCSymbol const *Symbol) {}
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -79,8 +80,8 @@ namespace {
virtual void EmitCodeAlignment(unsigned ByteAlignment,
unsigned MaxBytesToEmit = 0) {}
- virtual void EmitValueToOffset(const MCExpr *Offset,
- unsigned char Value = 0) {}
+ virtual bool EmitValueToOffset(const MCExpr *Offset,
+ unsigned char Value = 0) { return false; }
virtual void EmitFileDirective(StringRef Filename) {}
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
@@ -93,7 +94,11 @@ namespace {
StringRef FileName) {}
virtual void EmitInstruction(const MCInst &Inst) {}
- virtual void Finish() {}
+ virtual void FinishImpl() {}
+
+ virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
+ RecordProcEnd(Frame);
+ }
/// @}
};
diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp
index 32ba924..7dd06e7 100644
--- a/lib/MC/MCObjectFileInfo.cpp
+++ b/lib/MC/MCObjectFileInfo.cpp
@@ -31,8 +31,6 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
if (T.isMacOSX() && T.isMacOSXVersionLT(10, 5))
CommDirectiveSupportsAlignment = false;
- StructorOutputOrder = Structors::PriorityOrder;
-
TextSection // .text
= Ctx->getMachOSection("__TEXT", "__text",
MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
@@ -260,12 +258,17 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
}
}
- StructorOutputOrder = Structors::ReversePriorityOrder;
+ // Solaris requires different flags for .eh_frame to seemingly every other
+ // platform.
+ EHSectionFlags = ELF::SHF_ALLOC;
+ if (T.getOS() == Triple::Solaris)
+ EHSectionFlags |= ELF::SHF_WRITE;
+
// ELF
BSSSection =
Ctx->getELFSection(".bss", ELF::SHT_NOBITS,
- ELF::SHF_WRITE |ELF::SHF_ALLOC,
+ ELF::SHF_WRITE | ELF::SHF_ALLOC,
SectionKind::getBSS());
TextSection =
@@ -389,8 +392,6 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
// COFF
- StructorOutputOrder = Structors::ReversePriorityOrder;
-
TextSection =
Ctx->getCOFFSection(".text",
COFF::IMAGE_SCN_CNT_CODE |
@@ -408,12 +409,22 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getReadOnly());
- StaticCtorSection =
- Ctx->getCOFFSection(".ctors",
- COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ |
- COFF::IMAGE_SCN_MEM_WRITE,
- SectionKind::getDataRel());
+ if (T.getOS() == Triple::Win32) {
+ StaticCtorSection =
+ Ctx->getCOFFSection(".CRT$XCU",
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getReadOnly());
+ } else {
+ StaticCtorSection =
+ Ctx->getCOFFSection(".ctors",
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ |
+ COFF::IMAGE_SCN_MEM_WRITE,
+ SectionKind::getDataRel());
+ }
+
+
StaticDtorSection =
Ctx->getCOFFSection(".dtors",
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -501,6 +512,12 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_MEM_WRITE,
SectionKind::getDataRel());
+ TLSDataSection =
+ Ctx->getCOFFSection(".tls$",
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ |
+ COFF::IMAGE_SCN_MEM_WRITE,
+ SectionKind::getDataRel());
}
void MCObjectFileInfo::InitMCObjectFileInfo(StringRef TT, Reloc::Model relocm,
@@ -559,7 +576,7 @@ void MCObjectFileInfo::InitEHFrameSection() {
else if (Env == IsELF)
EHFrameSection =
Ctx->getELFSection(".eh_frame", ELF::SHT_PROGBITS,
- ELF::SHF_ALLOC,
+ EHSectionFlags,
SectionKind::getDataRel());
else
EHFrameSection =
diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
index 663d0ca..906bdc3 100644
--- a/lib/MC/MCObjectStreamer.cpp
+++ b/lib/MC/MCObjectStreamer.cpp
@@ -105,6 +105,14 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
DF->getContents().resize(DF->getContents().size() + Size, 0);
}
+void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
+ RecordProcStart(Frame);
+}
+
+void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
+ RecordProcEnd(Frame);
+}
+
void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
MCStreamer::EmitLabel(Symbol);
@@ -164,7 +172,7 @@ void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
MCLineEntry::Make(this, getCurrentSection());
// If this instruction doesn't need relaxation, just emit it as data.
- if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
+ if (!getAssembler().getBackend().mayNeedRelaxation(Inst)) {
EmitInstToData(Inst);
return;
}
@@ -173,9 +181,9 @@ void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
// possible and emit it as data.
if (getAssembler().getRelaxAll()) {
MCInst Relaxed;
- getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
- while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
- getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
+ getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
+ while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
+ getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed);
EmitInstToData(Relaxed);
return;
}
@@ -224,12 +232,12 @@ void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData());
}
-void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
- unsigned char Value) {
+bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
+ unsigned char Value) {
int64_t Res;
if (Offset->EvaluateAsAbsolute(Res, getAssembler())) {
new MCOrgFragment(*Offset, Value, getCurrentSectionData());
- return;
+ return false;
}
MCSymbol *CurrentPos = getContext().CreateTempSymbol();
@@ -241,8 +249,9 @@ void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext());
if (!Delta->EvaluateAsAbsolute(Res, getAssembler()))
- report_fatal_error("expected assembly-time absolute expression");
+ return true;
EmitFill(Res, Value, 0);
+ return false;
}
// Associate GPRel32 fixup with data and resize data area
@@ -255,14 +264,15 @@ void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
DF->getContents().resize(DF->getContents().size() + 4, 0);
}
-void MCObjectStreamer::Finish() {
+void MCObjectStreamer::FinishImpl() {
// Dump out the dwarf file & directory tables and line tables.
+ const MCSymbol *LineSectionSymbol = NULL;
if (getContext().hasDwarfFiles())
- MCDwarfFileTable::Emit(this);
+ LineSectionSymbol = MCDwarfFileTable::Emit(this);
// If we are generating dwarf for assembly source files dump out the sections.
if (getContext().getGenDwarfForAssembly())
- MCGenDwarfInfo::Emit(this);
+ MCGenDwarfInfo::Emit(this, LineSectionSymbol);
getAssembler().Finish();
}
diff --git a/lib/MC/MCObjectWriter.cpp b/lib/MC/MCObjectWriter.cpp
index 1888739..030f247 100644
--- a/lib/MC/MCObjectWriter.cpp
+++ b/lib/MC/MCObjectWriter.cpp
@@ -68,6 +68,8 @@ MCObjectWriter::IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
const MCSymbolData &DataA = Asm.getSymbolData(SA);
const MCSymbolData &DataB = Asm.getSymbolData(SB);
+ if(!DataA.getFragment() || !DataB.getFragment())
+ return false;
return IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA,
*DataB.getFragment(),
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index aac020d..bd5956f 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -30,6 +30,7 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
@@ -122,6 +123,9 @@ private:
int64_t CppHashLineNumber;
SMLoc CppHashLoc;
+ /// AssemblerDialect. ~OU means unset value and use value provided by MAI.
+ unsigned AssemblerDialect;
+
public:
AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI);
@@ -143,6 +147,15 @@ public:
virtual MCAsmLexer &getLexer() { return Lexer; }
virtual MCContext &getContext() { return Ctx; }
virtual MCStreamer &getStreamer() { return Out; }
+ virtual unsigned getAssemblerDialect() {
+ if (AssemblerDialect == ~0U)
+ return MAI.getAssemblerDialect();
+ else
+ return AssemblerDialect;
+ }
+ virtual void setAssemblerDialect(unsigned i) {
+ AssemblerDialect = i;
+ }
virtual bool Warning(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>());
@@ -301,6 +314,12 @@ public:
&GenericAsmParser::ParseDirectiveCFIRestoreState>(".cfi_restore_state");
AddDirectiveHandler<
&GenericAsmParser::ParseDirectiveCFISameValue>(".cfi_same_value");
+ AddDirectiveHandler<
+ &GenericAsmParser::ParseDirectiveCFIRestore>(".cfi_restore");
+ AddDirectiveHandler<
+ &GenericAsmParser::ParseDirectiveCFIEscape>(".cfi_escape");
+ AddDirectiveHandler<
+ &GenericAsmParser::ParseDirectiveCFISignalFrame>(".cfi_signal_frame");
// Macro directives.
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>(
@@ -334,6 +353,9 @@ public:
bool ParseDirectiveCFIRememberState(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveCFIRestoreState(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveCFISameValue(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIRestore(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIEscape(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFISignalFrame(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc);
@@ -358,7 +380,8 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx,
MCStreamer &_Out, const MCAsmInfo &_MAI)
: Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
GenericParser(new GenericAsmParser), PlatformParser(0),
- CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0) {
+ CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0),
+ AssemblerDialect(~0U) {
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
SavedDiagContext = SrcMgr.getDiagContext();
@@ -782,8 +805,7 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E,
}
}
- assert(0 && "Invalid expression kind!");
- return 0;
+ llvm_unreachable("Invalid expression kind!");
}
/// ParseExpression - Parse an expression and return it.
@@ -820,7 +842,6 @@ bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
if (!ModifiedRes) {
return TokError("invalid modifier '" + getTok().getIdentifier() +
"' (no symbols present)");
- return true;
}
Res = ModifiedRes;
@@ -1070,10 +1091,10 @@ bool AsmParser::ParseStatement() {
Out.EmitLabel(Sym);
// If we are generating dwarf for assembly source files then gather the
- // info to make a dwarf subprogram entry for this label if needed.
+ // info to make a dwarf label entry for this label if needed.
if (getContext().getGenDwarfForAssembly())
- MCGenDwarfSubprogramEntry::Make(Sym, &getStreamer(), getSourceManager(),
- IDLoc);
+ MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(),
+ IDLoc);
// Consume any end of statement token, if present, to avoid spurious
// AddBlankLine calls().
@@ -1544,23 +1565,27 @@ void AsmParser::HandleMacroExit() {
ActiveMacros.pop_back();
}
-static void MarkUsed(const MCExpr *Value) {
+static bool IsUsedIn(const MCSymbol *Sym, const MCExpr *Value) {
switch (Value->getKind()) {
- case MCExpr::Binary:
- MarkUsed(static_cast<const MCBinaryExpr*>(Value)->getLHS());
- MarkUsed(static_cast<const MCBinaryExpr*>(Value)->getRHS());
+ case MCExpr::Binary: {
+ const MCBinaryExpr *BE = static_cast<const MCBinaryExpr*>(Value);
+ return IsUsedIn(Sym, BE->getLHS()) || IsUsedIn(Sym, BE->getRHS());
break;
+ }
case MCExpr::Target:
case MCExpr::Constant:
- break;
+ return false;
case MCExpr::SymbolRef: {
- static_cast<const MCSymbolRefExpr*>(Value)->getSymbol().setUsed(true);
- break;
+ const MCSymbol &S = static_cast<const MCSymbolRefExpr*>(Value)->getSymbol();
+ if (S.isVariable())
+ return IsUsedIn(Sym, S.getVariableValue());
+ return &S == Sym;
}
case MCExpr::Unary:
- MarkUsed(static_cast<const MCUnaryExpr*>(Value)->getSubExpr());
- break;
+ return IsUsedIn(Sym, static_cast<const MCUnaryExpr*>(Value)->getSubExpr());
}
+
+ llvm_unreachable("Unknown expr kind!");
}
bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) {
@@ -1571,7 +1596,9 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) {
if (ParseExpression(Value))
return true;
- MarkUsed(Value);
+ // Note: we don't count b as used in "a = b". This is to allow
+ // a = b
+ // b = c
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in assignment");
@@ -1593,7 +1620,9 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) {
//
// FIXME: Diagnostics. Note the location of the definition as a label.
// FIXME: Diagnose assignment to protected identifier (e.g., register name).
- if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable())
+ if (IsUsedIn(Sym, Value))
+ return Error(EqualLoc, "Recursive use of '" + Name + "'");
+ else if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable())
; // Allow redefinitions of undefined symbols only used in directives.
else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef))
return Error(EqualLoc, "redefinition of '" + Name + "'");
@@ -1961,6 +1990,7 @@ bool AsmParser::ParseDirectiveOrg() {
CheckForValidSection();
const MCExpr *Offset;
+ SMLoc Loc = getTok().getLoc();
if (ParseExpression(Offset))
return true;
@@ -1980,9 +2010,11 @@ bool AsmParser::ParseDirectiveOrg() {
Lex();
- // FIXME: Only limited forms of relocatable expressions are accepted here, it
- // has to be relative to the current section.
- getStreamer().EmitValueToOffset(Offset, FillExpr);
+ // Only limited forms of relocatable expressions are accepted here, it
+ // has to be relative to the current section. The streamer will return
+ // 'true' if the expression wasn't evaluatable.
+ if (getStreamer().EmitValueToOffset(Offset, FillExpr))
+ return Error(Loc, "expected assembly-time absolute expression");
return false;
}
@@ -2417,13 +2449,13 @@ bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.file' directive");
- if (getContext().getGenDwarfForAssembly() == true)
- Error(DirectiveLoc, "input can't have .file dwarf directives when -g is "
- "used to generate dwarf debug info for assembly code");
-
if (FileNumber == -1)
getStreamer().EmitFileDirective(Filename);
else {
+ if (getContext().getGenDwarfForAssembly() == true)
+ Error(DirectiveLoc, "input can't have .file dwarf directives when -g is "
+ "used to generate dwarf debug info for assembly code");
+
if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename))
Error(FileNumberLoc, "file number already allocated");
}
@@ -2812,6 +2844,56 @@ bool GenericAsmParser::ParseDirectiveCFISameValue(StringRef IDVal,
return false;
}
+/// ParseDirectiveCFIRestore
+/// ::= .cfi_restore register
+bool GenericAsmParser::ParseDirectiveCFIRestore(StringRef IDVal,
+ SMLoc DirectiveLoc) {
+ int64_t Register = 0;
+ if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ return true;
+
+ getStreamer().EmitCFIRestore(Register);
+
+ return false;
+}
+
+/// ParseDirectiveCFIEscape
+/// ::= .cfi_escape expression[,...]
+bool GenericAsmParser::ParseDirectiveCFIEscape(StringRef IDVal,
+ SMLoc DirectiveLoc) {
+ std::string Values;
+ int64_t CurrValue;
+ if (getParser().ParseAbsoluteExpression(CurrValue))
+ return true;
+
+ Values.push_back((uint8_t)CurrValue);
+
+ while (getLexer().is(AsmToken::Comma)) {
+ Lex();
+
+ if (getParser().ParseAbsoluteExpression(CurrValue))
+ return true;
+
+ Values.push_back((uint8_t)CurrValue);
+ }
+
+ getStreamer().EmitCFIEscape(Values);
+ return false;
+}
+
+/// ParseDirectiveCFISignalFrame
+/// ::= .cfi_signal_frame
+bool GenericAsmParser::ParseDirectiveCFISignalFrame(StringRef Directive,
+ SMLoc DirectiveLoc) {
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return Error(getLexer().getLoc(),
+ "unexpected token in '" + Directive + "' directive");
+
+ getStreamer().EmitCFISignalFrame();
+
+ return false;
+}
+
/// ParseDirectiveMacrosOnOff
/// ::= .macros_on
/// ::= .macros_off
diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp
index 185b516..c4cdc3c 100644
--- a/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/lib/MC/MCParser/COFFAsmParser.cpp
@@ -45,6 +45,7 @@ class COFFAsmParser : public MCAsmParserExtension {
AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
AddDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
+ AddDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
// Win64 EH directives.
AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
@@ -102,6 +103,7 @@ class COFFAsmParser : public MCAsmParserExtension {
bool ParseDirectiveScl(StringRef, SMLoc);
bool ParseDirectiveType(StringRef, SMLoc);
bool ParseDirectiveEndef(StringRef, SMLoc);
+ bool ParseDirectiveSecRel32(StringRef, SMLoc);
// Win64 EH directives.
bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
@@ -217,6 +219,21 @@ bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
return false;
}
+bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
+ StringRef SymbolID;
+ if (getParser().ParseIdentifier(SymbolID))
+ return true;
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+
+ MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID);
+
+ Lex();
+ getStreamer().EmitCOFFSecRel32(Symbol);
+ return false;
+}
+
bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
StringRef SymbolID;
if (getParser().ParseIdentifier(SymbolID))
diff --git a/lib/MC/MCPureStreamer.cpp b/lib/MC/MCPureStreamer.cpp
index 1a2a92e..a770c97 100644
--- a/lib/MC/MCPureStreamer.cpp
+++ b/lib/MC/MCPureStreamer.cpp
@@ -46,9 +46,9 @@ public:
unsigned MaxBytesToEmit = 0);
virtual void EmitCodeAlignment(unsigned ByteAlignment,
unsigned MaxBytesToEmit = 0);
- virtual void EmitValueToOffset(const MCExpr *Offset,
+ virtual bool EmitValueToOffset(const MCExpr *Offset,
unsigned char Value = 0);
- virtual void Finish();
+ virtual void FinishImpl();
virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) {
@@ -96,7 +96,6 @@ public:
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename) {
report_fatal_error("unsupported directive in pure streamer");
- return false;
}
/// @}
@@ -185,9 +184,10 @@ void MCPureStreamer::EmitCodeAlignment(unsigned ByteAlignment,
getCurrentSectionData()->setAlignment(ByteAlignment);
}
-void MCPureStreamer::EmitValueToOffset(const MCExpr *Offset,
+bool MCPureStreamer::EmitValueToOffset(const MCExpr *Offset,
unsigned char Value) {
new MCOrgFragment(*Offset, Value, getCurrentSectionData());
+ return false;
}
void MCPureStreamer::EmitInstToFragment(const MCInst &Inst) {
@@ -224,10 +224,10 @@ void MCPureStreamer::EmitInstToData(const MCInst &Inst) {
DF->getContents().append(Code.begin(), Code.end());
}
-void MCPureStreamer::Finish() {
+void MCPureStreamer::FinishImpl() {
// FIXME: Handle DWARF tables?
- this->MCObjectStreamer::Finish();
+ this->MCObjectStreamer::FinishImpl();
}
MCStreamer *llvm::createPureStreamer(MCContext &Context, MCAsmBackend &MAB,
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index 60a0a9d..43e62ff 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -95,7 +95,7 @@ void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size,
/// client having to pass in a MCExpr for constant integers.
void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace,
unsigned Padding) {
- SmallString<32> Tmp;
+ SmallString<128> Tmp;
raw_svector_ostream OSE(Tmp);
MCObjectWriter::EncodeULEB128(Value, OSE, Padding);
EmitBytes(OSE.str(), AddrSpace);
@@ -104,7 +104,7 @@ void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace,
/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
void MCStreamer::EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace) {
- SmallString<32> Tmp;
+ SmallString<128> Tmp;
raw_svector_ostream OSE(Tmp);
MCObjectWriter::EncodeSLEB128(Value, OSE);
EmitBytes(OSE.str(), AddrSpace);
@@ -128,6 +128,10 @@ void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
AddrSpace);
}
+void MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
+ report_fatal_error("unsupported directive in streamer");
+}
+
void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
report_fatal_error("unsupported directive in streamer");
}
@@ -276,8 +280,17 @@ void MCStreamer::EmitCFIStartProc() {
report_fatal_error("Starting a frame before finishing the previous one!");
MCDwarfFrameInfo Frame;
- Frame.Function = LastSymbol;
+ EmitCFIStartProcImpl(Frame);
+ FrameInfos.push_back(Frame);
+ RegionIndicator = Code;
+}
+
+void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
+}
+
+void MCStreamer::RecordProcStart(MCDwarfFrameInfo &Frame) {
+ Frame.Function = LastSymbol;
// If the function is externally visible, we need to create a local
// symbol to avoid relocations.
StringRef Prefix = getContext().getAsmInfo().getPrivateGlobalPrefix();
@@ -287,16 +300,20 @@ void MCStreamer::EmitCFIStartProc() {
Frame.Begin = getContext().CreateTempSymbol();
EmitLabel(Frame.Begin);
}
-
- FrameInfos.push_back(Frame);
- RegionIndicator = Code;
}
void MCStreamer::EmitCFIEndProc() {
EnsureValidFrame();
MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
- CurFrame->End = getContext().CreateTempSymbol();
- EmitLabel(CurFrame->End);
+ EmitCFIEndProcImpl(*CurFrame);
+}
+
+void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
+}
+
+void MCStreamer::RecordProcEnd(MCDwarfFrameInfo &Frame) {
+ Frame.End = getContext().CreateTempSymbol();
+ EmitLabel(Frame.End);
}
void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
@@ -385,7 +402,7 @@ void MCStreamer::EmitCFIRememberState() {
MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
MCSymbol *Label = getContext().CreateTempSymbol();
EmitLabel(Label);
- MCCFIInstruction Instruction(MCCFIInstruction::Remember, Label);
+ MCCFIInstruction Instruction(MCCFIInstruction::RememberState, Label);
CurFrame->Instructions.push_back(Instruction);
}
@@ -395,7 +412,7 @@ void MCStreamer::EmitCFIRestoreState() {
MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
MCSymbol *Label = getContext().CreateTempSymbol();
EmitLabel(Label);
- MCCFIInstruction Instruction(MCCFIInstruction::Restore, Label);
+ MCCFIInstruction Instruction(MCCFIInstruction::RestoreState, Label);
CurFrame->Instructions.push_back(Instruction);
}
@@ -408,6 +425,30 @@ void MCStreamer::EmitCFISameValue(int64_t Register) {
CurFrame->Instructions.push_back(Instruction);
}
+void MCStreamer::EmitCFIRestore(int64_t Register) {
+ EnsureValidFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCSymbol *Label = getContext().CreateTempSymbol();
+ EmitLabel(Label);
+ MCCFIInstruction Instruction(MCCFIInstruction::Restore, Label, Register);
+ CurFrame->Instructions.push_back(Instruction);
+}
+
+void MCStreamer::EmitCFIEscape(StringRef Values) {
+ EnsureValidFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCSymbol *Label = getContext().CreateTempSymbol();
+ EmitLabel(Label);
+ MCCFIInstruction Instruction(MCCFIInstruction::Escape, Label, Values);
+ CurFrame->Instructions.push_back(Instruction);
+}
+
+void MCStreamer::EmitCFISignalFrame() {
+ EnsureValidFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ CurFrame->IsSignalFrame = true;
+}
+
void MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) {
W64UnwindInfos.push_back(Frame);
CurrentW64UnwindInfo = W64UnwindInfos.back();
@@ -558,6 +599,10 @@ void MCStreamer::EmitWin64EHEndProlog() {
EmitLabel(CurFrame->PrologEnd);
}
+void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
+ llvm_unreachable("This file format doesn't support this directive");
+}
+
void MCStreamer::EmitFnStart() {
errs() << "Not implemented yet\n";
abort();
@@ -630,3 +675,10 @@ void MCStreamer::EmitW64Tables() {
MCWin64EHUnwindEmitter::Emit(*this);
}
+
+void MCStreamer::Finish() {
+ if (!FrameInfos.empty() && !FrameInfos.back().End)
+ report_fatal_error("Unfinished frame!");
+
+ FinishImpl();
+}
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index e016f09..57f90d9 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -590,8 +590,10 @@ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
// assembler locals.
if (!Asm.getBackend().hasReliableSymbolDifference()) {
- if ((!SA.isTemporary() && Asm.getSubsectionsViaSymbols()) ||
- !SA.isInSection() || &SecA != &SecB)
+ if (!SA.isInSection() || &SecA != &SecB ||
+ (!SA.isTemporary() &&
+ FB.getAtom() != Asm.getSymbolData(SA).getFragment()->getAtom() &&
+ Asm.getSubsectionsViaSymbols()))
return false;
return true;
}
diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp
index 4052374..7144e68 100644
--- a/lib/MC/WinCOFFObjectWriter.cpp
+++ b/lib/MC/WinCOFFObjectWriter.cpp
@@ -22,8 +22,10 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCSectionCOFF.h"
+#include "llvm/MC/MCWinCOFFObjectWriter.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@@ -33,8 +35,6 @@
#include "llvm/Support/TimeValue.h"
-#include "../Target/X86/MCTargetDesc/X86FixupKinds.h"
-
#include <cstdio>
using namespace llvm;
@@ -128,8 +128,9 @@ public:
typedef DenseMap<MCSymbol const *, COFFSymbol *> symbol_map;
typedef DenseMap<MCSection const *, COFFSection *> section_map;
+ llvm::OwningPtr<MCWinCOFFObjectTargetWriter> TargetObjectWriter;
+
// Root level file contents.
- bool Is64Bit;
COFF::header Header;
sections Sections;
symbols Symbols;
@@ -139,7 +140,7 @@ public:
section_map SectionMap;
symbol_map SymbolMap;
- WinCOFFObjectWriter(raw_ostream &OS, bool is64Bit);
+ WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_ostream &OS);
~WinCOFFObjectWriter();
COFFSymbol *createSymbol(StringRef Name);
@@ -314,13 +315,13 @@ size_t StringTable::insert(llvm::StringRef String) {
//------------------------------------------------------------------------------
// WinCOFFObjectWriter class implementation
-WinCOFFObjectWriter::WinCOFFObjectWriter(raw_ostream &OS, bool is64Bit)
+WinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
+ raw_ostream &OS)
: MCObjectWriter(OS, true)
- , Is64Bit(is64Bit) {
+ , TargetObjectWriter(MOTW) {
memset(&Header, 0, sizeof(Header));
- Is64Bit ? Header.Machine = COFF::IMAGE_FILE_MACHINE_AMD64
- : Header.Machine = COFF::IMAGE_FILE_MACHINE_I386;
+ Header.Machine = TargetObjectWriter->getMachine();
}
WinCOFFObjectWriter::~WinCOFFObjectWriter() {
@@ -695,30 +696,13 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
if (CrossSection)
FixupKind = FK_PCRel_4;
- switch (FixupKind) {
- case FK_PCRel_4:
- case X86::reloc_riprel_4byte:
- case X86::reloc_riprel_4byte_movq_load:
- Reloc.Data.Type = Is64Bit ? COFF::IMAGE_REL_AMD64_REL32
- : COFF::IMAGE_REL_I386_REL32;
- // FIXME: Can anyone explain what this does other than adjust for the size
- // of the offset?
+ Reloc.Data.Type = TargetObjectWriter->getRelocType(FixupKind);
+
+ // FIXME: Can anyone explain what this does other than adjust for the size
+ // of the offset?
+ if (Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32 ||
+ Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32)
FixedValue += 4;
- break;
- case FK_Data_4:
- case X86::reloc_signed_4byte:
- Reloc.Data.Type = Is64Bit ? COFF::IMAGE_REL_AMD64_ADDR32
- : COFF::IMAGE_REL_I386_DIR32;
- break;
- case FK_Data_8:
- if (Is64Bit)
- Reloc.Data.Type = COFF::IMAGE_REL_AMD64_ADDR64;
- else
- llvm_unreachable("unsupported relocation type");
- break;
- default:
- llvm_unreachable("unsupported relocation type");
- }
coff_section->Relocations.push_back(Reloc);
}
@@ -878,11 +862,16 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
OS.write((char const *)&Strings.Data.front(), Strings.Data.size());
}
+MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_) :
+ Machine(Machine_) {
+}
+
//------------------------------------------------------------------------------
// WinCOFFObjectWriter factory function
namespace llvm {
- MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS, bool is64Bit) {
- return new WinCOFFObjectWriter(OS, is64Bit);
+ MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
+ raw_ostream &OS) {
+ return new WinCOFFObjectWriter(MOTW, OS);
}
}
diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp
index 7409daf..7238c9e 100644
--- a/lib/MC/WinCOFFStreamer.cpp
+++ b/lib/MC/WinCOFFStreamer.cpp
@@ -32,6 +32,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
+
using namespace llvm;
namespace {
@@ -60,6 +61,7 @@ public:
virtual void EmitCOFFSymbolStorageClass(int StorageClass);
virtual void EmitCOFFSymbolType(int Type);
virtual void EndCOFFSymbolDef();
+ virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment);
@@ -77,7 +79,7 @@ public:
virtual void EmitFileDirective(StringRef Filename);
virtual void EmitInstruction(const MCInst &Instruction);
virtual void EmitWin64EHHandlerData();
- virtual void Finish();
+ virtual void FinishImpl();
private:
virtual void EmitInstToFragment(const MCInst &Inst) {
@@ -251,7 +253,6 @@ void WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
default:
llvm_unreachable("unsupported attribute");
- break;
}
}
@@ -293,6 +294,16 @@ void WinCOFFStreamer::EndCOFFSymbolDef() {
CurSymbol = NULL;
}
+void WinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol)
+{
+ MCDataFragment *DF = getOrCreateDataFragment();
+
+ DF->addFixup(MCFixup::Create(DF->getContents().size(),
+ MCSymbolRefExpr::Create (Symbol, getContext ()),
+ FK_SecRel_4));
+ DF->getContents().resize(DF->getContents().size() + 4, 0);
+}
+
void WinCOFFStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
llvm_unreachable("not implemented");
}
@@ -389,9 +400,9 @@ void WinCOFFStreamer::EmitWin64EHHandlerData() {
MCWin64EHUnwindEmitter::EmitUnwindInfo(*this, getCurrentW64UnwindInfo());
}
-void WinCOFFStreamer::Finish() {
+void WinCOFFStreamer::FinishImpl() {
EmitW64Tables();
- MCObjectStreamer::Finish();
+ MCObjectStreamer::FinishImpl();
}
namespace llvm