Indu Bhagat [Sun, 2 Mar 2025 15:45:08 +0000 (07:45 -0800)]
ld: bfd: sframe: fix incorrect r_addend in RELA entries
With the fix in GAS, we now use a different PC-relative RELA for
updating the SFrame FDE function start address: The value is the offset
of the start PC of the function from the start of the SFrame section.
When RELAs are output (e.g. for relocatable links), there is need to
adjust the r_addend. This is because the r_addend values still have the
correct values for the _input_ SFrame section being linked / relocated.
The values must now be (before outputing the RELAs) with respect to the
_output_ SFrame section.
PS: This patch should be merged with the previous commits before final
commit (Otherwise the tests will fail). It is currently a separate
patch as I would like to check if this is OK to do. If such a "addend
fixup" is risky or wrong, it seems we will need a new type of RELOC for
SFrame sections.
bfd/
* elf-bfd.h: New declaration.
* elf-sframe.c (_bfd_elf_sframe_section_addend): New
definition.
* elflink.c (elf_link_input_bfd): Fixup the r_addend of
SFrame RELAs.
Indu Bhagat [Thu, 6 Feb 2025 21:38:04 +0000 (13:38 -0800)]
ld: bfd: sframe: fix incorrect r_offset in RELA entries
PR/32666 Incorrect .rela.sframe when using ld -r
Input SFrame sections are merged using _bfd_elf_merge_section_sframe (),
which clubs all SFrame FDEs together in one blob and all SFrame FREs in
another. This, of course, means the offset of an SFrame FDE in the output
section cannot be simply derived from the output_offset of the sections.
Fix this by providing _bfd_elf_sframe_section_offset () which returns
the new offset of the SFrame FDE in the merged SFrame section.
Unlike EH_Frame sections, which also use the _bfd_elf_section_offset (),
to update the r_offset, SFrame sections additionally need :
if (o->sec_info_type != SEC_INFO_TYPE_SFRAME)
irela->r_offset += o->output_offset;
because information in SFrame and EH_Frame sections is organised
differently. In case of SFrame, the SFrame FDE will not simply sit at
location "o->output_offset + offset of SFrame FDE in o". Recall that
information layout in an SFrame section is as follows:
SFrame Header
SFrame FDE 1
SFrame FDE 2
...
SFrame FDEn
SFrame FREs (Frame Row Entries)
Note how the SFrame FDEs and SFrame FREs are clubber together in groups
of their own.
Taking the above into account, the correct offset has already been
calculated via _bfd_elf_section_offset (). So for SFrame sections, the
r_offset of the RELA should not be offset further by the
o->output_offset (offset of the input SFrame section in the output
SFrame section).
Add a new enum to track the current state of the SFrame input section
during the linking process (SFRAME_SEC_DECODED, SFRAME_SEC_MERGED) for
each input SFrame section. This is then used to assert an assumption
that _bfd_elf_sframe_section_offset () is being used on an input SFrame
sections which have not been merged (via
_bfd_elf_merge_section_sframe ()) yet.
bfd/
* elf-bfd.h: New declaration.
* elf-sframe.c (_bfd_elf_sframe_section_offset): New definition.
* elf.c (_bfd_elf_section_offset): Adjust offset if SFrame
section.
* elflink.c (elf_link_input_bfd): RELA offset adjust be done
conditionally.
ld/testsuite/
* ld-x86-64/x86-64.exp: New test.
* ld-x86-64/sframe-reloc-1.d: New test.
Indu Bhagat [Tue, 4 Feb 2025 19:58:11 +0000 (11:58 -0800)]
objdump, readelf: sframe: apply relocations before textual dump
PR libsframe/32589 - function start address is zero in SFrame section dump
Currently, readelf and objdump display SFrame section in object file
with function start addresses of each function as 0. This makes it
difficult to correlate SFrame stack trace information with the
individual functions in the object file.
Use the dump_dwarf () interface to dump SFrame section. The current
infrastructure (for DWARF debug sections) already supports relocating
the section contents before dumping, so lets use that.
As a side effect, objdump now adds two new ways of dumping SFrame sections:
- objdump -WS <obj>
- objdump --dwarf=sframe
We do not publicize these options. The lone advertised user interfacing
option (in --help) remains:
- objdump --sframe
For objdump, we continue to keep the same error messaging as earlier (by
folding the check for section into the new dump_sframe_section ()
function):
$ objdump --sframe=sframe bubble_sort.o
...
No sframe section present
$ objdump --sframe=.sfram bubble_sort.o
...
No .sfram section present
Similarly for readelf:
$ readelf --sframe= bubble_sort.o
readelf: Error: Section name must be provided
$ readelf --sframe=.sfram bubble_sort.o
readelf: Warning: Section '.sfram' was not dumped because it does not exist
$ readelf --sframe=sframe bubble_sort.o
readelf: Warning: Section 'sframe' was not dumped because it does not exist
binutils/
* dwarf.c (display_sframe): New definition.
(dwarf_select_sections_all): Enable SFrame section too.
(struct dwarf_section_display): Add entry for SFrame section.
* dwarf.h (enum dwarf_section_display_enum): Add enumerator for
SFrame.
* objdump.c (dump_section_sframe): Remove.
(dump_sframe_section): Add new definition.
(dump_bfd): Use dump_sframe_section.
* binutils/readelf.c (dump_section_as_sframe): Remove.
gas/testsuite/
* gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d: Adjust for
new output.
Indu Bhagat [Fri, 28 Feb 2025 06:01:40 +0000 (22:01 -0800)]
gas: ld: sframe: fix RELA r_offset handling
In SFrame V2, SFrame function descriptor entry is a 32-bit signed
integer (sfde_func_start_address) which is meant to indicate the start
PC of the function. According to the specification, it intends to hold
the offset of the start PC of the function from the
_start_of_the_SFrame_section_. This value can then be used by
stacktracers to simply do:
sframe_find_fre ( pc - sframe_vaddr)
when looking up SFrame stack trace data corresponding to the program
counter (pc).
In the current implementation, however, GAS is actually emitting a
PC-relative RELA such that sfde_func_start_address is the offset of the
start PC of the function from the _start_of_the_SFrame_FDE_. ld.bfd
was then fixing up the value by adjusting the final values by r_offset
Co-Authored-By: Jens Remus <jremus@linux.ibm.com>
bfd/
* elf-sframe.c (_bfd_elf_merge_section_sframe): Do not fixup
SFrame FDE function start address.
* elfxx-x86.c (_bfd_x86_elf_finish_dynamic_sections): Likewise
for PLT entries.
gas/
* gen-sframe.c (output_sframe_funcdesc): New argument for SFrame
section start.
(output_sframe_internal): New symbol for SFrame section start.
include/
* sframe.h: Fix incorrect comment.
The symptom is that for a given dwarf2_per_cu, the language gets set
twice. First, set to `language_ada`, and then, to `language_minimal`.
It's unexpected for the language of a CU to get changed like this.
The CU at offset 0x0 in the main file looks like:
0x00000000: Compile Unit: length = 0x00000030, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00000034)
The thing to note is that the language attribute is only present in the
DIE in the DWO file, not on the DIE in the main file.
The first time the language gets set is here:
#0 dwarf2_per_cu::set_lang (this=0x50f0000044b0, lang=language_ada, dw_lang=DW_LANG_Ada95) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:20788
#1 0x0000555561666af6 in cutu_reader::prepare_one_comp_unit (this=0x7ffff10bf2b0, cu=0x51700008e000, pretend_language=language_minimal) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:21029
#2 0x000055556159f740 in cutu_reader::cutu_reader (this=0x7ffff10bf2b0, this_cu=0x50f0000044b0, per_objfile=0x516000066080, abbrev_table=0x510000004640, existing_cu=0x0, skip_partial=false, pretend_language=language_minimal, cache=0x7ffff11b95e0) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:3371
#3 0x00005555615a547a in process_psymtab_comp_unit (this_cu=0x50f0000044b0, per_objfile=0x516000066080, storage=0x7ffff11b95e0) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:3799
#4 0x00005555615a9292 in cooked_index_worker_debug_info::process_cus (this=0x51700008dc80, task_number=0, first=std::unique_ptr<dwarf2_per_cu> = {...}, end=std::unique_ptr<dwarf2_per_cu> = {...}) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:4122
In this code path (particularly this specific cutu_reader constructir),
the work is done to find and read the DWO file. So the language is
properly identifier as language_ada, all good so far.
The second time the language gets set is:
#0 dwarf2_per_cu::set_lang (this=0x50f0000044b0, lang=language_minimal, dw_lang=0) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:20788
#1 0x0000555561666af6 in cutu_reader::prepare_one_comp_unit (this=0x7ffff0f42730, cu=0x517000091b80, pretend_language=language_minimal) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:21029
#2 0x00005555615a1822 in cutu_reader::cutu_reader (this=0x7ffff0f42730, this_cu=0x50f0000044b0, per_objfile=0x516000066080, pretend_language=language_minimal, parent_cu=0x0, dwo_file=0x0) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:3464
#3 0x000055556158c850 in dw2_get_file_names (this_cu=0x50f0000044b0, per_objfile=0x516000066080) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:1956
#4 0x000055556158f4f5 in dw_expand_symtabs_matching_file_matcher (per_objfile=0x516000066080, file_matcher=...) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:2157
#5 0x00005555616329e2 in cooked_index_functions::expand_symtabs_matching (this=0x50200002ab50, objfile=0x516000065780, file_matcher=..., lookup_name=0x0, symbol_matcher=..., expansion_notify=..., search_flags=..., domain=..., lang_matcher=...) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:15912
#6 0x0000555562ca8a14 in objfile::map_symtabs_matching_filename (this=0x516000065780, name=0x50200002ad90 "break pck.adb", real_path=0x0, callback=...) at /home/smarchi/src/binutils-gdb/gdb/symfile-debug.c:207
#7 0x0000555562d68775 in iterate_over_symtabs (pspace=0x513000005600, name=0x50200002ad90 "break pck.adb", callback=...) at /home/smarchi/src/binutils-gdb/gdb/symtab.c:727
Here, we use the other cutu_reader constructor, the one that does not
look up the DWO file for the passed CU. If a DWO file exists for this
CU, the caller is expected to pass it as a parameter. That cutu_reader
constructor also ends up setting the language of the CU. But because it
didn't read the DWO file, it didn't figure out the language is
language_ada, so it tries to set the language to the default,
language_minimal.
A question is: why do we end up trying to set the CU's language is this
context. This is completely unrelated to what we're trying to do, that
is get the file names from the line table. Setting the language is a
side-effect of just constructing a cutu_reader, which we need to look up
attributes in dw2_get_file_names_reader. There are probably some
cleanups to be done here, to avoid doing useless work like looking up
and setting the CU's language when all we need is an object to help
reading the DIEs and attributes. But that is future work.
The same cutu_reader constructor is used in
`dwarf2_per_cu::ensure_lang`. Since this is the version of cutu_reader
that does not look up the DWO file, it will conclude that the language
is language_minimal and set that as the CU's language. In other words,
`dwarf2_per_cu::ensure_lang` will get the language wrong, pretty ironic.
Fix this by using the other cutu_reader constructor in those two spots.
Pass `per_objfile->get_cu (this_cu)`, as the `existing_cu` parameter. I
think this is necessary, because that constructor has an assert to check
that if `existing_cu` is nullptr, then there must not be an existing
`dwarf2_cu` in the per_objfile.
To avoid getting things wrong like this, I think that the second
cutu_reader constructor should be reserved for the spots that do pass a
non-nullptr dwo_file. The only spot at the moment in
create_cus_hash_table, where we read multiple units from the same DWO
file. In this context, I guess it makes sense for efficiency to get the
dwo_file once and pass it down to cutu_reader. For that constructor,
make the parameters non-optional, add "non-nullptr" asserts, and update
the code to assume the passed values are not nullptr.
What I don't know is if this change is problematic thread-wise, if the
functions I have modified to use the other cutu_reader constructor can
be called concurrently in worker threads. If so, I think it would be
problematic.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32742
Change-Id: I980d16875b9a43ab90e251504714d0d41165c7c8 Approved-By: Tom Tromey <tom@tromey.com>
Tom Tromey [Fri, 21 Feb 2025 16:18:28 +0000 (09:18 -0700)]
Avoid excessive CU expansion on failed matches
PR symtab/31010 points out that something like "ptype INT" will expand
all CUs in a typical program. The OP further points out that the
original patch for PR symtab/30520:
... did solve the problem, but the patch changed after (my) review and
reintroduced the bug.
In cooked_index_functions::expand_symtabs_matching, the final
component of a split name is compared with the entry's name using the
usual method of calling get_symbol_name_matcher.
This code iterates over languages and tries to split the original name
according to each style. But, the Ada splitter uses the decoded name
-- "int". This causes every C or C++ CU to be expanded.
Clearly this is wrong. And, it seems to me that looping over
languages and trying to guess the splitting style for the input text
is probably bad. However, fixing the problem is not so easy (again
due to Ada). I've filed a follow-up bug, PR symtab/32733, for this.
Meanwhile, this patch changes the code to be closer to the
originally-submitted patch. This works because the comparison is now
done between the full name and the "lookup_name_without_params"
object, which is a less adulterated variant of the original input.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31010 Tested-By: Simon Marchi <simon.marchi@efficios.com>
Tom Tromey [Fri, 21 Feb 2025 18:57:48 +0000 (11:57 -0700)]
Use wild matching for lookup_name_info::match_any
Currently, lookup_name_info::match_any symbol_name_match_type::FULL.
However, this seems wrong. Consider the expand_symtabs_matching
implementation of the cooked index: it compares name components, and
then if all the components match, it checks:
if ((match_type == symbol_name_match_type::FULL
|| (lang != language_ada
&& match_type == symbol_name_match_type::EXPRESSION)))
{
if (parent != nullptr)
continue;
That is, if the component-matching loop did not finish, and a full
match is requested, then fail to match. This handles cases where the
index is asked to look up "b::c" but finds "a::b::c".
However, match_any should match, well, any. So, it seems to me that
checking any parent matches is irrelevant -- and therefore this should
use wild matching.
Tom Tromey [Sun, 23 Feb 2025 22:34:40 +0000 (15:34 -0700)]
Handle ">>" in cp-name-parser.y
I noticed that a certain name didn't work correctly when trying to
remove the parameters. I put this into lookup_name_info-selftests.c.
I tracked this down to the fact that cp-name-parser.y doesn't handle
">>" to end templates. This patch fixes this in a simple way --
accepting the "RSH" token where appropriate and then un-pushing a ">".
Georg-Johann Lay [Sun, 16 Feb 2025 17:43:56 +0000 (18:43 +0100)]
AVR: gas/32704 - Improve code generation for __gcc_isr.
The prologue generated by __gcc_isr can be improved in
situations where:
* ZERO_REG is needed, and
* SREG is not clobbered by the ISR, and
* avr-gcc provides a GPR >= R16 with the Done chunk, and
* Code generation is for ordinary AVRs (not AVRrc).
For example, the prologue for
volatile char var;
__attribute__((signal)) void __vector_1 (void)
{
var = 1;
var = 0;
}
Jan Beulich [Fri, 7 Mar 2025 10:27:58 +0000 (11:27 +0100)]
gas: don't permit "repeat" expressions with .cfi_{escape,fde_data}
Repeat counts greater than 1 will emit data directly into the current
(sub-)section. That's wrong with .cfi_*, which defer data emission until
much later: N-1 instances of the specified data would not end up in
.eh_frame (or whatever the section that CFI data was specified to go
into). Simply disallow "repeat" expressions in such cases.
Jan Beulich [Fri, 7 Mar 2025 10:26:43 +0000 (11:26 +0100)]
gas: centralize declaration of listing_tail
Besides it being somewhat off to have three decls scattered across the
code base, it is generally bad practice for the definition of a symbol
to not also observe its declaration (making sure the two won't go out of
sync).
Compilers may split functions, e.g. into a "hot" and "cold" part, or
they may emit special case instantiations (e.g. as a result of IPA). It
can be helpful to be able to disassemble all of the parts or clones in
one go. Permit using "--disassemble=" multiple times.
Jan Beulich [Fri, 7 Mar 2025 10:23:13 +0000 (11:23 +0100)]
objdump: properly disassemble successive functions of the same name
... when only their symbol was requested for disassembly. Addressing the
respective FIXME is as easy as coverting the "else" there to an if()
with the opposite condition, thus accounting for the disabling the
original if() may have effected.
Tom de Vries [Fri, 7 Mar 2025 08:25:33 +0000 (09:25 +0100)]
[gdb/tdep] Support REX2 and EVEX prefix
The following amd64 insn:
...
0: 67 d5 44 8d 3d 00 00 00 00 lea 0x0(%eip),%r31d
...
uses the REX2 prefix [1], which is currently not supported in
amd64_get_insn_details.
Add the missing support in amd64_get_insn_details, as well as a corresponding
unit test.
Likewise for an amd64 insn using an EVEX prefix [2]:
...
0: 62 f1 7c 48 28 05 00 fc ff ff vmovaps -0x400(%rip),%zmm0
...
Tom de Vries [Fri, 7 Mar 2025 08:25:33 +0000 (09:25 +0100)]
[gdb/tdep] Fix vmovdqu decoding
PR tdep/31952 reports that displaced stepping over an instruction pointer
relative insn "vmovdqu 0x20(%rip),%ymm1" gives the wrong results.
This is caused by misclassification of the insn in amd64_get_insn_details,
which results in details.modrm_offset == -1, while the instruction in fact
does have a modrm byte.
The instruction is encoded as follows:
...
400557: c5 fe 6f 0d 20 00 00 00 vmovdqu 0x20(%rip),%ymm1
...
where:
- "0xc5 0xfe" is the vex2 prefix,
- "0x6f" is the opcode,
- "0x0d" is the modrm byte, and
- "0x20 0x00 0x00 0x00" is a 32-bit displacement.
The problem is related to details.opcode_len, which is 1.
While it is true that the length of the opcode in the insn (0x6f) is 1 byte,
the vex2 prefix implies that we're encoding an 2-byte opcode beginnning
with 0x0f [1].
Consequently, we should be using the twobyte_has_modrm map rather than the
onebyte_has_modrm map.
Fix this in amd64_get_insn_details, and add a selftest to check this.
Tom de Vries [Fri, 7 Mar 2025 08:25:33 +0000 (09:25 +0100)]
[gdb/tdep] Make amd64_get_insn_details more regular
In amd64_get_insn_details, I found this code with a comment explaining why
enc_prefix_offset is not set:
...
else if (vex2_prefix_p (*insn))
{
/* Don't record the offset in this case because this prefix has
no REX.B equivalent. */
insn += 2;
}
...
which I didn't understand until I looked at the only use of enc_prefix_offset,
in fixup_riprel:
...
/* REX.B should be unset (VEX.!B set) as we were using rip-relative
addressing, but ensure it's unset (set for VEX) anyway, tmp_regno
is not r8-r15. */
if (insn_details->enc_prefix_offset != -1)
{
gdb_byte *pfx = &dsc->insn_buf[insn_details->enc_prefix_offset];
if (rex_prefix_p (pfx[0]))
pfx[0] &= ~REX_B;
else if (vex3_prefix_p (pfx[0]))
pfx[1] |= VEX3_NOT_B;
else
gdb_assert_not_reached ("unhandled prefix");
}
...
Fix this by:
- setting enc_prefix_offset for the vex2 case in amd64_get_insn_details,
making the function more regular and easier to understand, and
- handling the vex2 case in the "enc_prefix_offset != -1" clause in
fixup_riprel.
Tom de Vries [Fri, 7 Mar 2025 08:25:33 +0000 (09:25 +0100)]
[gdb/tdep] Add vzeroupper and vzeroall in amd64-insn-decode selftest
After I posted a tentative patch for PR31952, Alexander Monakov pointed out
that the patch broke instruction decoding for instructions vzeroall and
vzeroupper.
Add selftests for these two instructions in amd64-insn-decode, both using
vex2 and vex3 prefixes.
Tom de Vries [Fri, 7 Mar 2025 08:25:33 +0000 (09:25 +0100)]
[gdb/tdep] Add vex2_to_vex3
I noticed here [1] that the vex2 prefix is essentially a special case of the
vex3 prefix, meaning it's possible to rewrite any insn with a vex2 prefix into
an equivalent one with a vex3 prefix.
Add function vex2_to_vex3 that does precisely that, in the selftests
namespace.
Tom de Vries [Fri, 7 Mar 2025 08:25:33 +0000 (09:25 +0100)]
[gdb/tdep] Fix rip-relative insn handling in amd64_get_used_input_int_reg
I wanted to add a unit test for an an rip-relative amd64 insn, so I did:
...
$ gcc -fPIE hello.c
...
and used an rip-relative insn from main:
...
4005db: 48 8d 3d 1e 00 00 00 lea 0x1e(%rip),%rdi
...
While writing the unit test, I found that amd64_get_used_input_int_reg returns
rbp as input register.
Fix this by using rip_relative_p in amd64_get_used_input_int_reg to handle
this case.
Tom de Vries [Fri, 7 Mar 2025 08:25:33 +0000 (09:25 +0100)]
[gdb/tdep] Add amd64-insn-decode selftest
Add a selftest that checks the results of amd64_get_insn_details and related
functions for two basic instructions.
Add a parameter assumptions to amd64_get_used_input_int_regs, to make sure
that this selftest:
...
/* INSN: add %eax,(%rcx). */
...
SELF_CHECK (amd64_get_used_input_int_regs (&details, false)
== ((1 << EAX_REG_NUM) | (1 << ECX_REG_NUM)));
...
passes because it found the "%eax" in the insn, rather than passing because of
this assumption:
...
/* Assume RAX is used. If not, we'd have to detect opcodes that implicitly
use RAX. */
used_regs_mask |= 1 << EAX_REG_NUM;
...
Tom de Vries [Fri, 7 Mar 2025 08:25:33 +0000 (09:25 +0100)]
[gdb/tdep] Refactor amd64_get_unused_input_int_reg, part 3
While reading amd64_get_unused_input_int_reg, I noticed that it avoids picking
RSP, which has to do with how the result of the only call to it is going to be
used.
Likewise for picking a register in the RAX ... RDI range.
Fix this by:
- adding an allowed_regs_mask parameter to amd64_get_unused_input_int_reg, and
- properly documenting the value of the corresponding argument in fixup_riprel.
Tom de Vries [Fri, 7 Mar 2025 08:25:33 +0000 (09:25 +0100)]
[gdb/tdep] Refactor amd64_get_unused_input_int_reg, part 2
I noticed that amd64_get_unused_input_int_reg uses a signed int for a bit
mask:
...
/* 1 bit for each reg */
int used_regs_mask = 0;
...
There's an assert:
...
gdb_assert (used_regs_mask < 256);
...
which is meant to assert on register numbers >= 8, but if for instance
sizeof (used_regs_mask) == 4 and used_regs_mask == (1 << 31), then that is not
caught because of the signedness.
We could fix this by changing the type to unsigned int, but that only
guarantees 16 bits in the reg mask. Intel CPUs with the APX extension support
32 int registers.
The implementation of amd64_get_unused_input_int_reg doesn't support analyzing
registers with register number >= 8 yet, but now that we're changing the type,
it seems like a good idea to anticipate this.
Fix this by using uint32_t.
Likewise, update the loop over the reg mask:
...
for (i = 0; i < 8; ++i)
{
if (! (used_regs_mask & (1 << i)))
return i;
...
to handle any used_regs_mask value rather than just those for
register number < 8.
Tom de Vries [Fri, 7 Mar 2025 08:25:33 +0000 (09:25 +0100)]
[gdb/tdep] Refactor amd64_get_unused_input_int_reg, part 1
While reading amd64_get_unused_input_int_reg, I noticed that it first asserts,
then throws an internal_error if no unused register can be found.
Looking at the documentation of gdbarch_displaced_step_copy_insn, it seems
that a failure can be indicated less abruptly, by returning a nullptr.
Fix this by:
- returning -1 in case of failure to find an unused register in
amd64_get_unused_input_int_reg, and
- propagating this to amd64_displaced_step_copy_insn.
Jan Beulich [Fri, 7 Mar 2025 07:30:36 +0000 (08:30 +0100)]
gas: leave expression symbols alone when processing equates
PR gas/32721
In this bogus piece of code distilled from fuzzing and slightly edited:
A=%eax|%!
Y=A
Z=A
or $6,Z
the first of the equates with A on the rhs changes A's section (due to
the use of S_GET_VALUE()), from expression to register, thus yielding Y
in the expression section (and X_op being O_symbol), but Z in the
register section (and X_op being O_register with X_add_value being -1).
There shouldn't be random O_register expressions, though, for targets
setting md_register_arithmetic to false. Plus both Y and Z would better
be exchangeable.
In pseudo_set() wire handling of O_symbol expressions referencing a
symbol in the expression section to that of other stuff ending up in
this section.
Also avoid bogus O_register expressions to be created, for targets
setting md_register_arithmetic to false: S_GET_VALUE() would resolve
any arithmetic, which must not happen for such targets. To be on the
safe side for such targets, also amend resolve_register(). Correct
another earlier oversight there too (affecting at least Z80), by using
the new expr_copy() helper there as well.
Undo 46b9f07dfe79 ("PR 32721, internal error in
tc-i386.c:parse_register"), albeit without losing the simplification it
did.
Jan Beulich [Fri, 7 Mar 2025 07:29:20 +0000 (08:29 +0100)]
v850: improve linker scripts for relocatable linking
Quite a few constructs where unconditional when they should take
$RELOCATING into account. The original observation was that output of
"ld -r" had .text start at 0x00100000.
Jan Beulich [Fri, 7 Mar 2025 07:28:59 +0000 (08:28 +0100)]
gas: fold is_end_of_line[] into lex_type[]
... by way of introducing LEX_EOL and LEX_EOS. As a prereq convert the
remaining open-coded accesses.
The Alpha change is actually a functional one: The array slot for '!'
having been set to 1 is very unlikely to have been correct. 1 means "end
of line", when surely "end of statement" was always meant.
Jan Beulich [Fri, 7 Mar 2025 07:23:53 +0000 (08:23 +0100)]
rl78: drop redundant statement separator check
With the switch to the use of is_end_of_stmt() in 2dd0370c433d
("rl78: use is_whitespace()") the open-coded checking against
line_separator_chars[] can be dropped.
Jan Beulich [Fri, 7 Mar 2025 07:21:00 +0000 (08:21 +0100)]
C54x: use is_end_of_stmt()
... instead of open-coding it.
In tic54x_stringer() this also fixes an array overrun issue: Converting
plain char to unsigned int could have yielded huge values when plain
char is a signed type.
In subsym_substitute() also convert a local variable to plain char, as
that's what it's really holding (and how it's used everywhere else).
Jan Beulich [Fri, 7 Mar 2025 07:14:11 +0000 (08:14 +0100)]
M68HC1x: use is_end_of_stmt()
... instead of open-coding it. With this there's no need for op_end (and
hence op_start) to be other than pointer to plain char. Which in turn
eliminates the need for several questionable casts.
Jan Beulich [Fri, 7 Mar 2025 07:10:35 +0000 (08:10 +0100)]
Arm: use is_end_of_stmt()
... instead of open-coding it. This also fixes an array underrun issue:
The wrong casting to plain int could have yielded negative values when
plain char is a signed type.
Jan Beulich [Fri, 7 Mar 2025 07:10:23 +0000 (08:10 +0100)]
Alpha: use is_end_of_stmt()
... instead of open-coding it. Note that writes to the array need to be
left alone; they can only be converted when the array is folded into
lex_type[].
Jan Beulich [Fri, 7 Mar 2025 07:08:14 +0000 (08:08 +0100)]
{,E}COFF: use is_end_of_stmt()
... instead of open-coding it. Convert a variable's type to plain char
then as well, as that's what it's really holding (and how it's used
everywhere else).
H.J. Lu [Fri, 7 Mar 2025 05:55:06 +0000 (13:55 +0800)]
gprof: Update PR gprof/32764 test
1. Remove gmon.out first before generating it in the configure check.
2. Make tst-gmon-gprof.out depend on the gprof binary.
3. Check that gmon.out is non-empty.
4. Don't include <sys/cdefs.h> in tst-gmon.c.
PR gprof/32764
* configure.ac: Remove gmon.out first.
* configure: Regenerated.
* testsuite/Makefile.am (tst-gmon-gprof.out): Depend on
$(GPROF).
* testsuite/Makefile.in: Regenerated.
* testsuite/tst-gmon-gprof.sh: Check that gmon.out is non-empty.
* testsuite/tst-gmon.c: Don't include <sys/cdefs.h>.
Nelson Chu [Sat, 8 Feb 2025 08:33:37 +0000 (16:33 +0800)]
RISC-V: Go PLT for CALL/JUMP/RVC_JUMP if `h->plt.offset' isn't -1
I got an request about the undefined behaviors, considering the following case,
$ cat test.c
void main ()
{
foo();
}
$ cat lib.h
void foo(void);
$ riscv64-unknown-linux-gnu-gcc test.c
riscv64-unknown-linux-gnu/bin/ld: /tmp/ccRO8fJl.o: in function `main':
test.c:(.text+0x8): undefined reference to `foo'
collect2: error: ld returned 1 exit status
$ riscv64-unknown-linux-gnu-gcc test.c -Wl,--unresolved-symbols=ignore-in-object-files
$ qemu-riscv64 a.out
Segmentation fault (core dumped)
Testing with x86 and aarch64, they won't get the segfault since they go plt
for the undefined foo symbol. So, after applying this patch, I can get the
following too,
The change of this patch should only affect the call behavior, which refer
to an undefined (weak) symbol, when building an dynamic executable. I think
the pic/pie behavior won't be affected as usual.
H.J. Lu [Thu, 6 Mar 2025 22:42:18 +0000 (06:42 +0800)]
gprof: Copy a simple test from glibc
Copy a simple gprof test from glibc to test the basic gprof functionality.
1. Tested natively on Linux/x86-64 and Linux/i686.
2. Tested for the x86_64-solaris cross target without cross-compiler.
3. Tested for the aarch64-linux-gnu cross target with cross-compiler.
Tom Tromey [Wed, 23 Oct 2024 17:17:51 +0000 (11:17 -0600)]
Update ada_add_block_renamings for compiler changes
With the hierarchical name patches to GNAT, ada_add_block_renamings
must now be updated as well -- the comment there about the supported
forms of DW_TAG_imported_declaration is no longer correct, and now
full names must sometimes be constructed during the lookup process.
Tom Tromey [Fri, 6 Sep 2024 20:38:44 +0000 (14:38 -0600)]
Add support for hierarchical Ada names
In the near future, GNAT will start emitting DWARF names in a more
standard way -- specifically, the package structure will be indicated
by nested DW_TAG_module DIEs and a given entity will be nested in its
package and only have a simple name.
This patch changes gdb to understand this style of naming, while still
supporting the existing GNAT output.
A few special cases are needed. I've commented them.
The name-computing code for the full DWARF reader is very complicated
-- much too complicated, in my opinion. There are already several
bugs in bugzilla about this (search for "physname"... but there are
others as well), so I haven't filed any new ones.
When I started this project, I thought it would solve some memory
overuse issues we sometimes see from how the index-sharding code
interacts with the GNAT-specific post-pass. However, to my surprise,
the Ada code in gdb relies on some details of symbol naming, and so
I've had to add code here to synthesize "linkage" names in some cases.
This is unfortunate, but I think can eventually be fixed; I will file
a bug to track this issue.
Tom Tromey [Tue, 3 Sep 2024 18:53:07 +0000 (12:53 -0600)]
Add "Ada linkage" mode to cooked_index_entry::full_name
Unfortunately, due to some details of how the Ada support in gdb
currently works, the DWARF reader will still have to synthesize some
"full name" entries after the cooked index has been constructed.
You can see one particular finding related to this in:
Tom Tromey [Wed, 12 Jun 2024 17:24:27 +0000 (11:24 -0600)]
Store new Ada entries in cooked_index_shard::m_entries
handle_gnat_encoded_entry might create synthetic cooked index entries
for Ada packages. These aren't currently kept in m_entries, but it
seems to me that they should be, particularly because a forthcoming
GNAT will emit explicit DW_TAG_module for these names -- with this
change, the indexes will be roughly equivalent regardless of which
compiler was used.
Tom Tromey [Wed, 12 Jun 2024 14:26:05 +0000 (08:26 -0600)]
Use DW_TAG_module for Ada
In GCC we decided to use DW_TAG_module to represent Ada packages, so
make this same decision in gdb. This also updates tag_matches_domain
to handle this case.
Tom Tromey [Fri, 6 Sep 2024 18:24:06 +0000 (12:24 -0600)]
Use dwarf2_full_name when computing type names
This changes a few spots in the DWARF reader to use dwarf2_full_name
when computing the name of a type. This gives the correct name when a
type is nested in a namespace. This oddity probably wasn't noticed
before because some of the types in question are either normally
anonymous in C++ (e.g, array type) or do not appear in a namespace
(base type).
Tom Tromey [Mon, 26 Aug 2024 18:54:17 +0000 (12:54 -0600)]
Compare unqualified names in ada_identical_enum_types_p
With the coming changes to GNAT, gdb must compare the unqualified
names of two enum types.
Currently, GNAT will fully-qualify enumeration constant names, so for
instance one might see "enum_with_gap__lit4" as the name.
GNAT also may emit a copy of an enumeration type when a newtype is
involved. E.g., in the arr_acc_idx_w_gap.exp test case, this can
occur for the base type of this subtype:
type Enum_Subrange is new Enum_With_Gaps range Lit1 .. Lit3;
(Note that the base type of this subrange is anonymous.)
With some forthcoming changes to GNAT, these names will no longer be
qualified -- and because the newtype is anonymous, they can't be
identically qualified. But, in gdb we still want "lit4" to resolve
without ambiguity in this scenario.
The fix is to change ada_identical_enum_types_p to compare unqualified
enum names. This will work correctly with both variants of the
compiler, and with -fgnat-encodings=all as well.
Tom Tromey [Mon, 26 Aug 2024 17:10:54 +0000 (11:10 -0600)]
Use ada_identical_enum_types_p in ada_atr_enum_rep
With the coming changes to GNAT, we may see two distinct but
equivalent enum types in the DWARF. In this case, it's better to use
ada_identical_enum_types_p rather than types_equal when comparing
these types... something that matters when using 'Enum_Rep.
Tom Tromey [Wed, 28 Aug 2024 14:06:58 +0000 (08:06 -0600)]
Fixes to gdb.ada/fun_overload_menu.exp
This patch applies a few fixes to gdb.ada/fun_overload_menu.exp.
It adds some comments to the source and uses this to extract line
numbers. This is used to ensure that two otherwise-equivalent results
are in fact different, so that the test really checks that the result
is correct.
It also changes the test_menu proc to accept a list of possible
results. This lets the test work regardless of the order in which the
menu items are presented by gdb.
Finally, like an earlier patch, it changes the test to optionally
accept unqualified names from gdb.
Tom Tromey [Thu, 5 Sep 2024 17:57:03 +0000 (11:57 -0600)]
Allow multiple locations in homonym.exp
With some forthcoming changes to GNAT, the two Get_Value functions in
this test case will end up with the same name (with the current GNAT,
one ends up with a "__2" suffix). This change will cause one test to
set multiple breakpoints; this patch changes the test to work with
either version of the compiler.
Tom Tromey [Thu, 12 Sep 2024 14:18:10 +0000 (08:18 -0600)]
Fix type name in ptype-o.exp
The "Rec" type in ptype-o.exp is currently named "prog__rec" by the
compiler. However, with my changes to GNAT, the type will no longer
have a prefix, as it is local to a procedure.
Changing this to just use "rec" works fine with the new compiler, but
then fails with older compilers. To allow correct operation with both
compilers, this patch simply moves the type into a new package. This
doesn't affect the meaning of the test, which is just ensuring that
ptype/o works in a certain case.
Note that the more obvious fix of just using "ptype/o rec" does not
work with the current GNAT. I haven't investigated this but I did
file a bug to track it: