diff options
Diffstat (limited to 'contrib/llvm/lib/MC')
43 files changed, 2126 insertions, 1940 deletions
diff --git a/contrib/llvm/lib/MC/ELFObjectWriter.cpp b/contrib/llvm/lib/MC/ELFObjectWriter.cpp index 3d16de5604f6..9fc33b6b3e5e 100644 --- a/contrib/llvm/lib/MC/ELFObjectWriter.cpp +++ b/contrib/llvm/lib/MC/ELFObjectWriter.cpp @@ -11,26 +11,26 @@ // //===----------------------------------------------------------------------===// -#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/MCFixupKindInfo.h" +#include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/Debug.h" #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/X86/MCTargetDesc/X86FixupKinds.h" -#include "../Target/ARM/MCTargetDesc/ARMFixupKinds.h" -#include "../Target/PowerPC/MCTargetDesc/PPCFixupKinds.h" #include <vector> using namespace llvm; @@ -38,6 +38,304 @@ 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(); + } + }; + + /// 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); @@ -92,11 +390,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); @@ -112,7 +406,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)); @@ -181,7 +475,7 @@ uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, if (const MCExpr *Value = Symbol.getVariableValue()) { int64_t IntValue; if (Value->EvaluateAsAbsolute(IntValue, Layout)) - return (uint64_t)IntValue; + return (uint64_t)IntValue; } } @@ -277,7 +571,7 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, MCDataFragment *ShndxF, const MCAssembler &Asm, const MCAsmLayout &Layout, - const SectionIndexMapTy &SectionIndexMap) { + const SectionIndexMapTy &SectionIndexMap) { // The string table must be emitted first because we need the index // into the string table for all the symbol names. assert(StringTable.size() && "Missing string table"); @@ -306,7 +600,8 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, Section.getType() == ELF::SHT_SYMTAB_SHNDX) continue; WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0, - ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), false); + ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), + false); LastLocalSymbolIndex++; } @@ -416,7 +711,7 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, // Offset of the symbol in the section int64_t a = Layout.getSymbolOffset(&SDB); - // Ofeset of the relocation in the section + // Offset of the relocation in the section int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); Value += b - a; } @@ -445,11 +740,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; @@ -459,7 +759,7 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, else assert(isInt<32>(Addend)); - ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend); + ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend, Fixup); Relocations[Fragment->getParent()].push_back(ERE); } @@ -745,8 +1045,10 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, MCDataFragment *F, const MCSectionData *SD) { std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; - // sort by the r_offset just like gnu as does - array_pod_sort(Relocs.begin(), Relocs.end()); + + // Sort the relocation entries. Most targets just sort by r_offset, but some + // (e.g., MIPS) have additional constraints. + TargetObjectWriter->sortRelocs(Asm, Relocs); for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { ELFRelocationEntry entry = Relocs[e - i - 1]; @@ -1053,14 +1355,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; @@ -1070,7 +1368,7 @@ void ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm, WriteBytes(cast<MCDataFragment>(F).getContents().str()); } } else { - Asm.WriteSectionData(&SD, Layout); + Asm.writeSectionData(&SD, Layout); } } @@ -1226,16 +1524,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]); @@ -1256,577 +1551,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 (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; - } - } 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(MCELFObjectTargetWriter *MOTW, - raw_ostream &_OS, - bool IsLittleEndian) - : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {} - -MipsELFObjectWriter::~MipsELFObjectWriter() {} - -unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel, - bool IsRelocWithSymbol, - int64_t Addend) { - // tbd - return 1; + return new ELFObjectWriter(MOTW, OS, IsLittleEndian); } diff --git a/contrib/llvm/lib/MC/ELFObjectWriter.h b/contrib/llvm/lib/MC/ELFObjectWriter.h deleted file mode 100644 index 862b085c76bf..000000000000 --- a/contrib/llvm/lib/MC/ELFObjectWriter.h +++ /dev/null @@ -1,446 +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(); - protected: - virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, - bool IsPCRel, bool IsRelocWithSymbol, - int64_t Addend); - }; -} - -#endif diff --git a/contrib/llvm/lib/MC/MCAsmBackend.cpp b/contrib/llvm/lib/MC/MCAsmBackend.cpp index 2c150f456cf6..0b2e4ae7ed07 100644 --- a/contrib/llvm/lib/MC/MCAsmBackend.cpp +++ b/contrib/llvm/lib/MC/MCAsmBackend.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCFixupKindInfo.h" using namespace llvm; MCAsmBackend::MCAsmBackend() @@ -21,14 +22,22 @@ MCAsmBackend::~MCAsmBackend() { const MCFixupKindInfo & MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { static const MCFixupKindInfo Builtins[] = { - { "FK_Data_1", 0, 8, 0 }, - { "FK_Data_2", 0, 16, 0 }, - { "FK_Data_4", 0, 32, 0 }, - { "FK_Data_8", 0, 64, 0 }, - { "FK_PCRel_1", 0, 8, MCFixupKindInfo::FKF_IsPCRel }, + { "FK_Data_1", 0, 8, 0 }, + { "FK_Data_2", 0, 16, 0 }, + { "FK_Data_4", 0, 32, 0 }, + { "FK_Data_8", 0, 64, 0 }, + { "FK_PCRel_1", 0, 8, MCFixupKindInfo::FKF_IsPCRel }, { "FK_PCRel_2", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, { "FK_PCRel_4", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, - { "FK_PCRel_8", 0, 64, MCFixupKindInfo::FKF_IsPCRel } + { "FK_PCRel_8", 0, 64, MCFixupKindInfo::FKF_IsPCRel }, + { "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_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/contrib/llvm/lib/MC/MCAsmInfo.cpp b/contrib/llvm/lib/MC/MCAsmInfo.cpp index 95861bc61c27..8286c1dfeae1 100644 --- a/contrib/llvm/lib/MC/MCAsmInfo.cpp +++ b/contrib/llvm/lib/MC/MCAsmInfo.cpp @@ -29,7 +29,6 @@ MCAsmInfo::MCAsmInfo() { HasSubsectionsViaSymbols = false; HasMachoZeroFillDirective = false; HasMachoTBSSDirective = false; - StructorOutputOrder = Structors::ReversePriorityOrder; HasStaticCtorDtorReferenceInStaticMode = false; LinkerRequiresNonEmptyDwarfLines = false; MaxInstLength = 4; @@ -50,6 +49,7 @@ MCAsmInfo::MCAsmInfo() { AllowQuotesInName = false; AllowNameToStartWithDigit = false; AllowPeriodsInName = true; + AllowUTF8 = true; ZeroDirective = "\t.zero\t"; AsciiDirective = "\t.ascii\t"; AscizDirective = "\t.asciz\t"; @@ -68,6 +68,7 @@ MCAsmInfo::MCAsmInfo() { AlignDirective = "\t.align\t"; AlignmentIsInBytes = true; TextAlignFillValue = 0; + GPRel64Directive = 0; GPRel32Directive = 0; GlobalDirective = "\t.globl\t"; HasSetDirective = true; @@ -91,6 +92,7 @@ MCAsmInfo::MCAsmInfo() { DwarfRequiresRelocationForSectionOffset = true; DwarfSectionOffsetDirective = 0; DwarfUsesLabelOffsetForRanges = true; + DwarfUsesRelocationsForStringPool = true; DwarfRegNumForCFI = false; HasMicrosoftFastStdCallMangling = false; diff --git a/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp b/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp index 434d9103a71a..881d99217bda 100644 --- a/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp +++ b/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp @@ -13,9 +13,10 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCAsmInfoCOFF.h" -#include "llvm/ADT/SmallVector.h" using namespace llvm; +void MCAsmInfoCOFF::anchor() { } + MCAsmInfoCOFF::MCAsmInfoCOFF() { GlobalPrefix = "_"; COMMDirectiveAlignmentIsInBytes = false; @@ -38,3 +39,15 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() { SupportsDataRegions = false; } + +void MCAsmInfoMicrosoft::anchor() { } + +MCAsmInfoMicrosoft::MCAsmInfoMicrosoft() { + AllowQuotesInName = true; +} + +void MCAsmInfoGNUCOFF::anchor() { } + +MCAsmInfoGNUCOFF::MCAsmInfoGNUCOFF() { + +} diff --git a/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp b/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp index b20e338f7904..c1e26350dc8e 100644 --- a/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp +++ b/contrib/llvm/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: @@ -39,7 +41,6 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() { ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. HasMachoZeroFillDirective = true; // Uses .zerofill HasMachoTBSSDirective = true; // Uses .tbss - StructorOutputOrder = Structors::PriorityOrder; HasStaticCtorDtorReferenceInStaticMode = true; CodeBegin = "L$start$code$"; @@ -57,8 +58,9 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() { HiddenVisibilityAttr = MCSA_PrivateExtern; HiddenDeclarationVisibilityAttr = MCSA_Invalid; + // Doesn't support protected visibility. - ProtectedVisibilityAttr = MCSA_Global; + ProtectedVisibilityAttr = MCSA_Invalid; HasDotTypeDotSizeDirective = false; HasNoDeadStrip = true; @@ -66,4 +68,5 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() { DwarfRequiresRelocationForSectionOffset = false; DwarfUsesLabelOffsetForRanges = false; + DwarfUsesRelocationsForStringPool = false; } diff --git a/contrib/llvm/lib/MC/MCAsmStreamer.cpp b/contrib/llvm/lib/MC/MCAsmStreamer.cpp index 3fcbb05907bc..11f0f7296337 100644 --- a/contrib/llvm/lib/MC/MCAsmStreamer.cpp +++ b/contrib/llvm/lib/MC/MCAsmStreamer.cpp @@ -29,6 +29,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Support/PathV2.h" #include <cctype> using namespace llvm; @@ -50,6 +51,7 @@ private: unsigned ShowInst : 1; unsigned UseLoc : 1; unsigned UseCFI : 1; + unsigned UseDwarfDirectory : 1; enum EHSymbolFlags { EHGlobal = 1, EHWeakDefinition = 1 << 1, @@ -59,17 +61,21 @@ 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, bool isVerboseAsm, bool useLoc, bool useCFI, + bool useDwarfDirectory, MCInstPrinter *printer, MCCodeEmitter *emitter, MCAsmBackend *asmbackend, bool showInst) : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm), - ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI) { + ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI), + UseDwarfDirectory(useDwarfDirectory) { if (InstPrinter && IsVerboseAsm) InstPrinter->setCommentStream(CommentStream); } @@ -150,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); @@ -179,6 +186,8 @@ public: virtual void EmitSLEB128Value(const MCExpr *Value); + virtual void EmitGPRel64Value(const MCExpr *Value); + virtual void EmitGPRel32Value(const MCExpr *Value); @@ -192,19 +201,18 @@ 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); - virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Filename); + virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename); virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, 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); @@ -216,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(); @@ -249,7 +258,7 @@ public: /// indicated by the hasRawTextSupport() predicate. virtual void EmitRawText(StringRef String); - virtual void Finish(); + virtual void FinishImpl(); /// @} }; @@ -334,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; @@ -386,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 @@ -398,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; @@ -465,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'; @@ -652,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; @@ -733,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; } @@ -748,13 +768,27 @@ void MCAsmStreamer::EmitFileDirective(StringRef Filename) { EmitEOL(); } -bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Filename){ +bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename) { + if (!UseDwarfDirectory && !Directory.empty()) { + if (sys::path::is_absolute(Filename)) + return EmitDwarfFileDirective(FileNo, "", Filename); + + SmallString<128> FullPathName = Directory; + sys::path::append(FullPathName, Filename); + return EmitDwarfFileDirective(FileNo, "", FullPathName); + } + if (UseLoc) { OS << "\t.file\t" << FileNo << ' '; + if (!Directory.empty()) { + PrintQuotedString(Directory, OS); + OS << ' '; + } PrintQuotedString(Filename, OS); EmitEOL(); } - return this->MCStreamer::EmitDwarfFileDirective(FileNo, Filename); + return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename); } void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, @@ -816,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(); @@ -965,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); @@ -1260,10 +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, LineSectionSymbol); if (!UseCFI) EmitFrames(false); @@ -1271,9 +1325,9 @@ void MCAsmStreamer::Finish() { MCStreamer *llvm::createAsmStreamer(MCContext &Context, formatted_raw_ostream &OS, bool isVerboseAsm, bool useLoc, - bool useCFI, MCInstPrinter *IP, - MCCodeEmitter *CE, MCAsmBackend *MAB, - bool ShowInst) { + bool useCFI, bool useDwarfDirectory, + MCInstPrinter *IP, MCCodeEmitter *CE, + MCAsmBackend *MAB, bool ShowInst) { return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI, - IP, CE, MAB, ShowInst); + useDwarfDirectory, IP, CE, MAB, ShowInst); } diff --git a/contrib/llvm/lib/MC/MCAssembler.cpp b/contrib/llvm/lib/MC/MCAssembler.cpp index 06c8aec91917..66ba9b81f3aa 100644 --- a/contrib/llvm/lib/MC/MCAssembler.cpp +++ b/contrib/llvm/lib/MC/MCAssembler.cpp @@ -13,13 +13,13 @@ #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCValue.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCAsmBackend.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" @@ -33,7 +33,7 @@ using namespace llvm; namespace { namespace stats { STATISTIC(EmittedFragments, "Number of emitted assembler fragments"); -STATISTIC(EvaluateFixup, "Number of evaluated fixups"); +STATISTIC(evaluateFixup, "Number of evaluated fixups"); STATISTIC(FragmentLayouts, "Number of fragment layouts"); STATISTIC(ObjectBytes, "Number of emitted object file bytes"); STATISTIC(RelaxationSteps, "Number of assembler layout and relaxation steps"); @@ -118,7 +118,7 @@ uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const { if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined()) report_fatal_error("unable to evaluate offset to undefined symbol '" + Target.getSymB()->getSymbol().getName() + "'"); - + uint64_t Offset = Target.getConstant(); if (Target.getSymA()) Offset += getSymbolOffset(&Assembler.getSymbolData( @@ -136,7 +136,7 @@ uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const { uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const { // The size is the last fragment's end offset. const MCFragment &F = SD->getFragmentList().back(); - return getFragmentOffset(&F) + getAssembler().ComputeFragmentSize(*this, F); + return getFragmentOffset(&F) + getAssembler().computeFragmentSize(*this, F); } uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const { @@ -237,13 +237,13 @@ const MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const { return SD->getFragment()->getAtom(); } -bool MCAssembler::EvaluateFixup(const MCAsmLayout &Layout, +bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, const MCFixup &Fixup, const MCFragment *DF, MCValue &Target, uint64_t &Value) const { - ++stats::EvaluateFixup; + ++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(); @@ -295,24 +292,22 @@ bool MCAssembler::EvaluateFixup(const MCAsmLayout &Layout, if (IsPCRel) { uint32_t Offset = Layout.getFragmentOffset(DF) + Fixup.getOffset(); - + // A number of ARM fixups in Thumb mode require that the effective PC // address be determined as the 32-bit aligned version of the actual offset. if (ShouldAlignPC) Offset &= ~0x3; 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; } -uint64_t MCAssembler::ComputeFragmentSize(const MCAsmLayout &Layout, +uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const { switch (F.getKind()) { case MCFragment::FT_Data: @@ -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) { @@ -374,7 +368,7 @@ void MCAsmLayout::LayoutFragment(MCFragment *F) { // Compute fragment offset and size. uint64_t Offset = 0; if (Prev) - Offset += Prev->Offset + getAssembler().ComputeFragmentSize(*this, *Prev); + Offset += Prev->Offset + getAssembler().computeFragmentSize(*this, *Prev); F->Offset = Offset; LastValidFragment[F->getParent()] = F; @@ -390,7 +384,7 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout, ++stats::EmittedFragments; // FIXME: Embed in fragments instead? - uint64_t FragmentSize = Asm.ComputeFragmentSize(Layout, F); + uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F); switch (F.getKind()) { case MCFragment::FT_Align: { MCAlignFragment &AF = cast<MCAlignFragment>(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; @@ -493,7 +485,7 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout, assert(OW->getStream().tell() - Start == FragmentSize); } -void MCAssembler::WriteSectionData(const MCSectionData *SD, +void MCAssembler::writeSectionData(const MCSectionData *SD, const MCAsmLayout &Layout) const { // Ignore virtual sections. if (SD->getSection().isVirtualSection()) { @@ -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 @@ -546,13 +537,13 @@ void MCAssembler::WriteSectionData(const MCSectionData *SD, } -uint64_t MCAssembler::HandleFixup(const MCAsmLayout &Layout, +uint64_t MCAssembler::handleFixup(const MCAsmLayout &Layout, MCFragment &F, const MCFixup &Fixup) { // Evaluate the fixup. MCValue Target; uint64_t FixedValue; - if (!EvaluateFixup(Layout, Fixup, &F, Target, FixedValue)) { + if (!evaluateFixup(Layout, Fixup, &F, Target, FixedValue)) { // The fixup was unresolved, we need a relocation. Inform the object // writer of the relocation, and give it an opportunity to adjust the // fixup value if need be. @@ -592,7 +583,7 @@ void MCAssembler::Finish() { } // Layout until everything fits. - while (LayoutOnce(Layout)) + while (layoutOnce(Layout)) continue; DEBUG_WITH_TYPE("mc-dump", { @@ -600,7 +591,7 @@ void MCAssembler::Finish() { dump(); }); // Finalize the layout, including fragment lowering. - FinishLayout(Layout); + finishLayout(Layout); DEBUG_WITH_TYPE("mc-dump", { llvm::errs() << "assembler backend - final-layout\n--\n"; @@ -621,8 +612,8 @@ void MCAssembler::Finish() { for (MCDataFragment::fixup_iterator it3 = DF->fixup_begin(), ie3 = DF->fixup_end(); it3 != ie3; ++it3) { MCFixup &Fixup = *it3; - uint64_t FixedValue = HandleFixup(Layout, *DF, Fixup); - getBackend().ApplyFixup(Fixup, DF->getContents().data(), + uint64_t FixedValue = handleFixup(Layout, *DF, Fixup); + getBackend().applyFixup(Fixup, DF->getContents().data(), DF->getContents().size(), FixedValue); } } @@ -631,8 +622,8 @@ void MCAssembler::Finish() { for (MCInstFragment::fixup_iterator it3 = IF->fixup_begin(), ie3 = IF->fixup_end(); it3 != ie3; ++it3) { MCFixup &Fixup = *it3; - uint64_t FixedValue = HandleFixup(Layout, *IF, Fixup); - getBackend().ApplyFixup(Fixup, IF->getCode().data(), + uint64_t FixedValue = handleFixup(Layout, *IF, Fixup); + getBackend().applyFixup(Fixup, IF->getCode().data(), IF->getCode().size(), FixedValue); } } @@ -645,8 +636,8 @@ void MCAssembler::Finish() { stats::ObjectBytes += OS.tell() - StartOffset; } -bool MCAssembler::FixupNeedsRelaxation(const MCFixup &Fixup, - const MCFragment *DF, +bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup, + const MCInstFragment *DF, const MCAsmLayout &Layout) const { if (getRelaxAll()) return true; @@ -654,34 +645,31 @@ bool MCAssembler::FixupNeedsRelaxation(const MCFixup &Fixup, // If we cannot resolve the fixup value, it requires relaxation. MCValue Target; uint64_t Value; - if (!EvaluateFixup(Layout, Fixup, DF, Target, Value)) + if (!evaluateFixup(Layout, Fixup, DF, Target, Value)) return true; - // Otherwise, relax if the value is too big for a (signed) i8. - // - // FIXME: This is target dependent! - return int64_t(Value) != int64_t(int8_t(Value)); + return getBackend().fixupNeedsRelaxation(Fixup, Value, DF, Layout); } -bool MCAssembler::FragmentNeedsRelaxation(const MCInstFragment *IF, +bool MCAssembler::fragmentNeedsRelaxation(const MCInstFragment *IF, const MCAsmLayout &Layout) const { // 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(), ie = IF->fixup_end(); it != ie; ++it) - if (FixupNeedsRelaxation(*it, IF, Layout)) + if (fixupNeedsRelaxation(*it, IF, Layout)) return true; return false; } -bool MCAssembler::RelaxInstruction(MCAsmLayout &Layout, +bool MCAssembler::relaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF) { - if (!FragmentNeedsRelaxation(&IF, Layout)) + if (!fragmentNeedsRelaxation(&IF, Layout)) return false; ++stats::RelaxedInstructions; @@ -692,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. // @@ -715,7 +703,7 @@ bool MCAssembler::RelaxInstruction(MCAsmLayout &Layout, return true; } -bool MCAssembler::RelaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) { +bool MCAssembler::relaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) { int64_t Value = 0; uint64_t OldSize = LF.getContents().size(); bool IsAbs = LF.getValue().EvaluateAsAbsolute(Value, Layout); @@ -732,8 +720,8 @@ bool MCAssembler::RelaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) { return OldSize != LF.getContents().size(); } -bool MCAssembler::RelaxDwarfLineAddr(MCAsmLayout &Layout, - MCDwarfLineAddrFragment &DF) { +bool MCAssembler::relaxDwarfLineAddr(MCAsmLayout &Layout, + MCDwarfLineAddrFragment &DF) { int64_t AddrDelta = 0; uint64_t OldSize = DF.getContents().size(); bool IsAbs = DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout); @@ -749,7 +737,7 @@ bool MCAssembler::RelaxDwarfLineAddr(MCAsmLayout &Layout, return OldSize != Data.size(); } -bool MCAssembler::RelaxDwarfCallFrameFragment(MCAsmLayout &Layout, +bool MCAssembler::relaxDwarfCallFrameFragment(MCAsmLayout &Layout, MCDwarfCallFrameFragment &DF) { int64_t AddrDelta = 0; uint64_t OldSize = DF.getContents().size(); @@ -764,7 +752,7 @@ bool MCAssembler::RelaxDwarfCallFrameFragment(MCAsmLayout &Layout, return OldSize != Data.size(); } -bool MCAssembler::LayoutSectionOnce(MCAsmLayout &Layout, +bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) { MCFragment *FirstInvalidFragment = NULL; // Scan for fragments that need relaxation. @@ -776,19 +764,19 @@ bool MCAssembler::LayoutSectionOnce(MCAsmLayout &Layout, default: break; case MCFragment::FT_Inst: - relaxedFrag = RelaxInstruction(Layout, *cast<MCInstFragment>(it2)); + relaxedFrag = relaxInstruction(Layout, *cast<MCInstFragment>(it2)); break; case MCFragment::FT_Dwarf: - relaxedFrag = RelaxDwarfLineAddr(Layout, + relaxedFrag = relaxDwarfLineAddr(Layout, *cast<MCDwarfLineAddrFragment>(it2)); break; case MCFragment::FT_DwarfFrame: relaxedFrag = - RelaxDwarfCallFrameFragment(Layout, + relaxDwarfCallFrameFragment(Layout, *cast<MCDwarfCallFrameFragment>(it2)); break; case MCFragment::FT_LEB: - relaxedFrag = RelaxLEB(Layout, *cast<MCLEBFragment>(it2)); + relaxedFrag = relaxLEB(Layout, *cast<MCLEBFragment>(it2)); break; } // Update the layout, and remember that we relaxed. @@ -802,20 +790,20 @@ bool MCAssembler::LayoutSectionOnce(MCAsmLayout &Layout, return false; } -bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) { +bool MCAssembler::layoutOnce(MCAsmLayout &Layout) { ++stats::RelaxationSteps; bool WasRelaxed = false; for (iterator it = begin(), ie = end(); it != ie; ++it) { MCSectionData &SD = *it; - while(LayoutSectionOnce(Layout, SD)) + while(layoutSectionOnce(Layout, SD)) WasRelaxed = true; } return WasRelaxed; } -void MCAssembler::FinishLayout(MCAsmLayout &Layout) { +void MCAssembler::finishLayout(MCAsmLayout &Layout) { // The layout is done. Mark every fragment as valid. for (unsigned int i = 0, n = Layout.getSectionOrder().size(); i != n; ++i) { Layout.getFragmentOffset(&*Layout.getSectionOrder()[i]->rbegin()); @@ -975,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/contrib/llvm/lib/MC/MCCodeGenInfo.cpp b/contrib/llvm/lib/MC/MCCodeGenInfo.cpp index 236e7de68a8a..d9dcfd0614bc 100644 --- a/contrib/llvm/lib/MC/MCCodeGenInfo.cpp +++ b/contrib/llvm/lib/MC/MCCodeGenInfo.cpp @@ -15,7 +15,9 @@ #include "llvm/MC/MCCodeGenInfo.h" using namespace llvm; -void MCCodeGenInfo::InitMCCodeGenInfo(Reloc::Model RM, CodeModel::Model CM) { +void MCCodeGenInfo::InitMCCodeGenInfo(Reloc::Model RM, CodeModel::Model CM, + CodeGenOpt::Level OL) { RelocationModel = RM; CMModel = CM; + OptLevel = OL; } diff --git a/contrib/llvm/lib/MC/MCContext.cpp b/contrib/llvm/lib/MC/MCContext.cpp index 82690ee3b3e9..d3c4fb1d7ca5 100644 --- a/contrib/llvm/lib/MC/MCContext.cpp +++ b/contrib/llvm/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), @@ -43,6 +46,8 @@ MCContext::MCContext(const MCAsmInfo &mai, const MCRegisterInfo &mri, SecureLogUsed = false; DwarfLocSeen = false; + GenDwarfForAssembly = false; + GenDwarfFileNumber = 0; } MCContext::~MCContext() { @@ -248,7 +253,8 @@ const MCSection *MCContext::getCOFFSection(StringRef Section, /// directory tables. If the file number has already been allocated it is an /// error and zero is returned and the client reports the error, else the /// allocated file number is returned. The file numbers may be in any order. -unsigned MCContext::GetDwarfFile(StringRef FileName, unsigned FileNumber) { +unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName, + unsigned FileNumber) { // TODO: a FileNumber of zero says to use the next available file number. // Note: in GenericAsmParser::ParseDirectiveFile() FileNumber was checked // to not be less than one. This needs to be change to be not less than zero. @@ -266,19 +272,23 @@ unsigned MCContext::GetDwarfFile(StringRef FileName, unsigned FileNumber) { // Get the new MCDwarfFile slot for this FileNumber. MCDwarfFile *&File = MCDwarfFiles[FileNumber]; - // Separate the directory part from the basename of the FileName. - std::pair<StringRef, StringRef> Slash = FileName.rsplit('/'); + if (Directory.empty()) { + // Separate the directory part from the basename of the FileName. + std::pair<StringRef, StringRef> Slash = FileName.rsplit('/'); + Directory = Slash.second; + if (!Directory.empty()) { + Directory = Slash.first; + FileName = Slash.second; + } + } // Find or make a entry in the MCDwarfDirs vector for this Directory. - StringRef Name; - unsigned DirIndex; // Capture directory name. - if (Slash.second.empty()) { - Name = Slash.first; - DirIndex = 0; // For FileNames with no directories a DirIndex of 0 is used. + unsigned DirIndex; + if (Directory.empty()) { + // For FileNames with no directories a DirIndex of 0 is used. + DirIndex = 0; } else { - StringRef Directory = Slash.first; - Name = Slash.second; DirIndex = 0; for (unsigned End = MCDwarfDirs.size(); DirIndex < End; DirIndex++) { if (Directory == MCDwarfDirs[DirIndex]) @@ -291,16 +301,16 @@ unsigned MCContext::GetDwarfFile(StringRef FileName, unsigned FileNumber) { } // The DirIndex is one based, as DirIndex of 0 is used for FileNames with // no directories. MCDwarfDirs[] is unlike MCDwarfFiles[] in that the - // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames are - // stored at MCDwarfFiles[FileNumber].Name . + // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames + // are stored at MCDwarfFiles[FileNumber].Name . DirIndex++; } // Now make the MCDwarfFile entry and place it in the slot in the MCDwarfFiles // vector. - char *Buf = static_cast<char *>(Allocate(Name.size())); - memcpy(Buf, Name.data(), Name.size()); - File = new (*this) MCDwarfFile(StringRef(Buf, Name.size()), DirIndex); + char *Buf = static_cast<char *>(Allocate(FileName.size())); + memcpy(Buf, FileName.data(), FileName.size()); + File = new (*this) MCDwarfFile(StringRef(Buf, FileName.size()), DirIndex); // return the allocated FileNumber. return FileNumber; @@ -314,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/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp index 16e66dc98e74..35f675dc6d1b 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp +++ b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp @@ -15,10 +15,13 @@ #include "llvm/MC/MCDisassembler.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.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; @@ -36,6 +39,12 @@ 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(); @@ -50,6 +59,9 @@ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(TripleName); assert(MAI && "Unable to create target asm info!"); + const MCInstrInfo *MII = TheTarget->createMCInstrInfo(); + assert(MII && "Unable to create target instruction info!"); + const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(TripleName); assert(MRI && "Unable to create target register info!"); @@ -73,13 +85,13 @@ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, // Set up the instruction printer. int AsmPrinterVariant = MAI->getAssemblerDialect(); MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant, - *MAI, *STI); + *MAI, *MII, *MRI, *STI); assert(IP && "Unable to create instruction printer!"); LLVMDisasmContext *DC = new LLVMDisasmContext(TripleName, DisInfo, TagType, GetOpInfo, SymbolLookUp, TheTarget, MAI, MRI, - Ctx, DisAsm, IP); + STI, MII, Ctx, DisAsm, IP); assert(DC && "Allocation failure!"); return DC; @@ -170,5 +182,5 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes, return Size; } } - return 0; + llvm_unreachable("Invalid DecodeStatus!"); } diff --git a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h index 238ff7d50025..880a31ad76b9 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h +++ b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h @@ -28,7 +28,9 @@ class MCContext; class MCAsmInfo; class MCDisassembler; class MCInstPrinter; +class MCInstrInfo; class MCRegisterInfo; +class MCSubtargetInfo; class Target; // @@ -61,6 +63,10 @@ private: llvm::OwningPtr<const llvm::MCAsmInfo> MAI; // The register information for the target architecture. llvm::OwningPtr<const llvm::MCRegisterInfo> MRI; + // The subtarget information for the target architecture. + llvm::OwningPtr<const llvm::MCSubtargetInfo> MSI; + // The instruction information for the target architecture. + llvm::OwningPtr<const llvm::MCInstrInfo> MII; // The assembly context for creating symbols and MCExprs. llvm::OwningPtr<const llvm::MCContext> Ctx; // The disassembler for the target architecture. @@ -78,6 +84,8 @@ public: LLVMSymbolLookupCallback symbolLookUp, const Target *theTarget, const MCAsmInfo *mAI, const MCRegisterInfo *mRI, + const MCSubtargetInfo *mSI, + const MCInstrInfo *mII, llvm::MCContext *ctx, const MCDisassembler *disAsm, MCInstPrinter *iP) : TripleName(tripleName), DisInfo(disInfo), TagType(tagType), GetOpInfo(getOpInfo), @@ -85,6 +93,8 @@ public: CommentStream(CommentsToEmit) { MAI.reset(mAI); MRI.reset(mRI); + MSI.reset(mSI); + MII.reset(mII); Ctx.reset(ctx); DisAsm.reset(disAsm); IP.reset(iP); diff --git a/contrib/llvm/lib/MC/MCDisassembler/EDDisassembler.cpp b/contrib/llvm/lib/MC/MCDisassembler/EDDisassembler.cpp index 83362a21f77b..b2672ca3ccba 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/EDDisassembler.cpp +++ b/contrib/llvm/lib/MC/MCDisassembler/EDDisassembler.cpp @@ -22,6 +22,7 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -34,10 +35,8 @@ #include "llvm/Support/MemoryObject.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/TargetSelect.h" using namespace llvm; -bool EDDisassembler::sInitialized = false; EDDisassembler::DisassemblerMap_t EDDisassembler::sDisassemblers; struct TripleMap { @@ -49,8 +48,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, @@ -77,90 +75,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; } -} -void EDDisassembler::initialize() { - if (sInitialized) - return; - - sInitialized = true; - - InitializeAllTargetInfos(); - InitializeAllTargetMCs(); - InitializeAllAsmParsers(); - InitializeAllDisassemblers(); + return -1; } -#undef BRINGUP_TARGET - 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) @@ -189,10 +166,16 @@ EDDisassembler::EDDisassembler(CPUKey &key) : return; InstInfos = Disassembler->getEDInfo(); - + + MII.reset(Tgt->createMCInstrInfo()); + + if (!MII) + return; + 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, + *MII, *MRI, *STI)); if (!InstPrinter) return; @@ -279,7 +262,7 @@ void EDDisassembler::initMaps(const MCRegisterInfo ®isterInfo) { RegRMap[registerName] = registerIndex; } - switch (Key.Arch) { + switch (TgtTriple.getArch()) { default: break; case Triple::x86: @@ -337,13 +320,9 @@ int EDDisassembler::printInst(std::string &str, MCInst &inst) { return 0; } -static void diag_handler(const SMDiagnostic &diag, - void *context) -{ - if (context) { - EDDisassembler *disassembler = static_cast<EDDisassembler*>(context); - diag.Print("", disassembler->ErrorStream); - } +static void diag_handler(const SMDiagnostic &diag, void *context) { + if (context) + diag.print("", static_cast<EDDisassembler*>(context)->ErrorStream); } int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands, @@ -351,7 +330,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: @@ -376,8 +355,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/contrib/llvm/lib/MC/MCDisassembler/EDDisassembler.h b/contrib/llvm/lib/MC/MCDisassembler/EDDisassembler.h index 38c22038c510..6f71908d2bcf 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/EDDisassembler.h +++ b/contrib/llvm/lib/MC/MCDisassembler/EDDisassembler.h @@ -25,6 +25,7 @@ #include <map> #include <set> +#include <string> #include <vector> namespace llvm { @@ -35,8 +36,9 @@ class MCContext; class MCAsmInfo; class MCAsmLexer; class MCDisassembler; -class MCInstPrinter; class MCInst; +class MCInstPrinter; +class MCInstrInfo; class MCParsedAsmOperand; class MCRegisterInfo; class MCStreamer; @@ -74,28 +76,26 @@ 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))); } }; typedef std::map<CPUKey, EDDisassembler*> DisassemblerMap_t; - /// True if the disassembler registry has been initialized; false if not - static bool sInitialized; /// A map from disassembler specifications to disassemblers. Populated /// lazily. static DisassemblerMap_t sDisassemblers; @@ -116,9 +116,6 @@ struct EDDisassembler { static EDDisassembler *getDisassembler(llvm::StringRef str, AssemblySyntax syntax); - /// initialize - Initializes the disassembler registry and the LLVM backend - static void initialize(); - //////////////////////// // Per-object members // //////////////////////// @@ -131,14 +128,18 @@ 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 llvm::OwningPtr<const llvm::MCAsmInfo> AsmInfo; /// The subtarget information for the target architecture llvm::OwningPtr<const llvm::MCSubtargetInfo> STI; + // The instruction information for the target architecture. + llvm::OwningPtr<const llvm::MCInstrInfo> MII; // The register information for the target architecture. llvm::OwningPtr<const llvm::MCRegisterInfo> MRI; /// The disassembler for the target architecture diff --git a/contrib/llvm/lib/MC/MCDisassembler/EDMain.cpp b/contrib/llvm/lib/MC/MCDisassembler/EDMain.cpp new file mode 100644 index 000000000000..c658717b0249 --- /dev/null +++ b/contrib/llvm/lib/MC/MCDisassembler/EDMain.cpp @@ -0,0 +1,280 @@ +//===-- EDMain.cpp - LLVM Enhanced Disassembly C API ----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the enhanced disassembler's public C API. +// +//===----------------------------------------------------------------------===// + +#include "EDDisassembler.h" +#include "EDInst.h" +#include "EDOperand.h" +#include "EDToken.h" +#include "llvm-c/EnhancedDisassembly.h" +using namespace llvm; + +int EDGetDisassembler(EDDisassemblerRef *disassembler, + const char *triple, + EDAssemblySyntax_t syntax) { + EDDisassembler::AssemblySyntax Syntax; + switch (syntax) { + default: llvm_unreachable("Unknown assembly syntax!"); + case kEDAssemblySyntaxX86Intel: + Syntax = EDDisassembler::kEDAssemblySyntaxX86Intel; + break; + case kEDAssemblySyntaxX86ATT: + Syntax = EDDisassembler::kEDAssemblySyntaxX86ATT; + break; + case kEDAssemblySyntaxARMUAL: + Syntax = EDDisassembler::kEDAssemblySyntaxARMUAL; + break; + } + + EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple, Syntax); + + if (!ret) + return -1; + *disassembler = ret; + return 0; +} + +int EDGetRegisterName(const char** regName, + EDDisassemblerRef disassembler, + unsigned regID) { + const char *name = ((EDDisassembler*)disassembler)->nameWithRegisterID(regID); + if (!name) + return -1; + *regName = name; + return 0; +} + +int EDRegisterIsStackPointer(EDDisassemblerRef disassembler, + unsigned regID) { + return ((EDDisassembler*)disassembler)->registerIsStackPointer(regID) ? 1 : 0; +} + +int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler, + unsigned regID) { + return ((EDDisassembler*)disassembler)->registerIsProgramCounter(regID) ? 1:0; +} + +unsigned int EDCreateInsts(EDInstRef *insts, + unsigned int count, + EDDisassemblerRef disassembler, + ::EDByteReaderCallback byteReader, + uint64_t address, + void *arg) { + unsigned int index; + + for (index = 0; index < count; ++index) { + EDInst *inst = ((EDDisassembler*)disassembler)->createInst(byteReader, + address, arg); + + if (!inst) + return index; + + insts[index] = inst; + address += inst->byteSize(); + } + + return count; +} + +void EDReleaseInst(EDInstRef inst) { + delete ((EDInst*)inst); +} + +int EDInstByteSize(EDInstRef inst) { + return ((EDInst*)inst)->byteSize(); +} + +int EDGetInstString(const char **buf, + EDInstRef inst) { + return ((EDInst*)inst)->getString(*buf); +} + +int EDInstID(unsigned *instID, EDInstRef inst) { + *instID = ((EDInst*)inst)->instID(); + return 0; +} + +int EDInstIsBranch(EDInstRef inst) { + return ((EDInst*)inst)->isBranch(); +} + +int EDInstIsMove(EDInstRef inst) { + return ((EDInst*)inst)->isMove(); +} + +int EDBranchTargetID(EDInstRef inst) { + return ((EDInst*)inst)->branchTargetID(); +} + +int EDMoveSourceID(EDInstRef inst) { + return ((EDInst*)inst)->moveSourceID(); +} + +int EDMoveTargetID(EDInstRef inst) { + return ((EDInst*)inst)->moveTargetID(); +} + +int EDNumTokens(EDInstRef inst) { + return ((EDInst*)inst)->numTokens(); +} + +int EDGetToken(EDTokenRef *token, + EDInstRef inst, + int index) { + return ((EDInst*)inst)->getToken(*(EDToken**)token, index); +} + +int EDGetTokenString(const char **buf, + EDTokenRef token) { + return ((EDToken*)token)->getString(*buf); +} + +int EDOperandIndexForToken(EDTokenRef token) { + return ((EDToken*)token)->operandID(); +} + +int EDTokenIsWhitespace(EDTokenRef token) { + return ((EDToken*)token)->type() == EDToken::kTokenWhitespace; +} + +int EDTokenIsPunctuation(EDTokenRef token) { + return ((EDToken*)token)->type() == EDToken::kTokenPunctuation; +} + +int EDTokenIsOpcode(EDTokenRef token) { + return ((EDToken*)token)->type() == EDToken::kTokenOpcode; +} + +int EDTokenIsLiteral(EDTokenRef token) { + return ((EDToken*)token)->type() == EDToken::kTokenLiteral; +} + +int EDTokenIsRegister(EDTokenRef token) { + return ((EDToken*)token)->type() == EDToken::kTokenRegister; +} + +int EDTokenIsNegativeLiteral(EDTokenRef token) { + if (((EDToken*)token)->type() != EDToken::kTokenLiteral) + return -1; + + return ((EDToken*)token)->literalSign(); +} + +int EDLiteralTokenAbsoluteValue(uint64_t *value, EDTokenRef token) { + if (((EDToken*)token)->type() != EDToken::kTokenLiteral) + return -1; + + return ((EDToken*)token)->literalAbsoluteValue(*value); +} + +int EDRegisterTokenValue(unsigned *registerID, + EDTokenRef token) { + if (((EDToken*)token)->type() != EDToken::kTokenRegister) + return -1; + + return ((EDToken*)token)->registerID(*registerID); +} + +int EDNumOperands(EDInstRef inst) { + return ((EDInst*)inst)->numOperands(); +} + +int EDGetOperand(EDOperandRef *operand, + EDInstRef inst, + int index) { + return ((EDInst*)inst)->getOperand(*(EDOperand**)operand, index); +} + +int EDOperandIsRegister(EDOperandRef operand) { + return ((EDOperand*)operand)->isRegister(); +} + +int EDOperandIsImmediate(EDOperandRef operand) { + return ((EDOperand*)operand)->isImmediate(); +} + +int EDOperandIsMemory(EDOperandRef operand) { + return ((EDOperand*)operand)->isMemory(); +} + +int EDRegisterOperandValue(unsigned *value, EDOperandRef operand) { + if (!((EDOperand*)operand)->isRegister()) + return -1; + *value = ((EDOperand*)operand)->regVal(); + return 0; +} + +int EDImmediateOperandValue(uint64_t *value, EDOperandRef operand) { + if (!((EDOperand*)operand)->isImmediate()) + return -1; + *value = ((EDOperand*)operand)->immediateVal(); + return 0; +} + +int EDEvaluateOperand(uint64_t *result, EDOperandRef operand, + ::EDRegisterReaderCallback regReader, void *arg) { + return ((EDOperand*)operand)->evaluate(*result, regReader, arg); +} + +#ifdef __BLOCKS__ + +struct ByteReaderWrapper { + EDByteBlock_t byteBlock; +}; + +static int readerWrapperCallback(uint8_t *byte, + uint64_t address, + void *arg) { + struct ByteReaderWrapper *wrapper = (struct ByteReaderWrapper *)arg; + return wrapper->byteBlock(byte, address); +} + +unsigned int EDBlockCreateInsts(EDInstRef *insts, + int count, + EDDisassemblerRef disassembler, + EDByteBlock_t byteBlock, + uint64_t address) { + struct ByteReaderWrapper wrapper; + wrapper.byteBlock = byteBlock; + + return EDCreateInsts(insts, + count, + disassembler, + readerWrapperCallback, + address, + (void*)&wrapper); +} + +int EDBlockEvaluateOperand(uint64_t *result, EDOperandRef operand, + EDRegisterBlock_t regBlock) { + return ((EDOperand*)operand)->evaluate(*result, regBlock); +} + +int EDBlockVisitTokens(EDInstRef inst, ::EDTokenVisitor_t visitor) { + return ((EDInst*)inst)->visitTokens((llvm::EDTokenVisitor_t)visitor); +} + +#else + +extern "C" unsigned int EDBlockCreateInsts() { + return 0; +} + +extern "C" int EDBlockEvaluateOperand() { + return -1; +} + +extern "C" int EDBlockVisitTokens() { + return -1; +} + +#endif diff --git a/contrib/llvm/lib/MC/MCDisassembler/EDOperand.cpp b/contrib/llvm/lib/MC/MCDisassembler/EDOperand.cpp index 6a4e56ff72c4..48b374659d5e 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/EDOperand.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/MC/MCDwarf.cpp b/contrib/llvm/lib/MC/MCDwarf.cpp index 4658a3093fab..84a34f1d8735 100644 --- a/contrib/llvm/lib/MC/MCDwarf.cpp +++ b/contrib/llvm/lib/MC/MCDwarf.cpp @@ -19,10 +19,12 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/FoldingSet.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/ADT/Hashing.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" +#include "llvm/Config/config.h" using namespace llvm; // Given a special op, return the address skip amount (in units of @@ -207,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()); @@ -320,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. @@ -372,10 +376,7 @@ void MCDwarfLineAddr::Encode(int64_t LineDelta, uint64_t AddrDelta, // it with DW_LNS_advance_line. if (Temp >= DWARF2_LINE_RANGE) { OS << char(dwarf::DW_LNS_advance_line); - SmallString<32> Tmp; - raw_svector_ostream OSE(Tmp); - MCObjectWriter::EncodeSLEB128(LineDelta, OSE); - OS << OSE.str(); + MCObjectWriter::EncodeSLEB128(LineDelta, OS); LineDelta = 0; Temp = 0 - DWARF2_LINE_BASE; @@ -411,10 +412,7 @@ void MCDwarfLineAddr::Encode(int64_t LineDelta, uint64_t AddrDelta, // Otherwise use DW_LNS_advance_pc. OS << char(dwarf::DW_LNS_advance_pc); - SmallString<32> Tmp; - raw_svector_ostream OSE(Tmp); - MCObjectWriter::EncodeULEB128(AddrDelta, OSE); - OS << OSE.str(); + MCObjectWriter::EncodeULEB128(AddrDelta, OS); if (NeedCopy) OS << char(dwarf::DW_LNS_copy); @@ -430,6 +428,349 @@ void MCDwarfFile::dump() const { print(dbgs()); } +// Utility function to write a tuple for .debug_abbrev. +static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form) { + MCOS->EmitULEB128IntValue(Name); + MCOS->EmitULEB128IntValue(Form); +} + +// When generating dwarf for assembly source files this emits +// the data for .debug_abbrev section which contains three DIEs. +static void EmitGenDwarfAbbrev(MCStreamer *MCOS) { + MCContext &context = MCOS->getContext(); + MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection()); + + // DW_TAG_compile_unit DIE abbrev (1). + MCOS->EmitULEB128IntValue(1); + MCOS->EmitULEB128IntValue(dwarf::DW_TAG_compile_unit); + MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1); + EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, 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_name, dwarf::DW_FORM_string); + EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string); + StringRef DwarfDebugFlags = context.getDwarfDebugFlags(); + if (!DwarfDebugFlags.empty()) + EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string); + EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string); + EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2); + EmitAbbrev(MCOS, 0, 0); + + // DW_TAG_label DIE abbrev (2). + MCOS->EmitULEB128IntValue(2); + 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_prototyped, dwarf::DW_FORM_flag); + EmitAbbrev(MCOS, 0, 0); + + // DW_TAG_unspecified_parameters DIE abbrev (3). + MCOS->EmitULEB128IntValue(3); + MCOS->EmitULEB128IntValue(dwarf::DW_TAG_unspecified_parameters); + MCOS->EmitIntValue(dwarf::DW_CHILDREN_no, 1); + EmitAbbrev(MCOS, 0, 0); + + // Terminate the abbreviations for this compilation unit. + MCOS->EmitIntValue(0, 1); +} + +// When generating dwarf for assembly source files this emits the data for +// .debug_aranges section. Which contains a header and a table of pairs of +// PointerSize'ed values for the address and size of section(s) with line table +// entries (just the default .text in our case) and a terminating pair of zeros. +static void EmitGenDwarfAranges(MCStreamer *MCOS) { + MCContext &context = MCOS->getContext(); + + // Create a symbol at the end of the section that we are creating the dwarf + // debugging info to use later in here as part of the expression to calculate + // the size of the section for the table. + MCOS->SwitchSection(context.getGenDwarfSection()); + MCSymbol *SectionEndSym = context.CreateTempSymbol(); + MCOS->EmitLabel(SectionEndSym); + context.setGenDwarfSectionEndSym(SectionEndSym); + + MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection()); + + // This will be the length of the .debug_aranges section, first account for + // the size of each item in the header (see below where we emit these items). + int Length = 4 + 2 + 4 + 1 + 1; + + // Figure the padding after the header before the table of address and size + // pairs who's values are PointerSize'ed. + const MCAsmInfo &asmInfo = context.getAsmInfo(); + int AddrSize = asmInfo.getPointerSize(); + int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1)); + if (Pad == 2 * AddrSize) + Pad = 0; + Length += Pad; + + // Add the size of the pair of PointerSize'ed values for the address and size + // of the one default .text section we have in the table. + Length += 2 * AddrSize; + // And the pair of terminating zeros. + Length += 2 * AddrSize; + + + // Emit the header for this section. + // The 4 byte length not including the 4 byte value for the length. + MCOS->EmitIntValue(Length - 4, 4); + // The 2 byte version, which is 2. + MCOS->EmitIntValue(2, 2); + // The 4 byte offset to the compile unit in the .debug_info from the start + // of the .debug_info, it is at the start of that section so this is zero. + MCOS->EmitIntValue(0, 4); + // The 1 byte size of an address. + MCOS->EmitIntValue(AddrSize, 1); + // The 1 byte size of a segment descriptor, we use a value of zero. + MCOS->EmitIntValue(0, 1); + // Align the header with the padding if needed, before we put out the table. + for(int i = 0; i < Pad; i++) + MCOS->EmitIntValue(0, 1); + + // Now emit the table of pairs of PointerSize'ed values for the section(s) + // address and size, in our case just the one default .text section. + const MCExpr *Addr = MCSymbolRefExpr::Create( + context.getGenDwarfSectionStartSym(), MCSymbolRefExpr::VK_None, context); + const MCExpr *Size = MakeStartMinusEndExpr(*MCOS, + *context.getGenDwarfSectionStartSym(), *SectionEndSym, 0); + MCOS->EmitAbsValue(Addr, AddrSize); + MCOS->EmitAbsValue(Size, AddrSize); + + // And finally the pair of terminating zeros. + MCOS->EmitIntValue(0, AddrSize); + MCOS->EmitIntValue(0, AddrSize); +} + +// 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 label DIEs. +static void EmitGenDwarfInfo(MCStreamer *MCOS, + const MCSymbol *AbbrevSectionSymbol, + const MCSymbol *LineSectionSymbol) { + MCContext &context = MCOS->getContext(); + + MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection()); + + // Create a symbol at the start and end of this section used in here for the + // expression to calculate the length in the header. + MCSymbol *InfoStart = context.CreateTempSymbol(); + MCOS->EmitLabel(InfoStart); + MCSymbol *InfoEnd = context.CreateTempSymbol(); + + // First part: the header. + + // The 4 byte total length of the information for this compilation unit, not + // including these 4 bytes. + const MCExpr *Length = MakeStartMinusEndExpr(*MCOS, *InfoStart, *InfoEnd, 4); + MCOS->EmitAbsValue(Length, 4); + + // The 2 byte DWARF version, which is 2. + MCOS->EmitIntValue(2, 2); + + // 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. + if (AbbrevSectionSymbol) { + MCOS->EmitSymbolValue(AbbrevSectionSymbol, 4); + } else { + MCOS->EmitIntValue(0, 4); + } + + const MCAsmInfo &asmInfo = context.getAsmInfo(); + int AddrSize = asmInfo.getPointerSize(); + // The 1 byte size of an address. + MCOS->EmitIntValue(AddrSize, 1); + + // Second part: the compile_unit DIE. + + // The DW_TAG_compile_unit DIE abbrev (1). + MCOS->EmitULEB128IntValue(1); + + // 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. + 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( + context.getGenDwarfSectionStartSym(), MCSymbolRefExpr::VK_None, context); + MCOS->EmitAbsValue(Start, AddrSize); + + // AT_high_pc, the last address of the default .text section. + const MCExpr *End = MCSymbolRefExpr::Create( + context.getGenDwarfSectionEndSym(), MCSymbolRefExpr::VK_None, context); + MCOS->EmitAbsValue(End, AddrSize); + + // AT_name, the name of the source file. Reconstruct from the first directory + // and file table entries. + const std::vector<StringRef> &MCDwarfDirs = + context.getMCDwarfDirs(); + if (MCDwarfDirs.size() > 0) { + MCOS->EmitBytes(MCDwarfDirs[0], 0); + MCOS->EmitBytes("/", 0); + } + const std::vector<MCDwarfFile *> &MCDwarfFiles = + MCOS->getContext().getMCDwarfFiles(); + MCOS->EmitBytes(MCDwarfFiles[1]->getName(), 0); + MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string. + + // AT_comp_dir, the working directory the assembly was done in. + llvm::sys::Path CWD = llvm::sys::Path::GetCurrentDirectory(); + MCOS->EmitBytes(StringRef(CWD.c_str()), 0); + MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string. + + // AT_APPLE_flags, the command line arguments of the assembler tool. + StringRef DwarfDebugFlags = context.getDwarfDebugFlags(); + if (!DwarfDebugFlags.empty()){ + MCOS->EmitBytes(DwarfDebugFlags, 0); + MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string. + } + + // AT_producer, the version of the assembler tool. + MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM "), 0); + MCOS->EmitBytes(StringRef(PACKAGE_VERSION), 0); + MCOS->EmitBytes(StringRef(")"), 0); + MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string. + + // AT_language, a 4 byte value. We use DW_LANG_Mips_Assembler as the dwarf2 + // draft has no standard code for assembler. + MCOS->EmitIntValue(dwarf::DW_LANG_Mips_Assembler, 2); + + // Third part: the list of label DIEs. + + // 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 MCGenDwarfLabelEntry *Entry = *it; + + // The DW_TAG_label DIE abbrev (2). + MCOS->EmitULEB128IntValue(2); + + // AT_name, of the label without any leading underbar. + MCOS->EmitBytes(Entry->getName(), 0); + MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string. + + // AT_decl_file, index into the file table. + MCOS->EmitIntValue(Entry->getFileNumber(), 4); + + // AT_decl_line, source line number. + MCOS->EmitIntValue(Entry->getLineNumber(), 4); + + // AT_low_pc, start address of the label. + const MCExpr *AT_low_pc = MCSymbolRefExpr::Create(Entry->getLabel(), + MCSymbolRefExpr::VK_None, context); + MCOS->EmitAbsValue(AT_low_pc, AddrSize); + + // DW_AT_prototyped, a one byte flag value of 0 saying we have no prototype. + MCOS->EmitIntValue(0, 1); + + // The DW_TAG_unspecified_parameters DIE abbrev (3). + MCOS->EmitULEB128IntValue(3); + + // Add the NULL DIE terminating the DW_TAG_unspecified_parameters DIE's. + MCOS->EmitIntValue(0, 1); + } + // 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 MCGenDwarfLabelEntry *Entry = *it; + delete Entry; + } + + // Add the NULL DIE terminating the Compile Unit DIE's. + MCOS->EmitIntValue(0, 1); + + // Now set the value of the symbol at the end of the info section. + MCOS->EmitLabel(InfoEnd); +} + +// +// When generating dwarf for assembly source files this emits the Dwarf +// sections. +// +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. + if (context.getMCLineSections().empty()) + return; + + // Output the data for .debug_aranges section. + EmitGenDwarfAranges(MCOS); + + // Output the data for .debug_abbrev section. + EmitGenDwarfAbbrev(MCOS); + + // Output the data for .debug_info section. + 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 label. +// +void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS, + SourceMgr &SrcMgr, SMLoc &Loc) { + // We won't create dwarf labels for temporary symbols or symbols not in + // the default text. + if (Symbol->isTemporary()) + return; + MCContext &context = MCOS->getContext(); + if (context.getGenDwarfSection() != MCOS->getCurrentSection()) + return; + + // 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 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 label. + int CurBuffer = SrcMgr.FindBufferContainingLoc(Loc); + unsigned LineNumber = SrcMgr.FindLineNumber(Loc, CurBuffer); + + // We create a temporary symbol for use for the AT_high_pc and AT_low_pc + // values so that they don't have things like an ARM thumb bit from the + // original symbol. So when used they won't get a low bit set after + // relocation. + MCSymbol *Label = context.CreateTempSymbol(); + MCOS->EmitLabel(Label); + + // Create and entry for the info and add it to the other entries. + MCGenDwarfLabelEntry *Entry = + new MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label); + MCOS->getContext().addMCGenDwarfLabelEntry(Entry); +} + static int getDataAlignmentFactor(MCStreamer &streamer) { MCContext &context = streamer.getContext(); const MCAsmInfo &asmInfo = context.getAsmInfo(); @@ -445,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(); @@ -520,6 +860,7 @@ namespace { const MCSymbol *personality, unsigned personalityEncoding, const MCSymbol *lsda, + bool IsSignalFrame, unsigned lsdaEncoding); MCSymbol *EmitFDE(MCStreamer &streamer, const MCSymbol &cieStart, @@ -536,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); @@ -639,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; @@ -655,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"); } @@ -738,8 +1104,8 @@ bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, // Compact Encoding Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_udata4); - if (VerboseAsm) Streamer.AddComment(Twine("Compact Unwind Encoding: 0x") + - Twine(llvm::utohexstr(Encoding))); + if (VerboseAsm) Streamer.AddComment("Compact Unwind Encoding: 0x" + + Twine::utohexstr(Encoding)); Streamer.EmitIntValue(Encoding, Size); @@ -766,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(); @@ -808,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); @@ -967,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; }; } @@ -991,17 +1361,17 @@ namespace llvm { return CIEKey::getTombstoneKey(); } static unsigned getHashValue(const CIEKey &Key) { - FoldingSetNodeID ID; - ID.AddPointer(Key.Personality); - ID.AddInteger(Key.PersonalityEncoding); - ID.AddInteger(Key.LsdaEncoding); - return ID.ComputeHash(); + return static_cast<unsigned>(hash_combine(Key.Personality, + Key.PersonalityEncoding, + Key.LsdaEncoding, + Key.IsSignalFrame)); } 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; } }; } @@ -1016,12 +1386,10 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getFrameInfos(); // Emit the compact unwind info if available. - // FIXME: This emits both the compact unwind and the old CIE/FDE - // information. Only one of those is needed. if (IsEH && MOFI->getCompactUnwindSection()) for (unsigned i = 0, n = Streamer.getNumFrameInfos(); i < n; ++i) { const MCDwarfFrameInfo &Frame = Streamer.getFrameInfo(i); - if (!Frame.CompactUnwindEncoding) + if (Frame.CompactUnwindEncoding) Emitter.EmitCompactUnwind(Streamer, Frame); } @@ -1039,11 +1407,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/contrib/llvm/lib/MC/MCELF.cpp b/contrib/llvm/lib/MC/MCELF.cpp index dad2e7ba9878..f9f98e0f730e 100644 --- a/contrib/llvm/lib/MC/MCELF.cpp +++ b/contrib/llvm/lib/MC/MCELF.cpp @@ -37,7 +37,7 @@ void MCELF::SetType(MCSymbolData &SD, unsigned Type) { assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT || Type == ELF::STT_FUNC || Type == ELF::STT_SECTION || Type == ELF::STT_FILE || Type == ELF::STT_COMMON || - Type == ELF::STT_TLS); + Type == ELF::STT_TLS || Type == ELF::STT_GNU_IFUNC); uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STT_Shift); SD.setFlags(OtherFlags | (Type << ELF_STT_Shift)); @@ -48,7 +48,7 @@ unsigned MCELF::GetType(const MCSymbolData &SD) { assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT || Type == ELF::STT_FUNC || Type == ELF::STT_SECTION || Type == ELF::STT_FILE || Type == ELF::STT_COMMON || - Type == ELF::STT_TLS); + Type == ELF::STT_TLS || Type == ELF::STT_GNU_IFUNC); return Type; } diff --git a/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp b/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp index 12a02a9e9740..171ab4d9bf28 100644 --- a/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp +++ b/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp @@ -7,17 +7,40 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/STLExtras.h" #include "llvm/MC/MCELFObjectWriter.h" 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) { +} + +void +MCELFObjectTargetWriter::sortRelocs(const MCAssembler &Asm, + std::vector<ELFRelocationEntry> &Relocs) { + // Sort by the r_offset, just like gnu as does. + array_pod_sort(Relocs.begin(), Relocs.end()); } diff --git a/contrib/llvm/lib/MC/MCELFStreamer.cpp b/contrib/llvm/lib/MC/MCELFStreamer.cpp index 9ada08ea9530..6c4d0e33a115 100644 --- a/contrib/llvm/lib/MC/MCELFStreamer.cpp +++ b/contrib/llvm/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) { @@ -130,10 +251,8 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_WeakDefinition: case MCSA_WeakDefAutoPrivate: case MCSA_Invalid: - case MCSA_ELF_TypeIndFunction: 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. @@ -162,6 +281,10 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, MCELF::SetType(SD, ELF::STT_FUNC); break; + case MCSA_ELF_TypeIndFunction: + MCELF::SetType(SD, ELF::STT_GNU_IFUNC); + break; + case MCSA_ELF_TypeObject: MCELF::SetType(SD, ELF::STT_OBJECT); break; @@ -205,10 +328,10 @@ void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, if (MCELF::GetBinding(SD) == ELF_STB_Local) { const MCSection *Section = getAssembler().getContext().getELFSection(".bss", - ELF::SHT_NOBITS, - ELF::SHF_WRITE | - ELF::SHF_ALLOC, - SectionKind::getBSS()); + ELF::SHT_NOBITS, + ELF::SHF_WRITE | + ELF::SHF_ALLOC, + SectionKind::getBSS()); Symbol->setSection(*Section); struct LocalCommon L = {&SD, Size, ByteAlignment}; @@ -266,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) { @@ -308,6 +438,10 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { case MCSymbolRefExpr::VK_ARM_TLSGD: case MCSymbolRefExpr::VK_ARM_TPOFF: case MCSymbolRefExpr::VK_ARM_GOTTPOFF: + case MCSymbolRefExpr::VK_Mips_TLSGD: + case MCSymbolRefExpr::VK_Mips_GOTTPREL: + case MCSymbolRefExpr::VK_Mips_TPREL_HI: + case MCSymbolRefExpr::VK_Mips_TPREL_LO: break; } MCSymbolData &SD = getAssembler().getOrCreateSymbolData(symRef.getSymbol()); @@ -349,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(), @@ -372,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/contrib/llvm/lib/MC/MCELFStreamer.h b/contrib/llvm/lib/MC/MCELFStreamer.h deleted file mode 100644 index 10bf77580998..000000000000 --- a/contrib/llvm/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/contrib/llvm/lib/MC/MCExpr.cpp b/contrib/llvm/lib/MC/MCExpr.cpp index da297fb1d95a..78801557af3e 100644 --- a/contrib/llvm/lib/MC/MCExpr.cpp +++ b/contrib/llvm/lib/MC/MCExpr.cpp @@ -14,9 +14,11 @@ #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCObjectWriter.h" #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 +59,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 +73,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 +93,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 +133,7 @@ void MCExpr::print(raw_ostream &OS) const { } } - assert(0 && "Invalid expression kind!"); + llvm_unreachable("Invalid expression kind!"); } void MCExpr::dump() const { @@ -171,7 +172,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 +189,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 +358,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 +583,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 +624,5 @@ const MCSection *MCExpr::FindAssociatedSection() const { } } - assert(0 && "Invalid assembly expression kind!"); - return 0; + llvm_unreachable("Invalid assembly expression kind!"); } diff --git a/contrib/llvm/lib/MC/MCInst.cpp b/contrib/llvm/lib/MC/MCInst.cpp index 4cb628b395c3..7bbfd2efa136 100644 --- a/contrib/llvm/lib/MC/MCInst.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/MC/MCInstPrinter.cpp b/contrib/llvm/lib/MC/MCInstPrinter.cpp index 2317a2891f8b..847bcc0a1604 100644 --- a/contrib/llvm/lib/MC/MCInstPrinter.cpp +++ b/contrib/llvm/lib/MC/MCInstPrinter.cpp @@ -8,8 +8,10 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCInstrInfo.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; @@ -19,11 +21,11 @@ MCInstPrinter::~MCInstPrinter() { /// getOpcodeName - Return the name of the specified opcode enum (e.g. /// "MOV32ri") or empty if we can't resolve it. StringRef MCInstPrinter::getOpcodeName(unsigned Opcode) const { - return ""; + return MII.getName(Opcode); } 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/contrib/llvm/lib/MC/MCLoggingStreamer.cpp b/contrib/llvm/lib/MC/MCLoggingStreamer.cpp deleted file mode 100644 index 3fe8ac72c8ec..000000000000 --- a/contrib/llvm/lib/MC/MCLoggingStreamer.cpp +++ /dev/null @@ -1,250 +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 Filename) { - LogCall("EmitDwarfFileDirective", - "FileNo:" + Twine(FileNo) + " Filename:" + Filename); - return Child->EmitDwarfFileDirective(FileNo, 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/contrib/llvm/lib/MC/MCMachOStreamer.cpp b/contrib/llvm/lib/MC/MCMachOStreamer.cpp index aa35815dd19c..bc6cf773217c 100644 --- a/contrib/llvm/lib/MC/MCMachOStreamer.cpp +++ b/contrib/llvm/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,14 +150,10 @@ void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { case MCAF_SubsectionsViaSymbols: getAssembler().setSubsectionsViaSymbols(true); return; - default: - llvm_unreachable("invalid assembler flag!"); } } void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) { - // FIXME: Flag the function ISA as thumb with DW_AT_APPLE_isa. - // Remember that the function is a thumb function. Fixup and relocation // values will need adjusted. getAssembler().setIsThumbFunc(Symbol); @@ -215,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); @@ -377,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 @@ -409,7 +404,7 @@ void MCMachOStreamer::Finish() { } } - this->MCObjectStreamer::Finish(); + this->MCObjectStreamer::FinishImpl(); } MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB, diff --git a/contrib/llvm/lib/MC/MCModule.cpp b/contrib/llvm/lib/MC/MCModule.cpp index b1d09d945a39..f5631608330c 100644 --- a/contrib/llvm/lib/MC/MCModule.cpp +++ b/contrib/llvm/lib/MC/MCModule.cpp @@ -1,4 +1,4 @@ -//===- lib/MC/MCModule.cpp - MCModule implementation --------------------------===// +//===- lib/MC/MCModule.cpp - MCModule implementation ----------------------===// // // The LLVM Compiler Infrastructure // diff --git a/contrib/llvm/lib/MC/MCNullStreamer.cpp b/contrib/llvm/lib/MC/MCNullStreamer.cpp index a6c0adb6793f..7ff2d1bf641b 100644 --- a/contrib/llvm/lib/MC/MCNullStreamer.cpp +++ b/contrib/llvm/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,11 +80,12 @@ 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 Filename) { + virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename) { return false; } virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, @@ -92,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/contrib/llvm/lib/MC/MCObjectFileInfo.cpp b/contrib/llvm/lib/MC/MCObjectFileInfo.cpp index df8b99d2be6c..b22ae331c9a9 100644 --- a/contrib/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/contrib/llvm/lib/MC/MCObjectFileInfo.cpp @@ -56,8 +56,8 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) { TLSThreadInitSection = Ctx->getMachOSection("__DATA", "__thread_init", - MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS, - SectionKind::getDataRel()); + MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS, + SectionKind::getDataRel()); CStringSection // .cstring = Ctx->getMachOSection("__TEXT", "__cstring", @@ -152,6 +152,24 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) { SectionKind::getReadOnly()); // Debug Information. + DwarfAccelNamesSection = + Ctx->getMachOSection("__DWARF", "__apple_names", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + DwarfAccelObjCSection = + Ctx->getMachOSection("__DWARF", "__apple_objc", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + // 16 character section limit... + DwarfAccelNamespaceSection = + Ctx->getMachOSection("__DWARF", "__apple_namespac", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + DwarfAccelTypesSection = + Ctx->getMachOSection("__DWARF", "__apple_types", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + DwarfAbbrevSection = Ctx->getMachOSection("__DWARF", "__debug_abbrev", MCSectionMachO::S_ATTR_DEBUG, @@ -168,10 +186,6 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) { Ctx->getMachOSection("__DWARF", "__debug_frame", MCSectionMachO::S_ATTR_DEBUG, SectionKind::getMetadata()); - DwarfPubNamesSection = - Ctx->getMachOSection("__DWARF", "__debug_pubnames", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); DwarfPubTypesSection = Ctx->getMachOSection("__DWARF", "__debug_pubtypes", MCSectionMachO::S_ATTR_DEBUG, @@ -207,8 +221,8 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) { void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { if (T.getArch() == Triple::x86) { PersonalityEncoding = (RelocM == Reloc::PIC_) - ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 - : dwarf::DW_EH_PE_absptr; + ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 + : dwarf::DW_EH_PE_absptr; LSDAEncoding = (RelocM == Reloc::PIC_) ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_absptr; @@ -216,8 +230,8 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_absptr; TTypeEncoding = (RelocM == Reloc::PIC_) - ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 - : dwarf::DW_EH_PE_absptr; + ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 + : dwarf::DW_EH_PE_absptr; } else if (T.getArch() == Triple::x86_64) { FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; @@ -244,10 +258,22 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { } } + // Solaris requires different flags for .eh_frame to seemingly every other + // platform. + EHSectionType = ELF::SHT_PROGBITS; + EHSectionFlags = ELF::SHF_ALLOC; + if (T.getOS() == Triple::Solaris) { + if (T.getArch() == Triple::x86_64) + EHSectionType = ELF::SHT_X86_64_UNWIND; + else + 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 = @@ -347,15 +373,13 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { DwarfFrameSection = Ctx->getELFSection(".debug_frame", ELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); - DwarfPubNamesSection = - Ctx->getELFSection(".debug_pubnames", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); DwarfPubTypesSection = Ctx->getELFSection(".debug_pubtypes", ELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); DwarfStrSection = - Ctx->getELFSection(".debug_str", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_str", ELF::SHT_PROGBITS, + ELF::SHF_MERGE | ELF::SHF_STRINGS, + SectionKind::getMergeable1ByteCString()); DwarfLocSection = Ctx->getELFSection(".debug_loc", ELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); @@ -390,12 +414,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 | @@ -434,11 +468,6 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) { COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_MEM_READ, SectionKind::getMetadata()); - DwarfPubNamesSection = - Ctx->getCOFFSection(".debug_pubnames", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); DwarfPubTypesSection = Ctx->getCOFFSection(".debug_pubtypes", COFF::IMAGE_SCN_MEM_DISCARDABLE | @@ -488,6 +517,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, @@ -505,8 +540,12 @@ void MCObjectFileInfo::InitMCObjectFileInfo(StringRef TT, Reloc::Model relocm, PersonalityEncoding = LSDAEncoding = FDEEncoding = FDECFIEncoding = TTypeEncoding = dwarf::DW_EH_PE_absptr; - EHFrameSection = 0; // Created on demand. - CompactUnwindSection = 0; // Used only by selected targets. + EHFrameSection = 0; // Created on demand. + CompactUnwindSection = 0; // Used only by selected targets. + DwarfAccelNamesSection = 0; // Used only by selected targets. + DwarfAccelObjCSection = 0; // Used only by selected targets. + DwarfAccelNamespaceSection = 0; // Used only by selected targets. + DwarfAccelTypesSection = 0; // Used only by selected targets. Triple T(TT); Triple::ArchType Arch = T.getArch(); @@ -541,8 +580,8 @@ void MCObjectFileInfo::InitEHFrameSection() { SectionKind::getReadOnly()); else if (Env == IsELF) EHFrameSection = - Ctx->getELFSection(".eh_frame", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC, + Ctx->getELFSection(".eh_frame", EHSectionType, + EHSectionFlags, SectionKind::getDataRel()); else EHFrameSection = diff --git a/contrib/llvm/lib/MC/MCObjectStreamer.cpp b/contrib/llvm/lib/MC/MCObjectStreamer.cpp index a04ae0812a3e..bad7cfe38a17 100644 --- a/contrib/llvm/lib/MC/MCObjectStreamer.cpp +++ b/contrib/llvm/lib/MC/MCObjectStreamer.cpp @@ -7,17 +7,17 @@ // //===----------------------------------------------------------------------===// -#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCObjectStreamer.h" - -#include "llvm/Support/ErrorHandling.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCAsmBackend.h" +#include "llvm/Support/ErrorHandling.h" using namespace llvm; MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, @@ -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,14 +249,30 @@ 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; } -void MCObjectStreamer::Finish() { +// Associate GPRel32 fixup with data and resize data area +void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { + MCDataFragment *DF = getOrCreateDataFragment(); + + DF->addFixup(MCFixup::Create(DF->getContents().size(), + Value, + FK_GPRel_4)); + DF->getContents().resize(DF->getContents().size() + 4, 0); +} + +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, LineSectionSymbol); getAssembler().Finish(); } diff --git a/contrib/llvm/lib/MC/MCObjectWriter.cpp b/contrib/llvm/lib/MC/MCObjectWriter.cpp index efe9f68ee22b..030f24793c55 100644 --- a/contrib/llvm/lib/MC/MCObjectWriter.cpp +++ b/contrib/llvm/lib/MC/MCObjectWriter.cpp @@ -33,14 +33,22 @@ void MCObjectWriter::EncodeSLEB128(int64_t Value, raw_ostream &OS) { } /// Utility function to encode a ULEB128 value. -void MCObjectWriter::EncodeULEB128(uint64_t Value, raw_ostream &OS) { +void MCObjectWriter::EncodeULEB128(uint64_t Value, raw_ostream &OS, + unsigned Padding) { do { uint8_t Byte = Value & 0x7f; Value >>= 7; - if (Value != 0) + if (Value != 0 || Padding != 0) Byte |= 0x80; // Mark this byte that that more bytes will follow. OS << char(Byte); } while (Value != 0); + + // Pad with 0x80 and emit a null byte at the end. + if (Padding != 0) { + for (; Padding != 1; --Padding) + OS << '\x80'; + OS << '\x00'; + } } bool @@ -60,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/contrib/llvm/lib/MC/MCParser/AsmParser.cpp b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp index 16487579abfc..2d61cac62585 100644 --- a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp @@ -14,7 +14,6 @@ #include "llvm/ADT/APFloat.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" @@ -30,6 +29,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 +122,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,9 +146,20 @@ 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); - virtual bool Error(SMLoc L, const Twine &Msg); + virtual bool Warning(SMLoc L, const Twine &Msg, + ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()); + virtual bool Error(SMLoc L, const Twine &Msg, + ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()); const AsmToken &Lex(); @@ -171,14 +185,17 @@ private: void HandleMacroExit(); void PrintMacroInstantiations(); - void PrintMessage(SMLoc Loc, const Twine &Msg, const char *Type, - bool ShowLine = true) const { - SrcMgr.PrintMessage(Loc, Msg, Type, ShowLine); + void PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg, + ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const { + SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges); } static void DiagHandler(const SMDiagnostic &Diag, void *Context); /// EnterIncludeFile - Enter the specified file. This returns true on failure. bool EnterIncludeFile(const std::string &Filename); + /// ProcessIncbinFile - Process the specified file for the .incbin directive. + /// This returns true on failure. + bool ProcessIncbinFile(const std::string &Filename); /// \brief Reset the current lexer position to that given by \arg Loc. The /// current token is not set; clients should ensure Lex() is called @@ -225,6 +242,7 @@ private: bool ParseDirectiveAbort(); // ".abort" bool ParseDirectiveInclude(); // ".include" + bool ParseDirectiveIncbin(); // ".incbin" bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if" // ".ifdef" or ".ifndef", depending on expect_defined @@ -295,6 +313,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>( @@ -328,6 +352,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); @@ -352,7 +379,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(); @@ -395,21 +423,21 @@ void AsmParser::PrintMacroInstantiations() { // Print the active macro instantiation stack. for (std::vector<MacroInstantiation*>::const_reverse_iterator it = ActiveMacros.rbegin(), ie = ActiveMacros.rend(); it != ie; ++it) - PrintMessage((*it)->InstantiationLoc, "while in macro instantiation", - "note"); + PrintMessage((*it)->InstantiationLoc, SourceMgr::DK_Note, + "while in macro instantiation"); } -bool AsmParser::Warning(SMLoc L, const Twine &Msg) { +bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { if (FatalAssemblerWarnings) - return Error(L, Msg); - PrintMessage(L, Msg, "warning"); + return Error(L, Msg, Ranges); + PrintMessage(L, SourceMgr::DK_Warning, Msg, Ranges); PrintMacroInstantiations(); return false; } -bool AsmParser::Error(SMLoc L, const Twine &Msg) { +bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { HadError = true; - PrintMessage(L, Msg, "error"); + PrintMessage(L, SourceMgr::DK_Error, Msg, Ranges); PrintMacroInstantiations(); return true; } @@ -427,6 +455,21 @@ bool AsmParser::EnterIncludeFile(const std::string &Filename) { return false; } +/// Process the specified .incbin file by seaching for it in the include paths +/// then just emiting the byte contents of the file to the streamer. This +/// returns true on failure. +bool AsmParser::ProcessIncbinFile(const std::string &Filename) { + std::string IncludedFile; + int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); + if (NewBuf == -1) + return true; + + // Pick up the bytes from the file and emit them. + getStreamer().EmitBytes(SrcMgr.getMemoryBuffer(NewBuf)->getBuffer(), + DEFAULT_ADDRSPACE); + return false; +} + void AsmParser::JumpToLoc(SMLoc Loc) { CurBuffer = SrcMgr.FindBufferContainingLoc(Loc); Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer), Loc.getPointer()); @@ -462,6 +505,17 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { HadError = false; AsmCond StartingCondState = TheCondState; + // If we are generating dwarf for assembly source files save the initial text + // section and generate a .file directive. + if (getContext().getGenDwarfForAssembly()) { + getContext().setGenDwarfSection(getStreamer().getCurrentSection()); + MCSymbol *SectionStartSym = getContext().CreateTempSymbol(); + getStreamer().EmitLabel(SectionStartSym); + getContext().setGenDwarfSectionStartSym(SectionStartSym); + getStreamer().EmitDwarfFileDirective(getContext().nextGenDwarfFileNumber(), + StringRef(), SrcMgr.getMemoryBuffer(CurBuffer)->getBufferIdentifier()); + } + // While we have input, parse each statement. while (Lexer.isNot(AsmToken::Eof)) { if (!ParseStatement()) continue; @@ -501,8 +555,9 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { // FIXME: We would really like to refer back to where the symbol was // first referenced for a source location. We need to add something // to track that. Currently, we just point to the end of the file. - PrintMessage(getLexer().getLoc(), "assembler local symbol '" + - Sym->getName() + "' not defined", "error", false); + PrintMessage(getLexer().getLoc(), SourceMgr::DK_Error, + "assembler local symbol '" + Sym->getName() + + "' not defined"); } } @@ -749,8 +804,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. @@ -787,7 +841,6 @@ bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) { if (!ModifiedRes) { return TokError("invalid modifier '" + getTok().getIdentifier() + "' (no symbols present)"); - return true; } Res = ModifiedRes; @@ -1036,6 +1089,12 @@ bool AsmParser::ParseStatement() { // Emit the label. Out.EmitLabel(Sym); + // If we are generating dwarf for assembly source files then gather the + // info to make a dwarf label entry for this label if needed. + if (getContext().getGenDwarfForAssembly()) + MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(), + IDLoc); + // Consume any end of statement token, if present, to avoid spurious // AddBlankLine calls(). if (Lexer.is(AsmToken::EndOfStatement)) { @@ -1163,6 +1222,8 @@ bool AsmParser::ParseStatement() { return ParseDirectiveAbort(); if (IDVal == ".include") return ParseDirectiveInclude(); + if (IDVal == ".incbin") + return ParseDirectiveIncbin(); if (IDVal == ".code16") return TokError(Twine(IDVal) + " not supported yet"); @@ -1205,7 +1266,19 @@ bool AsmParser::ParseStatement() { } OS << "]"; - PrintMessage(IDLoc, OS.str(), "note"); + PrintMessage(IDLoc, SourceMgr::DK_Note, OS.str()); + } + + // If we are generating dwarf for assembly source files and the current + // section is the initial text section then generate a .loc directive for + // the instruction. + if (!HadError && getContext().getGenDwarfForAssembly() && + getContext().getGenDwarfSection() == getStreamer().getCurrentSection() ) { + getStreamer().EmitDwarfLocDirective(getContext().getGenDwarfFileNumber(), + SrcMgr.FindLineNumber(IDLoc, CurBuffer), + 0, DWARF2_LINE_DEFAULT_IS_STMT ? + DWARF2_FLAG_IS_STMT : 0, 0, 0, + StringRef()); } // If parsing succeeded, match the instruction. @@ -1294,7 +1367,7 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { if (Parser->SavedDiagHandler) Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext); else - Diag.Print(0, OS); + Diag.print(0, OS); return; } @@ -1309,19 +1382,15 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { int LineNo = Parser->CppHashLineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo); - SMDiagnostic NewDiag(*Diag.getSourceMgr(), - Diag.getLoc(), - Filename, - LineNo, - Diag.getColumnNo(), - Diag.getMessage(), - Diag.getLineContents(), - Diag.getShowLine()); + SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), + Filename, LineNo, Diag.getColumnNo(), + Diag.getKind(), Diag.getMessage(), + Diag.getLineContents(), Diag.getRanges()); if (Parser->SavedDiagHandler) Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext); else - NewDiag.Print(0, OS); + NewDiag.print(0, OS); } bool AsmParser::expandMacro(SmallString<256> &Buf, StringRef Body, @@ -1458,6 +1527,11 @@ bool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc, } Lex(); } + // If there weren't any arguments, erase the token vector so everything + // else knows that. Leaving around the vestigal empty token list confuses + // things. + if (MacroArguments.size() == 1 && MacroArguments.back().empty()) + MacroArguments.clear(); // Macro instantiation is lexical, unfortunately. We construct a new buffer // to hold the macro body with substitutions. @@ -1495,23 +1569,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) { @@ -1522,7 +1600,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"); @@ -1544,8 +1624,12 @@ 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->isVariable() && !Sym->isUsed() && allow_redef) + ; // Allow redefinitions of variables that haven't yet been used. else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef)) return Error(EqualLoc, "redefinition of '" + Name + "'"); else if (!Sym->isVariable()) @@ -1912,6 +1996,7 @@ bool AsmParser::ParseDirectiveOrg() { CheckForValidSection(); const MCExpr *Offset; + SMLoc Loc = getTok().getLoc(); if (ParseExpression(Offset)) return true; @@ -1931,9 +2016,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; } @@ -2178,6 +2265,31 @@ bool AsmParser::ParseDirectiveInclude() { return false; } +/// ParseDirectiveIncbin +/// ::= .incbin "filename" +bool AsmParser::ParseDirectiveIncbin() { + if (getLexer().isNot(AsmToken::String)) + return TokError("expected string in '.incbin' directive"); + + std::string Filename = getTok().getString(); + SMLoc IncbinLoc = getLexer().getLoc(); + Lex(); + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '.incbin' directive"); + + // Strip the quotes. + Filename = Filename.substr(1, Filename.size()-2); + + // Attempt to process the included file. + if (ProcessIncbinFile(Filename)) { + Error(IncbinLoc, "Could not find incbin file '" + Filename + "'"); + return true; + } + + return false; +} + /// ParseDirectiveIf /// ::= .if expression bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) { @@ -2305,7 +2417,8 @@ bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) { } /// ParseDirectiveFile -/// ::= .file [number] string +/// ::= .file [number] filename +/// ::= .file number directory filename bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) { // FIXME: I'm not sure what this is. int64_t FileNumber = -1; @@ -2321,17 +2434,35 @@ bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) { if (getLexer().isNot(AsmToken::String)) return TokError("unexpected token in '.file' directive"); - StringRef Filename = getTok().getString(); - Filename = Filename.substr(1, Filename.size()-2); + // Usually the directory and filename together, otherwise just the directory. + StringRef Path = getTok().getString(); + Path = Path.substr(1, Path.size()-2); Lex(); + StringRef Directory; + StringRef Filename; + if (getLexer().is(AsmToken::String)) { + if (FileNumber == -1) + return TokError("explicit path specified, but no file number"); + Filename = getTok().getString(); + Filename = Filename.substr(1, Filename.size()-2); + Directory = Path; + Lex(); + } else { + Filename = Path; + } + if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.file' directive"); if (FileNumber == -1) getStreamer().EmitFileDirective(Filename); else { - if (getStreamer().EmitDwarfFileDirective(FileNumber, Filename)) + 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"); } @@ -2719,6 +2850,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/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp index 185b5168bd6c..c4cdc3c9f96f 100644 --- a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp index d89112645cd8..ffc400b203f9 100644 --- a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -476,6 +476,7 @@ bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) { .Case("common", MCSA_ELF_TypeCommon) .Case("notype", MCSA_ELF_TypeNoType) .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) + .Case("gnu_indirect_function", MCSA_ELF_TypeIndFunction) .Default(MCSA_Invalid); if (Attr == MCSA_Invalid) diff --git a/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp b/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp index dceece78ba10..3a3ff147117e 100644 --- a/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp +++ b/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp @@ -25,3 +25,7 @@ SMLoc MCAsmLexer::getLoc() const { SMLoc AsmToken::getLoc() const { return SMLoc::getFromPointer(Str.data()); } + +SMLoc AsmToken::getEndLoc() const { + return SMLoc::getFromPointer(Str.data() + Str.size() - 1); +} diff --git a/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp index 5239ec753e77..3a825f03b776 100644 --- a/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp @@ -33,8 +33,8 @@ const AsmToken &MCAsmParser::getTok() { return getLexer().getTok(); } -bool MCAsmParser::TokError(const Twine &Msg) { - Error(getLexer().getLoc(), Msg); +bool MCAsmParser::TokError(const Twine &Msg, ArrayRef<SMRange> Ranges) { + Error(getLexer().getLoc(), Msg, Ranges); return true; } diff --git a/contrib/llvm/lib/MC/MCPureStreamer.cpp b/contrib/llvm/lib/MC/MCPureStreamer.cpp index 086c9229bcdc..a770c974380a 100644 --- a/contrib/llvm/lib/MC/MCPureStreamer.cpp +++ b/contrib/llvm/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) { @@ -93,9 +93,9 @@ public: virtual void EmitFileDirective(StringRef Filename) { report_fatal_error("unsupported directive in pure streamer"); } - virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) { + virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename) { report_fatal_error("unsupported directive in pure streamer"); - return false; } /// @} @@ -184,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) { @@ -223,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/contrib/llvm/lib/MC/MCStreamer.cpp b/contrib/llvm/lib/MC/MCStreamer.cpp index 3afa22b0d0be..43e62ff89a0f 100644 --- a/contrib/llvm/lib/MC/MCStreamer.cpp +++ b/contrib/llvm/lib/MC/MCStreamer.cpp @@ -16,7 +16,6 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include <cstdlib> using namespace llvm; @@ -94,17 +93,18 @@ void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size, /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the /// client having to pass in a MCExpr for constant integers. -void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace) { - SmallString<32> Tmp; +void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace, + unsigned Padding) { + SmallString<128> Tmp; raw_svector_ostream OSE(Tmp); - MCObjectWriter::EncodeULEB128(Value, OSE); + MCObjectWriter::EncodeULEB128(Value, OSE, Padding); EmitBytes(OSE.str(), 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"); } @@ -142,8 +146,9 @@ void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, } bool MCStreamer::EmitDwarfFileDirective(unsigned FileNo, + StringRef Directory, StringRef Filename) { - return getContext().GetDwarfFile(Filename, FileNo) == 0; + return getContext().GetDwarfFile(Directory, Filename, FileNo) == 0; } void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, @@ -186,9 +191,8 @@ void MCStreamer::EmitDataRegion() { if (!MAI.getSupportsDataRegions()) return; // Generate a unique symbol name. - MCSymbol *NewSym = Context.GetOrCreateSymbol( - Twine(MAI.getDataBeginLabelName()) + - utostr(UniqueDataBeginSuffix++)); + MCSymbol *NewSym = Context.GetOrCreateSymbol(MAI.getDataBeginLabelName() + + Twine(UniqueDataBeginSuffix++)); EmitLabel(NewSym); RegionIndicator = Data; @@ -202,9 +206,8 @@ void MCStreamer::EmitCodeRegion() { if (!MAI.getSupportsDataRegions()) return; // Generate a unique symbol name. - MCSymbol *NewSym = Context.GetOrCreateSymbol( - Twine(MAI.getCodeBeginLabelName()) + - utostr(UniqueCodeBeginSuffix++)); + MCSymbol *NewSym = Context.GetOrCreateSymbol(MAI.getCodeBeginLabelName() + + Twine(UniqueCodeBeginSuffix++)); EmitLabel(NewSym); RegionIndicator = Code; @@ -218,9 +221,9 @@ void MCStreamer::EmitJumpTable8Region() { if (!MAI.getSupportsDataRegions()) return; // Generate a unique symbol name. - MCSymbol *NewSym = Context.GetOrCreateSymbol( - Twine(MAI.getJumpTable8BeginLabelName()) + - utostr(UniqueDataBeginSuffix++)); + MCSymbol *NewSym = + Context.GetOrCreateSymbol(MAI.getJumpTable8BeginLabelName() + + Twine(UniqueDataBeginSuffix++)); EmitLabel(NewSym); RegionIndicator = JumpTable8; @@ -234,9 +237,9 @@ void MCStreamer::EmitJumpTable16Region() { if (!MAI.getSupportsDataRegions()) return; // Generate a unique symbol name. - MCSymbol *NewSym = Context.GetOrCreateSymbol( - Twine(MAI.getJumpTable16BeginLabelName()) + - utostr(UniqueDataBeginSuffix++)); + MCSymbol *NewSym = + Context.GetOrCreateSymbol(MAI.getJumpTable16BeginLabelName() + + Twine(UniqueDataBeginSuffix++)); EmitLabel(NewSym); RegionIndicator = JumpTable16; @@ -251,9 +254,9 @@ void MCStreamer::EmitJumpTable32Region() { if (!MAI.getSupportsDataRegions()) return; // Generate a unique symbol name. - MCSymbol *NewSym = Context.GetOrCreateSymbol( - Twine(MAI.getJumpTable32BeginLabelName()) + - utostr(UniqueDataBeginSuffix++)); + MCSymbol *NewSym = + Context.GetOrCreateSymbol(MAI.getJumpTable32BeginLabelName() + + Twine(UniqueDataBeginSuffix++)); EmitLabel(NewSym); RegionIndicator = JumpTable32; @@ -277,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(); @@ -288,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) { @@ -386,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); } @@ -396,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); } @@ -409,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(); @@ -559,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(); @@ -631,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/contrib/llvm/lib/MC/MCSymbol.cpp b/contrib/llvm/lib/MC/MCSymbol.cpp index c2fad1674aa4..e013e77f58af 100644 --- a/contrib/llvm/lib/MC/MCSymbol.cpp +++ b/contrib/llvm/lib/MC/MCSymbol.cpp @@ -54,17 +54,14 @@ const MCSymbol &MCSymbol::AliasedSymbol() const { void MCSymbol::setVariableValue(const MCExpr *Value) { assert(!IsUsed && "Cannot set a variable that has already been used."); assert(Value && "Invalid variable value!"); - assert((isUndefined() || (isAbsolute() && isa<MCConstantExpr>(Value))) && - "Invalid redefinition!"); this->Value = Value; // Variables should always be marked as in the same "section" as the value. const MCSection *Section = Value->FindAssociatedSection(); - if (Section) { + if (Section) setSection(*Section); - } else { + else setUndefined(); - } } void MCSymbol::print(raw_ostream &OS) const { diff --git a/contrib/llvm/lib/MC/MachObjectWriter.cpp b/contrib/llvm/lib/MC/MachObjectWriter.cpp index a9219ad29c65..8e4066c894ba 100644 --- a/contrib/llvm/lib/MC/MachObjectWriter.cpp +++ b/contrib/llvm/lib/MC/MachObjectWriter.cpp @@ -8,13 +8,13 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCMachObjectWriter.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSymbol.h" @@ -584,9 +584,16 @@ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, // requires the compiler to use .set to absolutize the differences between // symbols which the compiler knows to be assembly time constants, so we // don't need to worry about considering symbol differences fully resolved. + // + // If the file isn't using sub-sections-via-symbols, we can make the + // same assumptions about any symbol that we normally make about + // assembler locals. if (!Asm.getBackend().hasReliableSymbolDifference()) { - if (!SA.isTemporary() || !SA.isInSection() || &SecA != &SecB) + if (!SA.isInSection() || &SecA != &SecB || + (!SA.isTemporary() && + FB.getAtom() != Asm.getSymbolData(SA).getFragment()->getAtom() && + Asm.getSubsectionsViaSymbols())) return false; return true; } @@ -628,7 +635,7 @@ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, } void MachObjectWriter::WriteObject(MCAssembler &Asm, - const MCAsmLayout &Layout) { + const MCAsmLayout &Layout) { unsigned NumSections = Asm.size(); // The section data starts after the header, the segment load command (and @@ -731,7 +738,7 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm, // Write the actual section data. for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) { - Asm.WriteSectionData(it, Layout); + Asm.writeSectionData(it, Layout); uint64_t Pad = getPaddingSize(it, Layout); for (unsigned int i = 0; i < Pad; ++i) diff --git a/contrib/llvm/lib/MC/SubtargetFeature.cpp b/contrib/llvm/lib/MC/SubtargetFeature.cpp index 348cd4c9ab1b..be4157994c68 100644 --- a/contrib/llvm/lib/MC/SubtargetFeature.cpp +++ b/contrib/llvm/lib/MC/SubtargetFeature.cpp @@ -13,8 +13,8 @@ #include "llvm/MC/SubtargetFeature.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/StringExtras.h" #include <algorithm> #include <cassert> #include <cctype> @@ -114,7 +114,7 @@ void SubtargetFeatures::AddFeature(const StringRef String, // Don't add empty features if (!String.empty()) { // Convert to lowercase, prepend flag and add to vector - Features.push_back(PrependFlag(LowercaseString(String), IsEnabled)); + Features.push_back(PrependFlag(String.lower(), IsEnabled)); } } @@ -154,21 +154,19 @@ static void Help(const SubtargetFeatureKV *CPUTable, size_t CPUTableSize, // Print the CPU table. errs() << "Available CPUs for this target:\n\n"; for (size_t i = 0; i != CPUTableSize; i++) - errs() << " " << CPUTable[i].Key - << std::string(MaxCPULen - std::strlen(CPUTable[i].Key), ' ') - << " - " << CPUTable[i].Desc << ".\n"; - errs() << "\n"; - + errs() << format(" %-*s - %s.\n", + MaxCPULen, CPUTable[i].Key, CPUTable[i].Desc); + errs() << '\n'; + // Print the Feature table. errs() << "Available features for this target:\n\n"; for (size_t i = 0; i != FeatTableSize; i++) - errs() << " " << FeatTable[i].Key - << std::string(MaxFeatLen - std::strlen(FeatTable[i].Key), ' ') - << " - " << FeatTable[i].Desc << ".\n"; - errs() << "\n"; - + errs() << format(" %-*s - %s.\n", + MaxFeatLen, FeatTable[i].Key, FeatTable[i].Desc); + errs() << '\n'; + errs() << "Use +feature to enable a feature, or -feature to disable it.\n" - << "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n"; + "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n"; std::exit(1); } diff --git a/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp b/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp index b15e225fc2a3..f706cac8d36c 100644 --- a/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/contrib/llvm/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); @@ -281,6 +282,7 @@ StringTable::StringTable() { // The string table data begins with the length of the entire string table // including the length header. Allocate space for this header. Data.resize(4); + update_length(); } size_t StringTable::size() const { @@ -313,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() { @@ -694,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); } @@ -798,9 +783,22 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, } if (Sec->Relocations.size() > 0) { - Sec->Header.NumberOfRelocations = Sec->Relocations.size(); + bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff; + + if (RelocationsOverflow) { + // Signal overflow by setting NumberOfSections to max value. Actual + // size is found in reloc #0. Microsoft tools understand this. + Sec->Header.NumberOfRelocations = 0xffff; + } else { + Sec->Header.NumberOfRelocations = Sec->Relocations.size(); + } Sec->Header.PointerToRelocations = offset; + if (RelocationsOverflow) { + // Reloc #0 will contain actual count, so make room for it. + offset += COFF::RelocationSize; + } + offset += COFF::RelocationSize * Sec->Relocations.size(); for (relocations::iterator cr = Sec->Relocations.begin(), @@ -835,8 +833,12 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, MCAssembler::const_iterator j, je; for (i = Sections.begin(), ie = Sections.end(); i != ie; i++) - if ((*i)->Number != -1) + if ((*i)->Number != -1) { + if ((*i)->Relocations.size() >= 0xffff) { + (*i)->Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL; + } WriteSectionHeader((*i)->Header); + } for (i = Sections.begin(), ie = Sections.end(), j = Asm.begin(), je = Asm.end(); @@ -849,13 +851,23 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, assert(OS.tell() == (*i)->Header.PointerToRawData && "Section::PointerToRawData is insane!"); - Asm.WriteSectionData(j, Layout); + Asm.writeSectionData(j, Layout); } if ((*i)->Relocations.size() > 0) { assert(OS.tell() == (*i)->Header.PointerToRelocations && "Section::PointerToRelocations is insane!"); + if ((*i)->Relocations.size() >= 0xffff) { + // In case of overflow, write actual relocation count as first + // relocation. Including the synthetic reloc itself (+ 1). + COFF::relocation r; + r.VirtualAddress = (*i)->Relocations.size() + 1; + r.SymbolTableIndex = 0; + r.Type = 0; + WriteRelocation(r); + } + for (relocations::const_iterator k = (*i)->Relocations.begin(), ke = (*i)->Relocations.end(); k != ke; k++) { @@ -877,11 +889,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/contrib/llvm/lib/MC/WinCOFFStreamer.cpp b/contrib/llvm/lib/MC/WinCOFFStreamer.cpp index 7409daf39085..67dc649d4913 100644 --- a/contrib/llvm/lib/MC/WinCOFFStreamer.cpp +++ b/contrib/llvm/lib/MC/WinCOFFStreamer.cpp @@ -25,13 +25,13 @@ #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCWin64EH.h" #include "llvm/MC/MCAsmBackend.h" -#include "llvm/ADT/StringMap.h" #include "llvm/Support/COFF.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" + using namespace llvm; namespace { @@ -60,6 +60,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 +78,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 +252,6 @@ void WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, default: llvm_unreachable("unsupported attribute"); - break; } } @@ -293,6 +293,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 +399,9 @@ void WinCOFFStreamer::EmitWin64EHHandlerData() { MCWin64EHUnwindEmitter::EmitUnwindInfo(*this, getCurrentW64UnwindInfo()); } -void WinCOFFStreamer::Finish() { +void WinCOFFStreamer::FinishImpl() { EmitW64Tables(); - MCObjectStreamer::Finish(); + MCObjectStreamer::FinishImpl(); } namespace llvm |