diff options
author | Eli Bendersky <eliben@chromium.org> | 2013-03-11 15:16:37 -0700 |
---|---|---|
committer | Eli Bendersky <eliben@chromium.org> | 2013-03-11 15:16:37 -0700 |
commit | 23c00401dad33ca247d2818e71540079bed63c5b (patch) | |
tree | df9f25d60f9538fbde84b78cf3c4e4a00eb6c3db /lib/MC | |
parent | 79da56afe68a0c5b2c2227681014dd13705d78cc (diff) | |
parent | 279b9184c2ff4fea93b198a3519b8cb3a1d8d195 (diff) |
Merge commit '279b9184c2ff4fea93b198a3519b8cb3a1d8d195'
Conflicts:
include/llvm/CodeGen/LexicalScopes.h
include/llvm/MC/MCAsmInfo.h
lib/Linker/LinkArchives.cpp
lib/Linker/LinkItems.cpp
lib/MC/MCAsmInfo.cpp
lib/MC/MCDwarf.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMSubtarget.cpp
lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
lib/Target/Mips/MipsAsmPrinter.cpp
lib/Target/Mips/MipsDelaySlotFiller.cpp
lib/Target/Mips/MipsISelDAGToDAG.cpp
lib/Target/Mips/MipsSubtarget.cpp
lib/Target/Mips/MipsSubtarget.h
lib/Target/Mips/MipsTargetObjectFile.cpp
lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
lib/Target/X86/X86FastISel.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86TargetMachine.cpp
lib/Transforms/CMakeLists.txt
lib/Transforms/LLVMBuild.txt
lib/Transforms/Makefile
test/MC/ARM/arm_instructions.s
test/MC/X86/AlignedBundling/pad-align-to-bundle-end.s
Diffstat (limited to 'lib/MC')
-rw-r--r-- | lib/MC/ELFObjectWriter.cpp | 48 | ||||
-rw-r--r-- | lib/MC/MCAsmInfo.cpp | 3 | ||||
-rw-r--r-- | lib/MC/MCAsmStreamer.cpp | 17 | ||||
-rw-r--r-- | lib/MC/MCAssembler.cpp | 20 | ||||
-rw-r--r-- | lib/MC/MCContext.cpp | 4 | ||||
-rw-r--r-- | lib/MC/MCDwarf.cpp | 70 | ||||
-rw-r--r-- | lib/MC/MCELF.cpp | 15 | ||||
-rw-r--r-- | lib/MC/MCELFObjectTargetWriter.cpp | 5 | ||||
-rw-r--r-- | lib/MC/MCELFStreamer.cpp | 21 | ||||
-rw-r--r-- | lib/MC/MCMachOStreamer.cpp | 15 | ||||
-rw-r--r-- | lib/MC/MCNullStreamer.cpp | 7 | ||||
-rw-r--r-- | lib/MC/MCObjectFileInfo.cpp | 34 | ||||
-rw-r--r-- | lib/MC/MCObjectStreamer.cpp | 31 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmLexer.cpp | 80 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 698 | ||||
-rw-r--r-- | lib/MC/MCParser/COFFAsmParser.cpp | 81 | ||||
-rw-r--r-- | lib/MC/MCParser/DarwinAsmParser.cpp | 239 | ||||
-rw-r--r-- | lib/MC/MCParser/ELFAsmParser.cpp | 99 | ||||
-rw-r--r-- | lib/MC/MCParser/MCAsmParser.cpp | 4 | ||||
-rw-r--r-- | lib/MC/MCPureStreamer.cpp | 10 | ||||
-rw-r--r-- | lib/MC/MCSectionMachO.cpp | 4 | ||||
-rw-r--r-- | lib/MC/MCStreamer.cpp | 16 | ||||
-rw-r--r-- | lib/MC/MachObjectWriter.cpp | 57 | ||||
-rw-r--r-- | lib/MC/WinCOFFObjectWriter.cpp | 29 | ||||
-rw-r--r-- | lib/MC/WinCOFFStreamer.cpp | 54 |
25 files changed, 1087 insertions, 574 deletions
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 00724465f6..0b97f2700b 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -135,16 +135,14 @@ class ELFObjectWriter : public MCObjectWriter { const MCSymbol *undefinedExplicitRelSym(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { - return TargetObjectWriter->undefinedExplicitRelSym(Target, Fixup, IsPCRel); + return TargetObjectWriter->undefinedExplicitRelSym(Target, 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 { @@ -152,7 +150,6 @@ class ELFObjectWriter : public MCObjectWriter { IsRelocWithSymbol, Addend); } - public: ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_ostream &_OS, bool IsLittleEndian) @@ -233,7 +230,8 @@ class ELFObjectWriter : public MCObjectWriter { F.getContents().append(&buf[0], &buf[8]); } - void WriteHeader(uint64_t SectionDataSize, + void WriteHeader(const MCAssembler &Asm, + uint64_t SectionDataSize, unsigned NumberOfSections); void WriteSymbolEntry(MCDataFragment *SymtabF, @@ -373,7 +371,8 @@ ELFObjectWriter::~ELFObjectWriter() {} // Emit the ELF header. -void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize, +void ELFObjectWriter::WriteHeader(const MCAssembler &Asm, + uint64_t SectionDataSize, unsigned NumberOfSections) { // ELF Header // ---------- @@ -411,7 +410,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 - Write32(getEFlags()); + Write32(Asm.getELFHeaderEFlags()); // e_ehsize = ELF header size Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr)); @@ -547,12 +546,17 @@ void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() || Data.getSymbol().isVariable(); + // Binding and Type share the same byte as upper and lower nibbles uint8_t Binding = MCELF::GetBinding(OrigData); - uint8_t Visibility = MCELF::GetVisibility(OrigData); uint8_t Type = MCELF::GetType(Data); - uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); - uint8_t Other = Visibility; + + // Other and Visibility share the same byte with Visability using the lower + // 2 bits + uint8_t Visibility = MCELF::GetVisibility(OrigData); + uint8_t Other = MCELF::getOther(OrigData) << + (ELF_Other_Shift - ELF_STV_Shift); + Other |= Visibility; uint64_t Value = SymbolValue(Data, Layout); uint64_t Size = 0; @@ -1319,6 +1323,8 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, case ELF::SHT_FINI_ARRAY: case ELF::SHT_PREINIT_ARRAY: case ELF::SHT_X86_64_UNWIND: + case ELF::SHT_MIPS_REGINFO: + case ELF::SHT_MIPS_OPTIONS: // Nothing to do. break; @@ -1332,6 +1338,24 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, break; } + if (TargetObjectWriter->getEMachine() == ELF::EM_ARM && + Section.getType() == ELF::SHT_ARM_EXIDX) { + StringRef SecName(Section.getSectionName()); + if (SecName == ".ARM.exidx") { + sh_link = SectionIndexMap.lookup( + Asm.getContext().getELFSection(".text", + ELF::SHT_PROGBITS, + ELF::SHF_EXECINSTR | ELF::SHF_ALLOC, + SectionKind::getText())); + } else if (SecName.startswith(".ARM.exidx")) { + sh_link = SectionIndexMap.lookup( + Asm.getContext().getELFSection(SecName.substr(sizeof(".ARM.exidx") - 1), + ELF::SHT_PROGBITS, + ELF::SHF_EXECINSTR | ELF::SHF_ALLOC, + SectionKind::getText())); + } + } + WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), Section.getFlags(), 0, Offset, Size, sh_link, sh_info, Alignment, Section.getEntrySize()); @@ -1532,7 +1556,7 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, } // Write out the ELF header ... - WriteHeader(SectionHeaderOffset, NumSections + 1); + WriteHeader(Asm, SectionHeaderOffset, NumSections + 1); // ... then the regular sections ... // + because of .shstrtab diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp index ffe1b0c50d..51bb435710 100644 --- a/lib/MC/MCAsmInfo.cpp +++ b/lib/MC/MCAsmInfo.cpp @@ -24,7 +24,8 @@ using namespace llvm; MCAsmInfo::MCAsmInfo() { PointerSize = 4; - StackSlotSize = 4; // @LOCALMOD + CalleeSaveStackSlotSize = 4; + IsLittleEndian = true; StackGrowsUp = false; HasSubsectionsViaSymbols = false; diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index dd5112c771..7eb7202332 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -71,7 +71,7 @@ public: MCInstPrinter *printer, MCCodeEmitter *emitter, MCAsmBackend *asmbackend, bool showInst) - : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), + : MCStreamer(SK_AsmStreamer, Context), OS(os), MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm), ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI), @@ -145,6 +145,7 @@ public: virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol); virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); + virtual void EmitLinkerOptions(ArrayRef<std::string> Options); virtual void EmitDataRegion(MCDataRegionType Kind); virtual void EmitThumbFunc(MCSymbol *Func); @@ -276,6 +277,10 @@ public: virtual void FinishImpl(); /// @} + + static bool classof(const MCStreamer *S) { + return S->getKind() == SK_AsmStreamer; + } }; } // end anonymous namespace. @@ -375,6 +380,16 @@ void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { EmitEOL(); } +void MCAsmStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) { + assert(!Options.empty() && "At least one option is required!"); + OS << "\t.linker_option \"" << Options[0] << '"'; + for (ArrayRef<std::string>::iterator it = Options.begin() + 1, + ie = Options.end(); it != ie; ++it) { + OS << ", " << '"' << *it << '"'; + } + OS << "\n"; +} + void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) { MCContext &Ctx = getContext(); const MCAsmInfo &MAI = Ctx.getAsmInfo(); diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 416af8b46f..a394d532d6 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -88,7 +88,8 @@ void MCAsmLayout::invalidateFragmentsFrom(MCFragment *F) { if (!isFragmentValid(F)) return; - // Otherwise, reset the last valid fragment to this fragment. + // Otherwise, reset the last valid fragment to the previous fragment + // (if this is the first fragment, it will be NULL). const MCSectionData &SD = *F->getParent(); LastValidFragment[&SD] = F->getPrevNode(); } @@ -273,7 +274,7 @@ MCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, raw_ostream &OS_) : Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_), OS(OS_), BundleAlignSize(0), RelaxAll(false), NoExecStack(false), - SubsectionsViaSymbols(false) { + SubsectionsViaSymbols(false), ELFHeaderEFlags(0) { } MCAssembler::~MCAssembler() { @@ -290,6 +291,7 @@ void MCAssembler::reset() { RelaxAll = false; NoExecStack = false; SubsectionsViaSymbols = false; + ELFHeaderEFlags = 0; // reset objects owned by us getBackend().reset(); @@ -428,7 +430,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout, } case MCFragment::FT_Org: { - MCOrgFragment &OF = cast<MCOrgFragment>(F); + const MCOrgFragment &OF = cast<MCOrgFragment>(F); int64_t TargetLocation; if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, Layout)) report_fatal_error("expected assembly-time absolute expression"); @@ -505,7 +507,7 @@ void MCAsmLayout::layoutFragment(MCFragment *F) { /// \brief Write the contents of a fragment to the given object writer. Expects /// a MCEncodedFragment. static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) { - MCEncodedFragment &EF = cast<MCEncodedFragment>(F); + const MCEncodedFragment &EF = cast<MCEncodedFragment>(F); OW->WriteBytes(EF.getContents()); } @@ -556,7 +558,7 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, switch (F.getKind()) { case MCFragment::FT_Align: { ++stats::EmittedAlignFragments; - MCAlignFragment &AF = cast<MCAlignFragment>(F); + const MCAlignFragment &AF = cast<MCAlignFragment>(F); uint64_t Count = FragmentSize / AF.getValueSize(); assert(AF.getValueSize() && "Invalid virtual align in concrete fragment!"); @@ -611,7 +613,7 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, case MCFragment::FT_Fill: { ++stats::EmittedFillFragments; - MCFillFragment &FF = cast<MCFillFragment>(F); + const MCFillFragment &FF = cast<MCFillFragment>(F); assert(FF.getValueSize() && "Invalid virtual align in concrete fragment!"); @@ -628,14 +630,14 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, } case MCFragment::FT_LEB: { - MCLEBFragment &LF = cast<MCLEBFragment>(F); + const MCLEBFragment &LF = cast<MCLEBFragment>(F); OW->WriteBytes(LF.getContents().str()); break; } case MCFragment::FT_Org: { ++stats::EmittedOrgFragments; - MCOrgFragment &OF = cast<MCOrgFragment>(F); + const MCOrgFragment &OF = cast<MCOrgFragment>(F); for (uint64_t i = 0, e = FragmentSize; i != e; ++i) OW->Write8(uint8_t(OF.getValue())); @@ -674,7 +676,7 @@ void MCAssembler::writeSectionData(const MCSectionData *SD, // 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 // directives to fill the contents of virtual sections. - MCDataFragment &DF = cast<MCDataFragment>(*it); + const MCDataFragment &DF = cast<MCDataFragment>(*it); assert(DF.fixup_begin() == DF.fixup_end() && "Cannot have fixups in virtual section!"); for (unsigned i = 0, e = DF.getContents().size(); i != e; ++i) diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index aa52b49047..1a7df6041e 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -40,7 +40,7 @@ MCContext::MCContext(const MCAsmInfo &mai, const MCRegisterInfo &mri, CompilationDir(llvm::sys::Path::GetCurrentDirectory().str()), CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0), DwarfLocSeen(false), GenDwarfForAssembly(false), GenDwarfFileNumber(0), - AllowTemporaryLabels(true), AutoReset(DoAutoReset) { + AllowTemporaryLabels(true), DwarfCompileUnitID(0), AutoReset(DoAutoReset) { MachOUniquingMap = 0; ELFUniquingMap = 0; @@ -83,6 +83,8 @@ void MCContext::reset() { DwarfDebugFlags = StringRef(); MCLineSections.clear(); MCLineSectionOrder.clear(); + DwarfCompileUnitID = 0; + MCLineTableSymbols.clear(); CurrentDwarfLoc = MCDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0); // If we have the MachO uniquing map, free it. diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index a28d3525f9..fea057af3e 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -101,7 +101,8 @@ void MCLineEntry::Make(MCStreamer *MCOS, const MCSection *Section) { } // Add the line entry to this section's entries. - LineSection->addLineEntry(LineEntry); + LineSection->addLineEntry(LineEntry, + MCOS->getContext().getDwarfCompileUnitID()); } // @@ -131,7 +132,12 @@ static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS, // static inline void EmitDwarfLineTable(MCStreamer *MCOS, const MCSection *Section, - const MCLineSection *LineSection) { + const MCLineSection *LineSection, + unsigned CUID) { + // This LineSection does not contain any LineEntry for the given Compile Unit. + if (!LineSection->containEntriesForID(CUID)) + return; + unsigned FileNum = 1; unsigned LastLine = 1; unsigned Column = 0; @@ -141,8 +147,8 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS, // Loop through each MCLineEntry and encode the dwarf line number table. for (MCLineSection::const_iterator - it = LineSection->getMCLineEntries()->begin(), - ie = LineSection->getMCLineEntries()->end(); it != ie; ++it) { + it = LineSection->getMCLineEntries(CUID).begin(), + ie = LineSection->getMCLineEntries(CUID).end(); it != ie; ++it) { if (FileNum != it->getFileNum()) { FileNum = it->getFileNum(); @@ -215,9 +221,36 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) { // Switch to the section where the table will be emitted into. MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection()); - // Create a symbol at the beginning of this section. - MCSymbol *LineStartSym = context.CreateTempSymbol(); - // Set the value of the symbol, as we are at the start of the section. + const DenseMap<unsigned, MCSymbol *> &MCLineTableSymbols = + MCOS->getContext().getMCLineTableSymbols(); + // CUID and MCLineTableSymbols are set in DwarfDebug, when DwarfDebug does + // not exist, CUID will be 0 and MCLineTableSymbols will be empty. + // Handle Compile Unit 0, the line table start symbol is the section symbol. + const MCSymbol *LineStartSym = EmitCU(MCOS, 0); + // Handle the rest of the Compile Units. + for (unsigned Is = 1, Ie = MCLineTableSymbols.size(); Is < Ie; Is++) + EmitCU(MCOS, Is); + + // Now delete the MCLineSections that were created in MCLineEntry::Make() + // and used to emit the line table. + const DenseMap<const MCSection *, MCLineSection *> &MCLineSections = + MCOS->getContext().getMCLineSections(); + for (DenseMap<const MCSection *, MCLineSection *>::const_iterator it = + MCLineSections.begin(), ie = MCLineSections.end(); it != ie; + ++it) + delete it->second; + + return LineStartSym; +} + +const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) { + MCContext &context = MCOS->getContext(); + + // Create a symbol at the beginning of the line table. + MCSymbol *LineStartSym = MCOS->getContext().getMCLineTableSymbol(CUID); + if (!LineStartSym) + LineStartSym = context.CreateTempSymbol(); + // Set the value of the symbol, as we are at the start of the line table. MCOS->EmitLabel(LineStartSym); // Create a symbol for the end of the section (to be set when we get there). @@ -239,8 +272,7 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) { // total length, the 2 bytes for the version, and these 4 bytes for the // length of the prologue. MCOS->EmitAbsValue(MakeStartMinusEndExpr(*MCOS, *LineStartSym, *ProEndSym, - (4 + 2 + 4)), - 4, 0); + (4 + 2 + 4)), 4, 0); // Parameters of the state machine, are next. MCOS->EmitIntValue(DWARF2_LINE_MIN_INSN_LENGTH, 1); @@ -301,11 +333,7 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) { ++it) { const MCSection *Sec = *it; const MCLineSection *Line = MCLineSections.lookup(Sec); - EmitDwarfLineTable(MCOS, Sec, Line); - - // Now delete the MCLineSections that were created in MCLineEntry::Make() - // and used to emit the line table. - delete Line; + EmitDwarfLineTable(MCOS, Sec, Line, CUID); } if (MCOS->getContext().getAsmInfo().getLinkerRequiresNonEmptyDwarfLines() @@ -638,9 +666,15 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, } // AT_producer, the version of the assembler tool. - MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM ")); - MCOS->EmitBytes(StringRef(PACKAGE_VERSION)); - MCOS->EmitBytes(StringRef(")")); + StringRef DwarfDebugProducer = context.getDwarfDebugProducer(); + if (!DwarfDebugProducer.empty()){ + MCOS->EmitBytes(DwarfDebugProducer); + } + else { + MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM ")); + MCOS->EmitBytes(StringRef(PACKAGE_VERSION)); + MCOS->EmitBytes(StringRef(")")); + } 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 @@ -786,7 +820,7 @@ void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS, static int getDataAlignmentFactor(MCStreamer &streamer) { MCContext &context = streamer.getContext(); const MCAsmInfo &asmInfo = context.getAsmInfo(); - int size = asmInfo.getStackSlotSize(); // @LOCALMOD + int size = asmInfo.getCalleeSaveStackSlotSize(); if (asmInfo.isStackGrowthDirectionUp()) return size; else diff --git a/lib/MC/MCELF.cpp b/lib/MC/MCELF.cpp index 4db2846bc3..560cdbc6ab 100644 --- a/lib/MC/MCELF.cpp +++ b/lib/MC/MCELF.cpp @@ -52,6 +52,8 @@ unsigned MCELF::GetType(const MCSymbolData &SD) { return Type; } +// Visibility is stored in the first two bits of st_other +// st_other values are stored in the second byte of get/setFlags void MCELF::SetVisibility(MCSymbolData &SD, unsigned Visibility) { assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL || Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED); @@ -68,4 +70,17 @@ unsigned MCELF::GetVisibility(MCSymbolData &SD) { return Visibility; } +// Other is stored in the last six bits of st_other +// st_other values are stored in the second byte of get/setFlags +void MCELF::setOther(MCSymbolData &SD, unsigned Other) { + uint32_t OtherFlags = SD.getFlags() & ~(0x3f << ELF_Other_Shift); + SD.setFlags(OtherFlags | (Other << ELF_Other_Shift)); +} + +unsigned MCELF::getOther(MCSymbolData &SD) { + unsigned Other = + (SD.getFlags() & (0x3f << ELF_Other_Shift)) >> ELF_Other_Shift; + return Other; +} + } diff --git a/lib/MC/MCELFObjectTargetWriter.cpp b/lib/MC/MCELFObjectTargetWriter.cpp index 74cd042a0f..4cac84d666 100644 --- a/lib/MC/MCELFObjectTargetWriter.cpp +++ b/lib/MC/MCELFObjectTargetWriter.cpp @@ -24,11 +24,6 @@ MCELFObjectTargetWriter::MCELFObjectTargetWriter(bool Is64Bit_, IsN64(IsN64_){ } -/// Default e_flags = 0 -unsigned MCELFObjectTargetWriter::getEFlags() const { - return 0; -} - const MCSymbol *MCELFObjectTargetWriter::ExplicitRelSym(const MCAssembler &Asm, const MCValue &Target, const MCFragment &F, diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 27587d312a..c1428d8587 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -300,7 +300,9 @@ void MCELFStreamer::EmitFileDirective(StringRef Filename) { void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { switch (expr->getKind()) { - case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!"); + case MCExpr::Target: + cast<MCTargetExpr>(expr)->fixELFSymbolsInTLSFixups(getAssembler()); + break; case MCExpr::Constant: break; @@ -332,6 +334,19 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { case MCSymbolRefExpr::VK_Mips_GOTTPREL: case MCSymbolRefExpr::VK_Mips_TPREL_HI: case MCSymbolRefExpr::VK_Mips_TPREL_LO: + case MCSymbolRefExpr::VK_PPC_TPREL16_HA: + case MCSymbolRefExpr::VK_PPC_TPREL16_LO: + case MCSymbolRefExpr::VK_PPC_DTPREL16_HA: + case MCSymbolRefExpr::VK_PPC_DTPREL16_LO: + case MCSymbolRefExpr::VK_PPC_GOT_TPREL16_HA: + case MCSymbolRefExpr::VK_PPC_GOT_TPREL16_LO: + case MCSymbolRefExpr::VK_PPC_TLS: + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA: + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_LO: + case MCSymbolRefExpr::VK_PPC_TLSGD: + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_HA: + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO: + case MCSymbolRefExpr::VK_PPC_TLSLD: break; } MCSymbolData &SD = getAssembler().getOrCreateSymbolData(symRef.getSymbol()); @@ -502,6 +517,10 @@ void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { llvm_unreachable("Generic ELF doesn't support this directive"); } +MCSymbolData &MCELFStreamer::getOrCreateSymbolData(MCSymbol *Symbol) { + return getAssembler().getOrCreateSymbolData(*Symbol); +} + void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { llvm_unreachable("ELF doesn't support this directive"); } diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index f947dda83d..7d08d0ecd5 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -34,9 +34,9 @@ private: void EmitDataRegion(DataRegionData::KindTy Kind); void EmitDataRegionEnd(); public: - MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, - raw_ostream &OS, MCCodeEmitter *Emitter) - : MCObjectStreamer(Context, MAB, OS, Emitter) {} + MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, + MCCodeEmitter *Emitter) + : MCObjectStreamer(SK_MachOStreamer, Context, MAB, OS, Emitter) {} /// @name MCStreamer Interface /// @{ @@ -48,6 +48,7 @@ public: virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol); virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); + virtual void EmitLinkerOptions(ArrayRef<std::string> Options); virtual void EmitDataRegion(MCDataRegionType Kind); virtual void EmitThumbFunc(MCSymbol *Func); virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); @@ -86,6 +87,10 @@ public: virtual void FinishImpl(); /// @} + + static bool classof(const MCStreamer *S) { + return S->getKind() == SK_MachOStreamer; + } }; } // end anonymous namespace. @@ -178,6 +183,10 @@ void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { } } +void MCMachOStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) { + getAssembler().getLinkerOptions().push_back(Options); +} + void MCMachOStreamer::EmitDataRegion(MCDataRegionType Kind) { switch (Kind) { case MCDR_DataRegion: diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index 3eee5caf6f..89f74c1709 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -19,7 +19,7 @@ namespace { class MCNullStreamer : public MCStreamer { public: - MCNullStreamer(MCContext &Context) : MCStreamer(Context) {} + MCNullStreamer(MCContext &Context) : MCStreamer(SK_NullStreamer, Context) {} /// @name MCStreamer Interface /// @{ @@ -109,6 +109,11 @@ namespace { } /// @} + + static bool classof(const MCStreamer *S) { + return S->getKind() == SK_NullStreamer; + } + }; } diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp index e34bc2653d..1e2086e565 100644 --- a/lib/MC/MCObjectFileInfo.cpp +++ b/lib/MC/MCObjectFileInfo.cpp @@ -186,6 +186,10 @@ 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, @@ -256,6 +260,25 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { TTypeEncoding = (CMModel == CodeModel::Small) ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; } + } else if (T.getArch() == Triple::aarch64) { + FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; + + // The small model guarantees static code/data size < 4GB, but not where it + // will be in memory. Most of these could end up >2GB away so even a signed + // pc-relative 32-bit address is insufficient, theoretically. + if (RelocM == Reloc::PIC_) { + PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | + dwarf::DW_EH_PE_sdata8; + LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8; + FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; + TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | + dwarf::DW_EH_PE_sdata8; + } else { + PersonalityEncoding = dwarf::DW_EH_PE_absptr; + LSDAEncoding = dwarf::DW_EH_PE_absptr; + FDEEncoding = dwarf::DW_EH_PE_udata4; + TTypeEncoding = dwarf::DW_EH_PE_absptr; + } } else if (T.getArch() == Triple::ppc64) { PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8; @@ -381,6 +404,9 @@ 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()); @@ -437,6 +463,9 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { DwarfStrOffDWOSection = Ctx->getELFSection(".debug_str_offsets.dwo", ELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); + DwarfAddrSection = + Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); } @@ -521,6 +550,11 @@ 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 | diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index 8130c9b532..e835eea7df 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -20,22 +20,19 @@ #include "llvm/Support/ErrorHandling.h" using namespace llvm; -MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter_) - : MCStreamer(Context), - Assembler(new MCAssembler(Context, TAB, - *Emitter_, *TAB.createObjectWriter(OS), - OS)), - CurSectionData(0) -{ -} - -MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter_, +MCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context, + MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *Emitter_) + : MCStreamer(Kind, Context), + Assembler(new MCAssembler(Context, TAB, *Emitter_, |