You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
RISC-V: Reorganize arch-related initialization and management
objdump reuses the disassembler function returned by the disassembler
function. That's good and benefits well from various optimizations.
However, by default, GDB (default_print_insn in gdb/arch-utils.c) assumes
that the disassembler function logic is simple and calls that function for
every instruction to be disassembled. This is clearly a waste of time
because it probes BFD (ELF information) and re-initializes
riscv_rps_dis for every instruction.
After the support of mapping symbol with ISA string with commit 40f1a1a
("RISC-V: Output mapping symbols with ISA string."), this kind of per-
instruction initialization of riscv_rps_dis can also occur on ELF files with
mapping symbol + ISA string (in riscv_get_map_state function). It can be
worse if the object is assembled using Binutils commit 0ce50fc
("RISC-V: Always generate mapping symbols at the start of the sections.")
or later.
To avoid repeated initialization, this commit
- Caches the default / override architectures (in two "contexts") and
- enables switching between them.
riscv_dis_arch_context_t and new utility functions are defined for this
purpose. We still have to read the ".riscv.attributes" section on every
instruction on GDB but at least the most time-consuming part (updating the
actual architecture from the architecture string) is avoided.
Likewise, we still have to probe whether we have to update the architecture
for every instruction with a mapping symbol with ISA string is suitable but
at least we don't actually update the architecture unless necessary
(either context itself or the ISA string of the current context is changed).
This commit improves the disassembler performance well in those situations:
- When long "disas" command is used on GDB
- When ELF files with mapping symbols + ISA string is used
This commit now implements new mapping symbol handling ("$x" means revert
to the previous architecture [with "$x+arch"] if exists, otherwise revert to
the default one usually read from an ELF attribute), the recent consensus
made by Kito and Nelson.
On the benchmark using GDB batch files, the author measured significant
performance improvements (35-96% on various big RISC-V programs).
Unfortunately, on interactive usecases of GDB, this improvement is rarely
observable since we don't usually disassemble such a big chunk at once and
the current disassembler is not very slow.
On the benchmark using unstripped ELF files with mapping symbols + ISA
string "$xrv...", performance improvements are significant and easily
observable in the real world (150%-264% performance improvments).
Aside from optimization, this commit, along with "RISC-V: Reorganize
disassembler state initialization", makes state initialization clearer and
makes further changes easier.
Also, although not practical in the real world, this commit now allows
multi-XLEN object disassembling if the object file has mapping symbols
with ISA string and the machine is XLEN-neutral (e.g. objdump with
"-m riscv" option). It may help testing Binutils / GAS.
opcodes/ChangeLog:
* riscv-dis.c
(initial_default_arch): Special default architecture
string which is handled separately.
(riscv_subsets): Remove as it is replaced to a member of the
disassembler context.
(riscv_dis_arch_context_t): New type to manage RISC-V architecture
context for the disassembler. Two instance of this type is
defined in this file - "default" and "override".
(dis_arch_context_default): New. Architecture context inferred
from either an ELF attribute or initial_default_arch.
(dis_arch_context_override): New. Architecture context inferred
from mapping symbols with ISA string.
(dis_arch_context_current): New. A pointer to either
dis_arch_context_default or dis_arch_context_override.
(riscv_rps_dis): Add summary. Use initial values from
dis_arch_context_default.
(from_last_map_symbol): Make it file scope to decide whether we
should revert the architecture to the default in
riscv_get_map_state function.
(set_riscv_current_dis_arch_context): New function to update
riscv_rps_dis and dis_arch_context_current.
(set_riscv_dis_arch_context): New function to update the
architecture for the given context.
(free_riscv_dis_arch_context): New function to free memory.
(update_riscv_dis_xlen): Consider dis_arch_context_current->xlen
when guessing correct XLEN.
(is_arch_changed): New. Set to true if the architecture is
changed.
(init_riscv_dis_state_for_arch): New function to track whether
the architecture string is changed.
(init_riscv_dis_state_for_arch_and_options): Keep track of the
architecture string change and update XLEN if it has changed.
(update_riscv_dis_arch): New function to set both the architecture
and the context. Call initialization functions if needed.
(riscv_get_map_state): Add update argument. Keep track of the
mapping symbols with ISA string and update the architecture and
the context if required.
(riscv_search_mapping_symbol): Move from_last_map_symbol to
file scope. Call riscv_get_map_state function with architecture
and context updates enabled.
(riscv_data_length): Call riscv_get_map_state function with
architecture and context updates disabled.
(riscv_get_disassembler): Add an error handling on Tag_RISCV_arch.
Call update_riscv_dis_arch function to update the architecture
and the context.
(disassemble_free_riscv) Free disassembler context memory.
Co-developed-by: Nelson Chu <[email protected]>
0 commit comments