Add (or suppress) a DT_GNU_FLAGS_1 dynamic section
with a bit flag value of DF_GNU_1_UNIQUE.
bfd/
* elflink.c (bfd_elf_size_dynamic_sections): Call
_bfd_elf_add_dynamic_entry to add a DT_GNU_FLAGS_1 section.
include/
* bfdlink.h (struct bfd_link_info): New field gnu_flags_1.
ld/
* emultempl/elf.em (gld${EMULATION_NAME}_handle_option):
Parse -z unique / -z nounique options.
DT_GNU_FLAGS_1 added to the DT_VALRNGLO-DT_VALRNGHI range.
DT_GNU_FLAGS_1 value DF_GNU_1_UNIQUE added.
* elf/common.h (DT_GNU_FLAGS_1, DF_GNU_1_UNIQUE): Define.
Replace the "SPECIAL_expr" comment with either "DW_FORM_block" or
"DW_FORM_exprloc" in the abbrev.
gdb/testsuite/ChangeLog:
* lib/dwarf.exp (Dwarf::_handle_attribute): Handle SPECIAL_expr
specially, set attr_form_comment to the actual FORM string used.
Since DWARF version 4 expressions are represented by DW_FORM_exprloc
instead of a block form. Support this in the testsuite Dwarf Assembler
by setting the SPECIAL_expr form once we know the CU version.
This doesn't change any testsuite results, it just makes the produced
DWARF valid. gdb also accepts expressions in block form for DWARF
version 4 and above, but this is technically incorrect.
gdb/testsuite/ChangeLog:
* lib/dwarf.exp (Dwarf::_read_constants): Don't set
_constants(SPECIAL_expr) here, but set it...
(Dwarf::cu): ...here based on _cu_version.
When running test-case gdb.base/info-shared.exp, I see in gdb.log:
...
Executing on host: \
gcc ... -fPIC -fpic -c -o info-shared-solib1.c.o info-shared-solib1.c
...
The -fPIC comes from the test-case:
...
if { [gdb_compile_shlib $srcfile_lib1 $binfile_lib1 \
[list additional_flags=-fPIC]] != "" } {
...
but the -fpic, which overrides the -fPIC comes from gdb_compile_shlib.
The proc gdb_compile_shlib adds the -fpic or similar dependent on platform
and compiler. However, in some cases it doesn't add anything, which is
probably why all those test-case pass -fPIC.
Fix this by removing -fPIC from all the calls to gdb_compile_shlib, and
ensuring that gdb_compile_shlib takes care of adding it, if required.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2020-12-14 Tom de Vries <tdevries@suse.de>
* lib/gdb.exp (gdb_compile_shlib): Make sure it's not necessary to
pass -fPIC.
* gdb.ada/catch_ex_std.exp: Don't pass -fPIC to gdb_compile_shlib.
* gdb.base/break-probes.exp: Same.
* gdb.base/ctxobj.exp: Same.
* gdb.base/dso2dso.exp: Same.
* gdb.base/global-var-nested-by-dso.exp: Same.
* gdb.base/info-shared.exp: Same.
* gdb.base/jit-reader-simple.exp: Same.
* gdb.base/print-file-var.exp: Same.
* gdb.base/skip-solib.exp: Same.
* gdb.btrace/dlopen.exp: Same.
Some code in GDB will examine the structure of an expression to see if
it starts with OP_TYPE, and then proceed to extract the type by hand.
There is no need to do this dissection manually. evaluate_type does
the same thing via an "allowed" API.
This patch changes such code to use evaluate_type. In two cases this
simplifies the code.
Regression tested on x86-64 Fedora 28.
gdb/ChangeLog
2020-12-14 Tom Tromey <tom@tromey.com>
* dtrace-probe.c (dtrace_process_dof_probe): Use value_type.
* typeprint.c (whatis_exp): Always use evaluate_type.
(maintenance_print_type): Likewise. Simplify.
When running test-case gdb.base/gnu-debugdata.exp on SLE-11, I run into:
...
FAIL: gdb.base/gnu-debugdata.exp: xz
...
The fact that xz is not installed does not mean there's a fail, merely that
the test is unsupported.
Fix this by detecting the "spawn failed" reply in run_on_host and issuing
UNSUPPORTED instead.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2020-12-14 Tom de Vries <tdevries@suse.de>
PR testsuite/26963
* lib/gdb.exp (run_on_host): Declare test unsupported if spawn fails.
When running test-case gdb.base/solib-corrupted.exp on SLE-11, I get:
...
(gdb) PASS: gdb.base/solib-corrupted.exp: normal list
p/x _r_debug->r_map->l_next = _r_debug->r_map^M
'_r_debug' has unknown type; cast it to its declared type^M
(gdb) FAIL: gdb.base/solib-corrupted.exp: make solibs looping
...
The reason that _r_debug has unknown type is that glibc debuginfo is not
installed. The test-case attempts to detect this but doesn't handle this
particular error string.
Fix this by adding the "unknown type" line to the regexp detecting missing
glibc debuginfo.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2020-12-14 Tom de Vries <tdevries@suse.de>
PR testsuite/26962
* gdb.base/solib-corrupted.exp: Handle "'_r_debug' has unknown type;
cast it to its declared type".
On SLE-11, I run into:
...
FAIL: gdb.base/batch-preserve-term-settings.exp: batch run: spawn shell \
(timeout)
...
The problem is that the shell prompt has PS1="\h:\w> ", but the test expects
a shell prompt ending in a space preceded by either '$' or '#':
...
set shell_prompt_re "\[$#\] "
...
We could easily fix this by adding '>' to shell_prompt_re, but this wouldn't
work for other PS1 setting.
Fix this instead by setting the shell prompt to "gdb-subshell$ " (as in
gdb.base/multi-line-starts-subshell.exp).
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2020-12-14 Tom de Vries <tdevries@suse.de>
PR testsuite/26951
* gdb.base/batch-preserve-term-settings.exp: Use "gdb-subshell$ " as
shell prompt.
GNAT can generate a mangled name with "B_N" (where N is a number) in
the middle, like "hello__B_1__fourth.0". This is used for names local
to a block. Multiple levels of block-local name can also occur, a
possibility that was neglected by v1 of this patch. This patch
changes gdb to handle these names.
The wild name matcher is updated a straightforward way. The full
matcher is rewritten. The hash function is updated to ensure that
this works.
This version does not seem to have the performance problems that
affected v1. In particular, the previously-slow "bt" problem has been
fixed.
gdb/ChangeLog
2020-12-14 Tom Tromey <tromey@adacore.com>
* dictionary.c (language_defn::search_name_hash): Ignore "B".
* ada-lang.c (advance_wild_match): Ignore "B".
(full_match): Remove.
(do_full_match): Rewrite.
gdb/testsuite/ChangeLog
2020-12-14 Tom Tromey <tromey@adacore.com>
* gdb.ada/nested.exp: Add new tests.
* gdb.ada/nested/hello.adb (Fourth, Fifth): New procedures.
get_var_value is only used when an exact match is needed. This
changes this function to ensure this sort of matching is done.
gdb/ChangeLog
2020-12-14 Tom Tromey <tromey@adacore.com>
* ada-lang.c (get_var_value): Only consider exact matches.
To handle thick pointers with -fgnat-encodings=minimal, gdb will
rewrite the underlying array type to remove the bounds. However, if
the same DWARF type is used both for a thick pointer and for an
ordinary array, this will have the side effect of removing the bounds
from the array. This breaks the printing of objects of this type.
This patch fixes the problem by copying the array type, its range, and
its bounds.
gdb/ChangeLog
2020-12-14 Tom Tromey <tromey@adacore.com>
* dwarf2/read.c (rewrite_array_type): New function.
(quirk_ada_thick_pointer_struct): Use rewrite_array_type.
gdb/testsuite/ChangeLog
2020-12-14 Tom Tromey <tromey@adacore.com>
* gdb.dwarf2/ada-thick-pointer.exp: New file.
fixed_point_binop did not account for division by zero. This would
lead to gdb getting SIGFPE and subsequently cause some test cases to
hang.
gdb/ChangeLog
2020-12-14 Tom Tromey <tromey@adacore.com>
* valarith.c (fixed_point_binop): Call error on division by zero.
gdb/testsuite/ChangeLog
2020-12-14 Tom Tromey <tromey@adacore.com>
* gdb.dwarf2/dw2-fixed-point.exp: Add test for division by zero.
* libdep_plugin.c: New file: Processes archives that contain a
special library dependencies element.
* Makefile.am: Add build rules for libdep_plugin.
* Makefile.in: Regenerate.
* NEWS: Mention the new plugin.
* ld.texi: Document the new plugin.
The static variables used by bfd_section_from_shdr to detect loops
in ELF sections have a problem: Comparing a BFD pointer doesn't
guarantee that the current bfd is the same as the one previously used
to allocate the sections_being_created array. For example, doing
size bad_elf_1 bad_elf_2
with two corrupted ELF files containing section loops will leave the
section_being_created array allocated for the first file and since
bfd_close is called for bad_elf_1 before bfd_elf_2 is opened, it is
possible that the BFD for the second file is allocated in the same
memory as the first file. If bad_elf_2 has more sections than
bad_elf_1 then we might write beyond the end of the array.
So this patch implements the FIXME Nick put in a comment about
attaching the array to the BFD.
* elf-bfd.h (struct elf_obj_tdata): Add being_created.
* elf.c (bfd_section_from_shdr): Delete static vars for loop
detection. Use new tdata variable instead.
* elfcode.h (elf_object_p): Allocate being_created.
/usr/include/sys/mman.h:81:0: note: this is the location of the previous definition
#define SHARED 0x10
PR 27064
* deffilep.y (SHARED_K): Rename from SHARED. Update uses.
rx-elf is an odd target with non-standard names for default text, data
and bss sections. This patch tweaks a new test to make it pass.
* testsuite/gas/elf/section27.s: Reorder .text, .data and .bss
so that output section order does not depend on those sections
being already created. Use ".section .text" rather than ".text".
During an incremental link, we should simply ignore the Gnu properties
sections. We were not handling them properly -- failing to process the
properties from the base file. While that could be fixed, the property
sections are meant for deployed binaries, and incremental linking is
for development, so keeping the properties sections just adds to the
likelihood of forcing a full link sooner.
gold/
PR gold/23539
* object.cc (Sized_relobj_file::layout_gnu_property_section): Ignore
Gnu properties during incremental links.
When processing the incremental update, incoming .rodata merge sections
do not match the corresponding section in the base file, because the
SHF_MERGE flag had not been masked out of the latter.
gold/
PR gold/24123
* layout.cc (Layout::init_fixed_output_section): Mask out flags that
should be ignored when matching sections.
I noticed that the argumen to parse_and_eval_type could be "const".
This patch implements this change.
I wonder if this could be removed. It's only called via
check_stub_method_group, which seems questionable to me. However, I
didn't look into doing this.
gdb/ChangeLog
2020-12-13 Tom Tromey <tom@tromey.com>
* gdbtypes.c (safe_parse_type): Make argument const.
* value.h (parse_and_eval_type): Make argument const.
* eval.c (parse_and_eval_type): Make argument const.
When running test-case gdb.base/endianity.exp using gcc-4.8, we get:
...
(gdb) x/x &o.v^M
0x7fffffffd120: 0x00000004^M
(gdb) XFAIL: gdb.base/endianity.exp: x/x &o.v
x/xh &o.w^M
0x7fffffffd124: 0x0003^M
(gdb) FAIL: gdb.base/endianity.exp: x/xh &o.w
...
The gcc 4.8 compiler does not support the scalar_storage_order attribute, so
the testcase is compiled without that attribute, and the expected results are
different.
Fix this by rather than xfailing, skipping the tests if the compiler does not
support the scalar_storage_order attribute.
Tested on x86_64-linux, with gcc-4.8, gcc-7, and clang-10.
gdb/testsuite/ChangeLog:
2020-12-13 Tom de Vries <tdevries@suse.de>
PR testsuite/26953
* gdb.base/endianity.exp: Skip tests requiring scalar_storage_order
attribute support if compiler doesn't support it.
The single test-case in the testsuite that creates an ada shared library is
gdb.ada/catch_ex_std.exp.
The test-case does use gdb_compile_shlib, but with a few tweaks that make sure
things are properly handled for ada.
Move the ada-specific code to gdb_compile_shlib, such that gdb_compile_sh can
be used for ada shared libs without tweaks.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2020-12-13 Tom de Vries <tdevries@suse.de>
* lib/gdb.exp (gdb_compile_shlib): Handle ada.
* gdb.ada/catch_ex_std.exp: Use gdb_compile_shlib to compile from
source to shared lib. Add ada to options.
There's a single test-case in the testsuite that explicitly calls gnatbind and
gnatlink: gdb.ada/catch_ex_std.exp.
Instead, use gnatmake and pass specific gnatbind and gnatlink options using
gnatmake passthrough options -bargs and -largs.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2020-12-13 Tom de Vries <tdevries@suse.de>
* gdb.ada/catch_ex_std.exp: Use gnatmake -bargs and -largs instead of
calling gnatbind and gnatlink.
We currently have two flushing commands 'flushregs' and 'maint
flush-symbol-cache'. I'm planning to add at least one more so I
thought it might be nice if we bundled these together into one place.
And so I created the 'maint flush ' command prefix. Currently there
are two commands:
(gdb) maint flush symbol-cache
(gdb) maint flush register-cache
Unfortunately, even though both of the existing flush commands are
maintenance commands, I don't know how keen we about deleting existing
commands for fear of breaking things in the wild. So, both of the
existing flush commands 'maint flush-symbol-cache' and 'flushregs' are
still around as deprecated aliases to the new commands.
I've updated the testsuite to use the new command syntax, and updated
the documentation too.
gdb/ChangeLog:
* NEWS: Mention new commands, and that the old commands are now
deprecated.
* cli/cli-cmds.c (maintenanceflushlist): Define.
* cli/cli-cmds.h (maintenanceflushlist): Declare.
* maint.c (_initialize_maint_cmds): Initialise
maintenanceflushlist.
* regcache.c: Add 'cli/cli-cmds.h' include.
(reg_flush_command): Add header comment.
(_initialize_regcache): Create new 'maint flush register-cache'
command, make 'flushregs' an alias.
* symtab.c: Add 'cli/cli-cmds.h' include.
(_initialize_symtab): Create new 'maint flush symbol-cache'
command, make old command an alias.
gdb/doc/ChangeLog:
* gdb.texinfo (Symbols): Document 'maint flush symbol-cache'.
(Maintenance Commands): Document 'maint flush register-cache'.
gdb/testsuite/ChangeLog:
* gdb.base/c-linkage-name.exp: Update to use new 'maint flush ...'
commands.
* gdb.base/killed-outside.exp: Likewise.
* gdb.opt/inline-bt.exp: Likewise.
* gdb.perf/gmonster-null-lookup.py: Likewise.
* gdb.perf/gmonster-print-cerr.py: Likewise.
* gdb.perf/gmonster-ptype-string.py: Likewise.
* gdb.python/py-unwind.exp: Likewise.
I've made all labels normal labels so that there's no confusion between
the different targets which is which and I match them in the .d files
with .* as Alan suggested.
Hex offsets I match with [0-9a-fx]+ since some targets prefix them with
0x, some don't, etc.
* testsuite/gas/i386/align-branch-9.s: Don't use labels that are
automatically local for ELF targets.
* testsuite/gas/i386/branch.s: Likewise.
* testsuite/gas/i386/x86-64-align-branch-9.s: Likewise.
* testsuite/gas/i386/x86-64-branch.s: Likewise.
* testsuite/gas/i386/align-branch-9.d: Adjust to match more targets.
* testsuite/gas/i386/branch.d: Likewise.
* testsuite/gas/i386/ilp32/x86-64-branch.d: Likewise.
* testsuite/gas/i386/x86-64-align-branch-9.d: Likewise.
* testsuite/gas/i386/x86-64-branch.d: Likewise.
Consider this GDB session:
(gdb) define set xxx_yyy
Type commands for definition of "set xxx_yyy".
End with a line saying just "end".
>echo in set xxx_yyy command\n
>end
(gdb) alias set qqq_aaa=set xxx_yyy
(gdb) maintenance deprecate set qqq_aaa
(gdb) set qqq_aaa
Warning: 'qqq_aaa', an alias for the command 'xxx_yyy' is deprecated.
No alternative known.
in set xxx_yyy command
(gdb)
Notice the warning mentions 'qqq_aaa' and 'xxx_yyy', I consider this
to be wrong. I think the proper warning should read:
(gdb) set qqq_aaa
Warning: 'set qqq_aaa', an alias for the command 'set xxx_yyy', is deprecated.
No alternative known.
With the 'set' prefixes added and a comma before the final 'is
deprecated'. That is what this patch does. The expected results are
updated as needed.
gdb/ChangeLog:
* cli/cli-decode.c (deprecated_cmd_warning): Ignore the prefix
result from lookup_cmd_composition_1, use the prefixes from both
the command and the alias instead.
(lookup_cmd_composition_1): Initial prefix command is the based on
the search list being passed in. Simplify the logic for tracking
the prefix command. Replace a use of alloca with a local
std::string.
gdb/testsuite/ChangeLog:
* gdb.base/commands.exp: Update expected results.
Rewrite deprecated_cmd_warning to be i18n friendly. While I'm going
through the function I also cleaned up some whitespace issues,
replaced uses of NULL with nullptr, and moved some comments to avoid
having to add { ... }.
Though the message being printed has a 'Warning: ' prefix I could have
changed from using printf_filtered to use warning, however, I haven't
done that in this commit as that would change what GDB outputs and I
wanted this commit NOT to change the output.
There should be no user visible changes after this commit.
gdb/ChangeLog:
* cli/cli-decode.c (deprecated_cmd_warning): Use nullptr instead
of NULL. Don't print message piece by piece, but sentence at a
time to allow internationalisation. Some whitespace cleanup.
I noticed that deprecated aliases that have a prefix don't give a
deprecated command warning. For example looking in mi/mi-main.c we
see this:
c = add_alias_cmd ("target-async", "mi-async", class_run, 0, &setlist);
deprecate_cmd (c, "set mi-async");
c = add_alias_cmd ("target-async", "mi-async", class_run, 0, &showlist);
deprecate_cmd (c, "show mi-async");
So both 'set target-async' and 'show target-async' are deprecated and
should be giving a warning, however, in use we see no warning given.
This is a consequence of how the code that should give this
warning (deprecated_cmd_warning) performs a second command lookup in
order to distinguish between aliases and real commands, and that the
code that calls this (lookup_cmd_1) strips off prefix commands as it
calls itself recursively.
As a result when we are considering an alias like 'set target-async'
we first enter lookup_cmd_1 with text = "set target-async", we spot
the 'set' command prefix and then recursively call lookup_cmd_1 with
text = "target-async".
We spot that 'target-async' is a known alias but that it is
deprecated, and so call deprecated_cmd_warning passing in the value of
text, which remember is now "target-async".
In deprecated_cmd_warning we again perform a command lookup starting
from the top-level cmdlist, but now we're trying to find just
"target-async", this fails (as this command requires the 'set' prefix,
and so no warning is given.
I resolved this issue by passing a command list to the function
deprecated_cmd_warning, this is the list in which the command can be
found.
A new test is added to cover this case.
However, there is an additional problem which will be addressed in a
subsequent patch.
Consider this GDB session:
(gdb) define set xxx_yyy
Type commands for definition of "set xxx_yyy".
End with a line saying just "end".
>echo in set xxx_yyy command\n
>end
(gdb) alias set qqq_aaa=set xxx_yyy
(gdb) maintenance deprecate set qqq_aaa
(gdb) set qqq_aaa
Warning: 'qqq_aaa', an alias for the command 'xxx_yyy' is deprecated.
No alternative known.
in set xxx_yyy command
(gdb)
Notice the warning mentions 'qqq_aaa' and 'xxx_yyy', I consider this
to be wrong. I think the proper warning should read:
(gdb) set qqq_aaa
Warning: 'set qqq_aaa', an alias for the command 'set xxx_yyy' is deprecated.
No alternative known.
With the 'set' prefixes added. A later patch will resolve this
issue.
gdb/ChangeLog:
PR cli/15104
* cli/cli-decode.c (lookup_cmd_1): Pass command list to
deprecated_cmd_warning.
(deprecated_cmd_warning): Take extra parameter, call
lookup_cmd_composition_1 and pass new parameter through.
(lookup_cmd_composition_1): New function, takes implementation of
lookup_cmd_composition but with extra parameter.
(lookup_cmd_composition): Now calls lookup_cmd_composition_1
passing in cmdlist.
* command.h (deprecated_cmd_warning): Add extra parameter to
declaration.
* top.c (execute_command): Pass cmdlist to deprecated_cmd_warning.
gdb/testsuite/ChangeLog:
PR cli/15104
* gdb.base/commands.exp: Add additional tests.
* gdb.base/completion.exp: Add additional tests.
Consider this gdb session, where on line #3 tab completion is used:
(gdb) alias xxx_yyy_zzz=break
(gdb) maint deprecate xxx_yyy_zzz
(gdb) xxx_yyy_<TAB>
The third line then updates to look like this:
(gdb) xxx_yyy_Warning: 'xxx_yyy_zzz', an alias for the command 'break' is deprecated.
No alternative known.
zzz
What's happened is during tab completion the alias has been resolved
to the actual command being aliased, and at this stage the warning is
issued. Clearly this is not what we want during tab completion.
In this commit I add a new parameter to the lookup function, a boolean
that indicates if the lookup is being done as part of completion.
This flag is used to suppress the warning. Now we get the expected
behaviour, the alias completes without any warning, but the warning is
still given once the user executes the alias.
gdb/ChangeLog:
* cli/cli-decode.c (lookup_cmd_1): Move header comment into
command.h, add extra parameter, and use this to guard giving a
warning.
* command.h (lookup_cmd_1): Add comment from cli/cli-decode.c,
include argument names in declaration, add new argument.
* completer.c (complete_line_internal_1): Remove unneeded
brackets, pass extra argument to lookup_cmd_1.
gdb/testsuite/ChangeLog:
* gdb.base/completion.exp: Add additional tests.
Make use of the safe-ctype replacements for the standard ctype
character checking functions in gdbsupport/common-utils.cc. The
gdbsupport library is included into both gdb and gdbserver, and on the
gdbserver side there are two targets, gdbserver itself, and also
libinproctrace.so.
libiberty was already being included in the gdbserver link command,
but was missing from the libinproctrace.so link. As a result, after
changing gdbsupport/common-utils.cc to depend on libiberty,
libinproctrace.so would no longer link until I modified its link line.
gdbserver/ChangeLog:
* Makefile.in (IPA_LIB): Include libiberty library.
gdbsupport/ChangeLog:
* gdbsupport/common-utils.cc: Change 'ctype.h' include to
'safe-ctype.h'.
(extract_string_maybe_quoted): Use safe-ctype function versions.
(is_digit_in_base): Likewise.
(digit_to_int): Likewise.
(strtoulst): Likewise.
(skip_spaces): Likewise.
(skip_to_space): Likewise.
gdb/ChangeLog:
* infrun.h (debug_infrun): Make a bool.
* infrun.c (debug_infrun): Make a bool.
(_initialize_infrun): Use add_setshow_boolean_cmd to define "set
debug infrun".
Change-Id: If934106a6d3f879b93d265855eb705b1d606339a
The same pattern happens often to define a "debug_printf" macro:
#define displaced_debug_printf(fmt, ...) \
do \
{ \
if (debug_displaced) \
debug_prefixed_printf ("displaced", __func__, fmt, ##__VA_ARGS__); \
} \
while (0)
Move this pattern behind a helper macro, debug_prefixed_printf_cond and
update the existing macros to use it.
gdb/ChangeLog:
* displaced-stepping.h (displaced_debug_printf): Use
debug_prefixed_printf_cond.
* dwarf2/read.c (dwarf_read_debug_printf): Likewise.
(dwarf_read_debug_printf_v): Likewise.
* infrun.h (infrun_debug_printf): Likewise.
* linux-nat.c (linux_nat_debug_printf): Likewise.
gdbsupport/ChangeLog:
* common-debug.h (debug_prefixed_printf_cond): New.
* event-loop.h (event_loop_debug_printf): Use
debug_prefixed_printf_cond.
Change-Id: I1ff48b98b8d1cc405d1c7e8da8ceadf4e3a17f99
When running test-case gdb.arch/i386-mpx-call.exp with target board unix/-m32,
we run into:
...
(gdb) continue^M
Continuing.^M
(gdb) FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation
...
Let's look first for reference at -m64, where the test passes.
The test-case uses -mmpx -fcheck-pointer-bounds to generate pointer checks in
the exec. Effectively, -fcheck-pointer-bounds modifies the calling ABI: a
call passes pointer bounds as well as arguments. The call to upper (with
four pointer arguments and an int argument, passed in 5 registers) is modified
like this:
...
lea -0xa0(%rbp),%rcx
lea -0x80(%rbp),%rdx
lea -0x60(%rbp),%rsi
lea -0x40(%rbp),%rax
mov $0x0,%r8d
+ bndmov -0x110(%rbp),%bnd3
+ bndmov -0x100(%rbp),%bnd2
+ bndmov -0xf0(%rbp),%bnd1
+ bndmov -0xe0(%rbp),%bnd0
mov %rax,%rdi
- callq <upper>
+ bnd callq <upper>
...
passsing the four pointer bounds in bounds registers BND0-3.
The top-level mechanism of the test is as follows:
- run the exec to after all mallocs are done, such that all pointer variables
are valid
- do inferior calls, similar to those present in the program
The inferior call mechanism doesn't differentiate between a call to a function
compiled with -fcheck-pointer-bounds, and one without. It merely resets the
bound registers to all-allowed state (see amd64_push_dummy_call), to make sure
the checks don't trigger during the inferior call. [ This is the same as what
happens when executing a call without bnd prefix when the BNDPRESERVE bit of
the BNDCFG register is set to 0, a provision for calling an instrumented
function using a non-instrumented call. ]
First, two inferior calls are done (default_run and verify_default_values)
with the bound registers unmodified by the test. So, the memory accesses are
performed with the bounds registers set by amd64_push_dummy_call to
all-allowed, and the bounds checks do not trigger.
Then we try to do an inferior call with modified bounds registers, set to
none-allowed. In order to do that, we set a breakpoint at *upper before
doing the inferior call. Once we hit the breakpoint during the inferior call,
the bounds registers are set to none-allowed, and we continue expecting to run
into an triggered bounds check, which takes the shape of a sigsegv.
Back to -m32. Here, the pointer arguments are passed in memory rather than
registers, so with -fcheck-pointer-bounds, the pointer bounds are placed in
the Bounds Table using bndstx:
...
movl $0x0,0x10(%eax)
lea -0x70(%ebp),%edx
mov %edx,0xc(%eax)
lea -0x5c(%ebp),%edx
mov %edx,0x8(%eax)
lea -0x48(%ebp),%edx
mov %edx,0x4(%eax)
lea -0x34(%ebp),%edx
mov %edx,(%eax)
lea 0xc(%eax),%edx
mov 0xc(%eax),%ecx
bndmov -0xa8(%ebp),%bnd1
bndstx %bnd1,(%edx,%ecx,1)
lea 0x8(%eax),%edx
mov 0x8(%eax),%ecx
bndmov -0xa0(%ebp),%bnd3
bndstx %bnd3,(%edx,%ecx,1)
lea 0x4(%eax),%edx
mov 0x4(%eax),%ecx
bndmov -0x98(%ebp),%bnd1
bndstx %bnd1,(%edx,%ecx,1)
mov (%eax),%edx
bndmov -0x90(%ebp),%bnd3
bndstx %bnd3,(%eax,%edx,1)
bnd call 804893f <upper>
...
Again, the bounds registers are reset at the start of the inferior call by
amd64_push_dummy_call, and modified by the test-case, but neither has any
effect. The code in upper reads the pointer bounds from the Bounds Table, not
from the bounds registers.
Note that for a test.c with an out-of-bounds access:
...
$ cat test.c
void foo (int *a) { volatile int v = a[1]; }
int main (void) { int a; foo (&a); return 0; }
$ gcc test.c -mmpx -fcheck-pointer-bounds -g -m32
$ ./a.out
Saw a #BR! status 1 at 0x804848d
...
and inferior call foo (&a) right before "bnd call foo" (at the point that the
bounds for a are setup in the bounds table) doesn't trigger a bounds violation:
...
(gdb) call foo (&a)
(gdb)
...
This is because the bounds table doesn't associate a pointer with bounds, but
rather a pair of pointer and pointer location. So, the bound is setup for &a,
with as location the pushed argument in the frame. The inferior call however
executes in a dummy frame, so the bound is checked for &a with as location the
pushed argument in the dummy frame, which is different, so the bounds check
doesn't trigger.
In conclusion, this is expected behaviour.
Update the test-case to not expect to override effective pointer bounds using
the bounds registers when the bounds passing is done via the Bounds Table.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2020-12-11 Tom de Vries <tdevries@suse.de>
PR testsuite/26991
* gdb.arch/i386-mpx-call.exp: Don't expect to trigger bounds
violations by setting bounds registers if the bounds are passed in the
Bounds Table.
I noticed that some of the lexers were calling write_dollar_variable
from the lexer. This seems like a bad practice, so this patch moves
the side effects into the parsers.
I tested this by re-running gdb.fortran and gdb.modula2; the Pascal
compiler on my machine seems not to work, so I couldn't test
gdb.pascal.
I note that the type-tracking in the Pascal is also incorrect, in that
a convenience variable's type may change between parsing and
evaluation (or even during the course of evaluation).
gdb/ChangeLog
2020-12-11 Tom Tromey <tom@tromey.com>
* p-exp.y (intvar): Remove global.
(DOLLAR_VARIABLE): Change type.
(start): Update.
(exp): Call write_dollar_variable here...
(yylex): ... not here.
* m2-exp.y (DOLLAR_VARIABLE): Change type.
(variable): Call write_dollar_variable here...
(yylex): ... not here.
* f-exp.y (DOLLAR_VARIABLE): Change type.
(exp): Call write_dollar_variable here...
(yylex): ... not here.