1*0b57cec5SDimitry Andric //===- llvm/CodeGen/AddressPool.cpp - Dwarf Debug Framework ---------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "AddressPool.h" 10*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 11*0b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 12*0b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 13*0b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 14*0b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h" 15*0b57cec5SDimitry Andric #include <utility> 16*0b57cec5SDimitry Andric 17*0b57cec5SDimitry Andric using namespace llvm; 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry Andric unsigned AddressPool::getIndex(const MCSymbol *Sym, bool TLS) { 20*0b57cec5SDimitry Andric HasBeenUsed = true; 21*0b57cec5SDimitry Andric auto IterBool = 22*0b57cec5SDimitry Andric Pool.insert(std::make_pair(Sym, AddressPoolEntry(Pool.size(), TLS))); 23*0b57cec5SDimitry Andric return IterBool.first->second.Number; 24*0b57cec5SDimitry Andric } 25*0b57cec5SDimitry Andric 26*0b57cec5SDimitry Andric MCSymbol *AddressPool::emitHeader(AsmPrinter &Asm, MCSection *Section) { 27*0b57cec5SDimitry Andric static const uint8_t AddrSize = Asm.getDataLayout().getPointerSize(); 28*0b57cec5SDimitry Andric StringRef Prefix = "debug_addr_"; 29*0b57cec5SDimitry Andric MCSymbol *BeginLabel = Asm.createTempSymbol(Prefix + "start"); 30*0b57cec5SDimitry Andric MCSymbol *EndLabel = Asm.createTempSymbol(Prefix + "end"); 31*0b57cec5SDimitry Andric 32*0b57cec5SDimitry Andric Asm.OutStreamer->AddComment("Length of contribution"); 33*0b57cec5SDimitry Andric Asm.EmitLabelDifference(EndLabel, BeginLabel, 34*0b57cec5SDimitry Andric 4); // TODO: Support DWARF64 format. 35*0b57cec5SDimitry Andric Asm.OutStreamer->EmitLabel(BeginLabel); 36*0b57cec5SDimitry Andric Asm.OutStreamer->AddComment("DWARF version number"); 37*0b57cec5SDimitry Andric Asm.emitInt16(Asm.getDwarfVersion()); 38*0b57cec5SDimitry Andric Asm.OutStreamer->AddComment("Address size"); 39*0b57cec5SDimitry Andric Asm.emitInt8(AddrSize); 40*0b57cec5SDimitry Andric Asm.OutStreamer->AddComment("Segment selector size"); 41*0b57cec5SDimitry Andric Asm.emitInt8(0); // TODO: Support non-zero segment_selector_size. 42*0b57cec5SDimitry Andric 43*0b57cec5SDimitry Andric return EndLabel; 44*0b57cec5SDimitry Andric } 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric // Emit addresses into the section given. 47*0b57cec5SDimitry Andric void AddressPool::emit(AsmPrinter &Asm, MCSection *AddrSection) { 48*0b57cec5SDimitry Andric if (isEmpty()) 49*0b57cec5SDimitry Andric return; 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric // Start the dwarf addr section. 52*0b57cec5SDimitry Andric Asm.OutStreamer->SwitchSection(AddrSection); 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric MCSymbol *EndLabel = nullptr; 55*0b57cec5SDimitry Andric 56*0b57cec5SDimitry Andric if (Asm.getDwarfVersion() >= 5) 57*0b57cec5SDimitry Andric EndLabel = emitHeader(Asm, AddrSection); 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric // Define the symbol that marks the start of the contribution. 60*0b57cec5SDimitry Andric // It is referenced via DW_AT_addr_base. 61*0b57cec5SDimitry Andric Asm.OutStreamer->EmitLabel(AddressTableBaseSym); 62*0b57cec5SDimitry Andric 63*0b57cec5SDimitry Andric // Order the address pool entries by ID 64*0b57cec5SDimitry Andric SmallVector<const MCExpr *, 64> Entries(Pool.size()); 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andric for (const auto &I : Pool) 67*0b57cec5SDimitry Andric Entries[I.second.Number] = 68*0b57cec5SDimitry Andric I.second.TLS 69*0b57cec5SDimitry Andric ? Asm.getObjFileLowering().getDebugThreadLocalSymbol(I.first) 70*0b57cec5SDimitry Andric : MCSymbolRefExpr::create(I.first, Asm.OutContext); 71*0b57cec5SDimitry Andric 72*0b57cec5SDimitry Andric for (const MCExpr *Entry : Entries) 73*0b57cec5SDimitry Andric Asm.OutStreamer->EmitValue(Entry, Asm.getDataLayout().getPointerSize()); 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric if (EndLabel) 76*0b57cec5SDimitry Andric Asm.OutStreamer->EmitLabel(EndLabel); 77*0b57cec5SDimitry Andric } 78