10b57cec5SDimitry Andric //===- llvm/CodeGen/AddressPool.cpp - Dwarf Debug Framework ---------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "AddressPool.h" 100b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 110b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 120b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 130b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 140b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h" 150b57cec5SDimitry Andric #include <utility> 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric using namespace llvm; 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric unsigned AddressPool::getIndex(const MCSymbol *Sym, bool TLS) { 200b57cec5SDimitry Andric HasBeenUsed = true; 210b57cec5SDimitry Andric auto IterBool = 220b57cec5SDimitry Andric Pool.insert(std::make_pair(Sym, AddressPoolEntry(Pool.size(), TLS))); 230b57cec5SDimitry Andric return IterBool.first->second.Number; 240b57cec5SDimitry Andric } 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric MCSymbol *AddressPool::emitHeader(AsmPrinter &Asm, MCSection *Section) { 270b57cec5SDimitry Andric static const uint8_t AddrSize = Asm.getDataLayout().getPointerSize(); 280b57cec5SDimitry Andric StringRef Prefix = "debug_addr_"; 290b57cec5SDimitry Andric MCSymbol *BeginLabel = Asm.createTempSymbol(Prefix + "start"); 300b57cec5SDimitry Andric MCSymbol *EndLabel = Asm.createTempSymbol(Prefix + "end"); 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric Asm.OutStreamer->AddComment("Length of contribution"); 33*5ffd83dbSDimitry Andric Asm.emitLabelDifference(EndLabel, BeginLabel, 340b57cec5SDimitry Andric 4); // TODO: Support DWARF64 format. 35*5ffd83dbSDimitry Andric Asm.OutStreamer->emitLabel(BeginLabel); 360b57cec5SDimitry Andric Asm.OutStreamer->AddComment("DWARF version number"); 370b57cec5SDimitry Andric Asm.emitInt16(Asm.getDwarfVersion()); 380b57cec5SDimitry Andric Asm.OutStreamer->AddComment("Address size"); 390b57cec5SDimitry Andric Asm.emitInt8(AddrSize); 400b57cec5SDimitry Andric Asm.OutStreamer->AddComment("Segment selector size"); 410b57cec5SDimitry Andric Asm.emitInt8(0); // TODO: Support non-zero segment_selector_size. 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric return EndLabel; 440b57cec5SDimitry Andric } 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric // Emit addresses into the section given. 470b57cec5SDimitry Andric void AddressPool::emit(AsmPrinter &Asm, MCSection *AddrSection) { 480b57cec5SDimitry Andric if (isEmpty()) 490b57cec5SDimitry Andric return; 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric // Start the dwarf addr section. 520b57cec5SDimitry Andric Asm.OutStreamer->SwitchSection(AddrSection); 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric MCSymbol *EndLabel = nullptr; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric if (Asm.getDwarfVersion() >= 5) 570b57cec5SDimitry Andric EndLabel = emitHeader(Asm, AddrSection); 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric // Define the symbol that marks the start of the contribution. 600b57cec5SDimitry Andric // It is referenced via DW_AT_addr_base. 61*5ffd83dbSDimitry Andric Asm.OutStreamer->emitLabel(AddressTableBaseSym); 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric // Order the address pool entries by ID 640b57cec5SDimitry Andric SmallVector<const MCExpr *, 64> Entries(Pool.size()); 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric for (const auto &I : Pool) 670b57cec5SDimitry Andric Entries[I.second.Number] = 680b57cec5SDimitry Andric I.second.TLS 690b57cec5SDimitry Andric ? Asm.getObjFileLowering().getDebugThreadLocalSymbol(I.first) 700b57cec5SDimitry Andric : MCSymbolRefExpr::create(I.first, Asm.OutContext); 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric for (const MCExpr *Entry : Entries) 73*5ffd83dbSDimitry Andric Asm.OutStreamer->emitValue(Entry, Asm.getDataLayout().getPointerSize()); 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric if (EndLabel) 76*5ffd83dbSDimitry Andric Asm.OutStreamer->emitLabel(EndLabel); 770b57cec5SDimitry Andric } 78