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
#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>
}
MCSymbol *AddressPool::emitHeader(AsmPrinter &Asm, MCSection *Section) {
- static const uint8_t AddrSize = Asm.getDataLayout().getPointerSize();
+ static const uint8_t AddrSize = Asm.MAI->getCodePointerSize();
MCSymbol *EndLabel =
Asm.emitDwarfUnitLength("debug_addr", "Length of contribution");
: MCSymbolRefExpr::create(I.first, Asm.OutContext);
for (const MCExpr *Entry : Entries)
- Asm.OutStreamer->emitValue(Entry, Asm.getDataLayout().getPointerSize());
+ Asm.OutStreamer->emitValue(Entry, Asm.MAI->getCodePointerSize());
if (EndLabel)
Asm.OutStreamer->emitLabel(EndLabel);
}
dwarf::FormParams AsmPrinter::getDwarfFormParams() const {
- return {getDwarfVersion(), uint8_t(getPointerSize()),
+ return {getDwarfVersion(), uint8_t(MAI->getCodePointerSize()),
OutStreamer->getContext().getDwarfFormat(),
doesDwarfUseRelocationsAcrossSections()};
}
default:
llvm_unreachable("Invalid encoded value.");
case dwarf::DW_EH_PE_absptr:
- return MF->getDataLayout().getPointerSize();
+ return MAI->getCodePointerSize();
case dwarf::DW_EH_PE_udata2:
return 2;
case dwarf::DW_EH_PE_udata4:
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/GlobalVariable.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
// 16-bit platforms like MSP430 and AVR take this path, so sink this
// assert to platforms that use it.
auto GetPointerSizedFormAndOp = [this]() {
- unsigned PointerSize = Asm->getDataLayout().getPointerSize();
+ unsigned PointerSize = Asm->MAI->getCodePointerSize();
assert((PointerSize == 4 || PointerSize == 8) &&
"Add support for other sizes if necessary");
struct FormAndOp {
void MSP430MCAsmInfo::anchor() { }
MSP430MCAsmInfo::MSP430MCAsmInfo(const Triple &TT) {
- CodePointerSize = 2;
+ // Since MSP430-GCC already generates 32-bit DWARF information, we will
+ // also store 16-bit pointers as 32-bit pointers in DWARF, because using
+ // 32-bit DWARF pointers is already a working and tested path for LLDB
+ // as well.
+ CodePointerSize = 4;
CalleeSaveStackSlotSize = 2;
CommentString = ";";
; RUN: llvm-dwarfdump -v %t | FileCheck %s
; Ported from generic test to cover 2-byte address size case
+; Check that 16-bit addresses of MSP430 are properly stored
+; in 32-bit DWARF fields
; Check that we emit ranges for this which has a non-traditional section and a normal section.
; CHECK: DW_AT_high_pc
; CHECK: .debug_ranges contents:
-; CHECK-NEXT: 00000000 0000 0030
-; CHECK-NEXT: 00000000 0000 0030
+; CHECK-NEXT: 00000000 00000000 00000030
+; CHECK-NEXT: 00000000 00000000 00000030
; CHECK-NEXT: 00000000 <End of list>
; Function Attrs: nounwind uwtable
; This file was based on output of
;
-; clang -target msp430 -S -emit-llvm -gdwarf-5 -Os dwarf-basics-v5.c
+; clang -target msp430-elf -S -emit-llvm -gdwarf-5 -Os dwarf-basics-v5.c
;
; for the following dwarf-basics-v5.c
;
; CHECK: file format elf32-msp430
; CHECK: .debug_info contents:
-; CHECK: Compile Unit: length = 0x{{.*}}, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x02 (next unit at 0x{{.*}})
+; CHECK: Compile Unit: length = 0x{{.*}}, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x04 (next unit at 0x{{.*}})
; CHECK: DW_TAG_compile_unit
-; CHECK: DW_AT_producer ("clang version 14.0.0 (git@...)")
-; CHECK: DW_AT_language (DW_LANG_C99)
+; CHECK: DW_AT_producer ("clang version 17.0.0 (git@...)")
+; CHECK: DW_AT_language (DW_LANG_C11)
; CHECK: DW_AT_name ("dwarf-basics-v5.c")
; CHECK: DW_AT_str_offsets_base (0x00000008)
; CHECK: DW_AT_stmt_list (0x{{.*}})
; CHECK: DW_TAG_formal_parameter
; CHECK: DW_AT_location (indexed (0x0) loclist = 0x{{.*}}:
-; CHECK: [0x0000, 0x0004): DW_OP_reg12 R12)
+; CHECK: [0x00000000, 0x00000004): DW_OP_reg12 R12)
; CHECK: DW_AT_name ("y")
; CHECK: DW_AT_decl_file ("/tmp{{[/\\]}}dwarf-basics-v5.c")
; CHECK: DW_AT_decl_line (5)
; CHECK: NULL
; CHECK: .debug_aranges contents:
-; CHECK-NEXT: Address Range Header: length = 0x{{.*}}, format = DWARF32, version = 0x0002, cu_offset = 0x00000000, addr_size = 0x02, seg_size = 0x00
-; CHECK-NEXT: [0x0000, 0x0006)
+; CHECK-NEXT: Address Range Header: length = 0x{{.*}}, format = DWARF32, version = 0x0002, cu_offset = 0x00000000, addr_size = 0x04, seg_size = 0x00
+; CHECK-NEXT: [0x00000000, 0x00000006)
; CHECK: .debug_addr contents:
-; CHECK-NEXT: Address table header: length = 0x{{.*}}, format = DWARF32, version = 0x0005, addr_size = 0x02, seg_size = 0x00
+; CHECK-NEXT: Address table header: length = 0x{{.*}}, format = DWARF32, version = 0x0005, addr_size = 0x04, seg_size = 0x00
; CHECK-NEXT: Addrs: [
-; CHECK-NEXT: 0x0000
+; CHECK-NEXT: 0x00000000
; CHECK-NEXT: ]
; ModuleID = 'dwarf-basics-v5.c'
source_filename = "dwarf-basics-v5.c"
target datalayout = "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16"
-target triple = "msp430"
+target triple = "msp430-unknown-unknown-elf"
-%struct.X = type { i8* }
-
-; Function Attrs: mustprogress nofree norecurse nosync nounwind optsize readnone willreturn
-define dso_local i16 @f(i32 noundef %y, %struct.X* nocapture noundef readnone %p) local_unnamed_addr #0 !dbg !6 {
-entry:
- call void @llvm.dbg.value(metadata i32 %y, metadata !17, metadata !DIExpression()), !dbg !19
- call void @llvm.dbg.value(metadata %struct.X* %p, metadata !18, metadata !DIExpression()), !dbg !19
+; Function Attrs: mustprogress nofree norecurse nosync nounwind optsize willreturn memory(none)
+define dso_local i16 @f(i32 noundef %0, ptr nocapture noundef readnone %1) local_unnamed_addr #0 !dbg !6 {
+ call void @llvm.dbg.value(metadata i32 %0, metadata !17, metadata !DIExpression()), !dbg !19
+ call void @llvm.dbg.value(metadata ptr %1, metadata !18, metadata !DIExpression()), !dbg !19
ret i16 42, !dbg !20
}
-; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
+; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare void @llvm.dbg.value(metadata, metadata, metadata) #1
-attributes #0 = { mustprogress nofree norecurse nosync nounwind optsize readnone willreturn "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }
+attributes #0 = { mustprogress nofree norecurse nosync nounwind optsize willreturn memory(none) "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!2, !3, !4}
!llvm.ident = !{!5}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 14.0.0 (git@...)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 17.0.0 (git@...)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "dwarf-basics-v5.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "ead340d457001e2ce340630cfa3a9cb8")
!2 = !{i32 7, !"Dwarf Version", i32 5}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = !{i32 1, !"wchar_size", i32 2}
-!5 = !{!"clang version 14.0.0 (git@...)"}
+!5 = !{!"clang version 17.0.0 (git@...)"}
!6 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 5, type: !7, scopeLine: 6, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !16)
!7 = !DISubroutineType(types: !8)
!8 = !{!9, !10, !11}
!18 = !DILocalVariable(name: "p", arg: 2, scope: !6, file: !1, line: 5, type: !11)
!19 = !DILocation(line: 0, scope: !6)
!20 = !DILocation(line: 7, column: 3, scope: !6)
+
; CHECK: file format elf32-msp430
; CHECK: .debug_info contents:
-; CHECK: Compile Unit: length = 0x{{.*}}, format = DWARF32, version = 0x0003, abbr_offset = 0x0000, addr_size = 0x02 (next unit at 0x{{.*}})
+; CHECK: Compile Unit: length = 0x{{.*}}, format = DWARF32, version = 0x0003, abbr_offset = 0x0000, addr_size = 0x04 (next unit at 0x{{.*}})
; CHECK: DW_TAG_compile_unit
; CHECK: DW_AT_producer ("clang version 11.0.0 (git@...)")
; CHECK: DW_TAG_formal_parameter
; CHECK: DW_AT_location (0x{{.*}}:
-; CHECK: [0x0000, 0x0004): DW_OP_reg12 R12)
+; CHECK: [0x00000000, 0x00000004): DW_OP_reg12 R12)
; CHECK: DW_AT_name ("y")
; CHECK: DW_AT_decl_file ("/tmp{{[/\\]}}dwarf-basics.c")
; CHECK: DW_AT_decl_line (5)
; RUN: --implicit-check-not=DW_TAG --implicit-check-not=NULL --implicit-check-not=_pc %s
; Ported from X86 test to cover 2-byte address size case
+; Check that 16-bit addresses of MSP430 are properly stored
+; in 32-bit DWARF fields
; Generated from the following source. f4 is used to put a hole in the CU
; ranges while keeping f2 and f4 in the same section (as opposed to
; CHECK-LABEL: .debug_info contents:
; CHECK: DW_TAG_compile_unit
; CHECK: DW_AT_low_pc
-; CHECK-SAME: (0x0000)
+; CHECK-SAME: (0x00000000)
; RNG: DW_AT_ranges
; RNG-SAME: (indexed (0x3) rangelist = [[CU_RANGE:.*]]
; EXPRORFORM: DW_AT_ranges
; EXPRORFORM-SAME: (indexed (0x0) rangelist = [[CU_RANGE:.*]]
; CHECK: DW_TAG_subprogram
; CHECK: DW_AT_low_pc
-; CHECK-SAME: (indexed (00000000) address = 0x0000 ".text")
+; CHECK-SAME: (indexed (00000000) address = 0x00000000 ".text")
; CHECK: DW_AT_high_pc
; CHECK-SAME: (0x00000002)
; CHECK: DW_AT_name
; EXPR: DW_AT_low_pc
; EXPR-SAME: (DW_OP_addrx 0x0, DW_OP_const4u 0x2, DW_OP_plus)
; FORM: DW_AT_low_pc
-; FORM-SAME: [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0x2 address = 0x0002 ".text")
+; FORM-SAME: [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0x2 address = 0x00000002 ".text")
; EXPRORFORM: DW_AT_high_pc
; EXPRORFORM-SAME: (0x0000000a)
; RNG: DW_AT_ranges
; EXPR: DW_AT_low_pc
; EXPR-SAME: [DW_FORM_exprloc] (DW_OP_addrx 0x0, DW_OP_const4u 0x6, DW_OP_plus)
; FORM: DW_AT_low_pc
-; FORM-SAME: [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0x6 address = 0x0006 ".text")
+; FORM-SAME: [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0x6 address = 0x00000006 ".text")
; EXPRORFORM: DW_AT_high_pc
; EXPRORFORM-SAME: (0x00000004)
; RNG: DW_AT_ranges
; RNG-SAME: (indexed (0x1) rangelist = [[INL_RANGE:.*]]
; CHECK: DW_TAG_call_site
; RNG: DW_AT_call_return_pc
-; RNG-SAME: (indexed (00000001) address = 0x0006 ".text")
+; RNG-SAME: (indexed (00000001) address = 0x00000006 ".text")
; EXPR: DW_AT_call_return_pc
; EXPR-SAME: [DW_FORM_exprloc] (DW_OP_addrx 0x0, DW_OP_const4u 0x6, DW_OP_plus)
; FORM: DW_AT_call_return_pc
-; FORM-SAME: [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0x6 address = 0x0006 ".text")
+; FORM-SAME: [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0x6 address = 0x00000006 ".text")
; CHECK: DW_TAG_call_site
; RNG: DW_AT_call_return_pc
-; RNG-SAME: (indexed (00000002) address = 0x000a ".text")
+; RNG-SAME: (indexed (00000002) address = 0x0000000a ".text")
; EXPR: DW_AT_call_return_pc
; EXPR-SAME: [DW_FORM_exprloc] (DW_OP_addrx 0x0, DW_OP_const4u 0xa, DW_OP_plus)
; FORM: DW_AT_call_return_pc
-; FORM-SAME: [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0xa address = 0x000a ".text")
+; FORM-SAME: [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0xa address = 0x0000000a ".text")
; CHECK: NULL
; CHECK: DW_TAG_subprogram
; EXPR: DW_AT_low_pc
; EXPR-SAME: [DW_FORM_exprloc] (DW_OP_addrx 0x0, DW_OP_const4u 0xe, DW_OP_plus)
; FORM: DW_AT_low_pc
-; FORM-SAME: [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0xe address = 0x000e ".text")
+; FORM-SAME: [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0xe address = 0x0000000e ".text")
; EXPRORFORM: DW_AT_high_pc
; EXPRORFORM-SAME: (0x00000002)
; RNG: DW_AT_ranges
; CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (
; RNG-SAME: 00000003
; EXPRORFORM-SAME: 00000001
-; CHECK: ) address = 0x0000 ".other")
+; CHECK: ) address = 0x00000000 ".other")
; CHECK: DW_AT_high_pc
; CHECK-SAME: (0x00000006)
; CHECK: DW_AT_name
; CHECK-SAME: "f6"
; CHECK: DW_TAG_inlined_subroutine
; RNG: DW_AT_low_pc
-; RNG-SAME: (indexed (00000003) address = 0x0000 ".other")
+; RNG-SAME: (indexed (00000003) address = 0x00000000 ".other")
; EXPRORFORM: DW_AT_low_pc
-; EXPRORFORM-SAME: (indexed (00000001) address = 0x0000 ".other")
+; EXPRORFORM-SAME: (indexed (00000001) address = 0x00000000 ".other")
; CHECK: DW_AT_high_pc
; CHECK-SAME: (0x00000004)
; CHECK: DW_TAG_call_site
; CHECK-LABEL: .debug_addr contents:
; CHECK: 0x00000000: Address table
; CHECK-NEXT: Addrs: [
-; CHECK-NEXT: 0x0000
-; RNG-NEXT: 0x0006
-; RNG-NEXT: 0x000a
-; CHECK-NEXT: 0x0000
-; RNG-NEXT: 0x0004
+; CHECK-NEXT: 0x00000000
+; RNG-NEXT: 0x00000006
+; RNG-NEXT: 0x0000000a
+; CHECK-NEXT: 0x00000000
+; RNG-NEXT: 0x00000004
; CHECK-NEXT: ]
; CHECK-LABEL: .debug_rnglists contents:
; EXPRORFORM: 0x00000000: range list header: {{.*}}, offset_entry_count = 0x00000001
; CHECK: ranges:
; RNG-NEXT: [[F3_RANGE]]: [DW_RLE_base_addressx]:
-; RNG-SAME: 0x0000
+; RNG-SAME: 0x00000000
; RNG-NEXT: [DW_RLE_offset_pair ]
; RNG-NEXT: [DW_RLE_end_of_list ]
; RNG-NEXT: [[INL_RANGE]]: [DW_RLE_base_addressx]:
-; RNG-SAME: 0x0000
+; RNG-SAME: 0x00000000
; RNG-NEXT: [DW_RLE_offset_pair ]
; RNG-NEXT: [DW_RLE_end_of_list ]
; RNG-NEXT: [[F5_RANGE]]: [DW_RLE_base_addressx]:
-; RNG-SAME: 0x0000
+; RNG-SAME: 0x00000000
; RNG-NEXT: [DW_RLE_offset_pair ]
; RNG-NEXT: [DW_RLE_end_of_list ]
; CHECK-NEXT: [[CU_RANGE]]: [DW_RLE_base_addressx]:
-; CHECK-SAME: 0x0000
+; CHECK-SAME: 0x00000000
; CHECK-NEXT: [DW_RLE_offset_pair ]
; CHECK-NEXT: [DW_RLE_offset_pair ]
; RNG-NEXT: [DW_RLE_startx_length]:
-; RNG-SAME: 0x0003
+; RNG-SAME: 0x00000003
; EXPRORFORM-NEXT: [DW_RLE_startx_length]:
-; EXPRORFORM-SAME: 0x0001
+; EXPRORFORM-SAME: 0x00000001
; CHECK-NEXT: [DW_RLE_end_of_list ]
; Function Attrs: mustprogress noinline nounwind optnone uwtable