Ilya Kuklin c395a84600 [MSP430] Get the DWARF pointer size from MCAsmInfo instead of DataLayout.
This change will allow to put code pointers in DWARF info fields that are larger than actual pointer size, e.g. 16-bit pointers into 32-bit fields.

The need for this came up while creating support for MSP430 in LLDB. MSP430-GCC already generates DWARF info with 32-bit fields, so this change is necessary for LLDB to maintain compatibility with both GCC and LLVM binaries. Moreover, right now in LLDB there is no support for having DWARF pointer size different from ELF header type, e.g. 16-bit DWARF info within ELF32, and it seems there is no such thing as ELF16.

Since other mainline targets are made to have the same pointer size in both MCAsmInfo and DataLayout, there is no need to change anything there.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D148042
2023-05-04 12:37:30 -07:00

74 lines
2.4 KiB
C++

//===- llvm/CodeGen/AddressPool.cpp - Dwarf Debug Framework ---------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "AddressPool.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include <utility>
using namespace llvm;
unsigned AddressPool::getIndex(const MCSymbol *Sym, bool TLS) {
resetUsedFlag(true);
auto IterBool =
Pool.insert(std::make_pair(Sym, AddressPoolEntry(Pool.size(), TLS)));
return IterBool.first->second.Number;
}
MCSymbol *AddressPool::emitHeader(AsmPrinter &Asm, MCSection *Section) {
static const uint8_t AddrSize = Asm.MAI->getCodePointerSize();
MCSymbol *EndLabel =
Asm.emitDwarfUnitLength("debug_addr", "Length of contribution");
Asm.OutStreamer->AddComment("DWARF version number");
Asm.emitInt16(Asm.getDwarfVersion());
Asm.OutStreamer->AddComment("Address size");
Asm.emitInt8(AddrSize);
Asm.OutStreamer->AddComment("Segment selector size");
Asm.emitInt8(0); // TODO: Support non-zero segment_selector_size.
return EndLabel;
}
// Emit addresses into the section given.
void AddressPool::emit(AsmPrinter &Asm, MCSection *AddrSection) {
if (isEmpty())
return;
// Start the dwarf addr section.
Asm.OutStreamer->switchSection(AddrSection);
MCSymbol *EndLabel = nullptr;
if (Asm.getDwarfVersion() >= 5)
EndLabel = emitHeader(Asm, AddrSection);
// Define the symbol that marks the start of the contribution.
// It is referenced via DW_AT_addr_base.
Asm.OutStreamer->emitLabel(AddressTableBaseSym);
// Order the address pool entries by ID
SmallVector<const MCExpr *, 64> Entries(Pool.size());
for (const auto &I : Pool)
Entries[I.second.Number] =
I.second.TLS
? Asm.getObjFileLowering().getDebugThreadLocalSymbol(I.first)
: MCSymbolRefExpr::create(I.first, Asm.OutContext);
for (const MCExpr *Entry : Entries)
Asm.OutStreamer->emitValue(Entry, Asm.MAI->getCodePointerSize());
if (EndLabel)
Asm.OutStreamer->emitLabel(EndLabel);
}