]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Make location expressions be code in DWARF assembler
authorTom Tromey <tromey@adacore.com>
Tue, 16 Sep 2025 20:33:15 +0000 (14:33 -0600)
committerTom Tromey <tromey@adacore.com>
Mon, 6 Oct 2025 15:30:00 +0000 (09:30 -0600)
Currently the DWARF assembler implements manual parsing for location
expressions.  With a recent refactoring, this lead to the use of
[subst] in a number of places.

Following the same logic as the DW_AT_* change, this patch changes
location expressions to simply be nested Tcl code.  This avoids the
need for subst and also allows more complex logic, should that ever be
needed.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33402

50 files changed:
gdb/testsuite/gdb.cp/incomplete-type-overload.exp
gdb/testsuite/gdb.dlang/watch-loc.exp
gdb/testsuite/gdb.dwarf2/DW_OP_piece_with_DW_OP_GNU_uninit.exp
gdb/testsuite/gdb.dwarf2/ada-array-bound.exp
gdb/testsuite/gdb.dwarf2/ada-valprint-error.exp
gdb/testsuite/gdb.dwarf2/arr-opt-out.exp
gdb/testsuite/gdb.dwarf2/assign-variable-value-to-register.exp
gdb/testsuite/gdb.dwarf2/count.exp
gdb/testsuite/gdb.dwarf2/cpp-linkage-name.exp
gdb/testsuite/gdb.dwarf2/data-loc.exp
gdb/testsuite/gdb.dwarf2/dw2-entry-points.exp
gdb/testsuite/gdb.dwarf2/dw2-entry-value-2.exp
gdb/testsuite/gdb.dwarf2/dw2-fixed-point.exp
gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.exp
gdb/testsuite/gdb.dwarf2/dw2-inline-with-lexical-scope.exp
gdb/testsuite/gdb.dwarf2/dw2-lexical-block-bare.exp
gdb/testsuite/gdb.dwarf2/dw2-namespaceless-anonymous.exp
gdb/testsuite/gdb.dwarf2/dw2-noloc.exp
gdb/testsuite/gdb.dwarf2/dw2-ranges-func.exp
gdb/testsuite/gdb.dwarf2/dw2-unusual-field-names.exp
gdb/testsuite/gdb.dwarf2/dw2-using-debug-str.exp
gdb/testsuite/gdb.dwarf2/dyn-type-unallocated.exp
gdb/testsuite/gdb.dwarf2/dynamic-bit-offset.exp
gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp
gdb/testsuite/gdb.dwarf2/fission-absolute-dwo.exp
gdb/testsuite/gdb.dwarf2/fission-multi-cu.exp
gdb/testsuite/gdb.dwarf2/fission-relative-dwo.exp
gdb/testsuite/gdb.dwarf2/implptr-64bit.exp
gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp
gdb/testsuite/gdb.dwarf2/implptrconst.exp
gdb/testsuite/gdb.dwarf2/implptrpiece.exp
gdb/testsuite/gdb.dwarf2/implref-array.exp
gdb/testsuite/gdb.dwarf2/implref-const.exp
gdb/testsuite/gdb.dwarf2/implref-global.exp
gdb/testsuite/gdb.dwarf2/implref-struct.exp
gdb/testsuite/gdb.dwarf2/intbits.exp
gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.exp
gdb/testsuite/gdb.dwarf2/missing-type-name.exp
gdb/testsuite/gdb.dwarf2/negative-data-member-location.exp
gdb/testsuite/gdb.dwarf2/nonvar-access.exp
gdb/testsuite/gdb.dwarf2/opt-out-not-implptr.exp
gdb/testsuite/gdb.dwarf2/staticvirtual.exp
gdb/testsuite/gdb.dwarf2/symbol_needs_eval_fail.exp
gdb/testsuite/gdb.dwarf2/symbol_needs_eval_timeout.exp
gdb/testsuite/gdb.dwarf2/var-access.exp
gdb/testsuite/gdb.dwarf2/varval.exp
gdb/testsuite/gdb.dwarf2/void-type.exp
gdb/testsuite/gdb.python/make-visualizer.exp
gdb/testsuite/gdb.trace/entry-values.exp
gdb/testsuite/lib/dwarf.exp

index efb1fd34f4c6fb632780767ab5d0944f06208800..007c238eb6988a5cbbdcea25af7d98d527768e95 100644 (file)
@@ -120,32 +120,36 @@ Dwarf::assemble ${asm_file} {
        DW_TAG_variable {
            DW_AT_name "comp"
            DW_AT_type :$complete_label
-           DW_AT_location [subst {DW_OP_addr [gdb_target_symbol "comp"]}] \
-               SPECIAL_expr
+           DW_AT_location {
+               DW_OP_addr [gdb_target_symbol "comp"]
+           } SPECIAL_expr
            DW_AT_external 1 DW_FORM_flag
        }
 
        DW_TAG_variable {
            DW_AT_name "cp"
            DW_AT_type :$ptr_comp_label
-           DW_AT_location [subst {DW_OP_addr [gdb_target_symbol "cp"]}] \
-               SPECIAL_expr
+           DW_AT_location {
+               DW_OP_addr [gdb_target_symbol "cp"]
+           } SPECIAL_expr
            DW_AT_external 1 DW_FORM_flag
        }
 
        DW_TAG_variable {
            DW_AT_name "inc"
            DW_AT_type :$ptr_inc_label
-           DW_AT_location [subst {DW_OP_addr [gdb_target_symbol "inc"]}] \
-               SPECIAL_expr
+           DW_AT_location {
+               DW_OP_addr [gdb_target_symbol "inc"]
+           } SPECIAL_expr
            DW_AT_external 1 DW_FORM_flag
        }
 
        DW_TAG_variable {
            DW_AT_name "ip"
            DW_AT_type :$ptr_int_label
-           DW_AT_location [subst {DW_OP_addr [gdb_target_symbol "ip"]}] \
-               SPECIAL_expr
+           DW_AT_location {
+               DW_OP_addr [gdb_target_symbol "ip"]
+           } SPECIAL_expr
            DW_AT_external 1 DW_FORM_flag
        }
 
index 7cfc539f6a35b17510b12a046af58a8d36109f54..d16b779b57c593484d89d238c77a12377dc29111 100644 (file)
@@ -48,9 +48,9 @@ Dwarf::assemble $asm_file {
                tag_variable {
                    DW_AT_name my_data
                    DW_AT_type :$watch_struct_label
-                   DW_AT_location [subst {
-                       addr [gdb_target_symbol my_data]
-                   }] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_addr [gdb_target_symbol my_data]
+                   } SPECIAL_expr
                    DW_AT_external 1 flag
                }
 
index 291bc83e667ccabbe22cbae6183ca03327c7b04e..d812b0bcbb3ac145cdd37959c7ed06e4b8606b20 100644 (file)
@@ -49,23 +49,23 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name i64_var
                DW_AT_type :$i64_type
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_constu $::c64
                    DW_OP_stack_value
                    DW_OP_GNU_uninit
                    DW_OP_piece 8
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            DW_TAG_variable {
                DW_AT_name i32_var
                DW_AT_type :$i32_type
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_constu $::c32
                    DW_OP_stack_value
                    DW_OP_GNU_uninit
                    DW_OP_piece 4
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
        }
     }
index 779ce009e211dcc99744c95cd94a059fb23801f8..b85777b2fea0ca5eeed891210f1072966bf8477d 100644 (file)
@@ -72,9 +72,9 @@ Dwarf::assemble $asm_file {
                DW_AT_name "value"
                DW_AT_type :$struct
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location \
-                   [subst {DW_OP_addr [gdb_target_symbol "our_data"]}] \
-                   SPECIAL_expr
+               DW_AT_location {
+                   DW_OP_addr [gdb_target_symbol "our_data"]
+               } SPECIAL_expr
            }
        }
     }
index a7544265da89075e4c590fc3b4c1122f44132c31..a4b6a9562984fcfb78d1eac44a3c69b748bea380 100644 (file)
@@ -92,9 +92,9 @@ Dwarf::assemble $asm_file {
             DW_TAG_variable {
                DW_AT_name fd__global
                DW_AT_type :$ref_type_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol fd__global]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
             }
 
index d3ccec8af67a684a2b9599c3a66fab7d16ebddbd..38840aa1e4df14d47de6b70810ea563fdb8871da 100644 (file)
@@ -70,9 +70,9 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name the_table
                DW_AT_type :$array_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol global_array]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
        }
index 1ebd622f4309b78650a8fb6bcfcf009dfc8e5d2d..9cbbfe9c601870ea8a8615897a34d3bc542a53e6 100644 (file)
@@ -56,9 +56,9 @@ Dwarf::assemble $dwarf_file {
                DW_TAG_variable {
                    DW_AT_name foo
                    DW_AT_type :$float_label
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_regx $::st0_dwarf_regnum
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                }
            }
        }
index 92b0ebf194f8df0b86c40eb8cbfad8b791338a57..23b3c6946f279ff3252d5aa7cd66b62ca729ccc7 100644 (file)
@@ -81,8 +81,8 @@ Dwarf::assemble $asm_file {
            vla_length_label:
            DW_TAG_variable {
                DW_AT_location {
-                   lit6
-                   stack_value
+                   DW_OP_lit6
+                   DW_OP_stack_value
                } SPECIAL_expr
                DW_AT_name "__vla_array_length"
                DW_AT_type :$long_unsigned_int_label
index a21e980fcf0f5ad086e31a8b56eeeb6501867930..44d31f6aebdf55498548ed8447ac317d1a89ab5c 100644 (file)
@@ -72,9 +72,9 @@ Dwarf::assemble $asm_file {
                DW_AT_type :$b_l
                DW_AT_external 1 flag
                DW_AT_name global_var
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol global_var]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
        }
     }
index 615d04bfaf585ae502b18b5e1aeb48e4b0231537..7630dcc20a1eb425550fe80d42bc46a3ee52d1de 100644 (file)
@@ -60,19 +60,19 @@ Dwarf::assemble $asm_file {
            } {
                DW_TAG_subrange_type {
                    DW_AT_type        :$integer_label
-                   DW_AT_lower_bound [subst {
+                   DW_AT_lower_bound {
                        DW_OP_push_object_address
                        DW_OP_plus_uconst $voidp_size
                        DW_OP_deref
                        DW_OP_deref_size $int_size
-                   }] SPECIAL_expr
-                   DW_AT_upper_bound [subst {
+                   } SPECIAL_expr
+                   DW_AT_upper_bound {
                        DW_OP_push_object_address
                        DW_OP_plus_uconst $voidp_size
                        DW_OP_deref
                        DW_OP_plus_uconst $int_size
                        DW_OP_deref_size $int_size
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                }
            }
            array_ptr_label: DW_TAG_typedef {
@@ -82,33 +82,33 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name foo__three
                DW_AT_type :$array_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol table_1]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
            DW_TAG_variable {
                DW_AT_name foo__three_tdef
                DW_AT_type :$array_ptr_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol table_1]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
            DW_TAG_variable {
                DW_AT_name foo__five
                DW_AT_type :$array_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol table_2]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
            DW_TAG_variable {
                DW_AT_name foo__five_tdef
                DW_AT_type :$array_ptr_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol table_2]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
        }
index 2dda0e5258c5c498408bb3bf32de605b25d690a7..07f5d7401b314fe3365d31bfd03395bd9ff6a510 100644 (file)
@@ -80,12 +80,16 @@ Dwarf::assemble $asm_file {
                formal_parameter {
                    DW_AT_name I
                    DW_AT_type :$int_label
-                   DW_AT_location [subst {addr $global_I}] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_addr $global_I
+                   } SPECIAL_expr
                }
                formal_parameter {
                    DW_AT_name J
                    DW_AT_type :$int_label
-                   DW_AT_location [subst {addr $global_J}] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_addr $global_J
+                   } SPECIAL_expr
                }
                entry_point {
                    DW_AT_name foo
@@ -96,12 +100,16 @@ Dwarf::assemble $asm_file {
                    formal_parameter {
                        DW_AT_name J
                        DW_AT_type :$int_label
-                       DW_AT_location [subst {addr $global_J}] SPECIAL_expr
+                       DW_AT_location {
+                           DW_OP_addr $global_J
+                       } SPECIAL_expr
                    }
                    formal_parameter {
                        DW_AT_name K
                        DW_AT_type :$int_label
-                       DW_AT_location [subst {addr $global_K}] SPECIAL_expr
+                       DW_AT_location {
+                           DW_OP_addr $global_K
+                       } SPECIAL_expr
                    }
                }
                entry_point {
@@ -113,7 +121,9 @@ Dwarf::assemble $asm_file {
                    formal_parameter {
                        DW_AT_name J
                        DW_AT_type :$int_label
-                       DW_AT_location [subst {addr $global_J}] SPECIAL_expr
+                       DW_AT_location {
+                           DW_OP_addr $global_J
+                       } SPECIAL_expr
                    }
                }
            }
@@ -142,12 +152,16 @@ Dwarf::assemble $asm_file {
                formal_parameter {
                    DW_AT_name I
                    DW_AT_type :$int2_label
-                   DW_AT_location [subst {addr $global_I}] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_addr $global_I
+                   } SPECIAL_expr
                }
                formal_parameter {
                    DW_AT_name J
                    DW_AT_type :$int2_label
-                   DW_AT_location [subst {addr $global_J}] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_addr $global_J
+                   } SPECIAL_expr
                }
                entry_point {
                    DW_AT_name fooso
@@ -158,12 +172,16 @@ Dwarf::assemble $asm_file {
                    formal_parameter {
                        DW_AT_name J
                        DW_AT_type :$int2_label
-                       DW_AT_location [subst {addr $global_J}] SPECIAL_expr
+                       DW_AT_location {
+                           DW_OP_addr $global_J
+                       } SPECIAL_expr
                    }
                    formal_parameter {
                        DW_AT_name K
                        DW_AT_type :$int2_label
-                       DW_AT_location [subst {addr $global_K}] SPECIAL_expr
+                       DW_AT_location {
+                           DW_OP_addr $global_K
+                       } SPECIAL_expr
                    }
                }
            }
index 7dd859ccef68216436527f0022d7f4ed7c162fcc..2945e1c0bc38afde668f82cc35867d592e8b1ea2 100644 (file)
@@ -63,11 +63,11 @@ Dwarf::assemble $asm_file {
                DW_TAG_variable {
                     DW_AT_name argc
                     DW_AT_type :$integer
-                    DW_AT_location [subst {
+                    DW_AT_location {
                        DW_OP_entry_value {
                            DW_OP_regx $::dwarf_regnum
                        }
-                   }] SPECIAL_expr
+                    } SPECIAL_expr
                }
            }
 
@@ -79,13 +79,13 @@ Dwarf::assemble $asm_file {
                DW_TAG_variable {
                     DW_AT_name foo
                     DW_AT_type :$integer
-                    DW_AT_location [subst {
+                    DW_AT_location {
                        DW_OP_entry_value {
                            DW_OP_bregx $::dwarf_regnum 0
                            DW_OP_deref_size 4
                        }
                        DW_OP_stack_value
-                   }] SPECIAL_expr
+                    } SPECIAL_expr
                }
            }
        }
index e8a80830931d3669a7145e0948e87332aca99bdf..66adcc8c7ac383db91d0b508d651bf408723e787 100644 (file)
@@ -41,18 +41,18 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name pck__fp1_var
                DW_AT_type :$fp1_base_type
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol pck__fp1_var]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
 
            DW_TAG_variable {
                DW_AT_name pck__fp1_var2
                DW_AT_type :$fp1_base_type
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol pck__fp1_var2]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
 
@@ -66,9 +66,9 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name pck__fp2_var
                DW_AT_type :$fp2_base_type
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol pck__fp2_var]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
 
@@ -87,9 +87,9 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name pck__fp3_var
                DW_AT_type :$fp3_base_type
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol pck__fp3_var]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
 
@@ -103,9 +103,9 @@ Dwarf::assemble $asm_file {
             DW_TAG_variable {
                 DW_AT_name pck__fp1_range_var
                 DW_AT_type :$fp1_range_type
-                DW_AT_location [subst {
+                DW_AT_location {
                     DW_OP_addr [gdb_target_symbol pck__fp1_range_var]
-                }] SPECIAL_expr
+                } SPECIAL_expr
                 DW_AT_external 1 flag
             }
        }
index 0a1f5d8f7103f819d052d9da20317ea04d8ad7d4..a77b43072749151bdaeefed6cfdd9f084d00a166 100644 (file)
@@ -47,10 +47,10 @@ Dwarf::assemble $asm_file {
                    DW_AT_name param
                    DW_AT_variable_parameter 1 flag
                    DW_AT_type :$int_label
-                   DW_AT_location [subst {
-                       addr [gdb_target_symbol ptr]
-                       deref
-                   }] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_addr [gdb_target_symbol ptr]
+                       DW_OP_deref
+                   } SPECIAL_expr
                }
            }
        }
index 2674c17eb6b14befa498b55c11688faa94be6c95..8eaa3a1dcc93cfa542851bf37bc9341eecfc8f1d 100644 (file)
@@ -87,7 +87,9 @@ Dwarf::assemble $asm_file {
                } {
                    DW_TAG_variable {
                        DW_AT_abstract_origin %$num_label
-                       DW_AT_location [subst {addr $global_num_addr}] SPECIAL_expr
+                       DW_AT_location {
+                           DW_OP_addr $global_num_addr
+                       } SPECIAL_expr
                    }
                    lexical_block {
                        DW_AT_low_pc scope_label1 addr
@@ -95,7 +97,9 @@ Dwarf::assemble $asm_file {
                    } {
                        DW_TAG_variable {
                            DW_AT_abstract_origin %$value_label
-                           DW_AT_location [subst {addr $global_value_addr}] SPECIAL_expr
+                           DW_AT_location {
+                               DW_OP_addr $global_value_addr
+                           } SPECIAL_expr
                        }
                    }
                }
index a973a11a66b3579356441dabbdda8d81b2be4416..88fda0d42dbd8a1acf219e845a4c2bbffbbec8ef 100644 (file)
@@ -44,9 +44,9 @@ Dwarf::assemble $asm_file {
                        DW_AT_name testvar
                        DW_AT_type :$integer_label
                        DW_AT_external 1 flag
-                       DW_AT_location [subst {
+                       DW_AT_location {
                            DW_OP_addr [gdb_target_symbol main]
-                       }] SPECIAL_expr
+                       } SPECIAL_expr
                    }
                }
            }
index ebbe6c05f91f496531c9e6fdbd961740df9dbbd0..b0e07ca3588851b27ad6d0a1a1ab0ca3a8e00352 100644 (file)
@@ -43,9 +43,9 @@ Dwarf::assemble $asm_file {
                DW_TAG_variable {
                    DW_AT_name v
                    DW_AT_linkage_name _ZN12_GLOBAL__N_11vE
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_addr [gdb_target_symbol _ZN12_GLOBAL__N_11vE]
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                    DW_AT_type :$myint
                }
            }
index 00e2863cd165221ebc12dc2e6445811590c53a88..1ad4b45b3d8164918ab977a5562e86bc2def8d37 100644 (file)
@@ -68,16 +68,16 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name file_locaddr_resolvable
                DW_AT_type :$integer_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol file_locaddr_resolvable]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
            DW_TAG_variable {
                DW_AT_name file_locaddr_unresolvable
                DW_AT_type :$integer_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol file_locaddr_resolvable]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            DW_TAG_variable {
@@ -106,17 +106,17 @@ Dwarf::assemble $asm_file {
                DW_AT_name file_extern_locaddr_resolvable
                DW_AT_type :$integer_label
                DW_AT_external 1 flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol file_extern_locaddr_resolvable]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
            DW_TAG_variable {
                DW_AT_name file_extern_locaddr_unresolvable
                DW_AT_type :$integer_label
                DW_AT_external 1 flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol file_extern_locaddr_resolvable]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            DW_TAG_variable {
@@ -140,16 +140,16 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name main_local_locaddr_resolvable
                DW_AT_type :$integer_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol main_local_locaddr_resolvable]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
            DW_TAG_variable {
                DW_AT_name main_local_locaddr_unresolvable
                DW_AT_type :$integer_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol main_local_locaddr_resolvable]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            DW_TAG_variable {
@@ -178,17 +178,17 @@ Dwarf::assemble $asm_file {
                DW_AT_name main_extern_locaddr_resolvable
                DW_AT_type :$integer_label
                DW_AT_external 1 flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol main_extern_locaddr_resolvable]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
            DW_TAG_variable {
                DW_AT_name main_extern_locaddr_unresolvable
                DW_AT_type :$integer_label
                DW_AT_external 1 flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol main_extern_locaddr_resolvable]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
        }
     }
index 6fc5ba52fd02832b7b925a9a56cbfc7ac606e38a..5e452555a76c2f070cfa57a12d5553682b17371a 100644 (file)
@@ -88,7 +88,9 @@ proc do_test {suffix} {
                    DW_AT_name e
                    DW_AT_external 1 flag
                    DW_AT_type :$volatile_label
-                   DW_AT_location [subst {addr $e_var}] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_addr $e_var
+                   } SPECIAL_expr
                }
                subprogram {
                    DW_AT_external 1 flag
index f5f22e61abbffa27dece33c64610a7892e210cff..3961abdce26c2e8066bc69068a288794623facd3 100644 (file)
@@ -89,18 +89,18 @@ proc run_test { field_name } {
                DW_TAG_variable {
                    DW_AT_name obj
                    DW_AT_type :$stype
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_addr [gdb_target_symbol obj]
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                    DW_AT_external 1 flag
                }
 
                DW_TAG_variable {
                    DW_AT_name ptr
                    DW_AT_type :$ptype
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_addr [gdb_target_symbol ptr]
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                    DW_AT_external 1 flag
                }
            }
index 122ee614ad0842568c7090682f339b8f7121d5bf..11c63292ca0241c8db3118d3f922c2938236c946 100644 (file)
@@ -69,9 +69,9 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name global_var DW_FORM_strp
                DW_AT_type :$struct_type
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol global_var]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
 
index 91beb791d2d8b5dee71ed8a1148b38b34df9a2b2..1f95a6574aefdf18498387e8d78de89ef25fa6da 100644 (file)
@@ -104,9 +104,9 @@ Dwarf::assemble $asm_file {
            }
 
            DW_TAG_variable {
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol dyn_object]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_name "dyn_object"
                DW_AT_type :$array_type_label
            }
index a5cf54df80c02ea1141895b7a9a16a5832e4634a..072dd8974a5d44b6c479799a90af78455f5bad4e 100644 (file)
@@ -78,9 +78,9 @@ Dwarf::assemble $asm_file {
                DW_AT_name "value"
                DW_AT_type :$struct
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "our_data"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
        }
     }
index aeb0aa2ab6b5fed43bf700f466a04ce6416cc882..5312c96c2594eb915f3a56b22598b0576cff2812 100644 (file)
@@ -57,18 +57,18 @@ Dwarf::assemble $asm_file {
            } {
                DW_TAG_subrange_type {
                    DW_AT_type        :$integer_label
-                   DW_AT_lower_bound [subst {
+                   DW_AT_lower_bound {
                        DW_OP_push_object_address
                        DW_OP_const1u [expr {2 * $int_size}]
                        DW_OP_minus
                        DW_OP_deref_size $int_size
-                   }] SPECIAL_expr
-                   DW_AT_upper_bound [subst {
+                   } SPECIAL_expr
+                   DW_AT_upper_bound {
                        DW_OP_push_object_address
                        DW_OP_const1u $int_size
                        DW_OP_minus
                        DW_OP_deref_size $int_size
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                }
            }
            array_ptr_label: DW_TAG_pointer_type {
@@ -82,33 +82,33 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name foo__three_ptr
                DW_AT_type :$array_ptr_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol table_1_ptr]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
            DW_TAG_variable {
                DW_AT_name foo__three_ptr_tdef
                DW_AT_type :$array_typedef_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol table_1_ptr]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
            DW_TAG_variable {
                DW_AT_name foo__five_ptr
                DW_AT_type :$array_ptr_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol table_2_ptr]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
            DW_TAG_variable {
                DW_AT_name foo__five_ptr_tdef
                DW_AT_type :$array_typedef_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol table_2_ptr]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
        }
index e5ef01afd1c01c0167bc6ba21ab222a4fba7b22b..51344207de5a596edb4790aabca65bf7bbbb10d3 100644 (file)
@@ -77,9 +77,9 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name global_var
                DW_AT_type :$struct_type
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_GNU_addr_index [gdb_target_symbol global_var]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
 
index 13fb3bf27d043909a204661c3b7c1f62f7d8b240..e252c866f719ff0fdbedacf2c58ef16d467bab09 100644 (file)
@@ -71,9 +71,9 @@ Dwarf::assemble $asm_file_1 {
                DW_TAG_formal_parameter {
                    DW_AT_name arg
                    DW_AT_type :$int4_type
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_GNU_addr_index [gdb_target_symbol global_param]
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                }
            }
        }
index b533f61d65fc0594e151f1b5a6b0adf294de4798..e2bae0a1f7e264d8f6f596433f8b619a25759f41 100644 (file)
@@ -74,9 +74,9 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name global_var
                DW_AT_type :$struct_type
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_GNU_addr_index [gdb_target_symbol global_var]
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
 
index e7894dd12b23ea33c38bf4c1b7e38dfccf6067d2..8ceaa4e31319c836211b0de53a2c59fff945097c 100644 (file)
@@ -82,11 +82,11 @@ proc test_1 { name dwarf_version offset_size addr_size ref_addr_size two_cu } {
                         DW_AT_external 1 flag
                    } {
                        DW_TAG_variable {
-                            DW_AT_name p
-                           DW_AT_location [subst {
-                               GNU_implicit_pointer $variable_label 0
-                           }] SPECIAL_expr
-                            DW_AT_type :$pointer_label "DW_FORM_ref$ref_addr_size"
+                           DW_AT_name p
+                           DW_AT_location {
+                               DW_OP_GNU_implicit_pointer $variable_label 0
+                           } SPECIAL_expr
+                           DW_AT_type :$pointer_label "DW_FORM_ref$ref_addr_size"
                        }
                    }
                }
@@ -110,11 +110,11 @@ proc test_1 { name dwarf_version offset_size addr_size ref_addr_size two_cu } {
                         DW_AT_external 1 flag
                    } {
                        DW_TAG_variable {
-                            DW_AT_name p
-                           DW_AT_location [subst {
-                               GNU_implicit_pointer $variable_label 0
-                           }] SPECIAL_expr
-                            DW_AT_type %$pointer_label
+                           DW_AT_name p
+                           DW_AT_location {
+                               DW_OP_GNU_implicit_pointer $variable_label 0
+                           } SPECIAL_expr
+                           DW_AT_type %$pointer_label
                        }
                    }
                }
index 701c79db3dc7d3e7ddfdc06a29f7a86dd88dbb37..86a08eb577428fd3be2d867b2803969a05c1ea4d 100644 (file)
@@ -66,9 +66,9 @@ Dwarf::assemble $asm_file {
 
                DW_TAG_variable {
                    DW_AT_name p
-                   DW_AT_location [subst {
-                       GNU_implicit_pointer $variable_label 0
-                   }] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_GNU_implicit_pointer $variable_label 0
+                   } SPECIAL_expr
                    DW_AT_type :$pointer_label
                }
            }
index 5078296cc2028a59986d711b9335cba9f5e144f4..3b0187682cfd0afa8794efc20f77cea36ebae908 100644 (file)
@@ -67,17 +67,17 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name c
                DW_AT_type :$ptr_label
-               DW_AT_location [subst {
-                   GNU_implicit_pointer $var_label 0
-               }] SPECIAL_expr
+               DW_AT_location {
+                   DW_OP_GNU_implicit_pointer $var_label 0
+               } SPECIAL_expr
            }
 
            DW_TAG_variable {
                DW_AT_name d
                DW_AT_type :$ptr_label
-               DW_AT_location [subst {
-                   GNU_implicit_pointer $var_label 2
-               }] SPECIAL_expr
+               DW_AT_location {
+                   DW_OP_GNU_implicit_pointer $var_label 2
+               } SPECIAL_expr
            }
        }
     }
index 1b9dc5eb213206e281072899efde7731a1d48efe..18d3a348600867844e48ed9514b0f6135beab9c3 100644 (file)
@@ -78,24 +78,24 @@ Dwarf::assemble $asm_file {
                DW_AT_name s
                DW_AT_type :$struct_label
                DW_AT_location {
-                   const2u 0x5678
-                   stack_value
-                   piece 2
-                   const1u 2
-                   stack_value
-                   piece 1
-                   const1u 3
-                   stack_value
-                   piece 1
+                   DW_OP_const2u 0x5678
+                   DW_OP_stack_value
+                   DW_OP_piece 2
+                   DW_OP_const1u 2
+                   DW_OP_stack_value
+                   DW_OP_piece 1
+                   DW_OP_const1u 3
+                   DW_OP_stack_value
+                   DW_OP_piece 1
                } SPECIAL_expr
            }
 
            DW_TAG_variable {
                DW_AT_name p
                DW_AT_type :$ptr_label
-               DW_AT_location [subst {
-                   GNU_implicit_pointer $var_label 2
-               }] SPECIAL_expr
+               DW_AT_location {
+                   DW_OP_GNU_implicit_pointer $var_label 2
+               } SPECIAL_expr
            }
        }
     }
index 9dec17319083bacb0ba6fb394a64a84092a3b06a..5473a430fe533ddda5f40e8d18152b5114e36478 100644 (file)
@@ -91,9 +91,9 @@ Dwarf::assemble ${asm_file} {
                DW_AT_name "array"
                DW_AT_type :${array_label}
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "array"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            DW_TAG_subprogram {
@@ -104,9 +104,9 @@ Dwarf::assemble ${asm_file} {
                DW_TAG_variable {
                    DW_AT_name "ref"
                    DW_AT_type :${ref_label}
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_GNU_implicit_pointer ${variable_label} 0
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                }
            }
        }
index bf3892d837ce8d9026951d307320c6d22a363133..bebc3b63af742f4cbc337e765da9dd20cdae5e66 100644 (file)
@@ -83,9 +83,9 @@ Dwarf::assemble ${asm_file} {
                DW_TAG_variable {
                    DW_AT_name "ref"
                    DW_AT_type :${const_label}
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_GNU_implicit_pointer ${variable_label} 0
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                }
            }
        }
index a9397bd67bdaf3cc2d2f5ab247c4a428dc1b5aee..f4f4d0338e48468cb1d76352796ac238a64e6979 100644 (file)
@@ -70,9 +70,9 @@ Dwarf::assemble ${asm_file} {
                DW_AT_name "global_var"
                DW_AT_type :${int_label}
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "global_var"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            DW_TAG_subprogram {
@@ -83,9 +83,9 @@ Dwarf::assemble ${asm_file} {
                DW_TAG_variable {
                    DW_AT_name "ref"
                    DW_AT_type :${ref_label}
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_GNU_implicit_pointer ${variable_label} 0
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                }
            }
        }
index 450576e1eb13a602405fbef33a4347bc350c5c2f..b0ea0a1d722f49d6c8b233ef231e56daaf14e1d1 100644 (file)
@@ -98,18 +98,18 @@ Dwarf::assemble ${asm_file} {
                DW_AT_name "s1"
                DW_AT_type :${struct_label}
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "s1"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            DW_TAG_variable {
                DW_AT_name "s2"
                DW_AT_type :${struct_label}
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "s2"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            DW_TAG_subprogram {
@@ -120,9 +120,9 @@ Dwarf::assemble ${asm_file} {
                DW_TAG_variable {
                    DW_AT_name "ref"
                    DW_AT_type :${ref_label}
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_GNU_implicit_pointer ${variable_label} 0
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                }
            }
        }
index fc5a2ae2162dac4b711c004e72ad1623cf2b5116..c604123516b3ffb67d619e4e090122749f9361ff 100644 (file)
@@ -50,9 +50,9 @@ Dwarf::assemble ${asm_file} {
                DW_AT_name "v_i16_m1"
                DW_AT_type :${i7_type}
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "i16_m1"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            u1_type: DW_TAG_base_type {
@@ -68,9 +68,9 @@ Dwarf::assemble ${asm_file} {
                DW_AT_name "v_u16_1"
                DW_AT_type :${u1_type}
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "u16_1"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            u17_type: DW_TAG_base_type {
@@ -85,9 +85,9 @@ Dwarf::assemble ${asm_file} {
                DW_AT_name "v_u32_m2"
                DW_AT_type :${u17_type}
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "u32_m2"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            u31_type: DW_TAG_base_type {
@@ -102,9 +102,9 @@ Dwarf::assemble ${asm_file} {
                DW_AT_name "v_u32_1"
                DW_AT_type :${u31_type}
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "u32_1"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            u31_1_type: DW_TAG_base_type {
@@ -120,9 +120,9 @@ Dwarf::assemble ${asm_file} {
                DW_AT_name "v_u32_1_off"
                DW_AT_type :${u31_1_type}
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "u32_1_off"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            be30_1_type: DW_TAG_base_type {
@@ -138,9 +138,9 @@ Dwarf::assemble ${asm_file} {
                DW_AT_name "v_be30_1_off"
                DW_AT_type :${be30_1_type}
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "be30_1_off"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            u32_0_type: DW_TAG_base_type {
@@ -155,9 +155,9 @@ Dwarf::assemble ${asm_file} {
                DW_AT_name "v_u32_0"
                DW_AT_type :${u32_0_type}
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "u32_0"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            u0_0_type: DW_TAG_base_type {
@@ -171,9 +171,9 @@ Dwarf::assemble ${asm_file} {
                DW_AT_name "v_u0_0"
                DW_AT_type :${u0_0_type}
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "u32_0"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            just_bit_type: DW_TAG_base_type {
@@ -186,9 +186,9 @@ Dwarf::assemble ${asm_file} {
                DW_AT_name "v_just_bit"
                DW_AT_type :${just_bit_type}
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "just_bit_0"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
        }
     }
index ba01137db5e53afd5437a3f739dc7ebdeb89bafb..1664e68a4fb6fce315c7aec43a06d50e3f80a8c7 100644 (file)
@@ -202,11 +202,12 @@ Dwarf::assemble ${asm_file} {
                # chosen.
                DW_TAG_inheritance {
                    DW_AT_type :$class_A_label
-                   DW_AT_data_member_location [subst {
+                   DW_AT_data_member_location {
                        DW_OP_constu ${::B_a}
                        DW_OP_plus
                        DW_OP_pick 0
-                       DW_OP_drop}] SPECIAL_expr
+                       DW_OP_drop
+                   } SPECIAL_expr
                    DW_AT_accessibility 1 DW_FORM_data1
                }
                DW_TAG_member {
@@ -230,18 +231,18 @@ Dwarf::assemble ${asm_file} {
                DW_AT_name "g_A"
                DW_AT_type :$class_A_label
                DW_AT_external 1 flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "g_A"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            DW_TAG_variable {
                DW_AT_name "g_B"
                DW_AT_type :$class_B_label
                DW_AT_external 1 flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "g_B"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            # We can't use MACRO_AT for the definitions of foo and bar
index 6478991bc5a51a0500963a609564114b6d63e9a9..494ea7b356032bb987e175fe0e68c1f5ab2b37a1 100644 (file)
@@ -78,18 +78,18 @@ Dwarf::assemble $asm_file {
                DW_AT_name "var_a"
                DW_AT_type :$main_type
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "var_a"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            DW_TAG_variable {
                DW_AT_name "var_ptr"
                DW_AT_type :$ptr_type
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "var_ptr"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
        }
     }
index 48f272e53579e2f8fea89c4127a08e127dacfdb7..30c4f530af9c6999fbfad8272a5704d707aafb52 100644 (file)
@@ -57,9 +57,9 @@ Dwarf::assemble ${asm_file} {
            DW_TAG_variable {
                DW_AT_name "s"
                DW_AT_type :$struct_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "s"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
        }
     }
index abf34add464c1bd8d2a2ed861ecd6a9d6f9c2383..604d7a0bc7a46723f4d337cf43c4c890addd005b 100644 (file)
@@ -115,12 +115,12 @@ Dwarf::assemble $asm_file {
                    DW_AT_name def_s
                    DW_AT_type :$struct_s_label
                    DW_AT_location {
-                       const1u 0
-                       stack_value
-                       bit_piece 8 0
-                       const1s -1
-                       stack_value
-                       bit_piece 24 0
+                       DW_OP_const1u 0
+                       DW_OP_stack_value
+                       DW_OP_bit_piece 8 0
+                       DW_OP_const1s -1
+                       DW_OP_stack_value
+                       DW_OP_bit_piece 24 0
                    } SPECIAL_expr
                }
                # Composite location: non-byte-aligned pieces.
@@ -128,12 +128,12 @@ Dwarf::assemble $asm_file {
                    DW_AT_name def_t
                    DW_AT_type :$struct_t_label
                    DW_AT_location {
-                       const2s -184
-                       stack_value
-                       bit_piece 9 0
-                       const4u 1752286
-                       stack_value
-                       bit_piece 23 0
+                       DW_OP_const2s -184
+                       DW_OP_stack_value
+                       DW_OP_bit_piece 9 0
+                       DW_OP_const4u 1752286
+                       DW_OP_stack_value
+                       DW_OP_bit_piece 23 0
                    } SPECIAL_expr
                }
                # Composite location with some empty pieces.
@@ -141,11 +141,11 @@ Dwarf::assemble $asm_file {
                    DW_AT_name part_def_a
                    DW_AT_type :$array_a9_label
                    DW_AT_location {
-                       piece 3
-                       const4u 0xf1927314
-                       stack_value
-                       piece 4
-                       piece 2
+                       DW_OP_piece 3
+                       DW_OP_const4u 0xf1927314
+                       DW_OP_stack_value
+                       DW_OP_piece 4
+                       DW_OP_piece 2
                    } SPECIAL_expr
                }
                # Implicit location: immediate value.
@@ -153,7 +153,7 @@ Dwarf::assemble $asm_file {
                    DW_AT_name def_implicit_s
                    DW_AT_type :$struct_s_label
                    DW_AT_location {
-                       implicit_value 0x12 0x34 0x56 0x78
+                       DW_OP_implicit_value 0x12 0x34 0x56 0x78
                    } SPECIAL_expr
                }
                # Implicit location: immediate value for whole array, with
@@ -162,7 +162,7 @@ Dwarf::assemble $asm_file {
                    DW_AT_name def_implicit_a
                    DW_AT_type :$array_a9_label
                    DW_AT_location {
-                       implicit_value 0x1 0x12 0x23 0x34 0x45 \
+                       DW_OP_implicit_value 0x1 0x12 0x23 0x34 0x45 \
                            0x56 0x67 0x78 0x89 0x9a 0xab
                    } SPECIAL_expr
                }
@@ -170,26 +170,26 @@ Dwarf::assemble $asm_file {
                DW_TAG_variable {
                    DW_AT_name implicit_a_ptr
                    DW_AT_type :$char_ptr_label
-                   DW_AT_location [subst {
-                       implicit_pointer $implicit_a_label 5
-                   }] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_implicit_pointer $implicit_a_label 5
+                   } SPECIAL_expr
                }
                # Stack-value location.
                stack_b_label: DW_TAG_variable {
                    DW_AT_name def_stack_b
                    DW_AT_type :$struct_t_label
                    DW_AT_location {
-                       const4u 0x1a2b3c4d
-                       stack_value
+                       DW_OP_const4u 0x1a2b3c4d
+                       DW_OP_stack_value
                    } SPECIAL_expr
                }
                # Implicit pointer into stack value.
                DW_TAG_variable {
                    DW_AT_name implicit_b_ptr
                    DW_AT_type :$char_ptr_label
-                   DW_AT_location [subst {
-                       implicit_pointer $stack_b_label 1
-                   }] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_implicit_pointer $stack_b_label 1
+                   } SPECIAL_expr
                }
            }
        }
index 8c60d031e821b68180c2b5cd583403731cb34c13..e4bc3ddb117a2f92408e546c68d7dc33bb275978 100644 (file)
@@ -66,21 +66,21 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name i64_noptr
                DW_AT_type :$i64_array
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_constu $::c64
                    DW_OP_stack_value
                    DW_OP_piece 8
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            DW_TAG_variable {
                DW_AT_name i32_noptr
                DW_AT_type :$i32_array
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_constu $::c32
                    DW_OP_stack_value
                    DW_OP_piece 4
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
        }
     }
index 9fa1a2b1c0ded4593274ca3687ddfd2a63491f07..792b8519577f253f852b12920fdd51a2218377a0 100644 (file)
@@ -38,7 +38,9 @@ Dwarf::assemble $asm_file {
                    DW_AT_name ~S
                    DW_AT_external 1 flag
                    DW_AT_virtuality @DW_VIRTUALITY_virtual
-                   DW_AT_vtable_elem_location {const1u 1} SPECIAL_expr
+                   DW_AT_vtable_elem_location {
+                       DW_OP_const1u 1
+                   } SPECIAL_expr
                }
            }
        }
index 87ef2b2243e82ea6607f59fe825b1e3a36fbf0c6..93b01fca428884e4bef55ecebdcb30c38446e64f 100644 (file)
@@ -79,7 +79,7 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name a
                DW_AT_type :$int_type_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr $exec_mask_var
                    DW_OP_deref_size $int_size
 
@@ -91,7 +91,7 @@ Dwarf::assemble $asm_file {
                    DW_OP_skip 3
                    DW_OP_bregx $dwarf_regnum 0
                    DW_OP_stack_value
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
        }
index 9f797a5843c305e82f9d81fec881b7485e364edb..0c334427ab54db5bfd76420a987a144685a7eb4a 100644 (file)
@@ -79,24 +79,24 @@ Dwarf::assemble $asm_file {
            DW_TAG_variable {
                DW_AT_name exec_mask
                DW_AT_type :$int_type_label
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr $exec_mask_var
-               }] SPECIAL_expr
+               } SPECIAL_expr
                DW_AT_external 1 flag
            }
 
            # add info for subprogram main
            DW_TAG_subprogram {
                MACRO_AT_func { main }
-               DW_AT_frame_base [subst {
+               DW_AT_frame_base {
                    DW_OP_regx $dwarf_regnum
-               }] SPECIAL_expr
+               } SPECIAL_expr
            } {
                # define artificial variable a
                DW_TAG_variable {
                    DW_AT_name a
                    DW_AT_type :$int_type_label
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_lit1
                        DW_OP_addr $exec_mask_var
                        DW_OP_deref_size $int_size
@@ -112,7 +112,7 @@ Dwarf::assemble $asm_file {
                        # conditional jump to DW_OP_drop
                        DW_OP_bra -9
                        DW_OP_stack_value
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                    DW_AT_external 1 flag
                }
            }
index 3276b28a81f16f387959a27438069a0a0565ac3b..87604655d2b77c0592625a0b97bae467bc6c6a01 100644 (file)
@@ -166,64 +166,64 @@ Dwarf::assemble $asm_file {
                DW_TAG_variable {
                    DW_AT_name "a"
                    DW_AT_type :$array_a8_label
-                   DW_AT_location [subst {
-                       addr $buf_var
-                   }] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_addr $buf_var
+                   } SPECIAL_expr
                }
                # Memory pieces: two bytes from &buf[2], and two bytes
                # from &buf[0].
                DW_TAG_variable {
                    DW_AT_name "s1"
                    DW_AT_type :$struct_s_label
-                   DW_AT_location [subst {
-                       addr $buf_var
-                       plus_uconst 2
-                       piece 2
-                       addr $buf_var
-                       piece 2
-                   }] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_addr $buf_var
+                       DW_OP_plus_uconst 2
+                       DW_OP_piece 2
+                       DW_OP_addr $buf_var
+                       DW_OP_piece 2
+                   } SPECIAL_expr
                }
                # Register- and memory pieces: one byte each from r0,
                # &buf[4], r1, and &buf[5].
                DW_TAG_variable {
                    DW_AT_name "s2"
                    DW_AT_type :$struct_s_label
-                   DW_AT_location [subst {
-                       regx [lindex $dwarf_regnum 0]
-                       piece 1
-                       addr "$buf_var + 4"
-                       piece 1
-                       regx [lindex $dwarf_regnum 1]
-                       piece 1
-                       addr "$buf_var + 5"
-                       piece 1
-                   }] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_regx [lindex $dwarf_regnum 0]
+                       DW_OP_piece 1
+                       DW_OP_addr "$buf_var + 4"
+                       DW_OP_piece 1
+                       DW_OP_regx [lindex $dwarf_regnum 1]
+                       DW_OP_piece 1
+                       DW_OP_addr "$buf_var + 5"
+                       DW_OP_piece 1
+                   } SPECIAL_expr
                }
                # Memory pieces for bitfield access: 8 bytes optimized
                # out, 3 bytes from &buf[3], and 1 byte from &buf[1].
                DW_TAG_variable {
                    DW_AT_name "st1"
                    DW_AT_type :$struct_st_label
-                   DW_AT_location [subst {
-                       piece 8
-                       addr "$buf_var + 3"
-                       piece 3
-                       addr "$buf_var + 1"
-                       piece 1
-                   }] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_piece 8
+                       DW_OP_addr "$buf_var + 3"
+                       DW_OP_piece 3
+                       DW_OP_addr "$buf_var + 1"
+                       DW_OP_piece 1
+                   } SPECIAL_expr
                }
                # Register pieces for bitfield access: 4 bytes optimized
                # out, 3 bytes from r0, and 1 byte from r1.
                DW_TAG_variable {
                    DW_AT_name "t2"
                    DW_AT_type :$struct_t_label
-                   DW_AT_location [subst {
-                       piece 4
-                       regx [lindex $dwarf_regnum 0]
-                       piece 3
-                       regx [lindex $dwarf_regnum 1]
-                       piece 1
-                   }] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_piece 4
+                       DW_OP_regx [lindex $dwarf_regnum 0]
+                       DW_OP_piece 3
+                       DW_OP_regx [lindex $dwarf_regnum 1]
+                       DW_OP_piece 1
+                   } SPECIAL_expr
                }
                # One piece per bitfield, using piece offsets: 32 bits of
                # an implicit value, 9 bits of a stack value, 13 bits of
@@ -231,17 +231,17 @@ Dwarf::assemble $asm_file {
                DW_TAG_variable {
                    DW_AT_name "t3"
                    DW_AT_type :$struct_t_label
-                   DW_AT_location [subst {
-                       implicit_value 0x12 0x34 0x56 0x78 0x9a
-                       bit_piece 32 4
-                       const2s -280
-                       stack_value
-                       bit_piece 9 2
-                       regx [lindex $dwarf_regnum 0]
-                       bit_piece 13 14
-                       addr $buf_var
-                       bit_piece 10 42
-                   }] SPECIAL_expr
+                   DW_AT_location {
+                       DW_OP_implicit_value 0x12 0x34 0x56 0x78 0x9a
+                       DW_OP_bit_piece 32 4
+                       DW_OP_const2s -280
+                       DW_OP_stack_value
+                       DW_OP_bit_piece 9 2
+                       DW_OP_regx [lindex $dwarf_regnum 0]
+                       DW_OP_bit_piece 13 14
+                       DW_OP_addr $buf_var
+                       DW_OP_bit_piece 10 42
+                   } SPECIAL_expr
                }
            }
        }
index 97c4ef879072f41968f0720c695cb70217fde98d..b8f532b2e657d00d97b0ce5f980c4d16f0899794 100644 (file)
@@ -74,9 +74,9 @@ proc setup_exec { arg_bad } {
                    DW_AT_name "var_a"
                    DW_AT_type :${int_label}
                    DW_AT_external 1 DW_FORM_flag
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_addr [gdb_target_symbol "var_a"]
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                }
 
                var_a_abstract_label: DW_TAG_variable {
@@ -88,9 +88,9 @@ proc setup_exec { arg_bad } {
                    DW_AT_name "var_b"
                    DW_AT_type :${int_label}
                    DW_AT_external 1 DW_FORM_flag
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_addr [gdb_target_symbol "var_b"]
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                }
 
                var_c_label: DW_TAG_variable {
@@ -104,9 +104,9 @@ proc setup_exec { arg_bad } {
                    DW_AT_name "var_p"
                    DW_AT_type :${ptr_label}
                    DW_AT_external 1 DW_FORM_flag
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_addr [gdb_target_symbol "var_p"]
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                }
 
                if { $bad } {
@@ -166,17 +166,17 @@ proc setup_exec { arg_bad } {
                    DW_AT_name "var_s"
                    DW_AT_type :${struct_label}
                    DW_AT_external 1 DW_FORM_flag
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_addr [gdb_target_symbol "var_s"]
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                }
 
                var_untyped_label: DW_TAG_variable {
                    DW_AT_name "var_untyped"
                    DW_AT_external 1 DW_FORM_flag
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_addr [gdb_target_symbol "var_b"]
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                }
 
                int_array_label: DW_TAG_array_type {
@@ -202,9 +202,9 @@ proc setup_exec { arg_bad } {
                    DW_AT_name "varval3"
                    DW_AT_external 1 DW_FORM_flag
                    DW_AT_type :${int_array_of_1_label}
-                   DW_AT_location [subst {
+                   DW_AT_location {
                        DW_OP_addr [gdb_target_symbol "var_a"]
-                   }] SPECIAL_expr
+                   } SPECIAL_expr
                }
 
                DW_TAG_subprogram {
@@ -215,39 +215,39 @@ proc setup_exec { arg_bad } {
                    varval_label: DW_TAG_variable {
                        DW_AT_name "varval"
                        DW_AT_type :${int_label}
-                       DW_AT_location [subst {
+                       DW_AT_location {
                            DW_OP_GNU_variable_value ${var_a_label}
                            DW_OP_const1s 0
                            DW_OP_or
                            DW_OP_stack_value
-                       }] SPECIAL_expr
+                       } SPECIAL_expr
                    }
                    varval2_label: DW_TAG_variable {
                        DW_AT_name "varval2"
                        DW_AT_type :${int_label}
-                       DW_AT_location [subst {
+                       DW_AT_location {
                            DW_OP_GNU_variable_value ${var_a_abstract_label}
                            DW_OP_stack_value
-                       }] SPECIAL_expr
+                       } SPECIAL_expr
                    }
                    var_a_concrete_label: DW_TAG_variable {
                        DW_AT_abstract_origin :${var_a_abstract_label}
-                       DW_AT_location [subst {
+                       DW_AT_location {
                            DW_OP_addr [gdb_target_symbol "var_a"]
-                       }] SPECIAL_expr
+                       } SPECIAL_expr
                    }
                    DW_TAG_variable {
                        DW_AT_name "constval"
                        DW_AT_type :${int_label}
-                       DW_AT_location [subst {
+                       DW_AT_location {
                            DW_OP_GNU_variable_value ${var_c_label}
                            DW_OP_stack_value
-                       }] SPECIAL_expr
+                       } SPECIAL_expr
                    }
                    DW_TAG_variable {
                        DW_AT_name "mixedval"
                        DW_AT_type :${int_label}
-                       DW_AT_location [subst {
+                       DW_AT_location {
                            DW_OP_GNU_variable_value ${var_c_label}
                            DW_OP_GNU_variable_value ${var_b_label}
                            DW_OP_div
@@ -258,40 +258,40 @@ proc setup_exec { arg_bad } {
                            DW_OP_GNU_variable_value ${varval_label}
                            DW_OP_minus
                            DW_OP_stack_value
-                       }] SPECIAL_expr
+                       } SPECIAL_expr
                    }
                    DW_TAG_variable {
                        DW_AT_name "pointerval"
                        DW_AT_type :${ptr_label}
-                       DW_AT_location [subst {
+                       DW_AT_location {
                            DW_OP_GNU_variable_value ${var_p_label}
                            DW_OP_stack_value
-                       }] SPECIAL_expr
+                       } SPECIAL_expr
                    }
                    if { $bad } {
                        DW_TAG_variable {
                            DW_AT_name "badval"
                            DW_AT_type :${int_label}
-                           DW_AT_location [subst {
+                           DW_AT_location {
                                DW_OP_GNU_variable_value ${var_bad_label}
                                DW_OP_stack_value
-                           }] SPECIAL_expr
+                           } SPECIAL_expr
                        }
                    }
                    DW_TAG_variable {
                        DW_AT_name "structval"
                        DW_AT_type :${struct_label}
-                       DW_AT_location [subst {
+                       DW_AT_location {
                            DW_OP_GNU_variable_value ${var_s_label}
                            DW_OP_stack_value
-                       }] SPECIAL_expr
+                       } SPECIAL_expr
                    }
                    DW_TAG_variable {
                        DW_AT_name "untypedval"
-                       DW_AT_location [subst {
+                       DW_AT_location {
                            DW_OP_GNU_variable_value ${var_untyped_label}
                            DW_OP_stack_value
-                       }] SPECIAL_expr
+                       } SPECIAL_expr
                    }
                    if { $bad } {
                        DW_TAG_variable {
@@ -303,10 +303,10 @@ proc setup_exec { arg_bad } {
                        }
                        DW_TAG_variable {
                            DW_AT_name "bad_die_val2"
-                           DW_AT_location [subst {
+                           DW_AT_location {
                                DW_OP_GNU_variable_value ${ptr_label}+1
                                DW_OP_stack_value
-                           }] SPECIAL_expr
+                           } SPECIAL_expr
                        }
                    }
                }
index 963410f93e654c1c851b13f8cd79cb97120a3799..a747a7133e76bc8d86757095198dd91b6722a9b5 100644 (file)
@@ -74,18 +74,18 @@ Dwarf::assemble $asm_file {
                DW_AT_name "var_a"
                DW_AT_type :$int_type
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "var_a"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
 
            DW_TAG_variable {
                DW_AT_name "var_ptr"
                DW_AT_type :$ptr_type
                DW_AT_external 1 DW_FORM_flag
-               DW_AT_location [subst {
+               DW_AT_location {
                    DW_OP_addr [gdb_target_symbol "var_ptr"]
-               }] SPECIAL_expr
+               } SPECIAL_expr
            }
        }
     }
index 5794bbda8a2d7e80062f1f4cf926e1a42bdfbf66..2c6b40d4b9cc709c3a023bf799e43b0047b6503c 100644 (file)
@@ -98,9 +98,9 @@ Dwarf::assemble $asm_file {
            # Used for testing synthetic pointers.
            DW_TAG_variable {
                DW_AT_name synthptr
-               DW_AT_location [subst {
-                   GNU_implicit_pointer $variable_label 0
-               }] SPECIAL_expr
+               DW_AT_location {
+                   DW_OP_GNU_implicit_pointer $variable_label 0
+               } SPECIAL_expr
                DW_AT_type :$pointer_label
            }
 
index f6c4c5c1b6f64abb480e36dc32a6e5b7f05b111f..6c2270894534d5a826c17ea6c54d5888cb4f4573 100644 (file)
@@ -137,15 +137,15 @@ Dwarf::assemble $asm_file {
                    GNU_call_site_parameter {
                        DW_AT_location {DW_OP_reg0} SPECIAL_expr
                        DW_AT_GNU_call_site_value {
-                           addr global1
-                           deref_size 4
+                           DW_OP_addr global1
+                           DW_OP_deref_size 4
                        } SPECIAL_expr
                    }
                    GNU_call_site_parameter {
                        DW_AT_location {DW_OP_reg1} SPECIAL_expr
                        DW_AT_GNU_call_site_value {
-                           addr global2
-                           deref_size 4
+                           DW_OP_addr global2
+                           DW_OP_deref_size 4
                        } SPECIAL_expr
                    }
                }
index 95e33c1b31044238819615f21fea924f433a4667..55f33d4779712bde787b165f4f7b5857c7e663df 100644 (file)
@@ -488,10 +488,9 @@ proc get_func_info { name {options {debug}} } {
 # section automatically.
 #
 # If FORM is 'SPECIAL_expr', then VALUE is treated as a location
-# expression.  The effective form is then DW_FORM_block or DW_FORM_exprloc
-# for DWARF version >= 4, and VALUE is passed to the (internal)
-# '_location' proc to be translated.
-# This proc implements a miniature DW_OP_ assembler.
+# expression.  The effective form is then DW_FORM_block or
+# DW_FORM_exprloc for DWARF version >= 4, and VALUE is treated as
+# code, using DW_OP_* procs and evaluated in the appropriate scope.
 #
 # If FORM is not given, it is guessed:
 # * If VALUE starts with the "@" character, the rest of VALUE is
@@ -521,8 +520,6 @@ namespace eval Dwarf {
     variable _constants
     # DW_FORM short names.
     variable _FORM
-    # DW_OP short names.
-    variable _OP
 
     # The current output file.
     variable _output_file
@@ -591,10 +588,15 @@ namespace eval Dwarf {
     # code should be evaluated.
     variable _level
 
+    # Variables used when processing a location expression.  These are
+    # set by _location and may be used by the various DW_OP-handlers.
+    variable _loc_dwarf_version
+    variable _loc_addr_size
+    variable _loc_offset_size
+
     proc _process_one_constant {name value} {
        variable _constants
        variable _FORM
-       variable _OP
 
        set _constants($name) $value
 
@@ -643,7 +645,18 @@ namespace eval Dwarf {
            }
 
            OP {
-               set _OP($name2) $name
+               set handler _handle_default_OP
+               if {[llength [info procs _handle_DW_OP_$name2]] > 0} {
+                   set handler _handle_DW_OP_$name2
+               }
+               # Each DW_OP_* proc emits the opcode and then
+               # delegates to the argument handler.
+               # tclint-disable-next-line command-args
+               proc $name {args} [format {
+                   variable _constants
+                   _op .byte $_constants(%s) %s
+                   %s {*}$args
+               } $name $name $handler]
            }
 
            default {
@@ -1217,209 +1230,211 @@ namespace eval Dwarf {
        }
     }
 
-    # This is a miniature assembler for location expressions.  It is
-    # suitable for use in the attributes to a DIE.  Its output is
-    # prefixed with "=" to make it automatically use DW_FORM_block.
     #
-    # BODY is split by lines, and each line is taken to be a list.
-    #
-    # DWARF_VERSION is the DWARF version for the section where the location
-    # description is found.
+    # Handlers for DW_OP_* opcodes.
     #
-    # ADDR_SIZE is the length in bytes (4 or 8) of an address on the target
-    # machine (typically found in the header of the section where the location
-    # description is found).
+    # A handler is only needed if the opcode requires a parameter, or
+    # some sort of special handling.  Generic code handles emitting
+    # the actual opcode itself, so a handler should not do this.
     #
-    # OFFSET_SIZE is the length in bytes (4 or 8) of an offset into a DWARF
-    # section.  This typically depends on whether 32-bit or 64-bit DWARF is
-    # used, as indicated in the header of the section where the location
-    # description is found.
+    # Handlers are found by name when parsing the .def file.  If a
+    # handler isn't found, the default (_handle_default_OP) is used.
     #
-    # Each list's first element is the opcode, either short or long
-    # forms are accepted.
-    # FIXME argument handling
-    # FIXME move docs
-    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 {  [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]
-           _op .byte $_constants($opcode) $opcode
+    proc _handle_DW_OP_addr {size} {
+       variable _loc_addr_size
+       _op .${_loc_addr_size}byte $size
+    }
 
-           array unset argvec *
-           switch -exact -- $opcode {
-               DW_OP_addr {
-                   _get_args $line $opcode size
-                   _op .${addr_size}byte $argvec(size)
-               }
+    proc _handle_DW_OP_GNU_addr_index {symbol} {
+       variable _debug_addr_index
+       variable _cu_addr_size
 
-               DW_OP_GNU_addr_index {
-                   variable _debug_addr_index
-                   variable _cu_addr_size
+       _op .uleb128 ${_debug_addr_index}
+       incr _debug_addr_index
 
-                   _op .uleb128 ${_debug_addr_index}
-                   incr _debug_addr_index
+       _defer_output .debug_addr {
+           _op .${_cu_addr_size}byte $symbol
+       }
+    }
 
-                   _defer_output .debug_addr {
-                       _op .${_cu_addr_size}byte [lindex $line 1]
-                   }
-               }
+    proc _handle_DW_OP_regx {register} {
+       _op .uleb128 $register
+    }
 
-               DW_OP_regx {
-                   _get_args $line $opcode register
-                   _op .uleb128 $argvec(register)
-               }
+    proc _handle_DW_OP_pick {const} {
+       _op .byte $const
+    }
+    proc _handle_DW_OP_const1u {const} {
+       _op .byte $const
+    }
+    proc _handle_DW_OP_const1s {const} {
+       _op .byte $const
+    }
 
-               DW_OP_pick -
-               DW_OP_const1u -
-               DW_OP_const1s {
-                   _get_args $line $opcode const
-                   _op .byte $argvec(const)
-               }
+    proc _handle_DW_OP_const2u {const} {
+       _op .2byte $const
+    }
+    proc _handle_DW_OP_const2s {const} {
+       _op .2byte $const
+    }
 
-               DW_OP_const2u -
-               DW_OP_const2s {
-                   _get_args $line $opcode const
-                   _op .2byte $argvec(const)
-               }
+    proc _handle_DW_OP_const4u {const} {
+       _op .4byte $const
+    }
+    proc _handle_DW_OP_const4s {const} {
+       _op .4byte $const
+    }
 
-               DW_OP_const4u -
-               DW_OP_const4s {
-                   _get_args $line $opcode const
-                   _op .4byte $argvec(const)
-               }
+    proc _handle_DW_OP_const8u {const} {
+       _op .8byte $const
+    }
+    proc _handle_DW_OP_const8s {const} {
+       _op .8byte $const
+    }
 
-               DW_OP_const8u -
-               DW_OP_const8s {
-                   _get_args $line $opcode const
-                   _op .8byte $argvec(const)
-               }
+    proc _handle_DW_OP_constu {const} {
+       _op .uleb128 $const
+    }
+    proc _handle_DW_OP_consts {const} {
+       _op .sleb128 $const
+    }
 
-               DW_OP_constu {
-                   _get_args $line $opcode const
-                   _op .uleb128 $argvec(const)
-               }
-               DW_OP_consts {
-                   _get_args $line $opcode const
-                   _op .sleb128 $argvec(const)
-               }
+    proc _handle_DW_OP_plus_uconst {const} {
+       _op .uleb128 $const
+    }
 
-               DW_OP_plus_uconst {
-                   _get_args $line $opcode const
-                   _op .uleb128 $argvec(const)
-               }
+    proc _handle_DW_OP_piece {size} {
+       _op .uleb128 $size
+    }
 
-               DW_OP_piece {
-                   _get_args $line $opcode size
-                   _op .uleb128 $argvec(size)
-               }
+    proc _handle_DW_OP_bit_piece {size offset} {
+       _op .uleb128 $size
+       _op .uleb128 $offset
+    }
 
-               DW_OP_bit_piece {
-                   _get_args $line $opcode size offset
-                   _op .uleb128 $argvec(size)
-                   _op .uleb128 $argvec(offset)
-               }
+    proc _handle_DW_OP_skip {label} {
+       _op .2byte $label
+    }
+    proc _handle_DW_OP_bra {label} {
+       _op .2byte $label
+    }
 
-               DW_OP_skip -
-               DW_OP_bra {
-                   _get_args $line $opcode label
-                   _op .2byte $argvec(label)
-               }
+    proc _handle_DW_OP_entry_value {body} {
+       variable _loc_dwarf_version
+       variable _loc_addr_size
+       variable _loc_offset_size
 
-               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
+       set l1 [new_label "expr_start"]
+       set l2 [new_label "expr_end"]
+       _op .uleb128 "$l2 - $l1" "expression"
+       define_label $l1
+       variable _level
+       uplevel $_level [list _location $body $_loc_dwarf_version \
+                            $_loc_addr_size $_loc_offset_size]
+       define_label $l2
+    }
+
+    proc _handle_DW_OP_implicit_value {args} {
+       set l1 [new_label "value_start"]
+       set l2 [new_label "value_end"]
+       _op .uleb128 "$l2 - $l1"
+       define_label $l1
+       foreach value $args {
+           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_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
-               }
+    proc _handle_DW_OP_implicit_pointer {label offset} {
+       variable _loc_dwarf_version
+       variable _loc_addr_size
+       variable _loc_offset_size
+       # Here label is a section offset.
+       if { $_loc_dwarf_version == 2 } {
+           _op .${_loc_addr_size}byte $label
+       } else {
+           _op_offset $_loc_offset_size $label
+       }
+       _op .sleb128 $offset
+    }
 
-               DW_OP_implicit_pointer -
-               DW_OP_GNU_implicit_pointer {
-                   _get_args $line $opcode label offset
+    proc _handle_DW_OP_GNU_implicit_pointer {label offset} {
+       _handle_DW_OP_implicit_pointer $label $offset
+    }
 
-                   # Here label is a section offset.
-                   if { $dwarf_version == 2 } {
-                       _op .${addr_size}byte $argvec(label)
-                   } else {
-                       _op_offset $offset_size $argvec(label)
-                   }
-                   _op .sleb128 $argvec(offset)
-               }
+    proc _handle_DW_OP_GNU_variable_value {label} {
+       variable _loc_addr_size
+       variable _loc_offset_size
+       variable _loc_dwarf_version
+       # Here label is a section offset.
+       if { $_loc_dwarf_version == 2 } {
+           _op .${_loc_addr_size}byte $label
+       } else {
+           _op_offset $_loc_offset_size $label
+       }
+    }
 
-               DW_OP_GNU_variable_value {
-                   _get_args $line $opcode label
+    proc _handle_DW_OP_deref_size {size} {
+       _op .byte $size
+    }
 
-                   # Here label is a section offset.
-                   if { $dwarf_version == 2 } {
-                       _op .${addr_size}byte $argvec(label)
-                   } else {
-                       _op_offset $offset_size $argvec(label)
-                   }
-               }
+    proc _handle_DW_OP_bregx {register offset} {
+       _op .uleb128 $register
+       _op .sleb128 $offset
+    }
 
-               DW_OP_deref_size {
-                   _get_args $line $opcode size
-                   _op .byte $argvec(size)
-               }
+    proc _handle_DW_OP_fbreg {offset} {
+       _op .sleb128 $offset
+    }
 
-               DW_OP_bregx {
-                   _get_args $line $opcode register offset
-                   _op .uleb128 $argvec(register)
-                   _op .sleb128 $argvec(offset)
-               }
+    proc _handle_DW_OP_fbreg {reg} {
+       _op .sleb128 $reg
+    }
 
-               DW_OP_fbreg {
-                   _get_args $line $opcode offset
-                   _op .sleb128 $argvec(offset)
-               }
+    proc _handle_default_OP {} {
+       # Do nothing; if arguments are passed, Tcl will cause an
+       # error.
+    }
 
-               DW_OP_fbreg {
-                   _op .sleb128 [lindex $line 1]
-               }
+    # This is a miniature assembler for location expressions.  It is
+    # suitable for use in the attributes to a DIE.
+    #
+    # BODY is evaluated as code in the appropriate scope.
+    #
+    # DWARF_VERSION is the DWARF version for the section where the location
+    # description is found.
+    #
+    # ADDR_SIZE is the length in bytes (4 or 8) of an address on the target
+    # machine (typically found in the header of the section where the location
+    # description is found).
+    #
+    # OFFSET_SIZE is the length in bytes (4 or 8) of an offset into a DWARF
+    # section.  This typically depends on whether 32-bit or 64-bit DWARF is
+    # used, as indicated in the header of the section where the location
+    # description is found.
+    #
+    # FIXME move docs
+    proc _location { body dwarf_version addr_size offset_size } {
+       variable _loc_dwarf_version
+       set _loc_dwarf_version $dwarf_version
 
-               default {
-                   if {[llength $line] > 1} {
-                       error "Unimplemented: operands in location for $opcode"
-                   }
-               }
-           }
-       }
+       variable _loc_addr_size
+       set _loc_addr_size $addr_size
+
+       variable _loc_offset_size
+       set _loc_offset_size $offset_size
+
+       variable _level
+       uplevel $_level $body
     }
 
     # Return a label that references the current position in the