Luis Machado [Fri, 9 Oct 2020 16:50:17 +0000 (13:50 -0300)]
[Morello] Unwinding: Restore CLR and PCC properly
This patch teaches GDB how to handle restoring CLR and PCC values properly.
gdb/ChangeLog:
2020-10-20 Luis Machado <luis.machado@arm.com>
* aarch64-tdep.c (aarch64_prologue_prev_register): Use LR or CLR
depending on the request.
(aarch64_dwarf_reg_to_regnum): Redirect CLR to LR temporarily.
* aarch64-tdep.h (AARCH64_DWARF_CLR): New constant.
Luis Machado [Wed, 9 Sep 2020 16:09:47 +0000 (13:09 -0300)]
[Morello] Enable DWARF unwinding with C registers
Adjust unwinding functions to cope with the presence of C registers.
gdb/ChangeLog:
2020-10-20 Luis Machado <luis.machado@arm.com>
* aarch64-tdep.c (aarch64_prologue_prev_register): Handle the PCC and
CSP registers. Remove the LSB.
(aarch64_dwarf2_prev_register): Handle CSP, PCC and remove the LSB
from CLR.
(aarch64_dwarf2_frame_init_reg): Handle PCC and CSP.
(aarch64_dwarf_reg_to_regnum): Handle C registers.
Luis Machado [Thu, 1 Oct 2020 18:59:23 +0000 (15:59 -0300)]
[Morello] Record mapping symbols and mark C64 function symbols as special
This patch teaches GDB about AArch64 mapping symbols and special minimal
symbols.
FIXME-Morello: This is currently not actively used, but will be used to detect
capability mode functions later.
gdb/ChangeLog:
2020-10-20 Luis Machado <luis.machado@arm.com>
* aarch64-tdep.c: Include elf-bfd.h.
(MSYMBOL_SET_SPECIAL, MSYMBOL_IS_SPECIAL): New constants.
(aarch64_mapping_symbol): New struct.
(aarch64_mapping_symbol_vec): New typedef.
(aarch64_per_bfd): New struct.
(aarch64_bfd_data_key): New static global.
(aarch64_elf_make_msymbol_special, +aarch64_record_special_symbol): New
function.
(aarch64_gdbarch_init): Register hooks.
Luis Machado [Mon, 28 Sep 2020 19:32:03 +0000 (16:32 -0300)]
[Morello] Disable displaced stepping for Morello
Morello can't support displaced stepping at the moment given it has no API
to write capabilities, which is needed when GDB needs to adjust the X and C
registers during a displaced stepping operation.
gdb/ChangeLog:
2020-10-20 Luis Machado <luis.machado@arm.com>
* aarch64-linux-tdep.c (aarch64_linux_init_abi): Only set displaced
stepping hooks for non-Morello targets.
Luis Machado [Thu, 24 Sep 2020 18:09:24 +0000 (15:09 -0300)]
[Morello] Add support for Morello sigreturn/sigcontext frame
This patch teaches GDB how to interpret the Morello sigcontext
structure in a sigreturn frame and allows GDB to read back the
correct values of the registers.
gdb/ChangeLog:
2020-10-20 Luis Machado <luis.machado@arm.com>
* aarch64-linux-tdep.c: Include arch/aarch64-insn.h.
(AARCH64_MORELLO_MAGIC, AARCH64_MORELLO_SIGCONTEXT_SIZE)
(AARCH64_MORELLO_SIGCONTEXT_C0_OFFSET): New constants.
(aarch64_linux_sigframe_init): Update to handle Morello
sigreturn/sigcontext frames.
Luis Machado [Thu, 3 Sep 2020 17:20:46 +0000 (14:20 -0300)]
[Morello] Add capability fault codes and report fault information
Report capability faults with additional information, like tag, bounds,
sealed permissions and access faults.
gdb/ChangeLog
2020-10-20 Luis Machado <luis.machado@arm.com>
* aarch64-linux-tdep.c: Include value.h.
(aarch64_linux_report_signal_info): New function.
(aarch64_linux_init_abi): Register hook for reporting signal
information.
* arch/aarch64-cap-linux.h (SEGV_CAPTAGERR, SEGV_CAPSEALEDERR)
(SEGV_CAPBOUNDSERR, SEGV_CAPPERMERR, SEGV_CAPSTORETAGERR): New
constants.
Luis Machado [Fri, 17 Jul 2020 20:40:44 +0000 (17:40 -0300)]
[Morello] Add set/show ABI command for AArch64
Add a new command for developers to set and show the AArch64 ABI GDB is
using at the moment.
We define 2 ABI's: AAPCS64 and AAPCS64-cap.
Each of these ABI's should impact the architecture setup in different ways.
gdb/ChangeLog:
2020-10-20 Luis Machado <luis.machado@arm.com>
* aarch64-tdep.c (set_aarch64_cmdlist, show_aarch64_cmdlist,
aarch64_abi_strings, aarch64_current_abi_global)
(aarch64_current_abi_string): New static globals.
(aarch64_update_current_architecture, aarch64_set_abi)
(aarch64_show_abi): New functions.
(aarch64_gdbarch_init): Handle ABI identification.
(_initialize_aarch64_tdep): Add new ABI commands.
* aarch64-tdep.h (aarch64_abi_kind): New enum.
(struct gdbarch_tdep) <abi>: New field.
Luis Machado [Thu, 2 Jul 2020 19:31:11 +0000 (16:31 -0300)]
[General] More capability type handling (merge with others)
Teach more parts of GDB how to handle capabilities properly, add a function
to print capabilities in their natural format and initialize capability types
properly.
gdb/ChangeLog:
2020-10-20 Luis Machado <luis.machado@arm.com>
* c-typeprint.c (c_type_print_varspec_prefix)
(c_type_print_varspec_suffix): Handle capability type.
* dwarf2/read.c (read_base_type): Call init_capability_type for
capabilities.
* gdbtypes.c (init_capability_type): New function.
(type_align): Handle capability type.
(recursive_dump_type): Likewise.
(arch_capability_type): New function.
(gdbtypes_post_init): Call arch_capability_type for capability
types.
* gdbtypes.h (init_capability_type, arch_capability_type): New
prototypes.
* valprint.c: Include gdbsupport/capability.h.
(generic_value_print_capability): New function.
(generic_value_print): Handle capability types.
Luis Machado [Thu, 5 Mar 2020 17:02:22 +0000 (14:02 -0300)]
[Morello] Add capability register set support
This patch adds capability register set support to both GDB and GDBserver,
allowing the use of ptrace.
gdb/ChangeLog
2020-10-20 Luis Machado <luis.machado@arm.com>
* aarch64-linux-nat.c: Include arch/aarch64-cap-linux.h.
(fetch_cregs_from_thread)
(store_cregs_to_thread): New functions.
(aarch64_linux_nat_target::fetch_registers): Modify to check for
capability registers.
* aarch64-linux-tdep.c: Include arch/aarch64-cap-linux.h.
* aarch64-tdep.c (aarch64_cannot_store_register): Check for capability
registers.
(aarch64_gdbarch_init): Also save the last capability register number.
* aarch64-tdep.h (struct gdbarch_tdep) <cap_reg_last>: New field.
* arch/aarch64-cap-linux.h (AARCH64_LINUX_CREGS_SIZE,
AARCH64_MORELLO_REGS_NUM, AARCH64_C_REGS_NUM): New constants.
* arch/aarch64.c: Remove FIXME comment.
* nat/aarch64-linux.h (user_morello_state): New struct.
Luis Machado [Thu, 26 Mar 2020 14:58:01 +0000 (11:58 -0300)]
[Morello] Generate target descriptions based on runtime capability feature checks
This patch adds code to do runtime checks for Morello, so GDB can pick the
correct target description and register set.
gdb/ChangeLog:
2020-10-20 Luis Machado <luis.machado@arm.com>
* aarch64-linux-nat.c (aarch64_linux_nat_target::read_description):
Check for HWCAP2_MORELLO.
* aarch64-linux-tdep.c (aarch64_linux_core_read_description): Likewise.
* aarch64-tdep.c (tdesc_aarch64_list): Add one more dimension.
(aarch64_read_description): New parameter capability_p, use it to
generate the proper target description.
(aarch64_gdbarch_init): Update invocation of aarch64_read_description.
* aarch64-tdep.h (aarch64_read_description): New parameter capability_p.
* arch/aarch64.c (aarch64_create_target_description): New parameter
capability_p. Use it.
* arch/aarch64.h (aarch64_create_target_description): New parameter
capability_p.
gdbserver/ChangeLog:
2020-10-20 Luis Machado <luis.machado@arm.com>
* linux-aarch64-ipa.cc (get_ipa_tdesc): Update.
* linux-aarch64-low.cc (aarch64_target::low_arch_setup): Check for
HWCAP2_MORELLO and use it.
* linux-aarch64-tdesc.cc (tdesc_aarch64_list): Add one more dimension.
(aarch64_linux_read_description): New parameter capability_p. Use it.
* linux-aarch64-tdesc.h (aarch64_linux_read_description): New parameter
capability_p.
Luis Machado [Thu, 12 Mar 2020 19:37:28 +0000 (16:37 -0300)]
[Morello] Add Morello target description XML and registers
This patch adds a Morello register description XML and code to detect and use
said registers.
gdb/ChangeLog
2020-10-20 Luis Machado <luis.machado@arm.com>
* aarch64-tdep.c (aarch64_c_register_names): New static array.
(aarch64_gdbarch_init): Check for capability
XML feature and add registers to the target.
* aarch64-tdep.h (struct gdbarch_tdep) <cap_reg_base>: New field.
<has_capability>: New method.
* arch/aarch64.c: Include features/aarch64-capability.c.
(aarch64_create_target_description): Invoke
create_feature_aarch64_capability.
* features/Makefile (FEATURE_XMLFILES): Add aarch64-capability.xml
* features/aarch64-capability.xml: New file.
* features/aarch64-capability.c: Generate.
Luis Machado [Wed, 1 Apr 2020 19:38:42 +0000 (16:38 -0300)]
[Morello] Initial capability data structure support + Unit testing
This patch adds capability data structures and related functions. These are
Morello-specific, so the encodings only make sense for this particular
Architecture. The capability is restricted to 128 bits, but could be expanded
to hold other variations while keeping the capability class structure.
Unit tests were also included to validate the decoding/encoding functions. The
output is matched against auto-generated values based on a reference
implementation.
gdb/ChangeLog:
2020-10-20 Luis Machado <luis.machado@arm.com>
* gdb/aarch64-tdep.c: Include gdbsupport/capability.h.
(aarch64_capability_decoding_test): New function.
(_initialize_aarch64_tdep): Register capability tests.
gdbsupport/ChangeLog:
2020-10-20 Luis Machado <luis.machado@arm.com>
* gdbsupport/Makefile.am: Regenerate.
* gdbsupport/Makefile.in: Adjust to include gdbsupport/capability.*.
* gdbsupport/capability.cc: New file.
* gdbsupport/capability.h: New file.
This change adds basic support for TLS descriptors. Relaxation of
TLSDESC_GD to other relocations is limited to TLS_LE, other cases end
up retaining TLSDESC_GD.
There is one key difference from A64 for TLSDESC_GD -> LE transition
and that is in the case of static non-pie binaries. Morello
TLSDESC_GD relocations are relaxed to LE for static non-pie binaries
since it ought to be safe to do so and it aligns with llvm behaviour.
* testsuite/ld-aarch64/morello-tlsdesc.s: New file.
* testsuite/ld-aarch64/morello-tlsdesc.d: New test.
* testsuite/ld-aarch64/morello-tlsdesc-static.d: New test.
* testsuite/ld-aarch64/morello-tlsdesc-staticpie.d: New test.
* testsuite/ld-aarch64/aarch64-elf.exp: Add them.
[Morello] Pad section alignment to account for capability range format
The capability format has limitations on the alignment and length of
capability bounds and are subject to rounding. Add alignment and
padding at the boundaries of such long (typically >16M) sections so
that any capabilities referencing these sections do not end up
overlapping into neighbouring sections.
There are two cases where this is in use. The first and most
important due to the current implementation is the range for PCC,
which needs to span all executable sections and all PLT and GOT
sections. The other case is for linker and ldscript defined symbols
that may be used in dynamic relocations.
* emultempl/aarch64elf.em (elf64_c64_pad_section): New
function.
(gld${EMULATION_NAME}_after_allocation): Resize C64 sections.
* ldlang.c (lang_add_newdot): New function.
* ldlang.h (lang_add_newdot): New function declaration.
* testsuite/ld-aarch64/aarch64-elf.exp: Add new test.
* testsuite/ld-aarch64/morello-sec-round.d: New file.
* testsuite/ld-aarch64/morello-sec-round.ld: New file.
* testsuite/ld-aarch64/morello-sec-round.s: New file.
[Morello] Capability support for exception headers
- Identify and mark C64 frames
- Identify C64 registers including DDC.
- Identify 'purecap' argument to .cfi_startproc for C64 frames
- Emit 'C' in augmentation string for C64 frames
- Recognise the 'C' in the CIE augmentation string when parsing
exception headers
Difference from LLVM: The llvm assembler only uses purecap to add C to
the augmentation string. The GNU assembler on the other hand uses
-march and validates that purecap is passed to .cfi_startproc only for
-morello+c64. This means that for code compiled for A64, if llvm sees
`.cfi_startproc purecap`, it sets 'C' whereas the GNU assembler flags
an error.
* elf-bfd.h (elf_backend_data): New callback
elf_backend_eh_frame_augmentation_char.
* elf-eh-frame.c (_bfd_elf_parse_eh_frame): Use it.
* elfnn-aarch64.c (elf64_aarch64_eh_frame_augmentation_char):
New function.
(elf_backend_eh_frame_augmentation_char): New macro.
* elfxx-target.h [!elf_backend_eh_frame_augmentation_char]:
Set elf_backend_eh_frame_augmentation_char to NULL.
(elfNN_bed): Initialise
elf_backend_eh_frame_augmentation_char.
* config/tc-aarch64.c (REG_DW_CSP, REG_DW_CLR): New macros.
(s_aarch64_cfi_b_key_frame): Adjust for new entry_extras
struct.
(tc_aarch64_frame_initial_instructions): Adjust for C64.
(tc_aarch64_fde_entry_init_extra,
tc_aarch64_cfi_startproc_exp): New functions.
(tc_aarch64_regname_to_dw2regnum): Support capability
registers.
* config/tc-aarch64.h (fde_entry): Forward declaration.
(eh_entry_extras): New struct.
(tc_fde_entry_extras, tc_cie_entry_extras): Use it.
(tc_fde_entry_init_extra): Set to
tc_aarch64_fde_entry_init_extra.
(tc_output_cie_extra): Emit 'C' for C64.
(tc_cie_fde_equivalent_extra): Adjust for C64.
(tc_cie_entry_init_extra): Likewise.
(tc_cfi_startproc_exp): New macro.
(tc_aarch64_cfi_startproc_exp,
tc_aarch64_fde_entry_init_extra): New function declarations.
* dw2gencfi.c (tc_cfi_startproc_exp): New macro.
(dot_cfi_startproc): Use it.
* testsuite/gas/aarch64/morello-eh.d: New test.
* testsuite/gas/aarch64/morello-eh.s: New test.
[Morello] Add interworking and range extension veneers
Add veneers to branch from A64 to C64 and vice versa and for range
extension from C64 to C64. The veneers are named as
__foo_a64c64_veneer, __foo_c64a64_veneer or simply __foo_veneer
(where foo is the target function) based on whether the branch is from
A64 to C64, the other way around or for extended range.
A64 to C64 needs an additional BX since the ADRP in the veneer does
not generate a valid capability without the switch using BX. As a
result, the addendum LSB is no longer important for A64 -> C64 switch,
but we keep it anyway so that we can use the same veneer for long
range C64 to C64 branches.
* elfnn-aarch64.c (STUB_ENTRY_NAME): Add format specifier for
veneer type.
(C64_MAX_ADRP_IMM, C64_MIN_ADRP_IMM): New macros.
(aarch64_branch_reloc_p, c64_valid_for_adrp_p,
aarch64_interwork_stub): New functions.
(aarch64_c64_branch_stub, c64_aarch64_branch_stub): New stubs.
(elf_aarch64_stub_type): New members.
(aarch64_type_of_stub): Support C64 stubs.
(aarch64_lookup_stub_type_suffix): New function.
(elfNN_aarch64_stub_name): Use it.
(elfNN_aarch64_get_stub_entry): Add stub_type argument.
Adjust callers. Support C64 stubs.
(aarch64_build_one_stub): Likewise.
(aarch64_size_one_stub): Likewise.
(elfNN_aarch64_size_stubs): Likewise.
(elfNN_aarch64_build_stubs): Save and return error if stub
building failed.
(elfNN_aarch64_final_link_relocate): Emit stubs based on
whether source and target of a branch are different.
(aarch64_map_one_stub): Emit mapping symbol for C64 stubs.
* testsuite/ld-aarch64/aarch64-elf.exp: Add test.
* testsuite/ld-aarch64/morello-stubs-static.d: New file.
* testsuite/ld-aarch64/morello-stubs.d: New file.
* testsuite/ld-aarch64/morello-stubs.ld: New file.
* testsuite/ld-aarch64/morello-stubs.s: New file.
The jump targets have limited range (i.e. limited by ADRP range) and
hence cannot be used for very long jumps. The linker will throw an
error for such out of range jumps.
- The linker selects morello PLT stubs when it finds at least one
static relocation that needs a capability GOT slot.
- It is assumed that C64 is not compatible with BTI/PAC, so the latter
gets overridden. To allow this, the call to setup_plt_values is
delayed to take into account htab->c64_plt.
- If the caller is A64, the assembler emits R_AARCH64_JUMP_SLOT,
otherwise it emits R_MORELLO_JUMP_SLOT.
- The PLT stub is A64-compatible, in that it should do the right thing
when the execution state is A64.
- If the slots are 16-bytes (this happens when there is at least one
Morello relocation on the GOT), the references in .plt.got and in
.got are always capabilities; the dynamic linker will take care of
that. For PLT, the default trampoline is a capability. This is
true for A64 as well as C64.
- At present it is assumed that there is no interworking between A64
and C64 functions.
* elfnn-aarch64.c (elfNN_c64_small_plt0_entry,
elfNN_c64_small_plt_entry): New variables.
(elfNN_aarch64_howto_table): Add relocations.
(setup_plt_values): Choose C64 PLT when appropriate.
(bfd_elfNN_aarch64_set_options): Defer setup_plt_values
call...
(elfNN_aarch64_link_setup_gnu_properties) ... from here as
well...
(elfNN_aarch64_size_dynamic_sections): ... to here.
(elfNN_aarch64_final_link_relocate,
elfNN_aarch64_check_relocs, elfNN_aarch64_reloc_type_class):
Support new relocations.
(map_symbol_type): New member AARCH64_MAP_C64.
(elfNN_aarch64_output_arch_local_syms): Use it.
(aarch64_update_c64_plt_entry): New function.
(elfNN_aarch64_create_small_pltn_entry): Use it.
(elfNN_aarch64_init_small_plt0_entry): Emit C64 PLT when
appropriate.
* elfxx-aarch64.c (_bfd_aarch64_elf_put_addend,
_bfd_aarch64_elf_resolve_relocation): Add new relocations.
* libbfd.h (bfd_reloc_code_real_names): Likewise.
* reloc.c: New relocations BFD_RELOC_MORELLO_TSTBR14,
BFD_RELOC_MORELLO_BRANCH19, BFD_RELOC_MORELLO_JUMP26,
BFD_RELOC_MORELLO_CALL26, BFD_RELOC_MORELLO_JUMP_SLOT and
BFD_RELOC_MORELLO_IRELATIVE.
* bfd-in2.h: Regenerate.
* testsuite/ld-aarch64/aarch64-elf.exp: Add new tests.
* testsuite/ld-aarch64/c64-ifunc-2-local.d: New file.
* testsuite/ld-aarch64/c64-ifunc-2.d: New file.
* testsuite/ld-aarch64/c64-ifunc-3a.d: New file.
* testsuite/ld-aarch64/c64-ifunc-3b.d: New file.
* testsuite/ld-aarch64/c64-ifunc-4.d: New file.
* testsuite/ld-aarch64/c64-ifunc-4a.d: New file.
* testsuite/ld-aarch64/ifunc-2-local.s: Support capabilities.
* testsuite/ld-aarch64/ifunc-2.s: Likewise.
[Morello] Add symbol markers for reloc section for static binaries
Add symbols __cap_dynrelocs_start and __cap_dynrelocs_end to mark the
start and end of the .rela.dyn section when building a static
executable without PIE. This allows the runtime startup to traverse
the section and initialise capabilities without having to read the ELF
headers.
All relocations must be of type R_C64_RELATIVE and have the following
properties:
- Frag contains the base of the capability to be initialised
- Frag + 8 has the size and permissions encoded into 56 and 8 bits
respectively
- Addend is the offset from the capability base
- Implement R_MORELLO_LD128_GOT_LO12_NC and emit the correct
relocation based on the target register size.
- Add R_MORELLO_GLOB_DAT and R_MORELLO_RELATIVE dynamic relocations for GOT
entries
- Add support for capabilities in GOT
GOT slots for capabilities need to be 16 byte to accommodate
capabilities. For this purpose, we delay initialising size and
alignment of the GOT sections until we have walked all relocs in
check_relocs. If we encounter capability relocations during the walk,
set the GOT entry size and alignment to account for capabilities or
leave it pointer sized otherwise.
* elfnn-aarch64.c (GOT_ENTRY_SIZE): Adjust for C64
relocations. Adjust callers.
(GOT_RESERVED_HEADER_SLOTS, GOT_CAP): New macros.
(elfNN_aarch64_howto_table): Add R_MORELLO_LD128_GOT_LO12_NC
and R_MORELLO_GLOB_DAT.
(elf_aarch64_link_hash_table): New member c64_rel.
(bfd_elfNN_aarch64_set_options): Initialise it.
(cap_meta, c64_get_capsize): New functions.
(aarch64_reloc_got_type): Use GOT_CAP.
(elfNN_aarch64_final_link_relocate): Add
R_MORELLO_LD128_GOT_LO12_NC and R_MORELLO_GLOB_DAT.
(aarch64_elf_create_got_section): Move section initialisation
into a...
(aarch64_elf_init_got_section): ... New function.
(elfNN_aarch64_size_dynamic_sections): Call it.
(elfNN_aarch64_check_relocs): Add R_MORELLO_LD128_GOT_LO12_NC
and R_MORELLO_GLOB_DAT.
(elfNN_aarch64_finish_dynamic_symbol): Emit C64 relocations
when appropriate.
(elfNN_aarch64_got_elt_size): New function.
(elfNN_aarch64_got_header_size): Return GOT entry size based
on c64_rel.
(elf_backend_got_elt_size): New macro.
* elfxx-aarch64.c (_bfd_aarch64_elf_put_addend,
_bfd_aarch64_elf_resolve_relocation): Add
BFD_RELOC_MORELLO_LD128_GOT_LO12_NC.
* libbfd.h (bfd_reloc_code_real_names): Add
BFD_RELOC_MORELLO_GLOB_DAT and
BFD_RELOC_MORELLO_LD128_GOT_LO12_NC.
* reloc.c: Likewise.
* bfd-in2.h: Regenerate.
* testsuite/ld-aarch64/emit-relocs-morello-1.d: New file.
* testsuite/ld-aarch64/emit-relocs-morello-1.s: New test file.
* testsuite/ld-aarch64/aarch64-elf.exp: Add it to test runner.
Expand GOT slots based on whether we are emitting C64 relocations.
This patch only has infrastructure changes, i.e. it only makes
got_header_size a function and adjusts across architectures.
bfd/ChangeLog:
2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
Tamar Christina <tamar.christina@arm.com>
* elf-bfd.h (elf_backend_data): Make got_header_size a
function. Add callbacks to all targets that use it.
* elflink.c (_bfd_elf_create_got_section,
bfd_elf_gc_common_finalize_got_offsets,
_bfd_elf_common_section): Adjust got_header_size usage.
* config/tc-aarch64.c (ldst_lo12_determine_real_reloc_type):
Support alternate base loads and stores.
(parse_operands): Support relocations for alternate base
address operands.
* testsuite/gas/aarch64/morello-ldst-reloc.d: New file.
* testsuite/gas/aarch64/morello-ldst-reloc.s: New file.
Introduce three new relocations disguised as two relocations to
support capabilities.
R_MORELLO_CAPINIT is emitted as a static relocation by the assembler
and as a dynamic relocation by the linker; it's a one on one free!
The R_MORELLO_CAPINIT static relocation is emitted by the assembler to
provide capability information to the static linker. The static
linker may do one of two things:
- For local symbols that can be resolved at link time, the static
linker sets up frag and emits a R_MORELLO_RELATIVE dynamic
relocation that the dynamic linker can resolve in a manner similar
to R_AARCH64_RELATIVE. The dynamic linker will have all of the
information it needs (i.e. permissions, size and relative address)
to set up the capability without needing to peek into the symbol
table.
- For dynamic symbols, the static linker emits a R_MORELLO_CAPINIT
with the reference of the dynamic symbol it refers to. The dynamic
linker is then responsible for resolving the symbol at runtime and
setting up the capability based on the properties of the symbol it
is able to deduce.
Linker and Linker script defined symbols
----------------------------------------
For symbols defined by the linker or in linker scripts, capability
size and permissions are based on the section the symbol belongs to.
For linker defined symbols (i.e. _DYNAMIC or _GLOBAL_OFFSET_TABLE_)
this is straightforward since the linker puts them in the correct
section and at the start.
For symbols defined in the linker script, if they are anywhere but the
end of the output script definition, their range becomes the point at
which they are defined, up to the end of the output section. For
symbols defined at the end of the output section, the symbols are
defined with a zero size unless their name is of the form __start_.*
or __.*_start, indicating a start of the section that follows it. In
this case, the symbols are given the range and permission of the
output section following it.
Ideally, the last case (i.e. the heuristic looking for the name)
should be strictly for compatibility and should eventually be fixed in
the linker script to put the symbol into the output section it intends
to track. It may be a useful enhancement to add a warning to that
effect.
* config/tc-aarch64.c (s_aarch64_capinit): New function.
(md_pseudo_table): Use it.
(md_apply_fix): Add BFD_RELOC_MORELLO_CAPINIT.
(aarch64_fix_adjustable): Return FALSE for capabilities.
* testsuite/gas/aarch64/morello-capinit.d: New test file.
* testsuite/gas/aarch64/morello-capinit.s: Likewise.
The opcodes for these instructions overlap with their A64 equivalents;
in fact they're the same with one bit reduced in the immediate. Use
mapping symbols to determine the correct disassembly.
* aarch64-asm.c (aarch64_ins_addr_uimm): Shift only if
F_NOSHIFT is not set.
* aarch64-tbl.h (QL2_B_ADDR, QL2_X_ADDR, QL2_H_ADDR): New
macro.
(aarch64_opcode_table): New instructions.
* aarch64-asm-2.c: Regenerate.
* aarch64-dis-2.c: Regenerate.
* aarch64-opc-2.c: Regenerate.
The 17-bit signed offset needs to be 16-byte aligned, but the
PCC-relative address resolution rounds down the final address to the
16-byte boundary. Due to this, disassembly of the instruction will
show as if it is loading from the middle of an object.
This branch instructions take an address as their target operand. The
important distinction between the address register usage between these
instructions and other load and store instructions is that these
instructions do not support 64-bit registers as addresses.
* config/aarch64.h (aarch64_operand_class): Add FORM.
(aarch64_opnd): Likewise.
(aarch64_form): New struct.
(aarch64_forms): New array.
(get_form_from_value, get_form_from_str): New functions.
(aarch64_opnd_info): New member FORM.
Disassembly note: RET with capability is always disassembled with the
register name even if it is the default register, i.e. C30. This is
to make it visually simpler to differentiate between the A64 and
Morello RET instructions.
* aarch64-dis.c (aarch64_ext_a64c_immv): New function.
(aarch64_ext_regno): Set PRESENT flag for A64 RET.
* aarch64-dis.h (aarch64_ext_a64c_immv): New function.
* aarch64-opc.c (operand_general_constraint_met_p): Add
A64C_IMMV4. Remove ATTRIBUTE_UNUSED. Reject A64 RET without
operand when in C64.
(aarch64_match_operands_constraint): Remove ATTRIBUTE_UNUSED.
(aarch64_print_operand): Add A64C_IMMV4, Cam_SP and CST_REG.
* aarch64-tbl.h (QL1_A64C_CA, QL3_A64C_CA_CA_CA): New macros.
(aarch64_opcode_table): New instructions.
(AARCH64_OPERANDS): New operands.
* aarch64-asm-2.c: Regenerate.
* aarch64-dis-2.c: Regenerate.
* aarch64-opc-2.c: Regenerate.
[Morello] Add MOV and CPY instructions for capabilities
MOV is an alias of CPY in all cases except when moving CZR into a
capability register (e.g. mov c0, czr), in which case it is treated
as an alias of mov x0, xzr.
[Morello] Identify branch source and target using mapping symbols
Initialise section map data so that it can be used to identify C64
branch targets. This is a reliable way (as long as mapping symbols
are correctly placed!) to identify branch source and target types in
cases where the target type is not STT_FUNC. STT_FUNC targets can
already be identified using the LSB in the symbol table.
Use cases where the branch relocations are used (such as
elfNN_aarch64_size_stubs) have been adjusted to use the symbol cache
instead of reading the symbol table all over again. In addition to
being faster, it will also allow identification of the relocation
targets using the st_target_internal set earlier by check_relocs.
* elf-bfd.h (bfd_elf_section_data): New member
is_target_section_data.
* elfnn-aarch64.c (_aarch64_elf_section_data): New member
sorted.
(elf_aarch64_section_data_get, c64_value_p): New functions.
(elf_aarch64_compare_mapping): Move function up in the file.
(elf_aarch64_obj_tdata): New member secmaps_initialised.
(bfd_elfNN_aarch64_init_maps, bfd_elfNN_aarch64_set_options):
Use it.
(elfNN_aarch64_size_stubs): Use symbol cache.
(elfNN_aarch64_check_relocs): Call
bfd_elfNN_aarch64_init_maps. Mark C64 symbols in relocations
in the symbol cache.
* config/tc-aarch64.c (FIXUP_F_C64): New macro.
(output_inst, parse_operands): Use it.
(aarch64_force_relocation, aarch64_fix_adjustable): Defer
relocation of branches with different source and targets to
the linker.
* config/tc-aarch64.h (aarch64_fix): New member c64.
* elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Set LSB for C64 symbols.
(elfNN_aarch64_output_map_sym, elfNN_aarch64_output_stub_sym):
Initialise st_target_internal.
(aarch64_elfNN_swap_symbol_in, aarch64_elfNN_swap_symbol_out):
New functions.
(elfNN_aarch64_size_info): Add them as callbacks.
* config/tc-aarch64.c: Include cpu-aarch64.h.
(IS_C64): New macro.
(make_mapping_symbol, aarch64_frob_label): Set LSB of C64
symbol.
(aarch64_adjust_symtab): Mark all C64 functions.
(parse_operands): Set LSB when target of ADR is a function.
(aarch64_fix_adjustable): New function.
* config/tc-aarch64.h (AARCH64_SET_FLAG, AARCH64_RESET_FLAG,
AARCH64_FLAG_C64, AARCH64_IS_C64, AARCH64_SET_C64): New
macros.
(aarch64_fix_adjustable): New function.
(tc_fix_adjustable): Use it.
[Morello] Add mapping symbol to identify C64 code sections
Add a mapping symbol $c at the beginning of every C64 code section to
allow the disassembler to identify C64 code sections. This will allow
the disassembler to print the correct base address registers and also
choose the correct disassembly in cases where the opcodes for A64 and
C64 instructions are aliased.
To aid correct disassembly of instructions, pass CPU variant to
various helpers in libopcodes so that they can use that information to
choose between A64 and C64 disassembly.
The Morello architecture implements support for 129 bit capabilities
to replace traditional pointers to reference memory. A 129 bit
capability has a 64-bit virtual address in its lowest bits and the
next 64 bits have various access control metadata such as bounds
within which the virtual address can be, permissions and other
metadata for protection. The top 129th bit is stored out of band and
it indicates if the capability is valid.
Capability registers extends the 64-bit register file and are
similarly numberd c0 to c30. The stack capability register is csp and
it aliases with sp. One may access the lower 64 bits of the
capability registers by using the 64-bit register names, i.e. x0-x30
and sp. The Arm Architecture Reference Manual Supplement Morello for
A-profile Architecture has more details on the register layout.
To ensure backward compatibiility, processors implementing the Morello
architecture can run in two states, the standard A64 and a new state
called C64. In A64 state, base addresses of memory access
instructions are treated as pointers and traditional aarch64
applications should run out of the box in this state. In C64 state,
base address registers are expected to be valid capabilities.
There are additional load and store instructions that allow using
capabilities as address registers in A64 mode (and 64-bit registers in
C64 mode). These are called alternate base loads and stores.
The following new -march flags are implemented:
- a64c: This is the base feature flag to implement instruction
extensions for Morello that are distinct from its base A64 support.
Address registers are assumed to be 64-bit except for alternate base
loads and stores; they are assumed to be capability registers.
- morello: This enables instructions that are allowed on the Morello
architecture in A64. This includes armv8.2-a, a64c and other
extensions that are considered part of the Morello architecture.
- c64: This enables instructions that are allowed on the Morello
architecture in C64 state. Address registers are assumed to be
capabilities except for alternate base loads and stores; they are
assumed to be 64-bit registers.
To assemble code that is intended to run in A64 state on Morello,
build with -march=morello and for C64 state, build with
-march=morello+c64.
This patch implements bare support for registers and the -march flags.
[AArch64] Prefer error messages from opcodes enabled in CPU_VARIANT
Printing error messages from opcodes that would otherwise not be used
due to not being enabled is pointless when there are other
alternatives. Prefer error messages from enabled opcodes instead.
A more ideal fix would to sort error messages earlier when deciding
which KIND to return. That is, other fatal errors of a less serious
KIND from an enabled opcode should get priority over a more serious
KIND of a disabled opcode.
Added a new argument to find_memory_region_ftype, but did not pass it to
the function in gnu-nat.c. Fix this by passing memory_tagged as false.
As Luis pointed out, similar bugs may also appear on FreeBSD and NetBSD,
and I have reproduced them on both systems. This patch fixes them
incidentally.
Tested by rebuilding on GNU/Hurd, FreeBSD/amd64 and NetBSD/amd64.
Luis Machado [Thu, 31 Mar 2022 10:42:35 +0000 (11:42 +0100)]
[AArch64] MTE corefile support
Teach GDB how to dump memory tags for AArch64 when using the gcore command
and how to read memory tag data back from a core file generated by GDB
(via gcore) or by the Linux kernel.
The format is documented in the Linux Kernel documentation [1].
Each tagged memory range (listed in /proc/<pid>/smaps) gets dumped to its
own PT_AARCH64_MEMTAG_MTE segment. A section named ".memtag" is created for each
of those segments when reading the core file back.
To save a little bit of space, given MTE tags only take 4 bits, the memory tags
are stored packed as 2 tags per byte.
When reading the data back, the tags are unpacked.
I've added a new testcase to exercise the feature.
Build-tested with --enable-targets=all and regression tested on aarch64-linux
Ubuntu 20.04.
Luis Machado [Tue, 28 Jun 2022 11:57:34 +0000 (12:57 +0100)]
[AArch64] Support AArch64 MTE memory tag dumps in core files
The Linux kernel can dump memory tag segments to a core file, one segment
per mapped range. The format and documentation can be found in the Linux
kernel tree [1].
The following patch adjusts bfd and binutils so they can handle this new
segment type and display it accordingly. It also adds code required so GDB
can properly read/dump core file data containing memory tags.
Upon reading, each segment that contains memory tags gets mapped to a
section named "memtag". These sections will be used by GDB to lookup the tag
data. There can be multiple such sections with the same name, and they are not
numbered to simplify GDB's handling and lookup.
There is another patch for GDB that enables both reading
and dumping of memory tag segments.
John Baldwin [Tue, 2 Aug 2022 21:54:28 +0000 (14:54 -0700)]
fbsd-nat: Correct the return type of the have_regset method.
During the development of 40c23d880386d6e8202567eaa2a6b041feb1a652,
the return value of fbsd_nat_target::have_regset was changed from a
simple boolean to returning the size of the register set. The
comments and callers were all updated for this change, but the actual
return type was accidentally left as a bool. This change fixes the
return type to be a size_t.
Current callers of this only checked the value against 0 and thus
still worked correctly.
John Baldwin [Mon, 23 May 2022 18:02:55 +0000 (11:02 -0700)]
Tweak the std::hash<> specialization for aarch64_features.
Move the specialization into an explicit std namespace to workaround a
bug in older compilers. GCC 6.4.1 at least fails to compile the previous
version with the following error:
gdb/arch/aarch64.h:48:13: error: specialization of 'template<class _Tp> struct std::hash' in different namespace [-fpermissive]
John Baldwin [Wed, 18 May 2022 20:32:04 +0000 (13:32 -0700)]
Use aarch64_features to describe register features in target descriptions.
Replace the sve bool member of aarch64_features with a vq member that
holds the vector quotient. It is zero if SVE is not present.
Add std::hash<> specialization and operator== so that aarch64_features
can be used as a key with std::unordered_map<>.
Change the various functions that create or lookup aarch64 target
descriptions to accept a const aarch64_features object rather than a
growing number of arguments.
Replace the multi-dimension tdesc_aarch64_list arrays used to cache
target descriptions with unordered_maps indexed by aarch64_feature.
John Baldwin [Tue, 3 May 2022 23:05:10 +0000 (16:05 -0700)]
fbsd-nat: Add helper routines for register sets using PT_[G]SETREGSET.
FreeBSD's kernel has recently added PT_GETREGSET and PT_SETREGSET
operations to fetch a register set named by an ELF note type. These
helper routines provide helpers to check for a register set's
existence, fetch registers for a register set, and store registers to
a register set.
John Baldwin [Fri, 1 Apr 2022 20:16:46 +0000 (13:16 -0700)]
Use I386_GSBASE_REGNUM in i386fbsd_get_thread_local_address.
32-bit x86 arches always the I386_*BASE_REGNUM values. Only code that
needs to support both 64-bit and 32-bit arches needs to use
tdep->fsbase_regnum to compute a segment base register number.
John Baldwin [Fri, 1 Apr 2022 20:16:46 +0000 (13:16 -0700)]
FreeBSD/x86: Read segment base registers from NT_X86_SEGBASES.
FreeBSD kernels recently grew a new register core dump note containing
the base addresses of the %fs and %gs segments (corresponding to the
%fsbase and %gsbase registers). Parse this note to permit inspecting
TLS variables in core dumps. Native processes already supported TLS
via older ptrace() operations.
John Baldwin [Fri, 1 Apr 2022 20:16:46 +0000 (13:16 -0700)]
Recognize FreeBSD core dump note for x86 segment base registers.
This core dump note contains the value of the base address of the %fs
and %gs segments for both i386 and amd64 core dumps. It is primarily
useful in resolving the address of TLS variables in core dumps.
John Baldwin [Tue, 22 Mar 2022 19:05:43 +0000 (12:05 -0700)]
Add support for hardware breakpoints/watchpoints on FreeBSD/Aarch64.
This shares aarch64-nat.c and nat/aarch64-hw-point.c with the Linux
native target. Since FreeBSD writes all of the debug registers in one
ptrace op, use an unordered_set<> to track the "dirty" state for
threads rather than bitmasks of modified registers.
John Baldwin [Tue, 22 Mar 2022 19:05:43 +0000 (12:05 -0700)]
fbsd-nat: Add a low_delete_thread virtual method.
This method can be overridden by architecture-specific targets to
perform additional work when a thread is deleted.
Note that this method is only invoked on systems supporting LWP
events, but the pending use case (aarch64 debug registers) is not
supported on older kernels that do not support LWP events.
John Baldwin [Tue, 22 Mar 2022 19:05:43 +0000 (12:05 -0700)]
aarch64: Add an aarch64_nat_target mixin class.
This class includes platform-independent target methods for hardware
breakpoints and watchpoints using routines from
nat/aarch64-hw-point.c.
stopped_data_address is not platform-independent since the FAR
register holding the address for a breakpoint hit must be fetched in a
platform-specific manner. However, aarch64_stopped_data_address is
provided as a helper routine which performs platform-independent
validation given the value of the FAR register.
For tracking the per-process debug register mirror state, use an
unordered_map indexed by pid as recently adopted in x86-nat.c rather
than a manual linked-list.
John Baldwin [Tue, 22 Mar 2022 19:05:43 +0000 (12:05 -0700)]
nat: Split out platform-independent aarch64 debug register support.
Move non-Linux-specific support for hardware break/watchpoints from
nat/aarch64-linux-hw-point.c to nat/aarch64-hw-point.c. Changes
beyond a simple split of the code are:
- aarch64_linux_region_ok_for_watchpoint and
aarch64_linux_any_set_debug_regs_state renamed to drop linux_ as
they are not platform specific.
- Platforms must implement the aarch64_notify_debug_reg_change
function which is invoked from the platform-independent code when a
debug register changes for a given debug register state. This does
not use the indirection of a 'low' structure as is done for x86.
- The handling for kernel_supports_any_contiguous_range is not
pristine. For non-Linux it is simply defined to true. Some uses of
this could perhaps be implemented as new 'low' routines for the
various places that check it instead?
- Pass down ptid into aarch64_handle_breakpoint and
aarch64_handle_watchpoint rather than using current_lwp_ptid which
is only defined on Linux. In addition, pass the ptid on to
aarch64_notify_debug_reg_change instead of the unused state
argument.