12cab237bSDimitry Andric //===- llvm/CodeGen/AddressPool.cpp - Dwarf Debug Framework ---------------===//
291bc56edSDimitry Andric //
391bc56edSDimitry Andric // The LLVM Compiler Infrastructure
491bc56edSDimitry Andric //
591bc56edSDimitry Andric // This file is distributed under the University of Illinois Open Source
691bc56edSDimitry Andric // License. See LICENSE.TXT for details.
791bc56edSDimitry Andric //
891bc56edSDimitry Andric //===----------------------------------------------------------------------===//
991bc56edSDimitry Andric
1091bc56edSDimitry Andric #include "AddressPool.h"
112cab237bSDimitry Andric #include "llvm/ADT/SmallVector.h"
1291bc56edSDimitry Andric #include "llvm/CodeGen/AsmPrinter.h"
132cab237bSDimitry Andric #include "llvm/IR/DataLayout.h"
1491bc56edSDimitry Andric #include "llvm/MC/MCStreamer.h"
154ba319b5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h"
162cab237bSDimitry Andric #include <utility>
1791bc56edSDimitry Andric
1891bc56edSDimitry Andric using namespace llvm;
1991bc56edSDimitry Andric
getIndex(const MCSymbol * Sym,bool TLS)2091bc56edSDimitry Andric unsigned AddressPool::getIndex(const MCSymbol *Sym, bool TLS) {
2191bc56edSDimitry Andric HasBeenUsed = true;
2291bc56edSDimitry Andric auto IterBool =
2391bc56edSDimitry Andric Pool.insert(std::make_pair(Sym, AddressPoolEntry(Pool.size(), TLS)));
2491bc56edSDimitry Andric return IterBool.first->second.Number;
2591bc56edSDimitry Andric }
2691bc56edSDimitry Andric
274ba319b5SDimitry Andric
emitHeader(AsmPrinter & Asm,MCSection * Section)284ba319b5SDimitry Andric void AddressPool::emitHeader(AsmPrinter &Asm, MCSection *Section) {
294ba319b5SDimitry Andric static const uint8_t AddrSize = Asm.getDataLayout().getPointerSize();
304ba319b5SDimitry Andric uint64_t Length = sizeof(uint16_t) // version
314ba319b5SDimitry Andric + sizeof(uint8_t) // address_size
324ba319b5SDimitry Andric + sizeof(uint8_t) // segment_selector_size
334ba319b5SDimitry Andric + AddrSize * Pool.size(); // entries
34*b5893f02SDimitry Andric Asm.OutStreamer->AddComment("Length of contribution");
354ba319b5SDimitry Andric Asm.emitInt32(Length); // TODO: Support DWARF64 format.
36*b5893f02SDimitry Andric Asm.OutStreamer->AddComment("DWARF version number");
374ba319b5SDimitry Andric Asm.emitInt16(Asm.getDwarfVersion());
38*b5893f02SDimitry Andric Asm.OutStreamer->AddComment("Address size");
394ba319b5SDimitry Andric Asm.emitInt8(AddrSize);
40*b5893f02SDimitry Andric Asm.OutStreamer->AddComment("Segment selector size");
414ba319b5SDimitry Andric Asm.emitInt8(0); // TODO: Support non-zero segment_selector_size.
424ba319b5SDimitry Andric }
434ba319b5SDimitry Andric
4491bc56edSDimitry Andric // Emit addresses into the section given.
emit(AsmPrinter & Asm,MCSection * AddrSection)45ff0cc061SDimitry Andric void AddressPool::emit(AsmPrinter &Asm, MCSection *AddrSection) {
46*b5893f02SDimitry Andric if (isEmpty())
4791bc56edSDimitry Andric return;
4891bc56edSDimitry Andric
4991bc56edSDimitry Andric // Start the dwarf addr section.
50ff0cc061SDimitry Andric Asm.OutStreamer->SwitchSection(AddrSection);
5191bc56edSDimitry Andric
52*b5893f02SDimitry Andric if (Asm.getDwarfVersion() >= 5)
53*b5893f02SDimitry Andric emitHeader(Asm, AddrSection);
54*b5893f02SDimitry Andric
55*b5893f02SDimitry Andric // Define the symbol that marks the start of the contribution.
56*b5893f02SDimitry Andric // It is referenced via DW_AT_addr_base.
57*b5893f02SDimitry Andric Asm.OutStreamer->EmitLabel(AddressTableBaseSym);
58*b5893f02SDimitry Andric
5991bc56edSDimitry Andric // Order the address pool entries by ID
6091bc56edSDimitry Andric SmallVector<const MCExpr *, 64> Entries(Pool.size());
6191bc56edSDimitry Andric
6291bc56edSDimitry Andric for (const auto &I : Pool)
6391bc56edSDimitry Andric Entries[I.second.Number] =
6491bc56edSDimitry Andric I.second.TLS
6591bc56edSDimitry Andric ? Asm.getObjFileLowering().getDebugThreadLocalSymbol(I.first)
6697bc6c73SDimitry Andric : MCSymbolRefExpr::create(I.first, Asm.OutContext);
6791bc56edSDimitry Andric
6891bc56edSDimitry Andric for (const MCExpr *Entry : Entries)
69ff0cc061SDimitry Andric Asm.OutStreamer->EmitValue(Entry, Asm.getDataLayout().getPointerSize());
7091bc56edSDimitry Andric }
71