dwarf_loader: Add support for DW_TAG_GNU_template_parameter_pack

The representation for template parameter packs, such as in this
example, taken from Stack Overflow [1]:

  $ cat template_parameter_pack.cpp
  #include <iostream>

  template <class... Args>
  void printAll(Args&&... args)
  {
  	using swallow = int[];
  	swallow{ 0, (std::cout << args, 0)... };
  }

  int main()
  {
  	printAll(1, "23", 4);
  	std::cout << '\n';
  }
  $ g++ -g template_parameter_pack.cpp -o template_parameter_pack
  $ ./template_parameter_pack
  1234
  $

That generates:

  $ readelf -wi template_parameter_pack | grep DW_AT_name.*printAll -B2 -A20
   <1><1fca>: Abbrev Number: 82 (DW_TAG_subprogram)
      <1fcb>   DW_AT_external    : 1
      <1fcb>   DW_AT_name        : (indirect string, offset: 0xf15): printAll<int, char const (&)[3], int>
      <1fcf>   DW_AT_decl_file   : 1
      <1fd0>   DW_AT_decl_line   : 4
      <1fd1>   DW_AT_decl_column : 6
      <1fd2>   DW_AT_linkage_name: (indirect string, offset: 0x3ef): _Z8printAllIJiRA3_KciEEvDpOT_
      <1fd6>   DW_AT_low_pc      : 0x401187
      <1fde>   DW_AT_high_pc     : 0x8e
      <1fe6>   DW_AT_frame_base  : 1 byte block: 9c 	(DW_OP_call_frame_cfa)
      <1fe8>   DW_AT_call_all_tail_calls: 1
      <1fe8>   DW_AT_sibling     : <0x2023>
   <2><1fec>: Abbrev Number: 83 (DW_TAG_GNU_template_parameter_pack)
      <1fed>   DW_AT_name        : (indirect string, offset: 0x2ef): Args
      <1ff1>   DW_AT_sibling     : <0x2005>
   <3><1ff5>: Abbrev Number: 32 (DW_TAG_template_type_param)
      <1ff6>   DW_AT_type        : <0xeb>
   <3><1ffa>: Abbrev Number: 32 (DW_TAG_template_type_param)
      <1ffb>   DW_AT_type        : <0x2023>
   <3><1fff>: Abbrev Number: 32 (DW_TAG_template_type_param)
      <2000>   DW_AT_type        : <0xeb>
   <3><2004>: Abbrev Number: 0
   <2><2005>: Abbrev Number: 84 (DW_TAG_GNU_formal_parameter_pack)
  $

That for the current pahole use need some massaging, as it already puts
into the DW_TAG_subprogram the whole template signature, we need to chop
off that "<int, char const (&)[3], int>" when trying to use it for
--compile, i.e. to regenerate the original source code from the DWARF
info, so we will need to assume that for DW_TAG_subprogram that has a
DW_TAG_GNU_template_parameter_pack we need to remove whatever suffix
surrounded by <> is after the initial string to get its name.

Lets do this piecemeal tho and land this first, and yeah, there is that
DW_TAG_GNU_formal_parameter_pack thing as well that needs the exact same
treatment...

From a quick look it will expand all those actual concrete template
usages into a pair of DW_TAG_GNU_template_parameter_pack and
DW_TAG_GNU_formal_parameter_pack, or that is subject to compiler
optimizations, unsure at this point as I'm just looking at the output of
readelf for one sample program.

[1] https://stackoverflow.com/questions/36407941/inspect-template-parameter-pack-in-gdb

Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
5 files changed