In my earlier C++-ization patch for file_and_directory, I introduced
an error:
- if (strcmp (fnd.name, "<unknown>") != 0)
+ if (fnd.is_unknown ())
This change inverted the sense of the test, which causes failures with
.debug_names.
This patch fixes the bug. Regression tested on x86-64 Fedora 34. I
also tested it using the AdaCore internal test suite, with
.debug_names -- this was failing before, and now it works.
The documentation suggests that we implement gdb.Value.__init__,
however, this is not currently true, we really implement
gdb.Value.__new__. This will cause confusion if a user tries to
sub-class gdb.Value. They might write:
class MyVal (gdb.Value):
def __init__ (self, val):
gdb.Value.__init__(self, val)
obj = MyVal(123)
print ("Got: %s" % obj)
But, when they source this code they'll see:
(gdb) source ~/tmp/value-test.py
Traceback (most recent call last):
File "/home/andrew/tmp/value-test.py", line 7, in <module>
obj = MyVal(123)
File "/home/andrew/tmp/value-test.py", line 5, in __init__
gdb.Value.__init__(self, val)
TypeError: object.__init__() takes exactly one argument (the instance to initialize)
(gdb)
The reason for this is that, as we don't implement __init__ for
gdb.Value, Python ends up calling object.__init__ instead, which
doesn't expect any arguments.
The Python docs suggest that the reason why we might take this
approach is because we want gdb.Value to be immutable:
https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_new
But I don't see any reason why we should require gdb.Value to be
immutable when other types defined in GDB are not. This current
immutability can be seen in this code:
obj = gdb.Value(1234)
print("Got: %s" % obj)
obj.__init__ (5678)
print("Got: %s" % obj)
Which currently runs without error, but prints:
Got: 1234
Got: 1234
In this commit I propose that we switch to using __init__ to
initialize gdb.Value objects.
This does introduce some additional complexity, during the __init__
call a gdb.Value might already be associated with a gdb value object,
in which case we need to cleanly break that association before
installing the new gdb value object. However, the cost of doing this
is not great, and the benefit - being able to easily sub-class
gdb.Value seems worth it.
After this commit the first example above works without error, while
the second example now prints:
Got: 1234
Got: 5678
In order to make it easier to override the gdb.Value.__init__ method,
I have tweaked the definition of gdb.Value.__init__. The second,
optional argument to __init__ is a gdb.Type, if this argument is not
present then GDB figures out a suitable type.
However, if we want to override the __init__ method in a sub-class,
and still support the default argument, it is easier to write:
class MyVal (gdb.Value):
def __init__ (self, val, type=None):
gdb.Value.__init__(self, val, type)
Currently, passing None for the Type will result in an error:
TypeError: type argument must be a gdb.Type.
After this commit I now allow the type argument to be None, in which
case GDB figures out a suitable type just as if the type had not been
passed at all.
Unless a user is trying to reinitialize a value, or create sub-classes
of gdb.Value, there should be no user visible changes after this
commit.
While investigating some disassembler problems I ran into this case;
GDB compiled on a 32-bit arm target, with --enable-targets=all. Then
in GDB:
(gdb) set architecture i386
(gdb) disassemble 0x0,+4
unknown disassembler error (error = -1)
This is interesting because it shows a case where the libopcodes
disassembler is returning -1 without first calling the
memory_error_func callback. Indeed, the return from libopcodes
happens from this code snippet in i386-dis.c in the print_insn
function:
if (address_mode == mode_64bit && sizeof (bfd_vma) < 8)
{
(*info->fprintf_func) (info->stream,
_("64-bit address is disabled"));
return -1;
}
Notice how, prior to the return the disassembler tries to print a
helpful message out, but GDB doesn't print this message.
The reason this message goes missing is the call stack, it looks like
this:
gdb_pretty_print_disassembler::pretty_print_insn
gdb_disassembler::print_insn
gdbarch_print_insn
...
i386-dis.c:print_insn
When i386-dis.c:print_insn returns -1 this is handled in
gdb_disassembler::print_insn, where an exception is thrown. However,
the actual printing of the disassembler output is done in
gdb_pretty_print_disassembler::pretty_print_insn, and is only done if
an exception is not thrown.
In this commit I change this. The pretty_print_insn now uses
try/catch around the call to gdb_disassembler::print_insn, if we catch
an error then we first print any pending output in the instruction
buffer, before rethrowing the exception. As a result, even if an
exception is thrown we still print any pending disassembler output to
the screen; in the above case the helpful message will now be shown.
Before my patch we might expect to see this output:
(gdb) disassemble 0x0,+4
Dump of assembler code from 0x0 to 0x4:
0x0000000000000000: unknown disassembler error (error = -1)
(gdb)
But now we see this:
(gdb) disassemble 0x0,+4
Dump of assembler code from 0x0 to 0x4:
0x0000000000000000: 64-bit address is disabled
unknown disassembler error (error = -1)
If the disassembler returns -1 without printing a helpful message then
we would still expect a change in output, something like:
(gdb) disassemble 0x0,+4
Dump of assembler code from 0x0 to 0x4:
0x0000000000000000:
unknown disassembler error (error = -1)
Which I think is still acceptable, though at this point I think a
strong case can be made that this is a disassembler bug (not printing
anything, but still returning -1).
Notice however, that the error message is always printed on a new line
now. This is also true for the memory error case, where before we
might see this:
(gdb) disassemble 0x0,+4
Dump of assembler code from 0x0 to 0x4:
0x00000000: Cannot access memory at address 0x0
We now get this:
(gdb) disassemble 0x0,+4
Dump of assembler code from 0x0 to 0x4:
0x00000000:
Cannot access memory at address 0x0
For me, I'm happy to accept this change, having the error on a line by
itself, rather than just appended to the end of the previous line,
seems like an improvement, but I'm aware others might feel
differently, so I'd appreciate any feedback.
Permanent program breakpoints (ones inserted into the code) other than
the one GDB uses for POWER (0x7fe00008) did not result in stop but
caused GDB to loop infinitely.
This was because GDB did not recognize trap instructions other than
"trap". For example, "tw 12, 4, 4" was not be recognized, causing GDB
to loop forever.
This commit fixes this by providing POWER specific hook
(gdbarch_program_breakpoint_here_p) recognizing all tw, twi, td and tdi
instructions.
Tested on Linux on PowerPC e500 and on QEMU PPC64le.
Power ISA 3.0 B spec [1], sections 3.3.11 "Fixed-Point Trap Instructions"
and section C.6 "Trap Mnemonics" specify "tw, 31, 0, 0" (encoded as
0x7fe00008) as canonical unconditional trap instruction.
This commit changes the breakpoint instruction used by GDB from
"tw 12, r2, r2" to unconditional "trap".
[1]: https://openpowerfoundation.org/?resource_lib=power-isa-version-3-0
If a.so contains an SHT_RELR section, objcopy a.so will fail with:
a.so: unknown type [0x13] section `.relr.dyn'
This change allows objcopy to work.
bfd/
* elf.c (bfd_section_from_shdr): Support SHT_RELR.
struct linespec contains pointers to vectors, instead of containing
vectors directly. This is probably historical, when linespec_parser
(which contains a struct linespec field) was not C++-ified yet. But it
seems easy to change the pointers to vectors to just vectors today.
This simplifies the code, we don't need to manually allocate and delete
the vectors and there's no pointer that can be NULL.
As far as I understand, there was not meaningful distinction between a
NULL pointer to vector and an empty vector. So all NULL checks are
changed for !empty checks.
Change-Id: Ie759707da14d9d984169b93233343a86e2de9ee6
We can remove the empty check: if the vector has size 1, it is obviously
not empty. This code ended up like this because the empty check used to
be a NULL check.
Change-Id: I1571bd0228818ca93f6a6b444e9b010dc2da4c08
Functions agent_eval_command and agent_command are used to implement
maintenance commands, rename them accordingly (with the maint_ prefix),
as well as the agent_command_1 helper function.
Change-Id: Iacf96d4a0a26298e8dd4648a0f38da649ea5ef61
FreeBSD's kernel has recently added two new ELF auxiliary vector
entries. AT_FXRNG points to a root seed version for the kernel's
PRNG. Userland can use this to reseed a userland PRNG after the
kernel's PRNG has reseeded. AT_KPRELOAD is the base address of a
kernel-provided vDSO.
This change displays the proper name and description of these entries
in 'info auxv'.
include/ChangeLog:
* elf/common.h (AT_FREEBSD_FXRNG, AT_FREEBSD_KPRELOAD): Define.
I noticed that global_symbol_searcher::expand_symtabs always passes a
file matcher to expand_symtabs_matching. However, if 'filenames' is
empty, then this always returns true. It's slightly more efficient to
pass a null file matcher in this case, because that lets the "quick"
symbol implementations skip any filename checks.
Regression tested on x86-64 Fedora 34.
In commit 80ad340c90 ("[gdb/testsuite] use -Ttext-segment for jit-elf tests")
the following change was made:
...
proc compile_jit_elf_main_as_so {main_solib_srcfile main_solib_binfile options} {
- set options [concat $options debug]
+ global jit_load_address jit_load_increment
+
+ set options [list \
+ additional_flags="-DMAIN=jit_dl_main" \
+ additional_flags=-DLOAD_ADDRESS=$jit_load_address \
+ additional_flags=-DLOAD_INCREMENT=$jit_load_increment \
+ debug]
...
Before the change, the options argument was used, but after the change not
anymore.
Fix this by reverting back to using "set options [concat $options ...]".
Fixing this gets us twice the -DMAIN=jit_dl_main bit, once from a caller, and
once from compile_jit_elf_main_as_so. Fix this by removing the bit from
compile_jit_elf_main_as_so, which makes the code similar to compile_jit_main.
Tested on x86_64-linux.
On openSUSE Leap 15.2 aarch64 I ran into:
...
FAIL: gdb.tui/basic.exp: check main is where we expect on the screen
...
while this is passing on x86_64.
On x86_64-linux we have at the initial screen dump for "list -q main":
...
0 +-/home/vries/gdb_versions/devel/src/gdb/testsuite/gdb.tui/tui-layout.c--+
1 | 15 You should have received a copy of the GNU General Public |
2 | 16 along with this program. If not, see <http://www.gnu.org/|
3 | 17 |
4 | 18 int |
5 | 19 main () |
6 | 20 { |
7 | 21 return 0; |
8 | 22 } |
9 | 23 |
...
but on aarch64:
...
0 +-/home/tdevries/gdb/src/gdb/testsuite/gdb.tui/tui-layout.c--------------+
1 | 16 along with this program. If not, see <http://www.gnu.org/|
2 | 17 |
3 | 18 int |
4 | 19 main () |
5 | 20 { |
6 | 21 return 0; |
7 | 22 } |
8 | 23 |
9 | 24 |
...
The cause of the diffferent placement is that we have as line number for main
on x86_64:
...
$ gdb -q -batch outputs/gdb.tui/basic/basic -ex "info line main"
Line 20 of "tui-layout.c" starts at address 0x4004a7 <main> \
and ends at 0x4004ab <main+4>.
...
and on aarch64 instead:
...
$ gdb -q -batch outputs/gdb.tui/basic/basic -ex "info line main"
Line 21 of "tui-layout.c" starts at address 0x4005f4 <main> \
and ends at 0x4005f8 <main+4>.
...
Fix this by using a new source file main-one-line.c, that implements the
entire main function on a single line, in order to force the compiler to use
that line number.
Also try to do less hard-coding in the test-case.
Tested on x86_64-linux and aarch64-linux.
Consider test-case test.c:
...
int main (void) {
void *p = malloc (10);
return 0;
}
...
When compiled to a non-PIE exec:
...
$ gcc -m32 test.c
...
the call sequence looks like:
...
8048447: 83 ec 0c sub $0xc,%esp
804844a: 6a 0a push $0xa
804844c: e8 bf fe ff ff call 8048310 <malloc@plt>
...
which calls to:
...
08048310 <malloc@plt>:
8048310: ff 25 0c a0 04 08 jmp *0x804a00c
8048316: 68 00 00 00 00 push $0x0
804831b: e9 e0 ff ff ff jmp 8048300 <.plt>
...
where the first insn at 0x8048310 initially jumps to the following address
0x8048316, read from the .got.plt @ 0x804a00c:
...
804a000 0c9f0408 00000000 00000000 16830408 ................
804a010 26830408 &...
...
Likewise, when compiled as a PIE:
...
$ gcc -m32 -fPIE -pie test.c
...
we have this call sequence (with %ebx setup to point to the .got.plt):
...
0000055d <main>:
579: 83 ec 0c sub $0xc,%esp
57c: 6a 0a push $0xa
57e: 89 c3 mov %eax,%ebx
580: e8 6b fe ff ff call 3f0 <malloc@plt>
...
which calls to:
...
000003f0 <malloc@plt>:
3f0: ff a3 0c 00 00 00 jmp *0xc(%ebx)
3f6: 68 00 00 00 00 push $0x0
3fb: e9 e0 ff ff ff jmp 3e0 <.plt>
...
where the insn at 0x3f0 initially jumps to following address 0x3f6, read from
the .got.plt at offset 0xc:
...
2000 f41e0000 00000000 00000000 f6030000 ................
2010 06040000 ....
...
When instead doing an inferior call to malloc (with nosharedlib to force
malloc to resolve to malloc@plt rather than the functions in ld.so or libc.so)
with the non-PIE exec, we have the expected:
...
$ gdb -q -batch a.out -ex start -ex nosharedlib -ex "p /x (void *)malloc (10)"
Temporary breakpoint 1 at 0x8048444
Temporary breakpoint 1, 0x08048444 in main ()
$1 = 0x804b160
...
But with the PIE exec, we run into:
...
$ gdb -q -batch a.out -ex start -ex nosharedlib -ex "p /x (void *)malloc (10)"
Temporary breakpoint 1 at 0x56c
Temporary breakpoint 1, 0x5655556c in main ()
Program received signal SIGSEGV, Segmentation fault.
0x565553f0 in malloc@plt ()
...
The segfault happens because:
- the inferior call mechanism doesn't setup %ebx
- %ebx instead is 0
- the jump to "*0xc(%ebx)" reads from memory at 0xc
Fix this by setting up %ebx properly in i386_thiscall_push_dummy_call.
Fixes this failure with target board unix/-m32/-pie/-fPIE reported in
PR28467:
...
FAIL: gdb.base/nodebug.exp: p/c (int) array_index("abcdef",2)
...
Tested on x86_64-linux, with target board unix/-m32 and unix/-m32/-fPIE/-pie.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28467
When running test-case gdb.base/cached-source-file.exp with target board
readnow, we run into:
...
FAIL: gdb.base/cached-source-file.exp: rerun program (the program exited)
...
The problem is that when rereading, the readnow is ignored.
Fix this by copying the readnow handling code from symbol_file_add_with_addrs
to reread_symbols.
Tested on x86_64-linux.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26800
On openSUSE Leap 42.3, with system compiler gcc 4.8.5 I run into:
...
(gdb) print u_one_two_three^M
src/gdb/gdbtypes.h:1050: internal-error: field: \
Assertion `idx >= 0 && idx < num_fields ()' failed.^M
...
We run into trouble while doing this in
ada_is_unconstrained_packed_array_type:
...
1953 return TYPE_FIELD_BITSIZE (type, 0) > 0;
...
which tries to get field 0 from a type without fields:
...
(gdb) p type->num_fields ()
$6 = 0
...
which is the case because the type is a typedef:
...
(gdb) p type->code ()
$7 = TYPE_CODE_TYPEDEF
...
Fix this by using the type referenced by the typedef instead.
Tested on x86_64-linux.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28323
Commit b69c9d41e8 was broken in multiple ways regarding the realloc
of the target string, most notably in that "-little" wasn't actually
appended to the input_target or output_target. This caused asan
errors and "FAIL: Check if efi app format is recognized". I also
noticed that the input_target string wasn't being copied but rather
the output_target when dealing with the input target. Fix that too.
PR 26206
* objcopy.c (convert_efi_target): Rewrite. Allocate modified
target strings here..
(copy_main): ..rather than here. Do handle input_target,
not output_target for input.
It's not foolproof, for example we don't catch output to a linker
script, to a library specified with -l, or to an element of a thin
archive.
* ldlang.c (open_output): Exit with error on output file matching
an input file.
* testsuite/ld-misc/just-symbols.exp: Adjust ld -r test to suit.
This patch adds an #elif defined for PowerPC to setup the exit_0 macro.
This patch addes the needed macro definitionald logic to handle both elfV1
and elfV2.
The patch has been successfully tested on both PowerPC BE, Powerpc LE and
X86_64 with no regressions.
Test-cases gdb.arch/i386-{avx,sse}.exp use assembly instructions that require
the memory operands to be aligned to a certain boundary, and the test-cases
use C11's _Alignas to make that happen.
The draw-back of using _Alignas is that while it does enforce a minimum
alignment, the actual alignment may be bigger, which makes the following
scenario possible:
- copy say, gdb.arch/i386-avx.c as basis for a new test-case
- run the test-case and observe a PASS
- commit the new test-case in the supposition that the test-case is correct
and well-tested
- run later into a failure on a different test setup (which may be a setup
where reproduction and investigation is more difficult and time-consuming),
and find out that the specified alignment was incorrect and should have been
updated to say, 64 bytes. The initial PASS occurred only because the actual
alignment happened to be greater than required.
The idea of having precise alignment as a means of having more predictable
execution which allows flushing out bugs earlier, has been filed as PR
gcc/103095.
Add a new file lib/precise-aligned-alloc.c with functions
precise_aligned_alloc and precise_aligned_dup, to support precise alignment.
Use precise_aligned_dup in aforementioned test-cases to:
- verify that the specified alignment is indeed sufficient, rather
than too little but accidentally over-aligned.
- prevent the same type of problems in any new test-cases based on these
Tested on x86_64-linux, with both gcc and clang.
When running test-case gdb.arch/i386-avx.exp with clang I ran into:
...
(gdb) PASS: gdb.arch/i386-avx.exp: set first breakpoint in main
continue^M
Continuing.^M
^M
Program received signal SIGSEGV, Segmentation fault.^M
0x000000000040052b in main (argc=1, argv=0x7fffffffd3c8) at i386-avx.c:54^M
54 asm ("vmovaps 0(%0), %%ymm0\n\t"^M
(gdb) FAIL: gdb.arch/i386-avx.exp: continue to breakpoint: \
continue to first breakpoint in main
...
The problem is that the vmovaps insn requires an 256-bit (or 32-byte) aligned
address, and it's only 16-byte aligned:
...
(gdb) p /x $rax
$1 = 0x601030
...
Fix this by using a sufficiently aligned address, using _Alignas.
Compile using -std=gnu11 to support _Alignas.
Likewise in gdb.arch/i386-sse.exp.
Tested on x86_64-linux, with both gcc and clang.
The fixes gold failures to handle inline PLT sequences properly.
PowerPC gold was always turning these back into direct calls due to
gsym->use_plt_offset() returning false. This is fixed for dynamic
linking by correcting get_reference_flags, and for static linking by
overriding use_plt_offset() in relocate(). The rest of the patch
revolves around needing to create PLT entries for inline PLT calls
when statically linking (for gcc -mlongcall). The lplt section
handled that for local symbols, now it does globals too.
* powerpc.cc (Target_powerpc::plt_off): Return proper section
for static link.
(Target_powerpc::symval_for_branch): Make public.
(Target_powerpc::make_lplt_section): Add Symbol_table* param.
Adjust all calls.
(Target_powerpc::make_local_plt_entry): Likewise.
(Target_powerpc::make_local_plt_entry): New variant for global syms.
(Powerpc_relobj::do_relocate_sections): Don't write lplt contents.
(Output_data_plt_powerpc::do_write): Write lplt contents here.
(Output_data_plt_powerpc::Output_data_plt_powerpc): Save
symbol table pointer. Adjust all uses.
(Output_data_plt_powerpc::add_entry): Add stash parameter. Don't
do dynamic reloc handling when no reloc section. Save symbol
for local plt entries.
(Output_data_plt_powerpc::add_local_entry): Save symbol.
(Output_data_plt_powerpc::Local_plt_ent): New class.
(Output_data_plt_powerpc::sym_ents_): New vector.
(Target_powerpc::Scan::get_reference_flags): Return
FUNCTION_CALL|RELATIVE_REF for inline plt relocs.
(Target_powerpc::Scan::global): Make entries in lplt for inline
plt call relocation symbols.
(Target_powerpc::Relocate::relocate): Rename has_plt_offset to
use_plt_offset. Set use_plt_offset for inline plt relocs.
It's now possible to refer symbols in the main program from the
shared library. However, it still impossible to have the same
overriden features between shared objects and mains than ELF,
without using the runtime linking feature which isn't yet fully
available.
ld/ChangeLog:
* testsuite/ld-shared/shared.exp: Improve XCOFF support
* testsuite/ld-shared/main.c: Likewise.
* testsuite/ld-shared/sh1.c: Likewise.
* testsuite/ld-shared/xcoff.dat: Likewise.
This fixes a use-after-free that Simon pointed out.
process_psymtab_comp_unit_reader was allocating an artificial name for
a CU, and then discarding it. However, this name was preserved in the
cached file_and_directory. This patch arranges for the allocated name
to be preserved there.
We're including system headers after local headers in a bunch of
places, but this leads to conflicts when our local headers happen
to define symbols that show up in the system headers.
Use the more standard order of:
* config.h (via defs.h)
* system headers
* local library headers (e.g. bfd & libiberty)
* sim specific headers
ASan made me notice a memory leak, where the memory tied to the file
handle name string wasn't freed. When register a file handler with an
fd that is already registered, we re-use the file_handler object, so we
ended up creating a new std::string object and overwriting the
file_handler::name pointer, without free-ing the old std::string.
Fix this by allocating file_handler with new, deleting it with
delete, and making file_handler::name not a pointer.
Change-Id: Ie304cc78ab5ae5dfad9a1366e9890c09de651f43
This changes the DWARF reader to cache the result of
find_file_and_directory. This is not especially important now, but it
will help the new DWARF indexer.
This moves file_and_directory to a new file, and then C++-izes it --
replacing direct assignments with methods, and arranging for it to own
any string that must be computed. Finally, the CU's objfile will only
be used on demand; this is an important property for the new DWARF
indexer's parallel mode.
Running frv's allinsn in serial is quite slow due to the sheer number
of tests it contains. By splitting it up and running in parallel, the
execution time on my system goes from ~100sec to ~60sec.
I don't think it's very useful to show deprecated aliases to the
user. It encourages the user to use them, when the goal is the
opposite.
For example, before:
(gdb) help set index-cache enabled
set index-cache enabled, set index-cache off, set index-cache on
alias set index-cache off = set index-cache enabled off
alias set index-cache on = set index-cache enabled on
Enable the index cache.
When on, enable the use of the index cache.
(gdb) help set index-cache on
Warning: 'set index-cache on', an alias for the command 'set index-cache enabled', is deprecated.
Use 'set index-cache enabled on'.
set index-cache enabled, set index-cache off, set index-cache on
alias set index-cache off = set index-cache enabled off
alias set index-cache on = set index-cache enabled on
Enable the index cache.
When on, enable the use of the index cache.
After:
(gdb) help set index-cache enabled
Enable the index cache.
When on, enable the use of the index cache.
(gdb) help set index-cache on
Warning: 'set index-cache on', an alias for the command 'set index-cache enabled', is deprecated.
Use 'set index-cache enabled on'.
Enable the index cache.
When on, enable the use of the index cache.
Change-Id: I989b618a5ad96ba975367e9d16db95523cd57a4c
Commit 92228a334b ("gdb: small "maintenance info line-table"
readability improvements") change the output format of "maint info
line-table" slightly, adding some empty lines between each
line-table. This causes two tests to start failing, update them to
account for those empty lines.
Change-Id: I9d33a58fce3e860ba0554b25f5582e8066a5c519
Commit 4bce7cdaf4 ("gdbsupport: add array_view copy function") caused
an internal error when running gdb.ada/packed_array_assign.exp:
print pra(1) := pr^M
/home/smarchi/src/binutils-gdb/gdb/../gdbsupport/array-view.h:217: internal-error: copy: Assertion `dest.size () == src.size ()' failed.^M
I am not sure what's the root cause of this, whether it is a GDB bug
exposed by using the array_view copy function or not. Back out the
change that triggers the internal error for now, while we investigate
it.
Change-Id: I055ab14143e4cfd3ca7ce8f4855c6c3c05db52a7