# * If VALUE starts with the ":" character, then it is a label
# reference. The rest of VALUE is taken to be the name of a label,
# and DW_FORM_ref4 is used. See 'new_label' and 'define_label'.
+# * If VALUE starts with the "%" character, then it is a label
+# reference too, but DW_FORM_ref_addr is used.
# * Otherwise, VALUE is taken to be a string and DW_FORM_string is
# used. In order to prevent bugs where a numeric value is given but
# no form is specified, it is an error if the value looks like a number
return DW_FORM_ref4
}
+ % {
+ # Label reference, an offset from .debug_info. Assuming
+ # .Lcu1_begin is on .debug_info.
+ set cu1_label [_compute_label "cu1_begin"]
+ set new_value "[string range $value 1 end] - $cu1_label"
+
+ return DW_FORM_ref_addr
+ }
+
default {
return DW_FORM_string
}
_handle_macro_at_range $attr_value
} else {
if {[llength $attr] > 2} {
- set attr_form [lindex $attr end]
+ set attr_form [uplevel 2 [list subst [lindex $attr end]]]
+
+ if { [string index $attr_value 0] == ":" } {
+ # It is a label, get its value.
+ _guess_form $attr_value attr_value
+ }
} else {
# If the value looks like an integer, a form is required.
if [string is integer $attr_value] {
_op .2byte [lindex $line 1]
}
+ DW_OP_implicit_value {
+ set l1 [new_label "value_start"]
+ set l2 [new_label "value_end"]
+ _op .uleb128 "$l2 - $l1"
+ define_label $l1
+ foreach value [lrange $line 1 end] {
+ switch -regexp -- $value {
+ {^0x[[:xdigit:]]{1,2}$} {_op .byte $value}
+ {^0x[[:xdigit:]]{4}$} {_op .2byte $value}
+ {^0x[[:xdigit:]]{8}$} {_op .4byte $value}
+ {^0x[[:xdigit:]]{16}$} {_op .8byte $value}
+ default {
+ error "bad value '$value' in DW_OP_implicit_value"
+ }
+ }
+ }
+ define_label $l2
+ }
+
DW_OP_GNU_implicit_pointer {
if {[llength $line] != 3} {
error "usage: DW_OP_GNU_implicit_pointer LABEL OFFSET"
set _abbrev_section ".debug_abbrev"
foreach { name value } $options {
+ set value [uplevel 1 "subst \"$value\""]
switch -exact -- $name {
is_64 { set is_64 $value }
version { set _cu_version $value }