From 3405728e403ce7054f09e9a69846a57f680060db Mon Sep 17 00:00:00 2001 From: Andrew Stubbs Date: Mon, 27 Jul 2020 10:55:22 +0100 Subject: [PATCH] dwarf: Multi-register CFI address support Add support for architectures such as AMD GCN, in which the pointer size is larger than the register size. This allows the CFI information to include multi-register locations for the stack pointer, frame pointer, and return address. Note that this uses a newly proposed DWARF operator DW_OP_LLVM_piece_end, which is currently only recognized by the ROCGDB debugger from AMD. The exact name and encoding for this operator is subject to change if and when the DWARF standard accepts it. gcc/ChangeLog: * dwarf2cfi.cc (get_cfa_from_loc_descr): Support register spans with DW_OP_piece and DW_OP_LLVM_piece_end. * dwarf2out.cc (build_cfa_loc): Support register spans. include/ChangeLog: * dwarf2.def (DW_OP_LLVM_piece_end): New extension operator. --- gcc/ChangeLog.omp | 6 ++++++ gcc/dwarf2cfi.cc | 27 ++++++++++++++++++++++++++- gcc/dwarf2out.cc | 4 ++++ include/ChangeLog.omp | 4 ++++ include/dwarf2.def | 6 ++++++ 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp index bc3360e053cc..862c5c2dd31e 100644 --- a/gcc/ChangeLog.omp +++ b/gcc/ChangeLog.omp @@ -1,3 +1,9 @@ +2020-07-27 Andrew Stubbs + + * dwarf2cfi.cc (get_cfa_from_loc_descr): Support register spans + with DW_OP_piece and DW_OP_LLVM_piece_end. + * dwarf2out.cc (build_cfa_loc): Support register spans. + 2020-08-19 Sandra Loosemore Add a "combined" flag for "acc kernels loop" etc directives. diff --git a/gcc/dwarf2cfi.cc b/gcc/dwarf2cfi.cc index ab7c5cc5b27b..8d52622a4cbc 100644 --- a/gcc/dwarf2cfi.cc +++ b/gcc/dwarf2cfi.cc @@ -540,6 +540,10 @@ get_cfa_from_loc_descr (dw_cfa_location *cfa, struct dw_loc_descr_node *loc) cfa->indirect = 0; cfa->reg.set_by_dwreg (INVALID_REGNUM); + /* Record previous register pieces here. */ + struct cfa_reg span; + span.set_by_dwreg (INVALID_REGNUM); + for (ptr = loc; ptr != NULL; ptr = ptr->dw_loc_next) { enum dwarf_location_atom op = ptr->dw_loc_opc; @@ -622,7 +626,9 @@ get_cfa_from_loc_descr (dw_cfa_location *cfa, struct dw_loc_descr_node *loc) = (op == DW_OP_bregx ? ptr->dw_loc_oprnd1.v.val_int : op - DW_OP_breg0); cfa->reg.set_by_dwreg (regno); - cfa->base_offset = ptr->dw_loc_oprnd1.v.val_int; + cfa->base_offset = (DW_OP_bregx + ? ptr->dw_loc_oprnd2.v.val_int + : ptr->dw_loc_oprnd1.v.val_int); } else { @@ -647,6 +653,24 @@ get_cfa_from_loc_descr (dw_cfa_location *cfa, struct dw_loc_descr_node *loc) cfa->offset = 0; } break; + case DW_OP_piece: + if (span.reg != INVALID_REGNUM) + { + /* We only support contiguous pieces, for now. */ + gcc_assert (cfa->reg.reg == span.reg + span.span); + gcc_assert (known_eq (ptr->dw_loc_oprnd1.v.val_int, + span.span_width)); + span.span++; + cfa->reg = span; + } + else + { + cfa->reg.span_width = ptr->dw_loc_oprnd1.v.val_int; + span = cfa->reg; + } + break; + case DW_OP_LLVM_piece_end: + break; case DW_OP_deref: cfa->indirect = 1; break; @@ -705,6 +729,7 @@ get_cfa_from_loc_descr (dw_cfa_location *cfa, struct dw_loc_descr_node *loc) /* The offset is already in place. */ break; case DW_OP_plus_uconst: + gcc_assert (known_eq (cfa->offset, 0)); cfa->offset = ptr->dw_loc_oprnd1.v.val_unsigned; break; default: diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index 5681b01749ad..d7a39944424b 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -2833,7 +2833,11 @@ build_cfa_loc (dw_cfa_location *cfa, poly_int64 offset) head = build_span_loc (cfa->reg); if (maybe_ne (offset, 0)) + { + add_loc_descr (&head, new_loc_descr (DW_OP_LLVM_piece_end, 0, 0)); + add_loc_descr (&head, new_loc_descr (DW_OP_deref, 0, 0)); loc_descr_plus_const (&head, offset); + } } else if (cfa->indirect) { diff --git a/include/ChangeLog.omp b/include/ChangeLog.omp index a460e639d229..8290e4ea2867 100644 --- a/include/ChangeLog.omp +++ b/include/ChangeLog.omp @@ -1,3 +1,7 @@ +2020-07-27 Andrew Stubbs + + * dwarf2.def (DW_OP_LLVM_piece_end): New extension operator. + 2018-10-04 Cesar Philippidis Julian Brown diff --git a/include/dwarf2.def b/include/dwarf2.def index 4214c80907a0..a3625a619bf1 100644 --- a/include/dwarf2.def +++ b/include/dwarf2.def @@ -704,6 +704,12 @@ DW_OP (DW_OP_PGI_omp_thread_num, 0xf8) to 0 except explicitly documented for one action. Please refer AArch64 DWARF ABI documentation for details. */ DW_OP (DW_OP_AARCH64_operation, 0xea) + +/* AMD GCN extensions (originally for LLVM). See + http://llvm.org/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.html */ +// This clashes with DW_OP_AARCH64_operation, so use an alias instead +// DW_OP (DW_OP_LLVM_piece_end, 0xea) +#define DW_OP_LLVM_piece_end DW_OP_AARCH64_operation DW_END_OP DW_FIRST_ATE (DW_ATE_void, 0x0) -- 2.47.2