[gdb/testsuite] Fix 64-bit dwarf test-cases with -m32
authorTom de Vries <tdevries@suse.de>
Fri, 19 Nov 2021 14:09:05 +0000 (15:09 +0100)
committerTom de Vries <tdevries@suse.de>
Fri, 19 Nov 2021 14:09:05 +0000 (15:09 +0100)
When running test-case gdb.dwarf2/loc-sec-offset.exp with target board -m32,
I run into:
...
builtin_spawn -ignore SIGHUP gcc -fno-stack-protector -m32 \
  -fdiagnostics-color=never -c -o loc-sec-offset-dw641.o \
  loc-sec-offset-dw64.S^M
as: loc-sec-offset-dw641.o: unsupported relocation type: 0x1^M
loc-sec-offset-dw64.S: Assembler messages:^M
loc-sec-offset-dw64.S:29: Error: cannot represent relocation type \
  BFD_RELOC_64^M
...

Looking at line 29, we have:
...
        .8byte        .Labbrev1_begin   /* Abbrevs */
...

It would be nice if the assembler could handle this somehow.  But I guess
it's not unreasonable that an assembler for a 32-bit architecture will object
to handling 64-bit labels.

Instead, work around this in the dwarf assembler by emitting:
...
        .4byte        .Labbrev1_begin   /* Abbrevs (lsw) */
        .4byte        0                 /* Abbrevs (msw) */
...

Tested on x86_64-linux with target board unix/-m32.

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

gdb/testsuite/lib/dwarf.exp
gdb/testsuite/lib/gdb.exp

index 774cac712a2043e54c3e841046b50748cd47b4a3..7dd82b8a3816a0737c345809c84e10e234da38cf 100644 (file)
@@ -580,7 +580,7 @@ namespace eval Dwarf {
            DW_FORM_GNU_strp_alt -
            DW_FORM_sec_offset {
                variable _cu_offset_size
-               _op .${_cu_offset_size}byte $value
+               _op_offset $_cu_offset_size $value
            }
 
            DW_FORM_ref1 -
@@ -645,7 +645,7 @@ namespace eval Dwarf {
                    }
                }
 
-               _op .${_cu_offset_size}byte $_strings($value) "strp: $value"
+               _op_offset $_cu_offset_size $_strings($value) "strp: $value"
            }
 
            SPECIAL_expr {
@@ -971,6 +971,28 @@ namespace eval Dwarf {
        _emit $text
     }
 
+    proc _op_offset { size offset {comment ""} } {
+       if { $size == 4 } {
+           _op .4byte $offset $comment
+       } elseif { $size == 8 } {
+           if {[is_64_target]} {
+               _op .8byte $offset $comment
+           } else {
+               # This allows us to emit 64-bit dwarf for
+               # 32-bit targets.
+               if { [target_endianness] == "little" } {
+                   _op .4byte $offset "$comment (lsw)"
+                   _op .4byte 0 "$comment (msw)"
+               } else {
+                   _op .4byte 0 "$comment (msw)"
+                   _op .4byte $offset "$comment (lsw)"
+               }
+           }
+       } else {
+           error "Don't know how to handle offset size $size"
+       }
+    }
+
     proc _compute_label {name} {
        return ".L${name}"
     }
@@ -1185,7 +1207,7 @@ namespace eval Dwarf {
                    if { $dwarf_version == 2 } {
                        _op .${addr_size}byte $argvec(label)
                    } else {
-                       _op .${offset_size}byte $argvec(label)
+                       _op_offset $offset_size $argvec(label)
                    }
                    _op .sleb128 $argvec(offset)
                }
@@ -1197,7 +1219,7 @@ namespace eval Dwarf {
                    if { $dwarf_version == 2 } {
                        _op .${addr_size}byte $argvec(label)
                    } else {
-                       _op .${offset_size}byte $argvec(label)
+                       _op_offset $offset_size $argvec(label)
                    }
                }
 
@@ -1344,9 +1366,9 @@ namespace eval Dwarf {
        if { $_cu_version == 5 } {
            _op .byte 0x1 "DW_UT_compile"
            _op .byte $_cu_addr_size "Pointer size"
-           _op .${_cu_offset_size}byte $my_abbrevs Abbrevs
+           _op_offset $_cu_offset_size $my_abbrevs Abbrevs
        } else {
-           _op .${_cu_offset_size}byte $my_abbrevs Abbrevs
+           _op_offset $_cu_offset_size $my_abbrevs Abbrevs
            _op .byte $_cu_addr_size "Pointer size"
        }
 
@@ -1440,7 +1462,7 @@ namespace eval Dwarf {
        }
        define_label $start_label
        _op .2byte $_cu_version Version
-       _op .${_cu_offset_size}byte $my_abbrevs Abbrevs
+       _op_offset $_cu_offset_size $my_abbrevs Abbrevs
        _op .byte $_cu_addr_size "Pointer size"
        _op .8byte $signature Signature
        if { $type_label != "" } {
@@ -1666,7 +1688,9 @@ namespace eval Dwarf {
        if { ${with-offset-array} } {
            for {set list_idx 0} {$list_idx < $_debug_rnglists_list_count} {incr list_idx} {
                set list_label [_compute_list_label $list_idx]
-               _op .${_debug_rnglists_offset_size}byte "$list_label - $post_header_label" "offset of list $list_idx"
+               _op_offset $_debug_rnglists_offset_size \
+                   "$list_label - $post_header_label" \
+                   "offset of list $list_idx"
            }
        }
 
@@ -1852,7 +1876,9 @@ namespace eval Dwarf {
        if { ${with-offset-array} } {
            for {set list_idx 0} {$list_idx < $_debug_loclists_list_count} {incr list_idx} {
                set list_label [_compute_list_label $list_idx]
-               _op .${_debug_loclists_offset_size}byte "$list_label - $post_header_label" "offset of list $list_idx"
+               _op_offset $_debug_loclists_offset_size \
+                   "$list_label - $post_header_label" \
+                   "offset of list $list_idx"
            }
        }
 
index 97bedd5cb583a855f20d5e4397262d433169da7e..deb1b8f213842882c7600ce08f65598ae3b3c418 100644 (file)
@@ -7085,6 +7085,29 @@ proc get_endianness { } {
     return "little"
 }
 
+# Get the target's default endianness and return it.
+gdb_caching_proc target_endianness {
+    global gdb_prompt
+
+    set me "target_endianness"
+
+    set src { int main() { return 0; } }
+    if {![gdb_simple_compile $me $src executable]} {
+        return 0
+    }
+
+    clean_restart $obj
+    if ![runto_main] {
+        return 0
+    }
+    set res [get_endianness]
+
+    gdb_exit
+    remote_file build delete $obj
+
+    return $res
+}
+
 # ROOT and FULL are file names.  Returns the relative path from ROOT
 # to FULL.  Note that FULL must be in a subdirectory of ROOT.
 # For example, given ROOT = /usr/bin and FULL = /usr/bin/ls, this