binutils-gdb/gdb/testsuite/lib/jit-elf-helpers.exp

118 lines
3.8 KiB
Plaintext
Raw Normal View History

# Copyright 2020-2023 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Magic constants used to calculate a starting address when linking
# "jit" shared libraries. When loaded, will be mapped by jit-elf-main
# to the same address.
set jit_load_address 0x7000000
set jit_load_increment 0x1000000
# Compile jit-elf-main.c as an executable.
#
# BINSUFFIX is appended to the binary name.
# OPTIONS is passed to gdb_compile when compiling the program.
#
# On success, return 0.
# On failure, return -1.
proc compile_jit_main {main_srcfile main_binfile options} {
global jit_load_address jit_load_increment
set options [concat \
$options \
additional_flags=-DLOAD_ADDRESS=$jit_load_address \
additional_flags=-DLOAD_INCREMENT=$jit_load_increment \
debug]
if { [gdb_compile ${main_srcfile} ${main_binfile} \
executable $options] != "" } {
set f [file tail $main_binfile]
untested "failed to compile $f"
return -1
}
return 0
}
# Compile jit-elf-main.c as a shared library.
#
# OPTIONS is passed to gdb_compile when compiling the program.
#
# On success, return 0.
# On failure, return -1.
proc compile_jit_elf_main_as_so {main_solib_srcfile main_solib_binfile options} {
global jit_load_address jit_load_increment
set options [concat \
$options \
additional_flags=-DLOAD_ADDRESS=$jit_load_address \
additional_flags=-DLOAD_INCREMENT=$jit_load_increment \
debug]
if { [gdb_compile_shlib ${main_solib_srcfile} ${main_solib_binfile} \
$options] != "" } {
set f [file tail $main_solib_binfile]
untested "failed to compile shared library $f"
return -1
}
return 0
}
# Compile jit-elf-solib.c as a shared library in multiple copies and
# upload them to the target.
#
gdb: include the base address in in-memory bfd filenames The struct target_buffer (in gdb_bfd.c) is used to hold information about an in-memory BFD object created by GDB. For now this mechanism is used by GDB when loading information about JIT symfiles. This commit updates target_buffer (in gdb_bfd.c) to be more C++ like, and, at the same time, adds the base address of the symfile into the BFD filename. Right now, every in-memory BFD is given the filename "<in-memory>". This filename is visible in things like 'maint info symtabs' and 'maint info line-table'. If there are multiple in-memory BFD objects then it can be hard to match keep track if which BFD is which. This commit changes the name to be "<in-memory@ADDRESS>" where ADDRESS is replaced with the base address for where the in-memory symbol file was read from. As an example of how this is useful, here's the output of 'maint info jit' showing a single loaded JIT symfile: (gdb) maintenance info jit jit_code_entry address symfile address symfile size 0x00000000004056b0 0x0000000007000000 17320 And here's part of the output from 'maint info symtabs': (gdb) maintenance info symtabs ...snip... { objfile <in-memory@0x7000000> ((struct objfile *) 0x5258250) { ((struct compunit_symtab *) 0x4f0afb0) debugformat DWARF 4 producer GNU C17 9.3.1 20200408 (Red Hat 9.3.1-2) -mtune=generic -march=x86-64 -g -fno-stack-protector -fpic name jit-elf-solib.c dirname /tmp/binutils-gdb/build/gdb/testsuite blockvector ((struct blockvector *) 0x5477850) user ((struct compunit_symtab *) (null)) { symtab /tmp/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/jit-elf-solib.c ((struct symtab *) 0x4f0b030) fullname (null) linetable ((struct linetable *) 0x5477880) } } } I've added a new test that checks the new in-memory file names are generated correctly, and also checks that the in-memory JIT files can be dumped back out using 'dump binary memory'.
2022-10-05 22:26:11 +08:00
# OPTIONS_LIST is a list of additional options to pass through to
# gdb_compile_shlib.
#
# On success, return a list of target path to the shared libraries.
# On failure, return -1.
gdb: include the base address in in-memory bfd filenames The struct target_buffer (in gdb_bfd.c) is used to hold information about an in-memory BFD object created by GDB. For now this mechanism is used by GDB when loading information about JIT symfiles. This commit updates target_buffer (in gdb_bfd.c) to be more C++ like, and, at the same time, adds the base address of the symfile into the BFD filename. Right now, every in-memory BFD is given the filename "<in-memory>". This filename is visible in things like 'maint info symtabs' and 'maint info line-table'. If there are multiple in-memory BFD objects then it can be hard to match keep track if which BFD is which. This commit changes the name to be "<in-memory@ADDRESS>" where ADDRESS is replaced with the base address for where the in-memory symbol file was read from. As an example of how this is useful, here's the output of 'maint info jit' showing a single loaded JIT symfile: (gdb) maintenance info jit jit_code_entry address symfile address symfile size 0x00000000004056b0 0x0000000007000000 17320 And here's part of the output from 'maint info symtabs': (gdb) maintenance info symtabs ...snip... { objfile <in-memory@0x7000000> ((struct objfile *) 0x5258250) { ((struct compunit_symtab *) 0x4f0afb0) debugformat DWARF 4 producer GNU C17 9.3.1 20200408 (Red Hat 9.3.1-2) -mtune=generic -march=x86-64 -g -fno-stack-protector -fpic name jit-elf-solib.c dirname /tmp/binutils-gdb/build/gdb/testsuite blockvector ((struct blockvector *) 0x5477850) user ((struct compunit_symtab *) (null)) { symtab /tmp/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/jit-elf-solib.c ((struct symtab *) 0x4f0b030) fullname (null) linetable ((struct linetable *) 0x5477880) } } } I've added a new test that checks the new in-memory file names are generated correctly, and also checks that the in-memory JIT files can be dumped back out using 'dump binary memory'.
2022-10-05 22:26:11 +08:00
proc compile_and_download_n_jit_so {jit_solib_basename jit_solib_srcfile \
count {options_list {}}} {
global jit_load_address jit_load_increment
set binfiles_target {}
for {set i 1} {$i <= $count} {incr i} {
set binfile [standard_output_file ${jit_solib_basename}.$i.so]
# Note: compiling without debug info by default: some test
# do symbol renaming by munging on ELF symbol table, and that
# wouldn't work for .debug sections. Also, output for "info
# function" changes when debug info is present.
set addr [format 0x%x [expr $jit_load_address + $jit_load_increment * [expr $i-1]]]
gdb/testsuite: add text_segment option to gdb_compile LLVM's lld linker doesn't have the "-Ttext-segment" option, but "--image-base" can be used instead. To centralize the logic of checking which option is supported, add the text_segment option to gdb_compile. Change tests that are currently using -Ttext-segment to use that new option instead. This patch fixes only compilation error, for example: Before: $ make check TESTS="gdb.base/jit-elf.exp" RUNTESTFLAGS="CC_FOR_TARGET=clang LDFLAGS_FOR_TARGET=-fuse-ld=ld" Running /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/jit-elf.exp ... gdb compile failed, clang-13: warning: -Xlinker -Ttext-segment=0x7000000: 'linker' input unused [-Wunused-command-line-argument] After: $ make check TESTS="gdb.base/jit-elf.exp" RUNTESTFLAGS="CC_FOR_TARGET=clang LDFLAGS_FOR_TARGET=-fuse-ld=ld" Running /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/jit-elf.exp ... FAIL: gdb.base/jit-elf.exp: one_jit_test-1: continue to breakpoint: break here 1 FAIL: gdb.base/jit-elf.exp: one_jit_test-1: continue to breakpoint: break here 2 FAIL: gdb.base/jit-elf.exp: one_jit_test-2: continue to breakpoint: break here 1 FAIL: gdb.base/jit-elf.exp: one_jit_test-2: info function ^jit_function FAIL: gdb.base/jit-elf.exp: one_jit_test-2: continue to breakpoint: break here 2 FAIL: gdb.base/jit-elf.exp: attach: one_jit_test-2: continue to breakpoint: break here 1 FAIL: gdb.base/jit-elf.exp: attach: one_jit_test-2: break here 1: attach FAIL: gdb.base/jit-elf.exp: PIE: one_jit_test-1: continue to breakpoint: break here 1 FAIL: gdb.base/jit-elf.exp: PIE: one_jit_test-1: continue to breakpoint: break here 2 === gdb Summary === # of expected passes 26 # of unexpected failures 9 Change-Id: I3678c5c9bbfc2f80671698e28a038e6b3d14e635
2022-03-30 18:59:43 +08:00
# Use "text_segment=..." to ask the linker to relocate everything in the
# compiled shared library against a fixed base address. Combined
# with mapping the resulting binary to the same fixed base it allows
# to dynamically execute functions from it without any further adjustments.
gdb: include the base address in in-memory bfd filenames The struct target_buffer (in gdb_bfd.c) is used to hold information about an in-memory BFD object created by GDB. For now this mechanism is used by GDB when loading information about JIT symfiles. This commit updates target_buffer (in gdb_bfd.c) to be more C++ like, and, at the same time, adds the base address of the symfile into the BFD filename. Right now, every in-memory BFD is given the filename "<in-memory>". This filename is visible in things like 'maint info symtabs' and 'maint info line-table'. If there are multiple in-memory BFD objects then it can be hard to match keep track if which BFD is which. This commit changes the name to be "<in-memory@ADDRESS>" where ADDRESS is replaced with the base address for where the in-memory symbol file was read from. As an example of how this is useful, here's the output of 'maint info jit' showing a single loaded JIT symfile: (gdb) maintenance info jit jit_code_entry address symfile address symfile size 0x00000000004056b0 0x0000000007000000 17320 And here's part of the output from 'maint info symtabs': (gdb) maintenance info symtabs ...snip... { objfile <in-memory@0x7000000> ((struct objfile *) 0x5258250) { ((struct compunit_symtab *) 0x4f0afb0) debugformat DWARF 4 producer GNU C17 9.3.1 20200408 (Red Hat 9.3.1-2) -mtune=generic -march=x86-64 -g -fno-stack-protector -fpic name jit-elf-solib.c dirname /tmp/binutils-gdb/build/gdb/testsuite blockvector ((struct blockvector *) 0x5477850) user ((struct compunit_symtab *) (null)) { symtab /tmp/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/jit-elf-solib.c ((struct symtab *) 0x4f0b030) fullname (null) linetable ((struct linetable *) 0x5477880) } } } I've added a new test that checks the new in-memory file names are generated correctly, and also checks that the in-memory JIT files can be dumped back out using 'dump binary memory'.
2022-10-05 22:26:11 +08:00
set fname [format "jit_function_%04d" $i]
set options [list \
gdb: include the base address in in-memory bfd filenames The struct target_buffer (in gdb_bfd.c) is used to hold information about an in-memory BFD object created by GDB. For now this mechanism is used by GDB when loading information about JIT symfiles. This commit updates target_buffer (in gdb_bfd.c) to be more C++ like, and, at the same time, adds the base address of the symfile into the BFD filename. Right now, every in-memory BFD is given the filename "<in-memory>". This filename is visible in things like 'maint info symtabs' and 'maint info line-table'. If there are multiple in-memory BFD objects then it can be hard to match keep track if which BFD is which. This commit changes the name to be "<in-memory@ADDRESS>" where ADDRESS is replaced with the base address for where the in-memory symbol file was read from. As an example of how this is useful, here's the output of 'maint info jit' showing a single loaded JIT symfile: (gdb) maintenance info jit jit_code_entry address symfile address symfile size 0x00000000004056b0 0x0000000007000000 17320 And here's part of the output from 'maint info symtabs': (gdb) maintenance info symtabs ...snip... { objfile <in-memory@0x7000000> ((struct objfile *) 0x5258250) { ((struct compunit_symtab *) 0x4f0afb0) debugformat DWARF 4 producer GNU C17 9.3.1 20200408 (Red Hat 9.3.1-2) -mtune=generic -march=x86-64 -g -fno-stack-protector -fpic name jit-elf-solib.c dirname /tmp/binutils-gdb/build/gdb/testsuite blockvector ((struct blockvector *) 0x5477850) user ((struct compunit_symtab *) (null)) { symtab /tmp/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/jit-elf-solib.c ((struct symtab *) 0x4f0b030) fullname (null) linetable ((struct linetable *) 0x5477880) } } } I've added a new test that checks the new in-memory file names are generated correctly, and also checks that the in-memory JIT files can be dumped back out using 'dump binary memory'.
2022-10-05 22:26:11 +08:00
${options_list} \
additional_flags=-DFUNCTION_NAME=$fname \
text_segment=$addr]
if { [gdb_compile_shlib ${jit_solib_srcfile} ${binfile} \
$options] != "" } {
set f [file tail $binfile]
untested "failed to compile shared library $f"
return -1
}
set path [gdb_remote_download target ${binfile}]
lappend binfiles_target $path
}
return $binfiles_target
}