AArch64ELFStreamer.cpp revision 263508
1122394Sharti//===- lib/MC/AArch64ELFStreamer.cpp - ELF Object Output for AArch64 ------===// 2122394Sharti// 3122394Sharti// The LLVM Compiler Infrastructure 4122394Sharti// 5122394Sharti// This file is distributed under the University of Illinois Open Source 6122394Sharti// License. See LICENSE.TXT for details. 7216594Ssyrinx// 8216594Ssyrinx//===----------------------------------------------------------------------===// 9216594Ssyrinx// 10216594Ssyrinx// This file assembles .s files and emits AArch64 ELF .o object files. Different 11216594Ssyrinx// from generic ELF streamer in emitting mapping symbols ($x and $d) to delimit 12216594Ssyrinx// regions of data and code. 13216594Ssyrinx// 14133211Sharti//===----------------------------------------------------------------------===// 15133211Sharti 16133211Sharti#include "llvm/MC/MCELFStreamer.h" 17133211Sharti#include "llvm/ADT/SmallPtrSet.h" 18133211Sharti#include "llvm/ADT/Twine.h" 19122394Sharti#include "llvm/MC/MCAsmBackend.h" 20122394Sharti#include "llvm/MC/MCAssembler.h" 21122394Sharti#include "llvm/MC/MCCodeEmitter.h" 22310901Sngie#include "llvm/MC/MCContext.h" 23133211Sharti#include "llvm/MC/MCELF.h" 24133211Sharti#include "llvm/MC/MCELFStreamer.h" 25133211Sharti#include "llvm/MC/MCELFSymbolFlags.h" 26133211Sharti#include "llvm/MC/MCExpr.h" 27133211Sharti#include "llvm/MC/MCInst.h" 28133211Sharti#include "llvm/MC/MCObjectStreamer.h" 29133211Sharti#include "llvm/MC/MCSection.h" 30133211Sharti#include "llvm/MC/MCSectionELF.h" 31133211Sharti#include "llvm/MC/MCStreamer.h" 32133211Sharti#include "llvm/MC/MCSymbol.h" 33133211Sharti#include "llvm/MC/MCValue.h" 34122394Sharti#include "llvm/Support/Debug.h" 35150920Sharti#include "llvm/Support/ELF.h" 36122394Sharti#include "llvm/Support/ErrorHandling.h" 37122394Sharti#include "llvm/Support/raw_ostream.h" 38122394Sharti 39122394Shartiusing namespace llvm; 40216294Ssyrinx 41122394Shartinamespace { 42122394Sharti 43216594Ssyrinx/// Extend the generic ELFStreamer class so that it can emit mapping symbols at 44122394Sharti/// the appropriate points in the object files. These symbols are defined in the 45122394Sharti/// AArch64 ELF ABI: 46122394Sharti/// infocenter.arm.com/help/topic/com.arm.doc.ihi0056a/IHI0056A_aaelf64.pdf 47122394Sharti/// 48122394Sharti/// In brief: $x or $d should be emitted at the start of each contiguous region 49122394Sharti/// of A64 code or data in a section. In practice, this emission does not rely 50122394Sharti/// on explicit assembler directives but on inherent properties of the 51122394Sharti/// directives doing the emission (e.g. ".byte" is data, "add x0, x0, x0" an 52122394Sharti/// instruction). 53122394Sharti/// 54122394Sharti/// As a result this system is orthogonal to the DataRegion infrastructure used 55122394Sharti/// by MachO. Beware! 56122394Sharticlass AArch64ELFStreamer : public MCELFStreamer { 57122394Shartipublic: 58122394Sharti AArch64ELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, 59122394Sharti MCCodeEmitter *Emitter) 60122394Sharti : MCELFStreamer(Context, 0, TAB, OS, Emitter), MappingSymbolCounter(0), 61122394Sharti LastEMS(EMS_None) {} 62216594Ssyrinx 63292815Sngie ~AArch64ELFStreamer() {} 64216594Ssyrinx 65216594Ssyrinx virtual void ChangeSection(const MCSection *Section, 66216594Ssyrinx const MCExpr *Subsection) { 67292815Sngie // We have to keep track of the mapping symbol state of any sections we 68216594Ssyrinx // use. Each one should start off as EMS_None, which is provided as the 69216594Ssyrinx // default constructor by DenseMap::lookup. 70216594Ssyrinx LastMappingSymbols[getPreviousSection().first] = LastEMS; 71292815Sngie LastEMS = LastMappingSymbols.lookup(Section); 72216594Ssyrinx 73216594Ssyrinx MCELFStreamer::ChangeSection(Section, Subsection); 74122394Sharti } 75122394Sharti 76122394Sharti /// This function is the one used to emit instruction data into the ELF 77122394Sharti /// streamer. We override it to add the appropriate mapping symbol if 78122394Sharti /// necessary. 79122394Sharti virtual void EmitInstruction(const MCInst& Inst) { 80122394Sharti EmitA64MappingSymbol(); 81122394Sharti MCELFStreamer::EmitInstruction(Inst); 82122394Sharti } 83122394Sharti 84122394Sharti /// This is one of the functions used to emit data into an ELF section, so the 85122394Sharti /// AArch64 streamer overrides it to add the appropriate mapping symbol ($d) 86122394Sharti /// if necessary. 87122394Sharti virtual void EmitBytes(StringRef Data) { 88122394Sharti EmitDataMappingSymbol(); 89122394Sharti MCELFStreamer::EmitBytes(Data); 90122394Sharti } 91122394Sharti 92122394Sharti /// This is one of the functions used to emit data into an ELF section, so the 93122394Sharti /// AArch64 streamer overrides it to add the appropriate mapping symbol ($d) 94122394Sharti /// if necessary. 95122394Sharti virtual void EmitValueImpl(const MCExpr *Value, unsigned Size) { 96122394Sharti EmitDataMappingSymbol(); 97122394Sharti MCELFStreamer::EmitValueImpl(Value, Size); 98122394Sharti } 99122394Sharti 100122394Shartiprivate: 101122394Sharti enum ElfMappingSymbol { 102122394Sharti EMS_None, 103122394Sharti EMS_A64, 104122394Sharti EMS_Data 105122394Sharti }; 106122394Sharti 107122394Sharti void EmitDataMappingSymbol() { 108122394Sharti if (LastEMS == EMS_Data) return; 109122394Sharti EmitMappingSymbol("$d"); 110122394Sharti LastEMS = EMS_Data; 111122394Sharti } 112122394Sharti 113122394Sharti void EmitA64MappingSymbol() { 114122394Sharti if (LastEMS == EMS_A64) return; 115122394Sharti EmitMappingSymbol("$x"); 116122394Sharti LastEMS = EMS_A64; 117122394Sharti } 118122394Sharti 119122394Sharti void EmitMappingSymbol(StringRef Name) { 120240191Skevlo MCSymbol *Start = getContext().CreateTempSymbol(); 121122394Sharti EmitLabel(Start); 122122394Sharti 123122394Sharti MCSymbol *Symbol = 124122394Sharti getContext().GetOrCreateSymbol(Name + "." + 125122394Sharti Twine(MappingSymbolCounter++)); 126122394Sharti 127122394Sharti MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 128122394Sharti MCELF::SetType(SD, ELF::STT_NOTYPE); 129122394Sharti MCELF::SetBinding(SD, ELF::STB_LOCAL); 130150920Sharti SD.setExternal(false); 131122394Sharti AssignSection(Symbol, getCurrentSection().first); 132122394Sharti 133122394Sharti const MCExpr *Value = MCSymbolRefExpr::Create(Start, getContext()); 134122394Sharti Symbol->setVariableValue(Value); 135122394Sharti } 136122394Sharti 137122394Sharti int64_t MappingSymbolCounter; 138122394Sharti 139122394Sharti DenseMap<const MCSection *, ElfMappingSymbol> LastMappingSymbols; 140122394Sharti ElfMappingSymbol LastEMS; 141122394Sharti 142122394Sharti /// @} 143122394Sharti}; 144122394Sharti} 145122394Sharti 146122394Shartinamespace llvm { 147122394Sharti MCELFStreamer* createAArch64ELFStreamer(MCContext &Context, MCAsmBackend &TAB, 148122394Sharti raw_ostream &OS, MCCodeEmitter *Emitter, 149122394Sharti bool RelaxAll, bool NoExecStack) { 150122394Sharti AArch64ELFStreamer *S = new AArch64ELFStreamer(Context, TAB, OS, Emitter); 151122394Sharti if (RelaxAll) 152122394Sharti S->getAssembler().setRelaxAll(true); 153122394Sharti if (NoExecStack) 154122394Sharti S->getAssembler().setNoExecStack(true); 155122394Sharti return S; 156122394Sharti } 157122394Sharti} 158122394Sharti 159122394Sharti 160122394Sharti