diff options
-rw-r--r-- | bfd/elf64-mips.c | 4 | ||||
-rw-r--r-- | bfd/elf64-x86-64.c | 31 | ||||
-rw-r--r-- | bfd/elfn32-mips.c | 4 | ||||
-rw-r--r-- | bfd/version.h | 2 | ||||
-rw-r--r-- | gdb/NEWS | 2 | ||||
-rw-r--r-- | gdb/alpha-tdep.c | 87 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 42 | ||||
-rw-r--r-- | gdb/features/Makefile | 1 | ||||
-rw-r--r-- | gdb/features/alpha-core.xml | 136 | ||||
-rw-r--r-- | gdb/features/alpha.c | 111 | ||||
-rw-r--r-- | gdb/features/alpha.xml | 11 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp | 1 | ||||
-rw-r--r-- | gdb/testsuite/gdb.tui/esc-match.exp | 48 | ||||
-rw-r--r-- | gdb/testsuite/gdb.tui/esc-match.py | 26 | ||||
-rw-r--r-- | gdb/tui/tui-file.c | 6 | ||||
-rw-r--r-- | gdb/tui/tui-file.h | 11 | ||||
-rw-r--r-- | gdb/ui-file.c | 64 | ||||
-rw-r--r-- | gdb/ui-file.h | 46 | ||||
-rw-r--r-- | gdb/ui-style.c | 43 | ||||
-rw-r--r-- | gdb/ui-style.h | 26 | ||||
-rw-r--r-- | gdb/utils.c | 2 | ||||
-rw-r--r-- | libctf/ctf-create.c | 8 | ||||
-rw-r--r-- | libctf/doc/ctf-spec.texi | 11 | ||||
-rw-r--r-- | libctf/testsuite/libctf-writable/ctf-nonroot-addition.c | 38 | ||||
-rw-r--r-- | libctf/testsuite/libctf-writable/ctf-nonroot-addition.lk | 1 |
25 files changed, 668 insertions, 94 deletions
diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c index 8af7190..30923ef 100644 --- a/bfd/elf64-mips.c +++ b/bfd/elf64-mips.c @@ -1931,7 +1931,7 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] = false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - _bfd_mips_elf_got16_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS16_GOT16", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -2675,7 +2675,7 @@ static reloc_howto_type micromips_elf64_howto_table_rela[] = false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - _bfd_mips_elf_got16_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_GOT16", /* name */ false, /* partial_inplace */ 0, /* src_mask */ diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 6867d49..b9b3cf8 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -868,13 +868,6 @@ static const bfd_byte elf_x86_64_eh_frame_non_lazy_plt[] = DW_CFA_nop, DW_CFA_nop, DW_CFA_nop }; -static const sframe_frame_row_entry elf_x86_64_sframe_null_fre = -{ - 0, - {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */ - SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */ -}; - /* .sframe FRE covering the .plt section entry. */ static const sframe_frame_row_entry elf_x86_64_sframe_plt0_fre1 = { @@ -923,6 +916,14 @@ static const sframe_frame_row_entry elf_x86_64_sframe_sec_pltn_fre1 = SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */ }; +/* .sframe FRE covering the .plt.got section entry. */ +static const sframe_frame_row_entry elf_x86_64_sframe_pltgot_fre1 = +{ + 0, /* SFrame FRE start address. */ + {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */ + SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */ +}; + /* SFrame helper object for non-lazy PLT. */ static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_plt = { @@ -933,14 +934,14 @@ static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_plt = LAZY_PLT_ENTRY_SIZE, 1, /* Number of FREs for PLTn. */ /* Array of SFrame FREs for plt. */ - { &elf_x86_64_sframe_sec_pltn_fre1, &elf_x86_64_sframe_null_fre }, + { &elf_x86_64_sframe_sec_pltn_fre1 }, 0, 0, /* There is no second PLT necessary. */ - { &elf_x86_64_sframe_null_fre }, + { }, NON_LAZY_PLT_ENTRY_SIZE, 1, /* Number of FREs for PLT GOT. */ /* Array of SFrame FREs for PLT GOT. */ - { &elf_x86_64_sframe_null_fre }, + { &elf_x86_64_sframe_pltgot_fre1 }, }; /* SFrame helper object for non-lazy IBT enabled PLT. */ @@ -953,14 +954,14 @@ static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_ibt_plt = LAZY_PLT_ENTRY_SIZE, 1, /* Number of FREs for PLTn. */ /* Array of SFrame FREs for plt. */ - { &elf_x86_64_sframe_sec_pltn_fre1, &elf_x86_64_sframe_null_fre }, + { &elf_x86_64_sframe_sec_pltn_fre1 }, 0, 0, /* There is no second PLT necessary. */ - { &elf_x86_64_sframe_null_fre }, + { }, LAZY_PLT_ENTRY_SIZE, 1, /* Number of FREs for PLT GOT. */ /* Array of SFrame FREs for PLT GOT. */ - { &elf_x86_64_sframe_null_fre }, + { &elf_x86_64_sframe_pltgot_fre1 }, }; /* SFrame helper object for lazy PLT. */ @@ -981,7 +982,7 @@ static const struct elf_x86_sframe_plt elf_x86_64_sframe_plt = NON_LAZY_PLT_ENTRY_SIZE, 1, /* Number of FREs for PLT GOT. */ /* Array of SFrame FREs for PLT GOT. */ - { &elf_x86_64_sframe_null_fre }, + { &elf_x86_64_sframe_pltgot_fre1 }, }; /* SFrame helper object for lazy PLT with IBT. */ @@ -1002,7 +1003,7 @@ static const struct elf_x86_sframe_plt elf_x86_64_sframe_ibt_plt = LAZY_PLT_ENTRY_SIZE, 1, /* Number of FREs for PLT GOT. */ /* Array of SFrame FREs for PLT GOT. */ - { &elf_x86_64_sframe_null_fre }, + { &elf_x86_64_sframe_pltgot_fre1 }, }; /* These are the standard parameters. */ diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c index 25f989b..9df93e1 100644 --- a/bfd/elfn32-mips.c +++ b/bfd/elfn32-mips.c @@ -1911,7 +1911,7 @@ static reloc_howto_type elf_mips16_howto_table_rela[] = false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - _bfd_mips_elf_got16_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS16_GOT16", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -2655,7 +2655,7 @@ static reloc_howto_type elf_micromips_howto_table_rela[] = false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - _bfd_mips_elf_got16_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MICROMIPS_GOT16", /* name */ false, /* partial_inplace */ 0, /* src_mask */ diff --git a/bfd/version.h b/bfd/version.h index 9ae9431..a1f72c7 100644 --- a/bfd/version.h +++ b/bfd/version.h @@ -16,7 +16,7 @@ In releases, the date is not included in either version strings or sonames. */ -#define BFD_VERSION_DATE 20250630 +#define BFD_VERSION_DATE 20250703 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ #define REPORT_BUGS_TO @report_bugs_to@ @@ -236,6 +236,8 @@ vFile:stat debug information to be disabled at configure time. The flag to do that is --disable-gdb-mdebug-support. +* The Alpha target now supports target descriptions. + *** Changes in GDB 16 * Support for Nios II targets has been removed as this architecture diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index 92a6411..5e8a7a0 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -43,6 +43,9 @@ #include "alpha-tdep.h" #include <algorithm> +#include "target-descriptions.h" +#include "features/alpha.c" + /* Instruction decoding. The notations for registers, immediates and opcodes are the same as the one used in Compaq's Alpha architecture handbook. */ @@ -75,60 +78,38 @@ static const int subq_opcode = 0x10; static const int subq_function = 0x29; -/* Return the name of the REGNO register. +/* Alpha registers using their software names. An empty name corresponds to a register number that used to be used for a virtual register. That virtual register has been removed, but the index is still reserved to maintain compatibility with existing remote alpha targets. */ -static const char * -alpha_register_name (struct gdbarch *gdbarch, int regno) +static const char * const alpha_register_names[] = { - static const char * const register_names[] = - { - "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6", - "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp", - "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9", - "t10", "t11", "ra", "t12", "at", "gp", "sp", "zero", - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "fpcr", - "pc", "", "unique" - }; - - static_assert (ALPHA_NUM_REGS == ARRAY_SIZE (register_names)); - return register_names[regno]; -} + "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6", + "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp", + "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9", + "t10", "t11", "ra", "t12", "at", "gp", "sp", "zero", + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "fpcr", + "pc", "", "unique" +}; +static_assert (ALPHA_NUM_REGS == ARRAY_SIZE (alpha_register_names)); static int alpha_cannot_fetch_register (struct gdbarch *gdbarch, int regno) { - return (strlen (alpha_register_name (gdbarch, regno)) == 0); + return (strlen (alpha_register_names[regno]) == 0); } static int alpha_cannot_store_register (struct gdbarch *gdbarch, int regno) { return (regno == ALPHA_ZERO_REGNUM - || strlen (alpha_register_name (gdbarch, regno)) == 0); -} - -static struct type * -alpha_register_type (struct gdbarch *gdbarch, int regno) -{ - if (regno == ALPHA_SP_REGNUM || regno == ALPHA_GP_REGNUM) - return builtin_type (gdbarch)->builtin_data_ptr; - if (regno == ALPHA_PC_REGNUM) - return builtin_type (gdbarch)->builtin_func_ptr; - - /* Don't need to worry about little vs big endian until - some jerk tries to port to alpha-unicosmk. */ - if (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31) - return builtin_type (gdbarch)->builtin_double; - - return builtin_type (gdbarch)->builtin_int64; + || strlen (alpha_register_names[regno]) == 0); } /* Is REGNUM a member of REGGROUP? */ @@ -1715,11 +1696,39 @@ alpha_software_single_step (struct regcache *regcache) static struct gdbarch * alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { + tdesc_arch_data_up tdesc_data; + const struct target_desc *tdesc = info.target_desc; + /* Find a candidate among extant architectures. */ arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return arches->gdbarch; + if (tdesc == nullptr) + tdesc = tdesc_alpha; + + /* Validate target description. */ + if (tdesc_has_registers (tdesc)) + { + const struct tdesc_feature *feature; + bool valid_p; + + feature = tdesc_find_feature (tdesc, "org.gnu.gdb.alpha.core"); + if (feature == nullptr) + return nullptr; + + tdesc_data = tdesc_data_alloc (); + valid_p = true; + for (int i = 0; i < ALPHA_NUM_REGS; ++i) + valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i, + alpha_register_names[i]); + + if (!valid_p) + return nullptr; + } + + gdb_assert (tdesc_data != nullptr); + gdbarch *gdbarch = gdbarch_alloc (&info, gdbarch_tdep_up (new alpha_gdbarch_tdep)); alpha_gdbarch_tdep *tdep = gdbarch_tdep<alpha_gdbarch_tdep> (gdbarch); @@ -1756,8 +1765,7 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_pc_regnum (gdbarch, ALPHA_PC_REGNUM); set_gdbarch_fp0_regnum (gdbarch, ALPHA_FP0_REGNUM); - set_gdbarch_register_name (gdbarch, alpha_register_name); - set_gdbarch_register_type (gdbarch, alpha_register_type); + tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data)); set_gdbarch_cannot_fetch_register (gdbarch, alpha_cannot_fetch_register); set_gdbarch_cannot_store_register (gdbarch, alpha_cannot_store_register); @@ -1820,6 +1828,7 @@ INIT_GDB_FILE (alpha_tdep) gdbarch_register (bfd_arch_alpha, alpha_gdbarch_init, NULL); + initialize_tdesc_alpha (); /* Let the user set the fence post for heuristic_proc_start. */ /* We really would like to have both "0" and "unlimited" work, but diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index b6d626b..35b770f 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -49237,6 +49237,7 @@ registers using the capitalization used in the description. @menu * AArch64 Features:: +* Alpha Features:: * ARC Features:: * ARM Features:: * i386 Features:: @@ -49543,6 +49544,47 @@ of bytes. Extra registers are allowed in this feature, but they will not affect @value{GDBN}. +@node Alpha Features +@subsection Alpha Features +@cindex target descriptions, Alpha Features + +The @samp{org.gnu.gdb.alpha.core} feature is required for Alpha targets. It +must contain the following 64-bit registers; note that @value{GDBN} uses the +software names for Alpha registers: + +@itemize @minus +@item +@samp{v0}: function return value +@item +@samp{t0} through @samp{t12}: temporary registers +@item +@samp{s0} through @samp{s5}: saved registers +@item +@samp{fp}: frame pointer +@item +@samp{a0} through @samp{a5}: argument registers +@item +@samp{ra}: return address +@item +@samp{at}: assembler temporary register +@item +@samp{gp}: global pointer +@item +@samp{sp}: stack pointer +@item +@samp{zero}: always zero +@item +@samp{f0} through @samp{f30}: floating-point registers +@item +@samp{fpcr}: floating-point control register +@item +@samp{pc}: program counter +@item +@samp{}: an anonymous register for historical purpose +@item +@samp{unique}: PALcode memory slot +@end itemize + @node ARC Features @subsection ARC Features @cindex target descriptions, ARC Features diff --git a/gdb/features/Makefile b/gdb/features/Makefile index 7a8c799..750508a 100644 --- a/gdb/features/Makefile +++ b/gdb/features/Makefile @@ -100,6 +100,7 @@ OUTPUTS = $(patsubst %,$(outdir)/%.dat,$(WHICH)) # --enable-targets=all GDB. You can override this by passing XMLTOC # to make on the command line. XMLTOC = \ + alpha.xml \ microblaze-with-stack-protect.xml \ microblaze.xml \ mips-dsp-linux.xml \ diff --git a/gdb/features/alpha-core.xml b/gdb/features/alpha-core.xml new file mode 100644 index 0000000..c9e12f4 --- /dev/null +++ b/gdb/features/alpha-core.xml @@ -0,0 +1,136 @@ +<?xml version="1.0"?> +<!-- Copyright (C) 2025 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. --> + +<!DOCTYPE feature SYSTEM "gdb-target.dtd"> +<feature name="org.gnu.gdb.alpha.core"> + <!-- IEEE rounding mode values --> + <enum id="dyn_rm_enum" size="8"> + <!-- Chopped rounding mode --> + <evalue name="chop" value="0"/> + <!-- Minus infinity --> + <evalue name="-inf" value="1"/> + <!-- Normal rounding --> + <evalue name="norm" value="2"/> + <!-- Plus infinity --> + <evalue name="+inf" value="3"/> + </enum> + + <!-- Floating-Point Control Register Flags --> + <flags id="fpcr_flags" size="8"> + <!-- Denormal Operand Exception Disable --> + <field name="DNOD" start="47" end="47"/> + <!-- Denormal Operands to Zero --> + <field name="DNZ" start="48" end="48"/> + <!-- Invalid Operation Disable --> + <field name="INVD" start="49" end="49"/> + <!-- Division by Zero Disable --> + <field name="DZED" start="50" end="50"/> + <!-- Overflow Disable --> + <field name="OVFD" start="51" end="51"/> + <!-- Invalid Operation --> + <field name="INV" start="52" end="52"/> + <!-- Division by Zero --> + <field name="DZE" start="53" end="53"/> + <!-- Overflow --> + <field name="OVF" start="54" end="54"/> + <!-- Underflow --> + <field name="UNF" start="55" end="55"/> + <!-- Inexact Result --> + <field name="INE" start="56" end="56"/> + <!-- Integer Overflow --> + <field name="IOV" start="57" end="57"/> + <!-- Dynamic Rounding Mode --> + <field name="DYN_RM" start="58" end="59" type="dyn_rm_enum"/> + <!-- Underflow to Zero --> + <field name="UNDZ" start="60" end="60"/> + <!-- Underflow Disable --> + <field name="UNFD" start="61" end="61"/> + <!-- Inexact Disable --> + <field name="INED" start="62" end="62"/> + <!-- Summary Bit --> + <field name="SUM" start="63" end="63"/> + </flags> + + <!-- Integer Registers --> + <reg name="v0" bitsize="64" type="int64"/> + <reg name="t0" bitsize="64" type="int64"/> + <reg name="t1" bitsize="64" type="int64"/> + <reg name="t2" bitsize="64" type="int64"/> + <reg name="t3" bitsize="64" type="int64"/> + <reg name="t4" bitsize="64" type="int64"/> + <reg name="t5" bitsize="64" type="int64"/> + <reg name="t6" bitsize="64" type="int64"/> + <reg name="t7" bitsize="64" type="int64"/> + <reg name="s0" bitsize="64" type="int64"/> + <reg name="s1" bitsize="64" type="int64"/> + <reg name="s2" bitsize="64" type="int64"/> + <reg name="s3" bitsize="64" type="int64"/> + <reg name="s4" bitsize="64" type="int64"/> + <reg name="s5" bitsize="64" type="int64"/> + <reg name="fp" bitsize="64" type="int64"/> + <reg name="a0" bitsize="64" type="int64"/> + <reg name="a1" bitsize="64" type="int64"/> + <reg name="a2" bitsize="64" type="int64"/> + <reg name="a3" bitsize="64" type="int64"/> + <reg name="a4" bitsize="64" type="int64"/> + <reg name="a5" bitsize="64" type="int64"/> + <reg name="t8" bitsize="64" type="int64"/> + <reg name="t9" bitsize="64" type="int64"/> + <reg name="t10" bitsize="64" type="int64"/> + <reg name="t11" bitsize="64" type="int64"/> + <reg name="ra" bitsize="64" type="int64"/> + <reg name="t12" bitsize="64" type="int64"/> + <reg name="at" bitsize="64" type="int64"/> + <reg name="gp" bitsize="64" type="data_ptr"/> + <reg name="sp" bitsize="64" type="data_ptr"/> + <reg name="zero" bitsize="64" type="int64" save-restore="no"/> + + <!-- Floating-Point Registers --> + <reg name="f0" bitsize="64" type="float" group="float"/> + <reg name="f1" bitsize="64" type="float" group="float"/> + <reg name="f2" bitsize="64" type="float" group="float"/> + <reg name="f3" bitsize="64" type="float" group="float"/> + <reg name="f4" bitsize="64" type="float" group="float"/> + <reg name="f5" bitsize="64" type="float" group="float"/> + <reg name="f6" bitsize="64" type="float" group="float"/> + <reg name="f7" bitsize="64" type="float" group="float"/> + <reg name="f8" bitsize="64" type="float" group="float"/> + <reg name="f9" bitsize="64" type="float" group="float"/> + <reg name="f10" bitsize="64" type="float" group="float"/> + <reg name="f11" bitsize="64" type="float" group="float"/> + <reg name="f12" bitsize="64" type="float" group="float"/> + <reg name="f13" bitsize="64" type="float" group="float"/> + <reg name="f14" bitsize="64" type="float" group="float"/> + <reg name="f15" bitsize="64" type="float" group="float"/> + <reg name="f16" bitsize="64" type="float" group="float"/> + <reg name="f17" bitsize="64" type="float" group="float"/> + <reg name="f18" bitsize="64" type="float" group="float"/> + <reg name="f19" bitsize="64" type="float" group="float"/> + <reg name="f20" bitsize="64" type="float" group="float"/> + <reg name="f21" bitsize="64" type="float" group="float"/> + <reg name="f22" bitsize="64" type="float" group="float"/> + <reg name="f23" bitsize="64" type="float" group="float"/> + <reg name="f24" bitsize="64" type="float" group="float"/> + <reg name="f25" bitsize="64" type="float" group="float"/> + <reg name="f26" bitsize="64" type="float" group="float"/> + <reg name="f27" bitsize="64" type="float" group="float"/> + <reg name="f28" bitsize="64" type="float" group="float"/> + <reg name="f29" bitsize="64" type="float" group="float"/> + <reg name="f30" bitsize="64" type="float" group="float"/> + + <!-- Floating-Point Control Register --> + <reg name="fpcr" bitsize="64" type="fpcr_flags" group="float"/> + + <!-- Program Counter --> + <reg name="pc" bitsize="64" type="code_ptr"/> + + <!-- Reserved Index for Former Virtual Register --> + <reg name="" bitsize="64" type="int64" save-restore="no"/> + + <!-- PALcode Memory Slot --> + <reg name="unique" bitsize="64" type="int64" group="system"/> +</feature> diff --git a/gdb/features/alpha.c b/gdb/features/alpha.c new file mode 100644 index 0000000..35f12fc --- /dev/null +++ b/gdb/features/alpha.c @@ -0,0 +1,111 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: alpha.xml */ + +#include "osabi.h" +#include "target-descriptions.h" + +const struct target_desc *tdesc_alpha; +static void +initialize_tdesc_alpha (void) +{ + target_desc_up result = allocate_target_description (); + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result.get (), "org.gnu.gdb.alpha.core"); + tdesc_type_with_fields *type_with_fields; + type_with_fields = tdesc_create_enum (feature, "dyn_rm_enum", 8); + tdesc_add_enum_value (type_with_fields, 0, "chop"); + tdesc_add_enum_value (type_with_fields, 1, "-inf"); + tdesc_add_enum_value (type_with_fields, 2, "norm"); + tdesc_add_enum_value (type_with_fields, 3, "+inf"); + + type_with_fields = tdesc_create_flags (feature, "fpcr_flags", 8); + tdesc_add_flag (type_with_fields, 47, "DNOD"); + tdesc_add_flag (type_with_fields, 48, "DNZ"); + tdesc_add_flag (type_with_fields, 49, "INVD"); + tdesc_add_flag (type_with_fields, 50, "DZED"); + tdesc_add_flag (type_with_fields, 51, "OVFD"); + tdesc_add_flag (type_with_fields, 52, "INV"); + tdesc_add_flag (type_with_fields, 53, "DZE"); + tdesc_add_flag (type_with_fields, 54, "OVF"); + tdesc_add_flag (type_with_fields, 55, "UNF"); + tdesc_add_flag (type_with_fields, 56, "INE"); + tdesc_add_flag (type_with_fields, 57, "IOV"); + tdesc_type *field_type; + field_type = tdesc_named_type (feature, "dyn_rm_enum"); + tdesc_add_typed_bitfield (type_with_fields, "DYN_RM", 58, 59, field_type); + tdesc_add_flag (type_with_fields, 60, "UNDZ"); + tdesc_add_flag (type_with_fields, 61, "UNFD"); + tdesc_add_flag (type_with_fields, 62, "INED"); + tdesc_add_flag (type_with_fields, 63, "SUM"); + + tdesc_create_reg (feature, "v0", 0, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "t0", 1, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "t1", 2, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "t2", 3, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "t3", 4, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "t4", 5, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "t5", 6, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "t6", 7, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "t7", 8, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "s0", 9, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "s1", 10, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "s2", 11, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "s3", 12, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "s4", 13, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "s5", 14, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "fp", 15, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "a0", 16, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "a1", 17, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "a2", 18, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "a3", 19, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "a4", 20, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "a5", 21, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "t8", 22, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "t9", 23, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "t10", 24, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "t11", 25, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "ra", 26, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "t12", 27, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "at", 28, 1, NULL, 64, "int64"); + tdesc_create_reg (feature, "gp", 29, 1, NULL, 64, "data_ptr"); + tdesc_create_reg (feature, "sp", 30, 1, NULL, 64, "data_ptr"); + tdesc_create_reg (feature, "zero", 31, 0, NULL, 64, "int64"); + tdesc_create_reg (feature, "f0", 32, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f1", 33, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f2", 34, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f3", 35, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f4", 36, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f5", 37, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f6", 38, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f7", 39, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f8", 40, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f9", 41, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f10", 42, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f11", 43, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f12", 44, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f13", 45, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f14", 46, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f15", 47, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f16", 48, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f17", 49, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f18", 50, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f19", 51, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f20", 52, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f21", 53, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f22", 54, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f23", 55, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f24", 56, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f25", 57, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f26", 58, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f27", 59, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f28", 60, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f29", 61, 1, "float", 64, "float"); + tdesc_create_reg (feature, "f30", 62, 1, "float", 64, "float"); + tdesc_create_reg (feature, "fpcr", 63, 1, "float", 64, "fpcr_flags"); + tdesc_create_reg (feature, "pc", 64, 1, NULL, 64, "code_ptr"); + tdesc_create_reg (feature, "", 65, 0, NULL, 64, "int64"); + tdesc_create_reg (feature, "unique", 66, 1, "system", 64, "int64"); + + tdesc_alpha = result.release (); +} diff --git a/gdb/features/alpha.xml b/gdb/features/alpha.xml new file mode 100644 index 0000000..3ae0ab8 --- /dev/null +++ b/gdb/features/alpha.xml @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<!-- Copyright (C) 2025 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. --> + +<!DOCTYPE feature SYSTEM "gdb-target.dtd"> +<target version="1.0"> + <xi:include href="alpha-core.xml"/> +</target> diff --git a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp index 08d73d8..b11efa7 100644 --- a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp +++ b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp @@ -19,6 +19,7 @@ # instructions. require is_x86_64_m64_target have_avx +require support_displaced_stepping standard_testfile .S diff --git a/gdb/testsuite/gdb.tui/esc-match.exp b/gdb/testsuite/gdb.tui/esc-match.exp new file mode 100644 index 0000000..db78ebe --- /dev/null +++ b/gdb/testsuite/gdb.tui/esc-match.exp @@ -0,0 +1,48 @@ +# Copyright 2025 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Test that the ANSI escape sequence matcher works +# character-by-character. + +load_lib gdb-python.exp +require allow_python_tests allow_tui_tests + +tuiterm_env + +Term::clean_restart 24 80 + +set remote_python_file [gdb_remote_download host \ + ${srcdir}/${subdir}/esc-match.py] +gdb_test_no_output "source ${remote_python_file}" \ + "source esc-match.py" + +if {![Term::enter_tui]} { + unsupported "TUI not supported" + return +} + +Term::command "python print_it()" + +Term::dump_screen + +set text [Term::get_all_lines] +# We should not see the control sequence here. +gdb_assert {![regexp -- "\\\[35;1mOUTPUT\\\[m" $text]} \ + "output visible without control sequences" + +# Also check the styling. +set text [Term::get_region 0 1 78 23 "\n" true] +gdb_assert {[regexp -- "<fg:magenta>.*OUTPUT" $text]} \ + "output is magenta" diff --git a/gdb/testsuite/gdb.tui/esc-match.py b/gdb/testsuite/gdb.tui/esc-match.py new file mode 100644 index 0000000..7816002 --- /dev/null +++ b/gdb/testsuite/gdb.tui/esc-match.py @@ -0,0 +1,26 @@ +# Copyright (C) 2025 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import sys + +# Some text to print that includes styling. +OUT = "\033[35;1mOUTPUT\033[m" + + +def print_it(): + # Print to stderr avoids any buffering, showing the bug. + for c in OUT: + print(c, end="", file=sys.stderr) + print(file=sys.stderr) diff --git a/gdb/tui/tui-file.c b/gdb/tui/tui-file.c index 39aee9f..df6f503 100644 --- a/gdb/tui/tui-file.c +++ b/gdb/tui/tui-file.c @@ -21,7 +21,7 @@ #include "tui/tui-command.h" void -tui_file::puts (const char *linebuffer) +tui_file::do_puts (const char *linebuffer) { tui_puts (linebuffer); if (!m_buffered) @@ -29,7 +29,7 @@ tui_file::puts (const char *linebuffer) } void -tui_file::write (const char *buf, long length_buf) +tui_file::do_write (const char *buf, long length_buf) { tui_write (buf, length_buf); if (!m_buffered) @@ -41,5 +41,5 @@ tui_file::flush () { if (m_buffered) tui_cmd_win ()->refresh_window (); - stdio_file::flush (); + escape_buffering_file::flush (); } diff --git a/gdb/tui/tui-file.h b/gdb/tui/tui-file.h index dbd6fa9..b6dc058 100644 --- a/gdb/tui/tui-file.h +++ b/gdb/tui/tui-file.h @@ -23,18 +23,21 @@ /* A STDIO-like output stream for the TUI. */ -class tui_file : public stdio_file +class tui_file : public escape_buffering_file { public: tui_file (FILE *stream, bool buffered) - : stdio_file (stream), + : escape_buffering_file (stream), m_buffered (buffered) {} - void write (const char *buf, long length_buf) override; - void puts (const char *) override; void flush () override; +protected: + + void do_write (const char *buf, long length_buf) override; + void do_puts (const char *) override; + private: /* True if this stream is buffered. */ diff --git a/gdb/ui-file.c b/gdb/ui-file.c index f86b6b1..2e5c06f 100644 --- a/gdb/ui-file.c +++ b/gdb/ui-file.c @@ -408,7 +408,7 @@ tee_file::can_emit_style_escape () /* See ui-file.h. */ void -no_terminal_escape_file::write (const char *buf, long length_buf) +escape_buffering_file::write (const char *buf, long length_buf) { std::string copy (buf, length_buf); this->puts (copy.c_str ()); @@ -417,7 +417,60 @@ no_terminal_escape_file::write (const char *buf, long length_buf) /* See ui-file.h. */ void -no_terminal_escape_file::puts (const char *buf) +escape_buffering_file::puts (const char *buf) +{ + std::string local_buffer; + if (!m_buffer.empty ()) + { + gdb_assert (m_buffer[0] == '\033'); + m_buffer += buf; + /* If we need to keep buffering, we'll handle that below. */ + local_buffer = std::move (m_buffer); + buf = local_buffer.c_str (); + } + + while (*buf != '\0') + { + const char *esc = strchr (buf, '\033'); + if (esc == nullptr) + break; + + /* First, write out any prefix. */ + if (esc > buf) + { + do_write (buf, esc - buf); + buf = esc; + } + + int n_read = 0; + ansi_escape_result seen = examine_ansi_escape (esc, &n_read); + if (seen == ansi_escape_result::INCOMPLETE) + { + /* Start buffering. */ + m_buffer = buf; + return; + } + else if (seen == ansi_escape_result::NO_MATCH) + { + /* Just emit the ESC . */ + n_read = 1; + } + else + gdb_assert (seen == ansi_escape_result::MATCHED); + + do_write (esc, n_read); + buf += n_read; + } + + /* If there is any data remaining in BUF, we can flush it now. */ + if (*buf != '\0') + do_puts (buf); +} + +/* See ui-file.h. */ + +void +no_terminal_escape_file::do_puts (const char *buf) { while (*buf != '\0') { @@ -438,6 +491,13 @@ no_terminal_escape_file::puts (const char *buf) } void +no_terminal_escape_file::do_write (const char *buf, long len) +{ + std::string copy (buf, len); + do_puts (copy.c_str ()); +} + +void timestamped_file::write (const char *buf, long len) { if (debug_timestamp) diff --git a/gdb/ui-file.h b/gdb/ui-file.h index 3919e52..1219bde 100644 --- a/gdb/ui-file.h +++ b/gdb/ui-file.h @@ -362,24 +362,58 @@ private: ui_file *m_two; }; +/* A ui_file implementation that buffers terminal escape sequences. + Note that this does not buffer in general -- it only buffers when + an incomplete but potentially recognizable escape sequence is + started. */ + +class escape_buffering_file : public stdio_file +{ +public: + using stdio_file::stdio_file; + + /* Like the stdio_file methods but these forward to do_write and + do_puts, respectively. */ + void write (const char *buf, long length_buf) override final; + void puts (const char *linebuffer) override final; + + /* This class does not override 'flush'. While it does have an + internal buffer, it does not really make sense to flush the + buffer until an escape sequence has been fully processed. */ + +protected: + + /* Called to output some text. If the text contains a recognizable + terminal escape sequence, then it is guaranteed to be complete. + "Recognizable" here means that examine_ansi_escape did not return + INCOMPLETE. */ + virtual void do_puts (const char *buf) = 0; + virtual void do_write (const char *buf, long len) = 0; + +private: + + /* Buffer used only for incomplete escape sequences. */ + std::string m_buffer; +}; + /* A ui_file implementation that filters out terminal escape sequences. */ -class no_terminal_escape_file : public stdio_file +class no_terminal_escape_file : public escape_buffering_file { public: no_terminal_escape_file () { } - /* Like the stdio_file methods, but these filter out terminal escape - sequences. */ - void write (const char *buf, long length_buf) override; - void puts (const char *linebuffer) override; - void emit_style_escape (const ui_file_style &style) override { } + +protected: + + void do_puts (const char *linebuffer) override; + void do_write (const char *buf, long len) override; }; /* A base class for ui_file types that wrap another ui_file. */ diff --git a/gdb/ui-style.c b/gdb/ui-style.c index b8d73ab..c8f2e11 100644 --- a/gdb/ui-style.c +++ b/gdb/ui-style.c @@ -21,12 +21,14 @@ #include "gdbsupport/gdb_regex.h" /* A regular expression that is used for matching ANSI terminal escape - sequences. */ + sequences. Note that this will actually match any prefix of such a + sequence. This property is used so that other code can buffer + incomplete sequences as needed. */ static const char ansi_regex_text[] = - /* Introduction. */ - "^\033\\[" -#define DATA_SUBEXP 1 + /* Introduction. Only the escape character is truly required. */ + "^\033(\\[" +#define DATA_SUBEXP 2 /* Capture parameter and intermediate bytes. */ "(" /* Parameter bytes. */ @@ -36,12 +38,12 @@ static const char ansi_regex_text[] = /* End the first capture. */ ")" /* The final byte. */ -#define FINAL_SUBEXP 2 - "([\x40-\x7e])"; +#define FINAL_SUBEXP 3 + "([\x40-\x7e]))?"; /* The number of subexpressions to allocate space for, including the "0th" whole match subexpression. */ -#define NUM_SUBEXPRESSIONS 3 +#define NUM_SUBEXPRESSIONS 4 /* The compiled form of ansi_regex_text. */ @@ -371,6 +373,15 @@ ui_file_style::parse (const char *buf, size_t *n_read) *n_read = 0; return false; } + + /* If the final subexpression did not match, then that means there + was an incomplete sequence. These are ignored here. */ + if (subexps[FINAL_SUBEXP].rm_so == -1) + { + *n_read = 0; + return false; + } + /* Other failures mean the regexp is broken. */ gdb_assert (match == 0); /* The regexp is anchored. */ @@ -527,17 +538,25 @@ ui_file_style::parse (const char *buf, size_t *n_read) /* See ui-style.h. */ -bool -skip_ansi_escape (const char *buf, int *n_read) +ansi_escape_result +examine_ansi_escape (const char *buf, int *n_read) { + gdb_assert (*buf == '\033'); + regmatch_t subexps[NUM_SUBEXPRESSIONS]; int match = ansi_regex.exec (buf, ARRAY_SIZE (subexps), subexps, 0); - if (match == REG_NOMATCH || buf[subexps[FINAL_SUBEXP].rm_so] != 'm') - return false; + if (match == REG_NOMATCH) + return ansi_escape_result::NO_MATCH; + + if (subexps[FINAL_SUBEXP].rm_so == -1) + return ansi_escape_result::INCOMPLETE; + + if (buf[subexps[FINAL_SUBEXP].rm_so] != 'm') + return ansi_escape_result::NO_MATCH; *n_read = subexps[FINAL_SUBEXP].rm_eo; - return true; + return ansi_escape_result::MATCHED; } /* See ui-style.h. */ diff --git a/gdb/ui-style.h b/gdb/ui-style.h index 77a175d..f61152f 100644 --- a/gdb/ui-style.h +++ b/gdb/ui-style.h @@ -354,11 +354,35 @@ private: bool m_reverse = false; }; +/* Possible results for checking an ANSI escape sequence. */ +enum class ansi_escape_result +{ + /* The escape sequence is definitely not recognizable. */ + NO_MATCH, + + /* The escape sequence might be recognizable with more input. */ + INCOMPLETE, + + /* The escape sequence is definitely recognizable. */ + MATCHED, +}; + +/* Examine an ANSI escape sequence in BUF. BUF must begin with an ESC + character. Return a value indicating whether the sequence was + recognizable. If MATCHED is returned, then N_READ is updated to + reflect the number of chars read from BUF. */ + +extern ansi_escape_result examine_ansi_escape (const char *buf, int *n_read); + /* Skip an ANSI escape sequence in BUF. BUF must begin with an ESC character. Return true if an escape sequence was successfully skipped; false otherwise. If an escape sequence was skipped, N_READ is updated to reflect the number of chars read from BUF. */ -extern bool skip_ansi_escape (const char *buf, int *n_read); +static inline bool +skip_ansi_escape (const char *buf, int *n_read) +{ + return examine_ansi_escape (buf, n_read) == ansi_escape_result::MATCHED; +} #endif /* GDB_UI_STYLE_H */ diff --git a/gdb/utils.c b/gdb/utils.c index 3114a4b..10d3d51 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -1809,7 +1809,7 @@ void pager_file::write (const char *buf, long length_buf) { /* We have to make a string here because the pager uses - skip_ansi_escape, which requires NUL-termination. */ + examine_ansi_escape, which requires NUL-termination. */ std::string str (buf, length_buf); this->puts (str.c_str ()); } diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c index 25dd44d..5820830 100644 --- a/libctf/ctf-create.c +++ b/libctf/ctf-create.c @@ -788,7 +788,7 @@ ctf_add_struct_sized (ctf_dict_t *fp, uint32_t flag, const char *name, size_t initial_vlen = sizeof (ctf_lmember_t) * INITIAL_VLEN; /* Promote root-visible forwards to structs. */ - if (name != NULL) + if (name != NULL && flag == CTF_ADD_ROOT) type = ctf_lookup_by_rawname (fp, CTF_K_STRUCT, name); /* Prohibit promotion if this type was ctf_open()ed. */ @@ -832,7 +832,7 @@ ctf_add_union_sized (ctf_dict_t *fp, uint32_t flag, const char *name, size_t initial_vlen = sizeof (ctf_lmember_t) * INITIAL_VLEN; /* Promote root-visible forwards to unions. */ - if (name != NULL) + if (name != NULL && flag == CTF_ADD_ROOT) type = ctf_lookup_by_rawname (fp, CTF_K_UNION, name); /* Prohibit promotion if this type was ctf_open()ed. */ @@ -875,7 +875,7 @@ ctf_add_enum (ctf_dict_t *fp, uint32_t flag, const char *name) size_t initial_vlen = sizeof (ctf_enum_t) * INITIAL_VLEN; /* Promote root-visible forwards to enums. */ - if (name != NULL) + if (name != NULL && flag == CTF_ADD_ROOT) type = ctf_lookup_by_rawname (fp, CTF_K_ENUM, name); /* Prohibit promotion if this type was ctf_open()ed. */ @@ -1073,7 +1073,7 @@ ctf_add_enumerator (ctf_dict_t *fp, ctf_id_t enid, const char *name, /* Enumeration constant names are only added, and only checked for duplicates, if the enum they are part of is a root-visible type. */ - if (root == CTF_ADD_ROOT && ctf_dynhash_lookup (fp->ctf_names, name)) + if (root && ctf_dynhash_lookup (fp->ctf_names, name)) { if (fp->ctf_flags & LCTF_STRICT_NO_DUP_ENUMERATORS) return (ctf_set_errno (ofp, ECTF_DUPLICATE)); diff --git a/libctf/doc/ctf-spec.texi b/libctf/doc/ctf-spec.texi index 5b2b881..b9f60d3 100644 --- a/libctf/doc/ctf-spec.texi +++ b/libctf/doc/ctf-spec.texi @@ -829,7 +829,7 @@ of kind @code{CTF_K_UNKNOWN}. @item 4 @tab @code{CTF_K_ARRAY} -@tab An array. @xref{Arrays}. +@tab An array or SIMD vector. @xref{Arrays}. @item 5 @tab @code{CTF_K_FUNCTION} @@ -1064,7 +1064,7 @@ unused and will become used in future. @tindex CTF_FP_LDCPLX @item 6 @tab @code{CTF_FP_LDOUBLE} -@tab This is a @code{long double}. +@tab This is a @code{long double}, or quad-precision IEEE 754-2008 @code{__float128}. @tindex CTF_FP_LDOUBLE @item 7 @tab @code{CTF_FP_INTRVL} @@ -1232,6 +1232,13 @@ Arrays are encoded as types of kind @code{CTF_K_ARRAY} in a @code{ctf_stype_t}. Both size and kind for arrays are zero. The variable-length data is a @code{ctf_array_t}: @code{vlen} in the info word should be disregarded and is always zero. +@c In CTFv4 and BTF, the @code{kind_flag} member of @{ctf_array_t} is not set. + +SIMD vectors are also encoded as types of kind @code{CTF_K_ARRAY} in a +@code{ctf_stype_t}. Both size and kind for arrays are zero. The +variable-length data is a @code{ctf_array_t}: @code{vlen} in the info word +should be disregarded and is always zero. +@c In CTFv4 and BTF, the @code{kind_flag} member of @{ctf_array_t} is set. @verbatim typedef struct ctf_array diff --git a/libctf/testsuite/libctf-writable/ctf-nonroot-addition.c b/libctf/testsuite/libctf-writable/ctf-nonroot-addition.c new file mode 100644 index 0000000..94ce05c --- /dev/null +++ b/libctf/testsuite/libctf-writable/ctf-nonroot-addition.c @@ -0,0 +1,38 @@ +/* Make sure adding a non-root-visible type after adding a root-visible forward + adds a new type rather than promoting and returning the existing one. */ + +#include <ctf-api.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int +main (int argc, char *argv[]) +{ + ctf_dict_t *fp; + ctf_id_t root, nonroot; + int err; + + if ((fp = ctf_create (&err)) == NULL) + { + fprintf (stderr, "Cannot create: %s\n", ctf_errmsg (err)); + return 1; + } + + if ((root = ctf_add_forward (fp, CTF_ADD_ROOT, "foo", CTF_K_ENUM)) == CTF_ERR) + goto add_err; + + if ((nonroot = ctf_add_enum (fp, CTF_ADD_NONROOT, "foo")) == CTF_ERR) + goto add_err; + + if (nonroot == root) + fprintf (stderr, "Non-root addition should not promote root-visible forwards\n"); + else + printf ("All done.\n"); + + ctf_dict_close (fp); + return 0; + + add_err: + fprintf (stderr, "Cannot add: %s\n", ctf_errmsg (ctf_errno (fp))); +} diff --git a/libctf/testsuite/libctf-writable/ctf-nonroot-addition.lk b/libctf/testsuite/libctf-writable/ctf-nonroot-addition.lk new file mode 100644 index 0000000..b944f73 --- /dev/null +++ b/libctf/testsuite/libctf-writable/ctf-nonroot-addition.lk @@ -0,0 +1 @@ +All done. |