diff options
Diffstat (limited to 'gdb/testsuite/lib/dwarf.exp')
-rw-r--r-- | gdb/testsuite/lib/dwarf.exp | 214 |
1 files changed, 184 insertions, 30 deletions
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index bcf3d73..3a182c2 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -1,4 +1,4 @@ -# Copyright 2010-2024 Free Software Foundation, Inc. +# Copyright 2010-2025 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -678,6 +678,11 @@ namespace eval Dwarf { } } close $fd + + variable _constants + + # Add DW_FORM_strx_id as alias of DW_FORM_strx. + _process_one_constant DW_FORM_strx_id $_constants(DW_FORM_strx) } proc _quote {string} { @@ -823,6 +828,12 @@ namespace eval Dwarf { DW_FORM_indirect - DW_FORM_exprloc - + # Generate a DW_FORM_str index, but assume generation of .debug_str and + # .debug_str_offsets is taken care of elsewhere. + DW_FORM_strx_id { + _op .uleb128 $value + } + DW_FORM_strx - DW_FORM_strx1 - DW_FORM_strx2 - @@ -1061,7 +1072,10 @@ namespace eval Dwarf { } proc _section {name {flags ""} {type ""}} { - if {$flags == "" && $type == ""} { + if {$name == ".debug_str"} { + # Hard-code this because it's always desirable. + _emit " .section $name, \"MS\", %progbits, 1" + } elseif {$flags == "" && $type == ""} { _emit " .section $name" } elseif {$type == ""} { _emit " .section $name, \"$flags\"" @@ -1244,7 +1258,6 @@ namespace eval Dwarf { # used, as indicated in the header of the section where the location # description is found. # - # (FIXME should use 'info complete' here.) # Each list's first element is the opcode, either short or long # forms are accepted. # FIXME argument handling @@ -1252,9 +1265,18 @@ namespace eval Dwarf { proc _location { body dwarf_version addr_size offset_size } { variable _constants + set collected_lines "" foreach line [split $body \n] { # Ignore blank lines, and allow embedded comments. - if {[lindex $line 0] == "" || [regexp -- {^[ \t]*#} $line]} { + if { [regexp -- {^[ \t]*$} $line] || [regexp -- {^[ \t]*#} $line] } { + continue + } + if { $collected_lines != "" } { + set line "$collected_lines\n$line" + set collected_lines "" + } + if { ! [info complete $line] } { + set collected_lines $line continue } set opcode [_map_name [lindex $line 0] _OP] @@ -1340,6 +1362,17 @@ namespace eval Dwarf { _op .2byte $argvec(label) } + DW_OP_entry_value { + _get_args $line $opcode body + set l1 [new_label "expr_start"] + set l2 [new_label "expr_end"] + _op .uleb128 "$l2 - $l1" "expression" + define_label $l1 + _location $argvec(body) $dwarf_version $addr_size \ + $offset_size + define_label $l2 + } + DW_OP_implicit_value { set l1 [new_label "value_start"] set l2 [new_label "value_end"] @@ -1441,6 +1474,17 @@ namespace eval Dwarf { # default = default # fission 0|1 - boolean indicating if generating Fission debug info # default = 0 + # dwo_id - The value to use as the dwo_id field of skeleton and + # split_compile unit headers. May only be used with DWARF + # version 5. + # + # If a dwo_id value is specified (is non-zero), this unit is + # assumed to be part of a skeleton/split_unit pair. The unit + # type will be chosen according to the `fission` value. + # + # When using DWARF version 5 and fission is non-zero, it is + # mandatory to provide a non-zero dwo_id value. + # default = 0 # label <label> # - string indicating label to be defined at the start # of the CU header. @@ -1463,6 +1507,7 @@ namespace eval Dwarf { set _cu_version 4 set _cu_addr_size default set _cu_is_fission 0 + set dwo_id 0 set section ".debug_info" set _abbrev_section ".debug_abbrev" set label "" @@ -1474,6 +1519,7 @@ namespace eval Dwarf { version { set _cu_version $value } addr_size { set _cu_addr_size $value } fission { set _cu_is_fission $value } + dwo_id { set dwo_id $value } label { set label $value } default { error "unknown option $name" } } @@ -1524,12 +1570,42 @@ namespace eval Dwarf { # The CU header for DWARF 4 and 5 are slightly different. if { $_cu_version == 5 } { - _op .byte 0x1 "DW_UT_compile" + # The presence of a DWO_ID indicates that we generate a skeleton + # or split_compile unit. + if { $dwo_id != 0 } { + if { $_cu_is_fission } { + set unit_type_name "DW_UT_split_compile" + } else { + set unit_type_name "DW_UT_skeleton" + } + } else { + set unit_type_name "DW_UT_compile" + } + + _op .byte $_constants($unit_type_name) $unit_type_name _op .byte $_cu_addr_size "Pointer size" _op_offset $_cu_offset_size $my_abbrevs Abbrevs + + # Output DWO ID, if specified. + if { $dwo_id != 0 } { + _op .8byte $dwo_id "DWO_ID" + } else { + # To help catch user errors: if the caller asked to put this + # unit in the DWO file but didn't provide a DWO ID, it is likely + # an error. + if { $_cu_is_fission } { + error "DWO ID not specified for DWARF 5 split compile" + } + } } else { _op_offset $_cu_offset_size $my_abbrevs Abbrevs _op .byte $_cu_addr_size "Pointer size" + + # For DWARF versions < 5, the DWO ID is not in the unit header, + # so it makes not sense to specify one. + if { $dwo_id != 0 } { + error "DWO ID specified for DWARF < 5 unit" + } } _defer_output $_abbrev_section { @@ -1606,7 +1682,7 @@ namespace eval Dwarf { } if { $_cu_is_fission } { set section "$section.dwo" - set _abbrev_section "$section.dwo" + set _abbrev_section "$_abbrev_section.dwo" } _section $section @@ -3006,6 +3082,24 @@ namespace eval Dwarf { } } + # Emit a .debug_sup section with the given file name and build-id. + # The buildid should be represented as a hexadecimal string, like + # "ffeeddcc". + proc debug_sup {is_sup filename buildid} { + _defer_output .debug_sup { + # The version. + _op .2byte 0x5 + # Supplementary marker. + _op .byte $is_sup + _op .ascii [_quote $filename] + set len [expr {[string length $buildid] / 2}] + _op .uleb128 $len + foreach {a b} [split $buildid {}] { + _op .byte 0x$a$b + } + } + } + proc _note {type name hexdata} { set namelen [expr [string length $name] + 1] set datalen [expr [string length $hexdata] / 2] @@ -3130,10 +3224,11 @@ namespace eval Dwarf { } variable _debug_names set _debug_names [] - proc _debug_names_name { name tag cu hash } { + proc _debug_names_name { name tag cu hash {extra {}} } { variable _debug_names declare_labels entry_pool_offset - lappend _debug_names [list $name $tag $cu $hash $entry_pool_offset] + lappend _debug_names [list $name $tag $cu $hash $extra \ + $entry_pool_offset] } with_override Dwarf::cu Dwarf::_debug_names_cu { with_override Dwarf::tu Dwarf::_debug_names_tu { @@ -3196,14 +3291,13 @@ namespace eval Dwarf { # Hash Lookup Table - array of hashes. foreach idx $_debug_names { - set name [lindex $idx 0] - set hash [lindex $idx 3] + lassign $idx name tag cu hash extra label _op .4byte $hash "hash: $name" } # Name Table - array of string offsets. foreach idx $_debug_names { - set name [lindex $idx 0] + lassign $idx name tag cu hash extra label variable _strings if {![info exists _strings($name)]} { @@ -3220,8 +3314,7 @@ namespace eval Dwarf { # Name Table - array of entry offsets. set base_label "" foreach idx $_debug_names { - set name [lindex $idx 0] - set label [lindex $idx 4] + lassign $idx name tag cu hash extra label if { [string equal $base_label ""]} { set base_label $label } @@ -3234,31 +3327,42 @@ namespace eval Dwarf { set abbrev 1 variable _constants foreach idx $_debug_names { - set name [lindex $idx 0] - set tag [lindex $idx 1] - set cu [lindex $idx 2] + lassign $idx name tag cu hash extra label if { [regexp "^CU-($decimal)$" $cu dummy cu_index] } { - set attr_name compile_unit - set attr_val 1 + set attr_name DW_IDX_compile_unit } elseif { [regexp "^TU-($decimal)$" $cu dummy cu_index] } { - set attr_name type_unit - set attr_val 2 + set attr_name DW_IDX_type_unit } else { set cu_index [lsearch -exact $_debug_names_cus $cu] if { $cu_index == -1 } { - set attr_name type_unit - set attr_val 2 + set attr_name DW_IDX_type_unit } else { - set attr_name compile_unit - set attr_val 1 + set attr_name DW_IDX_compile_unit } } - _op .byte $abbrev "abbrev $abbrev" + _op .uleb128 $abbrev "abbrev $abbrev" _op .uleb128 $_constants(DW_TAG_$tag) "DW_TAG_$tag" - _op .byte $attr_val "DW_IDX_$attr_name (attribute)" - _op .byte 0x0f "DW_FORM_udata (form)" + _op .uleb128 $_constants($attr_name) \ + "$attr_name (attribute)" + _op .uleb128 0x0f "DW_FORM_udata (form)" + foreach word $extra { + if {$word == "static"} { + _op .uleb128 $_constants(DW_IDX_GNU_internal) \ + "DW_IDX_GNU_internal" + _op .uleb128 $_constants(DW_FORM_flag_present) \ + "DW_FORM_flag_present" + } elseif {[string match DW_LANG_* $word]} { + _op .uleb128 $_constants(DW_IDX_GNU_language) \ + "DW_IDX_GNU_language" + _op .uleb128 $_constants(DW_FORM_implicit_const) \ + "DW_FORM_flag_present" + _op .sleb128 $_constants($word) $word + } else { + error "unrecognized extra keyword $word" + } + } _op .byte 0 "abbrev terminator (attribute)" _op .byte 0 "abbrev terminator (form)" incr abbrev @@ -3269,9 +3373,7 @@ namespace eval Dwarf { # Entry Pool set abbrev 1 foreach idx $_debug_names { - set name [lindex $idx 0] - set cu [lindex $idx 2] - set label [lindex $idx 4] + lassign $idx name tag cu hash extra label if { [regexp "^CU-($decimal)$" $cu dummy cu_index] } { set comment "$name: CU index" @@ -3297,6 +3399,58 @@ namespace eval Dwarf { debug_names_end: } + # Add the strings in ARGS to the .debug_str section, and create a + # .debug_str_offsets section pointing to those strings. + # Current options are: + # dwo 0|1 - boolean indicating if the sections have the dwo suffix. + # default = 0 (no .dwo suffix) + # base_offset label + # - generate label, to be used in DW_AT_str_offsets_base. + # default = "" (don't generate a label). + proc debug_str_offsets { options args } { + parse_options { + { dwo 0 } + { base_offset "" } + } + + if { $dwo } { + _section .debug_str.dwo + } else { + _section .debug_str + } + + set num 0 + foreach arg $args { + set str_label [_compute_label "str_${num}"] + define_label $str_label + _op .asciz \"$arg\" ".debug_str_offsets string $num" + incr num + } + + declare_labels debug_str_offsets_start debug_str_offsets_end + set initial_length "$debug_str_offsets_end - $debug_str_offsets_start" + + if { $dwo } { + _section .debug_str_offsets.dwo + } else { + _section .debug_str_offsets + } + _op .4byte $initial_length "Initial_length" + debug_str_offsets_start: + _op .2byte 0x5 "version" + _op .2byte 0x0 "padding" + if { $base_offset != "" } { + $base_offset: + } + set num 0 + foreach arg $args { + set str_label [_compute_label "str_${num}"] + _op .4byte $str_label "string $num" + incr num + } + debug_str_offsets_end: + } + # The top-level interface to the DWARF assembler. # OPTIONS is a list with an even number of elements containing # option-name and option-value pairs. |